Skip to content
  • Home
  • 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

Community Forum

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

[Vorlage] Denon HEOS Script

Geplant Angeheftet Gesperrt Verschoben JavaScript
javascripttemplate
357 Beiträge 48 Kommentatoren 76.3k 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.
  • L Lacoste9

    wo holt ihr euch denn das Material Design?

    Meister MopperM Abwesend
    Meister MopperM Abwesend
    Meister Mopper
    schrieb am zuletzt editiert von
    #75

    Wenn ich das Skript stoppe, wird folgende Fehlermeldung geworfen:

    dd72b2c5-438c-411c-9edb-2888429a4092-grafik.png

    Weiß jemand, wie das abgestellt werden kann?

    Proxmox und HA

    1 Antwort Letzte Antwort
    0
    • B Offline
      B Offline
      BobBruni
      schrieb am zuletzt editiert von
      #76

      Hallo zusammen,

      ich bastel mir auch gerade eine Visualisierung für meine Denon. Das Abspielen / Auswahl der Presets (play_preset&preset=1|2|..|n ) geht wunderbar.
      Kann mir jemand sagen, ob es auch möglich ist, Spotify-Playlists aufzurufen?

      Vielen Dank!

      1 Antwort Letzte Antwort
      0
      • L Lacoste9

        wo holt ihr euch denn das Material Design?

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

        @Lacoste9 MD CSS v2, z.B. von hier: https://github.com/Uhula/ioBroker-Material-Design-Style

        @Meister-Mopper Den Fehler ignorieren, ist ein überflüssiger Aufruf im destroy, ist in meiner neuesten Version schon behoben. Ich versuche demnächst mal aus dem Script einen Adapter zu machen.

        @BobBruni Mit Spotify habe ich es noch nicht versucht, denke aber nicht, dass es gehen wird, da Spotify nicht native von HEOS unterstützt wird, sondern selbst deren Client "nachlädt" (siehe die HEOS App, die macht dad auch). Ich werde mal im API nachlesen, demnächst.

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

        C 1 Antwort Letzte Antwort
        0
        • XsevX Offline
          XsevX Offline
          Xsev
          schrieb am zuletzt editiert von Xsev
          #78

          Ich hab meistens nach einen Java-Script Adapter Update folgendes Problem. Es scheint als ob die Anmeldung bei Heos nicht mehr klappt. Ich bekomme es immer wieder zum laufen wenn ich alles neustarte inkl. neue Internetverbindung, Serverreboot etc. gibt es dafür eine andere Lösung? Adpater bzw. Script neustart reicht nicht aus.

          08:47:57.041	info	javascript.0 (14448) Start javascript script.js.HIFI.Heos
          08:47:57.047	info	javascript.0 (14448) script.js.HIFI.Heos: [Heos] connecting to HEOS ...
          08:47:57.084	info	javascript.0 (14448) script.js.HIFI.Heos: registered 1 subscription and 0 schedules
          08:47:57.102	info	javascript.0 (14448) script.js.HIFI.Heos: [Heos] connecting to 192.168.13.100 ...
          08:47:57.103	error	javascript.0 (14448) script.js.HIFI.Heos: [Heos] Error: connect ECONNREFUSED 192.168.13.100:1255
          08:47:57.104	info	javascript.0 (14448) script.js.HIFI.Heos: [Heos] disconnecting from HEOS ...
          08:47:57.105	error	javascript.0 (14448) script.js.HIFI.Heos: TypeError: this.nodessdp_client.destroy is not a function
          08:47:57.105	error	javascript.0 (14448) at Heos.disconnect (script.js.HIFI.Heos:543:30)
          08:47:57.105	error	javascript.0 (14448) at Socket.net_client.on (script.js.HIFI.Heos:629:18)
          
          javascript.0	2020-02-15 09:05:02.731	error	(14448) at process._tickCallback (internal/process/next_tick.js:63:19)
          javascript.0	2020-02-15 09:05:02.731	error	(14448) at emitErrorAndCloseNT (internal/streams/destroy.js:59:3)
          javascript.0	2020-02-15 09:05:02.731	error	(14448) at emitErrorNT (internal/streams/destroy.js:91:8)
          javascript.0	2020-02-15 09:05:02.731	error	(14448) at Socket.emit (events.js:198:13)
          javascript.0	2020-02-15 09:05:02.731	error	(14448) at Socket.net_client.on (script.js.HIFI.Heos:629:18)
          javascript.0	2020-02-15 09:05:02.731	error	(14448) at Heos.disconnect (script.js.HIFI.Heos:543:30)
          javascript.0	2020-02-15 09:05:02.731	error	(14448) script.js.HIFI.Heos: TypeError: this.nodessdp_client.destroy is not a function
          javascript.0	2020-02-15 09:05:02.730	info	(14448) script.js.HIFI.Heos: [Heos] disconnecting from HEOS ...
          javascript.0	2020-02-15 09:05:02.730	error	(14448) script.js.HIFI.Heos: [Heos] Error: connect ECONNREFUSED 192.168.13.100:1255
          javascript.0	2020-02-15 09:05:02.729	info	(14448) script.js.HIFI.Heos: [Heos] connecting to 192.168.13.100 ...
          javascript.0	2020-02-15 09:05:02.728	info	(14448) script.js.HIFI.Heos: registered 1 subscription and 0 schedules
          javascript.0	2020-02-15 09:05:02.727	info	(14448) script.js.HIFI.Heos: [Heos] connecting to HEOS ...
          javascript.0	2020-02-15 09:05:02.725	info	(14448) Start javascript script.js.HIFI.Heos
          
          1 Antwort Letzte Antwort
          0
          • J Offline
            J Offline
            jwedenig
            Most Active
            schrieb am zuletzt editiert von
            #79

            Hi!
            Ich habe seit Wochen das Heos Skript laufen, ohne Probleme!
            Seit gestern ist es so, wenn das Heos Skript aktiv ist, dass sich mein Denon Verstärker permanent ein und ausschaltet, immer wieder, ein-aus,ein-aus.
            Erst wenn ich das Heos Skript stoppe, dann gehts wieder.
            Hat irgendwer eine ähnliche Erfahrung?
            Liebe Grüße
            Jürgen

            D 1 Antwort Letzte Antwort
            0
            • J jwedenig

              Hi!
              Ich habe seit Wochen das Heos Skript laufen, ohne Probleme!
              Seit gestern ist es so, wenn das Heos Skript aktiv ist, dass sich mein Denon Verstärker permanent ein und ausschaltet, immer wieder, ein-aus,ein-aus.
              Erst wenn ich das Heos Skript stoppe, dann gehts wieder.
              Hat irgendwer eine ähnliche Erfahrung?
              Liebe Grüße
              Jürgen

              D Offline
              D Offline
              Desastro
              schrieb am zuletzt editiert von
              #80

              @jwedenig

              Hi

              Generiert das Script in dem Zusammenhang irgendwelche auffälligen Logeinträge?
              Wenn nicht, dann könnte es am Denon selbst liegen.
              Dann würd ich mal ein Netzwerkreset am Denon versuchen. Wie das geht, steht in der Anleitung.
              Danach musst du allerdings die Netzwerkeinstellungen neu einstellen.

              Gruß Thomas

              J 1 Antwort Letzte Antwort
              0
              • D Desastro

                @jwedenig

                Hi

                Generiert das Script in dem Zusammenhang irgendwelche auffälligen Logeinträge?
                Wenn nicht, dann könnte es am Denon selbst liegen.
                Dann würd ich mal ein Netzwerkreset am Denon versuchen. Wie das geht, steht in der Anleitung.
                Danach musst du allerdings die Netzwerkeinstellungen neu einstellen.

                Gruß Thomas

                J Offline
                J Offline
                jwedenig
                Most Active
                schrieb am zuletzt editiert von
                #81

                @Desastro
                Hi!
                Ja, danke Dir!
                Habe alles wieder resettet, jetzt gehts wieder.
                Habe aber das Problem immer wieder, muss mal forschen woran das liegt!
                Liebe Grüße
                Jürgen

                D 1 Antwort Letzte Antwort
                0
                • J jwedenig

                  @Desastro
                  Hi!
                  Ja, danke Dir!
                  Habe alles wieder resettet, jetzt gehts wieder.
                  Habe aber das Problem immer wieder, muss mal forschen woran das liegt!
                  Liebe Grüße
                  Jürgen

                  D Offline
                  D Offline
                  Desastro
                  schrieb am zuletzt editiert von
                  #82

                  @jwedenig

                  Hast du das Script in einer eigenen Javascript Instanz laufen, oder alles zusammen mit weiteren Scripts?
                  Wäre evtl. dann auch noch ein Test wert.

                  Gruß Thomas

                  J 2 Antworten Letzte Antwort
                  0
                  • D Desastro

                    @jwedenig

                    Hast du das Script in einer eigenen Javascript Instanz laufen, oder alles zusammen mit weiteren Scripts?
                    Wäre evtl. dann auch noch ein Test wert.

                    Gruß Thomas

                    J Offline
                    J Offline
                    jwedenig
                    Most Active
                    schrieb am zuletzt editiert von
                    #83

                    @Desastro
                    alles klar

                    1 Antwort Letzte Antwort
                    0
                    • D Desastro

                      @jwedenig

                      Hast du das Script in einer eigenen Javascript Instanz laufen, oder alles zusammen mit weiteren Scripts?
                      Wäre evtl. dann auch noch ein Test wert.

                      Gruß Thomas

                      J Offline
                      J Offline
                      jwedenig
                      Most Active
                      schrieb am zuletzt editiert von
                      #84

                      @Desastro
                      Hi!
                      Bin jetzt draufgekommen, dass wirklich der Javascript Adapter Schuld an diesem Problem ist, bei einem Reset hat es wieder funktioniert.
                      Du meinst eine 2te Instanz wäre eine Option?
                      Liebe Grüße
                      Jürgen

                      D 1 Antwort Letzte Antwort
                      0
                      • J jwedenig

                        @Desastro
                        Hi!
                        Bin jetzt draufgekommen, dass wirklich der Javascript Adapter Schuld an diesem Problem ist, bei einem Reset hat es wieder funktioniert.
                        Du meinst eine 2te Instanz wäre eine Option?
                        Liebe Grüße
                        Jürgen

                        D Offline
                        D Offline
                        Desastro
                        schrieb am zuletzt editiert von
                        #85

                        @jwedenig

                        Hi

                        Die 2. Instanz würde ich schon machen, hab ich auch so.
                        Kost ja quasi nix :grinning:

                        Gruß Thomas

                        J 1 Antwort Letzte Antwort
                        0
                        • D Desastro

                          @jwedenig

                          Hi

                          Die 2. Instanz würde ich schon machen, hab ich auch so.
                          Kost ja quasi nix :grinning:

                          Gruß Thomas

                          J Offline
                          J Offline
                          jwedenig
                          Most Active
                          schrieb am zuletzt editiert von
                          #86

                          @Desastro
                          Hi!
                          So, ich habe die 2. Instanz aktiviert.
                          Heute in der Früh hat GSD alles funktioniert bis auf eine Kleinigkeit:

                          Früher war es bei meinem Radiosender so, dass wenn Musik gespielt worden ist, dann habe ich das Cover und den Songtitel gesehen.
                          Jetzt sehe ich nur mehr das Logo des Radiosenders!
                          Sprich "Aktuelles Lied" und "Aktuelles Coverbild" werden in den Objekten nicht aktualisiert.
                          Hat wer eine Idee warum das so ist?

                          1 Antwort Letzte Antwort
                          0
                          • J Offline
                            J Offline
                            jwedenig
                            Most Active
                            schrieb am zuletzt editiert von
                            #87

                            das passiert, wenn ich die Objekte lösche und das Skript wieder neu starte, um die Objekte zu erzeugen

                            web.0	2020-02-28 09:28:07.539	info	(26785) ==>Connected system.user.admin from ::ffff:192.168.1.159
                            web.0	2020-02-28 09:28:05.988	info	(26785) ==>Connected system.user.admin from ::ffff:192.168.1.159
                            javascript.1	2020-02-28 09:26:58.908	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] signed in: success
                            javascript.1	2020-02-28 09:26:58.030	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] signed in: success
                            javascript.1	2020-02-28 09:26:58.021	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [HeosPlayer 192.168.1.177] starting HEOS player for IP 192.168.1.177
                            javascript.1	2020-02-28 09:26:58.013	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] connected to 192.168.1.177
                            javascript.1	2020-02-28 09:26:58.012	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] connected to HEOS
                            javascript.1	2020-02-28 09:26:58.010	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] connecting to 192.168.1.177 ...
                            javascript.1	2020-02-28 09:26:57.269	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: registered 1 subscription and 0 schedules
                            javascript.1	2020-02-28 09:26:57.267	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] connecting to HEOS ...
                            javascript.1	2020-02-28 09:26:57.263	info	(16326) Start javascript script.js.Weldscripts.Javascript.Heos_neu
                            javascript.1	2020-02-28 09:26:54.113	error	(16326) error in onStop callback: TypeError: this.nodessdp_client.destroy is not a function
                            javascript.1	2020-02-28 09:26:54.112	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] disconnecting from HEOS ...
                            javascript.1	2020-02-28 09:26:54.110	info	(16326) Stop script script.js.Weldscripts.Javascript.Heos_neu
                            javascript.1	2020-02-28 09:26:46.169	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] signed in: success
                            javascript.1	2020-02-28 09:26:45.882	warn	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] Command_not_recognized
                            javascript.1	2020-02-28 09:26:45.879	warn	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] Command_not_recognized
                            javascript.1	2020-02-28 09:26:45.496	warn	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] Command_not_recognized
                            javascript.1	2020-02-28 09:26:45.494	warn	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] Command_not_recognized
                            javascript.1	2020-02-28 09:26:45.476	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] command:
                            javascript.1	2020-02-28 09:26:45.474	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] command:
                            javascript.1	2020-02-28 09:26:45.415	warn	(16326) at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
                            javascript.1	2020-02-28 09:26:45.415	warn	(16326) at Socket.Readable.push (_stream_readable.js:224:10)
                            javascript.1	2020-02-28 09:26:45.415	warn	(16326) at readableAddChunk (_stream_readable.js:269:11)
                            javascript.1	2020-02-28 09:26:45.415	warn	(16326) at addChunk (_stream_readable.js:288:12)
                            javascript.1	2020-02-28 09:26:45.415	warn	(16326) at Socket.emit (events.js:198:13)
                            javascript.1	2020-02-28 09:26:45.415	warn	(16326) at Socket.net_client.on (script.js.Weldscripts.Javascript.Heos_neu:341:51)
                            javascript.1	2020-02-28 09:26:45.414	warn	(16326) at Heos.onData (script.js.Weldscripts.Javascript.Heos_neu:358:14)
                            javascript.1	2020-02-28 09:26:45.414	warn	(16326) at Heos.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:478:44)
                            javascript.1	2020-02-28 09:26:45.414	warn	(16326) at HeosPlayer.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:726:26)
                            javascript.1	2020-02-28 09:26:45.414	warn	(16326) at HeosPlayer.setState (script.js.Weldscripts.Javascript.Heos_neu:691:4)
                            javascript.1	2020-02-28 09:26:45.413	warn	(16326) at setState (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1425:20)
                            javascript.1	2020-02-28 09:26:45.412	warn	(16326) State "javascript.1.heos.192_168_1_177.duration_MMSS" not found
                            javascript.1	2020-02-28 09:26:45.412	warn	(16326) at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
                            javascript.1	2020-02-28 09:26:45.412	warn	(16326) at Socket.Readable.push (_stream_readable.js:224:10)
                            javascript.1	2020-02-28 09:26:45.412	warn	(16326) at readableAddChunk (_stream_readable.js:269:11)
                            javascript.1	2020-02-28 09:26:45.412	warn	(16326) at addChunk (_stream_readable.js:288:12)
                            javascript.1	2020-02-28 09:26:45.411	warn	(16326) at Socket.emit (events.js:198:13)
                            javascript.1	2020-02-28 09:26:45.411	warn	(16326) at Socket.net_client.on (script.js.Weldscripts.Javascript.Heos_neu:341:51)
                            javascript.1	2020-02-28 09:26:45.411	warn	(16326) at Heos.onData (script.js.Weldscripts.Javascript.Heos_neu:358:14)
                            javascript.1	2020-02-28 09:26:45.411	warn	(16326) at Heos.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:478:44)
                            javascript.1	2020-02-28 09:26:45.410	warn	(16326) at HeosPlayer.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:725:26)
                            javascript.1	2020-02-28 09:26:45.410	warn	(16326) at HeosPlayer.setState (script.js.Weldscripts.Javascript.Heos_neu:691:4)
                            javascript.1	2020-02-28 09:26:45.410	warn	(16326) at setState (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1425:20)
                            javascript.1	2020-02-28 09:26:45.409	warn	(16326) State "javascript.1.heos.192_168_1_177.duration" not found
                            javascript.1	2020-02-28 09:26:45.409	warn	(16326) at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
                            javascript.1	2020-02-28 09:26:45.409	warn	(16326) at Socket.Readable.push (_stream_readable.js:224:10)
                            javascript.1	2020-02-28 09:26:45.409	warn	(16326) at readableAddChunk (_stream_readable.js:269:11)
                            javascript.1	2020-02-28 09:26:45.408	warn	(16326) at addChunk (_stream_readable.js:288:12)
                            javascript.1	2020-02-28 09:26:45.408	warn	(16326) at Socket.emit (events.js:198:13)
                            javascript.1	2020-02-28 09:26:45.408	warn	(16326) at Socket.net_client.on (script.js.Weldscripts.Javascript.Heos_neu:341:51)
                            javascript.1	2020-02-28 09:26:45.408	warn	(16326) at Heos.onData (script.js.Weldscripts.Javascript.Heos_neu:358:14)
                            javascript.1	2020-02-28 09:26:45.408	warn	(16326) at Heos.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:478:44)
                            javascript.1	2020-02-28 09:26:45.407	warn	(16326) at HeosPlayer.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:724:26)
                            javascript.1	2020-02-28 09:26:45.407	warn	(16326) at HeosPlayer.setState (script.js.Weldscripts.Javascript.Heos_neu:691:4)
                            javascript.1	2020-02-28 09:26:45.407	warn	(16326) at setState (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1425:20)
                            javascript.1	2020-02-28 09:26:45.406	warn	(16326) State "javascript.1.heos.192_168_1_177.cur_pos_MMSS" not found
                            javascript.1	2020-02-28 09:26:45.406	warn	(16326) at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
                            javascript.1	2020-02-28 09:26:45.406	warn	(16326) at Socket.Readable.push (_stream_readable.js:224:10)
                            javascript.1	2020-02-28 09:26:45.405	warn	(16326) at readableAddChunk (_stream_readable.js:269:11)
                            javascript.1	2020-02-28 09:26:45.405	warn	(16326) at addChunk (_stream_readable.js:288:12)
                            javascript.1	2020-02-28 09:26:45.405	warn	(16326) at Socket.emit (events.js:198:13)
                            javascript.1	2020-02-28 09:26:45.405	warn	(16326) at Socket.net_client.on (script.js.Weldscripts.Javascript.Heos_neu:341:51)
                            javascript.1	2020-02-28 09:26:45.404	warn	(16326) at Heos.onData (script.js.Weldscripts.Javascript.Heos_neu:358:14)
                            javascript.1	2020-02-28 09:26:45.404	warn	(16326) at Heos.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:478:44)
                            javascript.1	2020-02-28 09:26:45.404	warn	(16326) at HeosPlayer.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:723:26)
                            javascript.1	2020-02-28 09:26:45.403	warn	(16326) at HeosPlayer.setState (script.js.Weldscripts.Javascript.Heos_neu:691:4)
                            javascript.1	2020-02-28 09:26:45.403	warn	(16326) at setState (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1425:20)
                            javascript.1	2020-02-28 09:26:45.402	warn	(16326) State "javascript.1.heos.192_168_1_177.cur_pos" not found
                            javascript.1	2020-02-28 09:26:45.401	warn	(16326) at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
                            javascript.1	2020-02-28 09:26:45.401	warn	(16326) at Socket.Readable.push (_stream_readable.js:224:10)
                            javascript.1	2020-02-28 09:26:45.400	warn	(16326) at readableAddChunk (_stream_readable.js:269:11)
                            javascript.1	2020-02-28 09:26:45.400	warn	(16326) at addChunk (_stream_readable.js:288:12)
                            javascript.1	2020-02-28 09:26:45.400	warn	(16326) at Socket.emit (events.js:198:13)
                            javascript.1	2020-02-28 09:26:45.399	warn	(16326) at Socket.net_client.on (script.js.Weldscripts.Javascript.Heos_neu:341:51)
                            javascript.1	2020-02-28 09:26:45.399	warn	(16326) at Heos.onData (script.js.Weldscripts.Javascript.Heos_neu:358:14)
                            javascript.1	2020-02-28 09:26:45.399	warn	(16326) at Heos.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:478:44)
                            javascript.1	2020-02-28 09:26:45.398	warn	(16326) at HeosPlayer.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:726:26)
                            javascript.1	2020-02-28 09:26:45.398	warn	(16326) at HeosPlayer.setState (script.js.Weldscripts.Javascript.Heos_neu:691:4)
                            javascript.1	2020-02-28 09:26:45.398	warn	(16326) at setState (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1425:20)
                            javascript.1	2020-02-28 09:26:45.397	warn	(16326) State "javascript.1.heos.192_168_1_177.duration_MMSS" not found
                            javascript.1	2020-02-28 09:26:45.397	warn	(16326) at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
                            javascript.1	2020-02-28 09:26:45.396	warn	(16326) at Socket.Readable.push (_stream_readable.js:224:10)
                            javascript.1	2020-02-28 09:26:45.396	warn	(16326) at readableAddChunk (_stream_readable.js:269:11)
                            javascript.1	2020-02-28 09:26:45.396	warn	(16326) at addChunk (_stream_readable.js:288:12)
                            javascript.1	2020-02-28 09:26:45.396	warn	(16326) at Socket.emit (events.js:198:13)
                            javascript.1	2020-02-28 09:26:45.395	warn	(16326) at Socket.net_client.on (script.js.Weldscripts.Javascript.Heos_neu:341:51)
                            javascript.1	2020-02-28 09:26:45.395	warn	(16326) at Heos.onData (script.js.Weldscripts.Javascript.Heos_neu:358:14)
                            javascript.1	2020-02-28 09:26:45.395	warn	(16326) at Heos.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:478:44)
                            javascript.1	2020-02-28 09:26:45.395	warn	(16326) at HeosPlayer.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:725:26)
                            javascript.1	2020-02-28 09:26:45.393	warn	(16326) at HeosPlayer.setState (script.js.Weldscripts.Javascript.Heos_neu:691:4)
                            javascript.1	2020-02-28 09:26:45.393	warn	(16326) at setState (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1425:20)
                            javascript.1	2020-02-28 09:26:45.391	warn	(16326) State "javascript.1.heos.192_168_1_177.duration" not found
                            javascript.1	2020-02-28 09:26:45.391	warn	(16326) at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
                            javascript.1	2020-02-28 09:26:45.391	warn	(16326) at Socket.Readable.push (_stream_readable.js:224:10)
                            javascript.1	2020-02-28 09:26:45.390	warn	(16326) at readableAddChunk (_stream_readable.js:269:11)
                            javascript.1	2020-02-28 09:26:45.390	warn	(16326) at addChunk (_stream_readable.js:288:12)
                            javascript.1	2020-02-28 09:26:45.390	warn	(16326) at Socket.emit (events.js:198:13)
                            javascript.1	2020-02-28 09:26:45.390	warn	(16326) at Socket.net_client.on (script.js.Weldscripts.Javascript.Heos_neu:341:51)
                            javascript.1	2020-02-28 09:26:45.390	warn	(16326) at Heos.onData (script.js.Weldscripts.Javascript.Heos_neu:358:14)
                            javascript.1	2020-02-28 09:26:45.389	warn	(16326) at Heos.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:478:44)
                            javascript.1	2020-02-28 09:26:45.389	warn	(16326) at HeosPlayer.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:724:26)
                            javascript.1	2020-02-28 09:26:45.389	warn	(16326) at HeosPlayer.setState (script.js.Weldscripts.Javascript.Heos_neu:691:4)
                            javascript.1	2020-02-28 09:26:45.388	warn	(16326) at setState (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1425:20)
                            javascript.1	2020-02-28 09:26:45.388	warn	(16326) State "javascript.1.heos.192_168_1_177.cur_pos_MMSS" not found
                            javascript.1	2020-02-28 09:26:45.385	warn	(16326) at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
                            javascript.1	2020-02-28 09:26:45.385	warn	(16326) at Socket.Readable.push (_stream_readable.js:224:10)
                            javascript.1	2020-02-28 09:26:45.384	warn	(16326) at readableAddChunk (_stream_readable.js:269:11)
                            javascript.1	2020-02-28 09:26:45.384	warn	(16326) at addChunk (_stream_readable.js:288:12)
                            javascript.1	2020-02-28 09:26:45.383	warn	(16326) at Socket.emit (events.js:198:13)
                            javascript.1	2020-02-28 09:26:45.383	warn	(16326) at Socket.net_client.on (script.js.Weldscripts.Javascript.Heos_neu:341:51)
                            javascript.1	2020-02-28 09:26:45.382	warn	(16326) at Heos.onData (script.js.Weldscripts.Javascript.Heos_neu:358:14)
                            javascript.1	2020-02-28 09:26:45.382	warn	(16326) at Heos.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:478:44)
                            javascript.1	2020-02-28 09:26:45.381	warn	(16326) at HeosPlayer.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:723:26)
                            javascript.1	2020-02-28 09:26:45.381	warn	(16326) at HeosPlayer.setState (script.js.Weldscripts.Javascript.Heos_neu:691:4)
                            javascript.1	2020-02-28 09:26:45.380	warn	(16326) at setState (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1425:20)
                            javascript.1	2020-02-28 09:26:45.379	warn	(16326) State "javascript.1.heos.192_168_1_177.cur_pos" not found
                            javascript.1	2020-02-28 09:26:45.348	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] signed in: success
                            javascript.1	2020-02-28 09:26:45.333	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [HeosPlayer 192.168.1.177] starting HEOS player for IP 192.168.1.177
                            javascript.1	2020-02-28 09:26:45.280	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] connected to 192.168.1.177
                            javascript.1	2020-02-28 09:26:45.279	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] connected to HEOS
                            
                            D 1 Antwort Letzte Antwort
                            0
                            • J jwedenig

                              das passiert, wenn ich die Objekte lösche und das Skript wieder neu starte, um die Objekte zu erzeugen

                              web.0	2020-02-28 09:28:07.539	info	(26785) ==>Connected system.user.admin from ::ffff:192.168.1.159
                              web.0	2020-02-28 09:28:05.988	info	(26785) ==>Connected system.user.admin from ::ffff:192.168.1.159
                              javascript.1	2020-02-28 09:26:58.908	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] signed in: success
                              javascript.1	2020-02-28 09:26:58.030	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] signed in: success
                              javascript.1	2020-02-28 09:26:58.021	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [HeosPlayer 192.168.1.177] starting HEOS player for IP 192.168.1.177
                              javascript.1	2020-02-28 09:26:58.013	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] connected to 192.168.1.177
                              javascript.1	2020-02-28 09:26:58.012	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] connected to HEOS
                              javascript.1	2020-02-28 09:26:58.010	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] connecting to 192.168.1.177 ...
                              javascript.1	2020-02-28 09:26:57.269	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: registered 1 subscription and 0 schedules
                              javascript.1	2020-02-28 09:26:57.267	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] connecting to HEOS ...
                              javascript.1	2020-02-28 09:26:57.263	info	(16326) Start javascript script.js.Weldscripts.Javascript.Heos_neu
                              javascript.1	2020-02-28 09:26:54.113	error	(16326) error in onStop callback: TypeError: this.nodessdp_client.destroy is not a function
                              javascript.1	2020-02-28 09:26:54.112	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] disconnecting from HEOS ...
                              javascript.1	2020-02-28 09:26:54.110	info	(16326) Stop script script.js.Weldscripts.Javascript.Heos_neu
                              javascript.1	2020-02-28 09:26:46.169	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] signed in: success
                              javascript.1	2020-02-28 09:26:45.882	warn	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] Command_not_recognized
                              javascript.1	2020-02-28 09:26:45.879	warn	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] Command_not_recognized
                              javascript.1	2020-02-28 09:26:45.496	warn	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] Command_not_recognized
                              javascript.1	2020-02-28 09:26:45.494	warn	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] Command_not_recognized
                              javascript.1	2020-02-28 09:26:45.476	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] command:
                              javascript.1	2020-02-28 09:26:45.474	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] command:
                              javascript.1	2020-02-28 09:26:45.415	warn	(16326) at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
                              javascript.1	2020-02-28 09:26:45.415	warn	(16326) at Socket.Readable.push (_stream_readable.js:224:10)
                              javascript.1	2020-02-28 09:26:45.415	warn	(16326) at readableAddChunk (_stream_readable.js:269:11)
                              javascript.1	2020-02-28 09:26:45.415	warn	(16326) at addChunk (_stream_readable.js:288:12)
                              javascript.1	2020-02-28 09:26:45.415	warn	(16326) at Socket.emit (events.js:198:13)
                              javascript.1	2020-02-28 09:26:45.415	warn	(16326) at Socket.net_client.on (script.js.Weldscripts.Javascript.Heos_neu:341:51)
                              javascript.1	2020-02-28 09:26:45.414	warn	(16326) at Heos.onData (script.js.Weldscripts.Javascript.Heos_neu:358:14)
                              javascript.1	2020-02-28 09:26:45.414	warn	(16326) at Heos.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:478:44)
                              javascript.1	2020-02-28 09:26:45.414	warn	(16326) at HeosPlayer.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:726:26)
                              javascript.1	2020-02-28 09:26:45.414	warn	(16326) at HeosPlayer.setState (script.js.Weldscripts.Javascript.Heos_neu:691:4)
                              javascript.1	2020-02-28 09:26:45.413	warn	(16326) at setState (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1425:20)
                              javascript.1	2020-02-28 09:26:45.412	warn	(16326) State "javascript.1.heos.192_168_1_177.duration_MMSS" not found
                              javascript.1	2020-02-28 09:26:45.412	warn	(16326) at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
                              javascript.1	2020-02-28 09:26:45.412	warn	(16326) at Socket.Readable.push (_stream_readable.js:224:10)
                              javascript.1	2020-02-28 09:26:45.412	warn	(16326) at readableAddChunk (_stream_readable.js:269:11)
                              javascript.1	2020-02-28 09:26:45.412	warn	(16326) at addChunk (_stream_readable.js:288:12)
                              javascript.1	2020-02-28 09:26:45.411	warn	(16326) at Socket.emit (events.js:198:13)
                              javascript.1	2020-02-28 09:26:45.411	warn	(16326) at Socket.net_client.on (script.js.Weldscripts.Javascript.Heos_neu:341:51)
                              javascript.1	2020-02-28 09:26:45.411	warn	(16326) at Heos.onData (script.js.Weldscripts.Javascript.Heos_neu:358:14)
                              javascript.1	2020-02-28 09:26:45.411	warn	(16326) at Heos.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:478:44)
                              javascript.1	2020-02-28 09:26:45.410	warn	(16326) at HeosPlayer.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:725:26)
                              javascript.1	2020-02-28 09:26:45.410	warn	(16326) at HeosPlayer.setState (script.js.Weldscripts.Javascript.Heos_neu:691:4)
                              javascript.1	2020-02-28 09:26:45.410	warn	(16326) at setState (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1425:20)
                              javascript.1	2020-02-28 09:26:45.409	warn	(16326) State "javascript.1.heos.192_168_1_177.duration" not found
                              javascript.1	2020-02-28 09:26:45.409	warn	(16326) at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
                              javascript.1	2020-02-28 09:26:45.409	warn	(16326) at Socket.Readable.push (_stream_readable.js:224:10)
                              javascript.1	2020-02-28 09:26:45.409	warn	(16326) at readableAddChunk (_stream_readable.js:269:11)
                              javascript.1	2020-02-28 09:26:45.408	warn	(16326) at addChunk (_stream_readable.js:288:12)
                              javascript.1	2020-02-28 09:26:45.408	warn	(16326) at Socket.emit (events.js:198:13)
                              javascript.1	2020-02-28 09:26:45.408	warn	(16326) at Socket.net_client.on (script.js.Weldscripts.Javascript.Heos_neu:341:51)
                              javascript.1	2020-02-28 09:26:45.408	warn	(16326) at Heos.onData (script.js.Weldscripts.Javascript.Heos_neu:358:14)
                              javascript.1	2020-02-28 09:26:45.408	warn	(16326) at Heos.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:478:44)
                              javascript.1	2020-02-28 09:26:45.407	warn	(16326) at HeosPlayer.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:724:26)
                              javascript.1	2020-02-28 09:26:45.407	warn	(16326) at HeosPlayer.setState (script.js.Weldscripts.Javascript.Heos_neu:691:4)
                              javascript.1	2020-02-28 09:26:45.407	warn	(16326) at setState (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1425:20)
                              javascript.1	2020-02-28 09:26:45.406	warn	(16326) State "javascript.1.heos.192_168_1_177.cur_pos_MMSS" not found
                              javascript.1	2020-02-28 09:26:45.406	warn	(16326) at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
                              javascript.1	2020-02-28 09:26:45.406	warn	(16326) at Socket.Readable.push (_stream_readable.js:224:10)
                              javascript.1	2020-02-28 09:26:45.405	warn	(16326) at readableAddChunk (_stream_readable.js:269:11)
                              javascript.1	2020-02-28 09:26:45.405	warn	(16326) at addChunk (_stream_readable.js:288:12)
                              javascript.1	2020-02-28 09:26:45.405	warn	(16326) at Socket.emit (events.js:198:13)
                              javascript.1	2020-02-28 09:26:45.405	warn	(16326) at Socket.net_client.on (script.js.Weldscripts.Javascript.Heos_neu:341:51)
                              javascript.1	2020-02-28 09:26:45.404	warn	(16326) at Heos.onData (script.js.Weldscripts.Javascript.Heos_neu:358:14)
                              javascript.1	2020-02-28 09:26:45.404	warn	(16326) at Heos.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:478:44)
                              javascript.1	2020-02-28 09:26:45.404	warn	(16326) at HeosPlayer.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:723:26)
                              javascript.1	2020-02-28 09:26:45.403	warn	(16326) at HeosPlayer.setState (script.js.Weldscripts.Javascript.Heos_neu:691:4)
                              javascript.1	2020-02-28 09:26:45.403	warn	(16326) at setState (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1425:20)
                              javascript.1	2020-02-28 09:26:45.402	warn	(16326) State "javascript.1.heos.192_168_1_177.cur_pos" not found
                              javascript.1	2020-02-28 09:26:45.401	warn	(16326) at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
                              javascript.1	2020-02-28 09:26:45.401	warn	(16326) at Socket.Readable.push (_stream_readable.js:224:10)
                              javascript.1	2020-02-28 09:26:45.400	warn	(16326) at readableAddChunk (_stream_readable.js:269:11)
                              javascript.1	2020-02-28 09:26:45.400	warn	(16326) at addChunk (_stream_readable.js:288:12)
                              javascript.1	2020-02-28 09:26:45.400	warn	(16326) at Socket.emit (events.js:198:13)
                              javascript.1	2020-02-28 09:26:45.399	warn	(16326) at Socket.net_client.on (script.js.Weldscripts.Javascript.Heos_neu:341:51)
                              javascript.1	2020-02-28 09:26:45.399	warn	(16326) at Heos.onData (script.js.Weldscripts.Javascript.Heos_neu:358:14)
                              javascript.1	2020-02-28 09:26:45.399	warn	(16326) at Heos.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:478:44)
                              javascript.1	2020-02-28 09:26:45.398	warn	(16326) at HeosPlayer.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:726:26)
                              javascript.1	2020-02-28 09:26:45.398	warn	(16326) at HeosPlayer.setState (script.js.Weldscripts.Javascript.Heos_neu:691:4)
                              javascript.1	2020-02-28 09:26:45.398	warn	(16326) at setState (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1425:20)
                              javascript.1	2020-02-28 09:26:45.397	warn	(16326) State "javascript.1.heos.192_168_1_177.duration_MMSS" not found
                              javascript.1	2020-02-28 09:26:45.397	warn	(16326) at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
                              javascript.1	2020-02-28 09:26:45.396	warn	(16326) at Socket.Readable.push (_stream_readable.js:224:10)
                              javascript.1	2020-02-28 09:26:45.396	warn	(16326) at readableAddChunk (_stream_readable.js:269:11)
                              javascript.1	2020-02-28 09:26:45.396	warn	(16326) at addChunk (_stream_readable.js:288:12)
                              javascript.1	2020-02-28 09:26:45.396	warn	(16326) at Socket.emit (events.js:198:13)
                              javascript.1	2020-02-28 09:26:45.395	warn	(16326) at Socket.net_client.on (script.js.Weldscripts.Javascript.Heos_neu:341:51)
                              javascript.1	2020-02-28 09:26:45.395	warn	(16326) at Heos.onData (script.js.Weldscripts.Javascript.Heos_neu:358:14)
                              javascript.1	2020-02-28 09:26:45.395	warn	(16326) at Heos.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:478:44)
                              javascript.1	2020-02-28 09:26:45.395	warn	(16326) at HeosPlayer.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:725:26)
                              javascript.1	2020-02-28 09:26:45.393	warn	(16326) at HeosPlayer.setState (script.js.Weldscripts.Javascript.Heos_neu:691:4)
                              javascript.1	2020-02-28 09:26:45.393	warn	(16326) at setState (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1425:20)
                              javascript.1	2020-02-28 09:26:45.391	warn	(16326) State "javascript.1.heos.192_168_1_177.duration" not found
                              javascript.1	2020-02-28 09:26:45.391	warn	(16326) at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
                              javascript.1	2020-02-28 09:26:45.391	warn	(16326) at Socket.Readable.push (_stream_readable.js:224:10)
                              javascript.1	2020-02-28 09:26:45.390	warn	(16326) at readableAddChunk (_stream_readable.js:269:11)
                              javascript.1	2020-02-28 09:26:45.390	warn	(16326) at addChunk (_stream_readable.js:288:12)
                              javascript.1	2020-02-28 09:26:45.390	warn	(16326) at Socket.emit (events.js:198:13)
                              javascript.1	2020-02-28 09:26:45.390	warn	(16326) at Socket.net_client.on (script.js.Weldscripts.Javascript.Heos_neu:341:51)
                              javascript.1	2020-02-28 09:26:45.390	warn	(16326) at Heos.onData (script.js.Weldscripts.Javascript.Heos_neu:358:14)
                              javascript.1	2020-02-28 09:26:45.389	warn	(16326) at Heos.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:478:44)
                              javascript.1	2020-02-28 09:26:45.389	warn	(16326) at HeosPlayer.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:724:26)
                              javascript.1	2020-02-28 09:26:45.389	warn	(16326) at HeosPlayer.setState (script.js.Weldscripts.Javascript.Heos_neu:691:4)
                              javascript.1	2020-02-28 09:26:45.388	warn	(16326) at setState (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1425:20)
                              javascript.1	2020-02-28 09:26:45.388	warn	(16326) State "javascript.1.heos.192_168_1_177.cur_pos_MMSS" not found
                              javascript.1	2020-02-28 09:26:45.385	warn	(16326) at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
                              javascript.1	2020-02-28 09:26:45.385	warn	(16326) at Socket.Readable.push (_stream_readable.js:224:10)
                              javascript.1	2020-02-28 09:26:45.384	warn	(16326) at readableAddChunk (_stream_readable.js:269:11)
                              javascript.1	2020-02-28 09:26:45.384	warn	(16326) at addChunk (_stream_readable.js:288:12)
                              javascript.1	2020-02-28 09:26:45.383	warn	(16326) at Socket.emit (events.js:198:13)
                              javascript.1	2020-02-28 09:26:45.383	warn	(16326) at Socket.net_client.on (script.js.Weldscripts.Javascript.Heos_neu:341:51)
                              javascript.1	2020-02-28 09:26:45.382	warn	(16326) at Heos.onData (script.js.Weldscripts.Javascript.Heos_neu:358:14)
                              javascript.1	2020-02-28 09:26:45.382	warn	(16326) at Heos.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:478:44)
                              javascript.1	2020-02-28 09:26:45.381	warn	(16326) at HeosPlayer.parseResponse (script.js.Weldscripts.Javascript.Heos_neu:723:26)
                              javascript.1	2020-02-28 09:26:45.381	warn	(16326) at HeosPlayer.setState (script.js.Weldscripts.Javascript.Heos_neu:691:4)
                              javascript.1	2020-02-28 09:26:45.380	warn	(16326) at setState (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1425:20)
                              javascript.1	2020-02-28 09:26:45.379	warn	(16326) State "javascript.1.heos.192_168_1_177.cur_pos" not found
                              javascript.1	2020-02-28 09:26:45.348	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] signed in: success
                              javascript.1	2020-02-28 09:26:45.333	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [HeosPlayer 192.168.1.177] starting HEOS player for IP 192.168.1.177
                              javascript.1	2020-02-28 09:26:45.280	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] connected to 192.168.1.177
                              javascript.1	2020-02-28 09:26:45.279	info	(16326) script.js.Weldscripts.Javascript.Heos_neu: [Heos] connected to HEOS
                              
                              D Offline
                              D Offline
                              Desastro
                              schrieb am zuletzt editiert von
                              #88

                              @jwedenig

                              Hi

                              Hast du bei der neuen Instanz in den Einstellungen "node-ssdp" bei den zusätzlichen Modulen mit eingetragen?
                              Mehr fällt mir da grad auch nicht ein.

                              Gruß Thomas

                              J 1 Antwort Letzte Antwort
                              0
                              • D Desastro

                                @jwedenig

                                Hi

                                Hast du bei der neuen Instanz in den Einstellungen "node-ssdp" bei den zusätzlichen Modulen mit eingetragen?
                                Mehr fällt mir da grad auch nicht ein.

                                Gruß Thomas

                                J Offline
                                J Offline
                                jwedenig
                                Most Active
                                schrieb am zuletzt editiert von
                                #89

                                @Desastro ja, habe ich, danke

                                1 Antwort Letzte Antwort
                                0
                                • UhulaU Uhula

                                  @Lacoste9 MD CSS v2, z.B. von hier: https://github.com/Uhula/ioBroker-Material-Design-Style

                                  @Meister-Mopper Den Fehler ignorieren, ist ein überflüssiger Aufruf im destroy, ist in meiner neuesten Version schon behoben. Ich versuche demnächst mal aus dem Script einen Adapter zu machen.

                                  @BobBruni Mit Spotify habe ich es noch nicht versucht, denke aber nicht, dass es gehen wird, da Spotify nicht native von HEOS unterstützt wird, sondern selbst deren Client "nachlädt" (siehe die HEOS App, die macht dad auch). Ich werde mal im API nachlesen, demnächst.

                                  C Offline
                                  C Offline
                                  chrisblu
                                  schrieb am zuletzt editiert von
                                  #90

                                  Hallo Uhula,

                                  ich bin immer noch total begeistert von deinem Skript und der Heos-Steuerung über den Broker.

                                  @Uhula sagte in [Vorlage] Denon HEOS Script:

                                  @Meister-Mopper Den Fehler ignorieren, ist ein überflüssiger Aufruf im destroy, ist in meiner neuesten Version schon behoben. Ich versuche demnächst mal aus dem Script einen Adapter zu machen.

                                  Ist die neuste Version von deinem Skript schon erhältlich, oder ist das die vom 15.11.?
                                  Ich bin auch schon sehr gespannt auf deinen Adapter. Wenn Du Tester brauchst, bin ich gerne dabei.

                                  Bei mir bekomme ich nach wie vor von den mp3s über DLNA oder Heos Netzwerkfreigabe keine Infos/Tags/Titel angezeigt.

                                  Viele Grüße, Christian

                                  UhulaU 1 Antwort Letzte Antwort
                                  0
                                  • C chrisblu

                                    Hallo Uhula,

                                    ich bin immer noch total begeistert von deinem Skript und der Heos-Steuerung über den Broker.

                                    @Uhula sagte in [Vorlage] Denon HEOS Script:

                                    @Meister-Mopper Den Fehler ignorieren, ist ein überflüssiger Aufruf im destroy, ist in meiner neuesten Version schon behoben. Ich versuche demnächst mal aus dem Script einen Adapter zu machen.

                                    Ist die neuste Version von deinem Skript schon erhältlich, oder ist das die vom 15.11.?
                                    Ich bin auch schon sehr gespannt auf deinen Adapter. Wenn Du Tester brauchst, bin ich gerne dabei.

                                    Bei mir bekomme ich nach wie vor von den mp3s über DLNA oder Heos Netzwerkfreigabe keine Infos/Tags/Titel angezeigt.

                                    Viele Grüße, Christian

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

                                    @chrisblu Bei mir läuft bereits das neue Script - recht stabil, unterstützt auch Raumgruppen; muss es aber noch an den neuen "0_userdata.0" State-Ordner anpassen, dann ist es javascript-Instanz unabhängig. Btw. die States werden dann nicht mehr unter der Player-IP-Adresse, sondern unter der Player-ID abgelegt (kam bei mir hin und wieder vor, das Player einen neue IP bekamen ..., die ID bleibt konstant).

                                    Zum Adapter dauert es noch, habe erst einmal das MD CSS v2 Projekt priorisiert.

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

                                    1 Antwort Letzte Antwort
                                    1
                                    • C Offline
                                      C Offline
                                      chrisblu
                                      schrieb am zuletzt editiert von
                                      #92

                                      @Uhula, das klingt gut. Bin schon gespannt.
                                      Danke für die Info, viele Grüße, Christian

                                      1 Antwort Letzte Antwort
                                      0
                                      • W Offline
                                        W Offline
                                        withstu
                                        schrieb am zuletzt editiert von
                                        #93

                                        @Uhula erstmal vielen Dank für deine Arbeit. Ich habe einige Bugs in deinem ersten Script gefixt (@jwedenig es werden auch wieder alle Song Infos aktualisiert). Auch wenn Version 2 bereits unterwegs ist, will ich euch meine Änderungen nicht vorenthalten. Unter anderem ist mir aufgefallen, dass das Filtern und Verarbeiten der Pakete vom node-ssdp nicht korrekt funktioniert, wenn eine Hue Bridge im Netzwerk funkt oder Pakete unvollständig sind. Zudem habe ich noch ein connected Flag für jeden Player hinzugefügt. Dieses muss leider extern über ein Script resettet werden z.B. in Kombination mit dem Ping Adapter. Für diesen Fall habe ich mir ein Blockly Script gebaut, welches das connected Flag resettet und bei Player Updates das Heos Script neu startet. Bei Bedarf kann ich das auch noch teilen:

                                        /****************************
                                         * 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!
                                         *     Alternativ kann die Bibliothek auch komplett über "npm install node-ssdp" installiert
                                         *     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(cmd) // write
                                         *   Hierüber können der Heos-Klasse Befehle übergeben werden, für cmd gilt:
                                         * 
                                         *   connect      
                                         *       Verbindung zu HEOS aufbauen bzw. erneut aufbauen (praktisch ein reset)
                                         *   disconnect   
                                         *       Verbindung zu HEOS beenden
                                         *   load_presets
                                         *       lädt die Favoriten neu
                                         * 
                                         *   alle anderen cmd-Werte werden "as is" versucht an HEOS zu senden, damit ist z.B. auch das
                                         *   Gruppieren von HEOS Speakern möglich.
                                         * 
                                         *   group/set_group?pid=<pid1>,<pid2>,...
                                         *       setzen einer Gruppe, die pids sind die der Player wie sie unter den Objekten
                                         *       für jeden Player abgelegt sind. Statt diese direkt zu verwenden, kann man auch
                                         *       die ioBroker binding-Funktionalität nutzen und Platzhalter verwenden.
                                         *       Bsp: group/set_group?pid={javascript.1.heos.192_168_2_46.pid},{javascript.1.heos.192_168_2_43.pid}
                                         * 
                                         *   group/set_group?pid=<pid1>  
                                         *       hebt die Gruppierung wieder auf
                                         *       Bsp: group/set_group?pid={javascript.1.heos.192_168_2_46.pid}
                                         * 
                                         * 
                                         * 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 = '';
                                        const HEOS_PASSWORD = '';
                                         
                                         
                                        /****************************
                                         * 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?' });
                                            createState( this.statePath+'last_error', '', {name: 'Letzter Fehler' });
                                            on({id: this.statePath+'command', change: "any"}, (obj) => {
                                                    this.executeCommand( obj.state.val );
                                                });
                                        }
                                         
                                        logDebug(msg) { console.debug('[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;
                                            this.unfinishedResponses = '';
                                            this.ssdpSeartTargetName = 'urn:schemas-denon-com:device:ACT-Denon:1';
                                        }
                                         
                                        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;
                                        	    this.nodessdp_client.on('response', (headers, statusCode, rinfo) => this.onNodeSSDPResponse(headers, statusCode, rinfo) );
                                        	    this.nodessdp_client.on('error', error => {	client.close(); this.logError(error); });
                                                this.nodessdp_client.search(this.ssdpSeartTargetName);
                                            } catch(err) { this.logError( 'connect: '+err.message ); } 
                                            
                                        }
                                         
                                         
                                        /** Alle Player stoppen und die TelNet Verbindung schließen 
                                         **/
                                        disconnect() {
                                            this.log('disconnecting from HEOS ...');
                                            unsubscribe('javascript.'+instance+'.heos');
                                        
                                            var i=0;
                                            for (i=0; i<this.players.length; i++) {
                                                var playerStatePath = this.players[i].heosPlayer.statePath;
                                                setState( playerStatePath+"connected", false );
                                            }
                                         
                                            if (typeof this.net_client!=='undefined') {
                                                this.registerChangeEvents( false );
                                                
                                                this.net_client.destroy();
                                                this.net_client.unref();
                                            }
                                            if (typeof this.nodessdp_client!=='undefined') {
                                                this.nodessdp_client.stop();
                                            }
                                            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;
                                                default:
                                                    if (this.state == stateCONNECTED) {
                                                        this.msgs.push( 'heos://'+cmd+'\n' );
                                                        this.sendNextMsg();
                                                    }
                                            
                                            }
                                        }
                                        
                                        sleep(milliseconds) {
                                           return new Promise(resolve => setTimeout(resolve, milliseconds));
                                        }
                                        
                                        /** es wurde mindestens ein Player erkannt, nun über dessen IP alle bekannten HEOS Player
                                         *  durch senden von "player/get_players" ermitteln
                                         */
                                        onNodeSSDPResponse(headers, statusCode, rinfo) { try {
                                            // rinfo {"address":"192.168.2.225","family":"IPv4","port":53871,"size":430}
                                            if (typeof this.net_client=='undefined') {
                                                if(headers.ST === this.ssdpSeartTargetName){
                                                    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.log('connected to HEOS');
                                                        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)  );
                                                } else {
                                                    this.log('Getting wrong ssdp entry. Keep trying...');
                                                }
                                            }
                                        } catch(err) { this.logError( 'onNodeSSDPResponse: '+err.message ); } }
                                        
                                        removeFirstOccurrence(str, searchstr)       {
                                        	var index = str.indexOf(searchstr);
                                        	if (index === -1) {
                                        		return str;
                                        	}
                                        	return str.slice(0, index) + str.slice(index + searchstr.length);
                                        }
                                         
                                        /** es liegen Antwort(en) vor
                                         **/
                                        onData(data) {  try {
                                            data = data.toString();
                                            this.logDebug("received data:" + data);
                                            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 = this.unfinishedResponses + data;
                                            this.unfinishedResponses = '';
                                        
                                            data=data.replace(/{\s*"heos"\s*:/g, '|{"heos":');  
                                            var responses = data.split('|');
                                            for (var r=0; r<responses.length; r++ ) {
                                                if(responses[r].trim().length > 0){
                                                    try {
                                                        JSON.parse(responses[r]);
                                                        this.parseResponse(responses[r]);
                                                    } catch(e) {
                                                        this.logDebug("invalid json (error: " + e.message + "): " + responses[r]);
                                                        this.unfinishedResponses += 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 || response.indexOf("command under process") > 0 )
                                                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('parse response: '+response);
                                            this.logDebug('parse message: '+JSON.stringify(jmsg));
                                         
                                            // cmd auswerten
                                            var cmd = jdata.heos.command.split('/');
                                            var cmd_group = cmd[0];
                                            cmd = cmd[1];
                                        
                                            // result ?
                                            var result = 'success';
                                            if (jdata.heos.hasOwnProperty('result') ) result = jdata.heos.result;
                                            if ( result!='success' ) { 
                                                setState(this.statePath+'last_error', cmd + ' | ' + jmsg.text);
                                                this.logWarn(jmsg.text);
                                            }
                                         
                                            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();
                                                            } else if(jdata.playload.length != this.players.length){
                                                                this.log("New Player detected. Restart.")
                                                                this.disconnect();
                                                            }                    
                                                            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')) ) {
                                                                this.logDebug("Payload:"+jdata.payload.toString());
                                                                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+'\n '+response ); } }
                                         
                                         
                                        /** 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();
                                         
                                            // Initialisierung 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 );
                                            setTimeout(() => {
                                                this.setState('connected', true);
                                            }, 10000 );
                                        }
                                         
                                        static version () { return "0.2"; }
                                         
                                        logDebug(msg) { console.debug('[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:"connected",                   name:"Verbunden?"},
                                                { 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 {
                                            this.logDebug('response type - cmd_group: ' + cmd_group + " - cmd: " + cmd);
                                            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 );
                                                            this.setState("mute", (jmsg.mute=='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);
                                                            this.setState("now_playing_media_song", jdata.payload.song);
                                                                                    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);
                                                            // type == station
                                                            if (jdata.payload.type=='station') {
                                                                this.setState("now_playing_media_station", jdata.payload.station);
                                                            } else {
                                                                this.setState("now_playing_media_station", null);
                                                            }
                                                            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 );
                                        
                                        C UhulaU 2 Antworten Letzte Antwort
                                        0
                                        • W withstu

                                          @Uhula erstmal vielen Dank für deine Arbeit. Ich habe einige Bugs in deinem ersten Script gefixt (@jwedenig es werden auch wieder alle Song Infos aktualisiert). Auch wenn Version 2 bereits unterwegs ist, will ich euch meine Änderungen nicht vorenthalten. Unter anderem ist mir aufgefallen, dass das Filtern und Verarbeiten der Pakete vom node-ssdp nicht korrekt funktioniert, wenn eine Hue Bridge im Netzwerk funkt oder Pakete unvollständig sind. Zudem habe ich noch ein connected Flag für jeden Player hinzugefügt. Dieses muss leider extern über ein Script resettet werden z.B. in Kombination mit dem Ping Adapter. Für diesen Fall habe ich mir ein Blockly Script gebaut, welches das connected Flag resettet und bei Player Updates das Heos Script neu startet. Bei Bedarf kann ich das auch noch teilen:

                                          /****************************
                                           * 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!
                                           *     Alternativ kann die Bibliothek auch komplett über "npm install node-ssdp" installiert
                                           *     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(cmd) // write
                                           *   Hierüber können der Heos-Klasse Befehle übergeben werden, für cmd gilt:
                                           * 
                                           *   connect      
                                           *       Verbindung zu HEOS aufbauen bzw. erneut aufbauen (praktisch ein reset)
                                           *   disconnect   
                                           *       Verbindung zu HEOS beenden
                                           *   load_presets
                                           *       lädt die Favoriten neu
                                           * 
                                           *   alle anderen cmd-Werte werden "as is" versucht an HEOS zu senden, damit ist z.B. auch das
                                           *   Gruppieren von HEOS Speakern möglich.
                                           * 
                                           *   group/set_group?pid=<pid1>,<pid2>,...
                                           *       setzen einer Gruppe, die pids sind die der Player wie sie unter den Objekten
                                           *       für jeden Player abgelegt sind. Statt diese direkt zu verwenden, kann man auch
                                           *       die ioBroker binding-Funktionalität nutzen und Platzhalter verwenden.
                                           *       Bsp: group/set_group?pid={javascript.1.heos.192_168_2_46.pid},{javascript.1.heos.192_168_2_43.pid}
                                           * 
                                           *   group/set_group?pid=<pid1>  
                                           *       hebt die Gruppierung wieder auf
                                           *       Bsp: group/set_group?pid={javascript.1.heos.192_168_2_46.pid}
                                           * 
                                           * 
                                           * 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 = '';
                                          const HEOS_PASSWORD = '';
                                           
                                           
                                          /****************************
                                           * 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?' });
                                              createState( this.statePath+'last_error', '', {name: 'Letzter Fehler' });
                                              on({id: this.statePath+'command', change: "any"}, (obj) => {
                                                      this.executeCommand( obj.state.val );
                                                  });
                                          }
                                           
                                          logDebug(msg) { console.debug('[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;
                                              this.unfinishedResponses = '';
                                              this.ssdpSeartTargetName = 'urn:schemas-denon-com:device:ACT-Denon:1';
                                          }
                                           
                                          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;
                                          	    this.nodessdp_client.on('response', (headers, statusCode, rinfo) => this.onNodeSSDPResponse(headers, statusCode, rinfo) );
                                          	    this.nodessdp_client.on('error', error => {	client.close(); this.logError(error); });
                                                  this.nodessdp_client.search(this.ssdpSeartTargetName);
                                              } catch(err) { this.logError( 'connect: '+err.message ); } 
                                              
                                          }
                                           
                                           
                                          /** Alle Player stoppen und die TelNet Verbindung schließen 
                                           **/
                                          disconnect() {
                                              this.log('disconnecting from HEOS ...');
                                              unsubscribe('javascript.'+instance+'.heos');
                                          
                                              var i=0;
                                              for (i=0; i<this.players.length; i++) {
                                                  var playerStatePath = this.players[i].heosPlayer.statePath;
                                                  setState( playerStatePath+"connected", false );
                                              }
                                           
                                              if (typeof this.net_client!=='undefined') {
                                                  this.registerChangeEvents( false );
                                                  
                                                  this.net_client.destroy();
                                                  this.net_client.unref();
                                              }
                                              if (typeof this.nodessdp_client!=='undefined') {
                                                  this.nodessdp_client.stop();
                                              }
                                              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;
                                                  default:
                                                      if (this.state == stateCONNECTED) {
                                                          this.msgs.push( 'heos://'+cmd+'\n' );
                                                          this.sendNextMsg();
                                                      }
                                              
                                              }
                                          }
                                          
                                          sleep(milliseconds) {
                                             return new Promise(resolve => setTimeout(resolve, milliseconds));
                                          }
                                          
                                          /** es wurde mindestens ein Player erkannt, nun über dessen IP alle bekannten HEOS Player
                                           *  durch senden von "player/get_players" ermitteln
                                           */
                                          onNodeSSDPResponse(headers, statusCode, rinfo) { try {
                                              // rinfo {"address":"192.168.2.225","family":"IPv4","port":53871,"size":430}
                                              if (typeof this.net_client=='undefined') {
                                                  if(headers.ST === this.ssdpSeartTargetName){
                                                      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.log('connected to HEOS');
                                                          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)  );
                                                  } else {
                                                      this.log('Getting wrong ssdp entry. Keep trying...');
                                                  }
                                              }
                                          } catch(err) { this.logError( 'onNodeSSDPResponse: '+err.message ); } }
                                          
                                          removeFirstOccurrence(str, searchstr)       {
                                          	var index = str.indexOf(searchstr);
                                          	if (index === -1) {
                                          		return str;
                                          	}
                                          	return str.slice(0, index) + str.slice(index + searchstr.length);
                                          }
                                           
                                          /** es liegen Antwort(en) vor
                                           **/
                                          onData(data) {  try {
                                              data = data.toString();
                                              this.logDebug("received data:" + data);
                                              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 = this.unfinishedResponses + data;
                                              this.unfinishedResponses = '';
                                          
                                              data=data.replace(/{\s*"heos"\s*:/g, '|{"heos":');  
                                              var responses = data.split('|');
                                              for (var r=0; r<responses.length; r++ ) {
                                                  if(responses[r].trim().length > 0){
                                                      try {
                                                          JSON.parse(responses[r]);
                                                          this.parseResponse(responses[r]);
                                                      } catch(e) {
                                                          this.logDebug("invalid json (error: " + e.message + "): " + responses[r]);
                                                          this.unfinishedResponses += 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 || response.indexOf("command under process") > 0 )
                                                  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('parse response: '+response);
                                              this.logDebug('parse message: '+JSON.stringify(jmsg));
                                           
                                              // cmd auswerten
                                              var cmd = jdata.heos.command.split('/');
                                              var cmd_group = cmd[0];
                                              cmd = cmd[1];
                                          
                                              // result ?
                                              var result = 'success';
                                              if (jdata.heos.hasOwnProperty('result') ) result = jdata.heos.result;
                                              if ( result!='success' ) { 
                                                  setState(this.statePath+'last_error', cmd + ' | ' + jmsg.text);
                                                  this.logWarn(jmsg.text);
                                              }
                                           
                                              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();
                                                              } else if(jdata.playload.length != this.players.length){
                                                                  this.log("New Player detected. Restart.")
                                                                  this.disconnect();
                                                              }                    
                                                              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')) ) {
                                                                  this.logDebug("Payload:"+jdata.payload.toString());
                                                                  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+'\n '+response ); } }
                                           
                                           
                                          /** 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();
                                           
                                              // Initialisierung 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 );
                                              setTimeout(() => {
                                                  this.setState('connected', true);
                                              }, 10000 );
                                          }
                                           
                                          static version () { return "0.2"; }
                                           
                                          logDebug(msg) { console.debug('[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:"connected",                   name:"Verbunden?"},
                                                  { 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 {
                                              this.logDebug('response type - cmd_group: ' + cmd_group + " - cmd: " + cmd);
                                              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 );
                                                              this.setState("mute", (jmsg.mute=='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);
                                                              this.setState("now_playing_media_song", jdata.payload.song);
                                                                                      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);
                                                              // type == station
                                                              if (jdata.payload.type=='station') {
                                                                  this.setState("now_playing_media_station", jdata.payload.station);
                                                              } else {
                                                                  this.setState("now_playing_media_station", null);
                                                              }
                                                              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 );
                                          
                                          C Offline
                                          C Offline
                                          chrisblu
                                          schrieb am zuletzt editiert von
                                          #94

                                          @withstu großartig, das funktioniert gut. Jetzt gehen auch die Titel und Cover bei DLNA-Wiedergabe bei mir wieder. Vielen Dank fürs teilen.
                                          Wie genau meinst Du das mit dem Ping Adapter? Fragst Du ab, ob die Box verbunden ist und wenn wieder da, verbindest Du neu?
                                          Könntest Du bitte das Blockly Skript auch posten, das bei Player-Updates neu startet?
                                          Vielen Dank,
                                          Christian

                                          W 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

                                          618

                                          Online

                                          32.4k

                                          Benutzer

                                          81.4k

                                          Themen

                                          1.3m

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

                                          • Du hast noch kein Konto? Registrieren

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