Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

group.play.streamhttp command won't accept an IP address or local name in URL referencing local device #275

Closed
gourdo1 opened this issue Dec 15, 2023 · 11 comments
Assignees
Labels

Comments

@gourdo1
Copy link

gourdo1 commented Dec 15, 2023

Description

Basically as in title. I setup my Sonos to play an .mp3 file on the local HomeAssistant device that's also running NodeRED. However, any URL pointing to the .mp3 file only works as long as the URL contains a DNS name (in my case xxxxxx.duckdns.org:9123). Local IP addresses, (192.168.1.x, 127.0.0.1) and local hostnames like localhost and homeassistant.local do not work. This is despite all of the above working from a browser on a device in the same LAN.

When Sonos doesn't play, there is no specific debug message in NodeRED either, just a msg.payload showing the chosen URL, which is the same message received when it does play properly.

What node/command (topic)/state (payload)

node: <--- Universal -->
command: <--- group.play.streamhttp -->
state: <--- ? -->

In case of a bug: Are you able to reproduce the error

<--- yes -->

Versions and Infrastructure

what system: Raspberry Pi 4 8GB, running HAOS:
- HA Core 2023.12.3
- HA Supervisor 2023.11.6
- HA Operating System 11.2
node-red-contrib-sonos-plus version: <--- 6.7.3 -->
Node-RED version: <--- 3.1.0 -->
NodeJS version: <--- ? -->

@hklages
Copy link
Owner

hklages commented Dec 15, 2023 via email

@gourdo1
Copy link
Author

gourdo1 commented Dec 15, 2023

Hmmm, so group.queue.uri doesn't seem to work. Is it supposed to queue a url that's then played with group.play.queue next?

I tried group queue.uri on its own, then group queue.uri followed by group.play.queue as well as group queue.uri followed by group.play, then the above with a 5 second delay in between nodes. In each case, it ignored the provided URL (DNS name or IP address) and played what was previously in the queue (a Spotify track).

group.play.streamhttp continues to work on its own, but only with a DNS name.

@hklages
Copy link
Owner

hklages commented Dec 16, 2023 via email

@gourdo1
Copy link
Author

gourdo1 commented Dec 18, 2023

Sorry for delay as I was out of town...

Lets go a step back. I have a few questions.

  • Why do you want to play a single mp3 file? (In case you want to play just
    a "notification" you can you group.play.notification)

So it's for an alarm system in which I want to use Sonos speakers which are placed throughout my home for a short recorded preamble message followed by a 5 minute alarm sound, all contained in that single mp3 file. I tried group.play.notification and it gives me this error on the Sonos app:
Unable to play 'alarm_final.mp3' - the connection to 192.168.2.4:9123 was lost.

  • Where is the file stored? Home Assistant recommendation is to store
    served files in the "www" folder.
    (Example to call that file in the browser:
    http://192.168.178.21:8123/local/doorbell.mp3 where 192.168.178.21 is the
    ip address of HA)

Yes. The file is placed in /config/www and is accessed via https://192.168.2.4:9123/local/alarm_final.mp3 (in fact when I click this link in github in my browser, it starts playing the file). My HA runs on a non-default port, but I'm pretty sure port isn't the issue as I can access the mp3 file multiple ways, including through group.play.streamhttp as long as I use the external DNS name of the server.

  • When using the group.queue.uri: Can you have a look at the queue (for
    instance group.get.queue). Is your file added to the queue? If yes you can
    send a group.clear.queue before. Then the file should be played.

Yup, I get a 51 object array, with the last object being my file...

So... I re-built the flow. It now clears the queue first, then I call my mp3 file with group.queue.uri, then I get the queue which now returns a single object array that looks like this in the debug node:

{"id":"Q:0/1","title":"alarm_final.mp3","artist":"","album":"","description":"","uri":"https://192.168.2.4:9123/local/alarm_final.mp3","artUri":"http://192.168.2.225:1400/getaa?u=https%3a%2f%2f192.168.2.4%3a9123%2flocal%2falarm_final.mp3&amp;v=5","metadata":"","sid":"","serviceName":"","upnpClass":"object.item","processingType":"queue"}

Then I play the queue with group.play.queue. The file doesn't play and the Sonos app still returns:

Unable to play 'alarm_final.mp3' - the connection to 192.168.2.4:9123 was lost

By the way, the reference to 192.168.2.225 seems to be the IP of my Sonos Arc... So I guess it's looking there for album art(?)

In any case, using the exact same methodology as above with all the queue commands, but changing the .mp3 URL to [my_ha_server_address].duckdns.org:9123 instead of an IP address works fine(!)

So I would guess that streamhttp isn't the underlying issue after all... I then re-tried group.play.notification with these substitutions in the URL:

  • 192.168.2.4
  • localhost
  • 127.0.0.1
  • homeassistant.local
  • xxx.xxx.147.48 (my external WAN IP)
  • xxxxxxx.duckdns.org

Interestingly, all fail except for the last one.

@hklages
Copy link
Owner

hklages commented Dec 18, 2023

Thanks for testing that.

  1. Lets verify the mp3 file. Please unzip and copy the doorbell.mp3 to the www directory and check that. This file works on many installation and should also work on yours (play notification, in queue).
    doorbell.zip

I assume that file also results in a "connection .... was lost" error.

  1. Do you have installed duckdns as Home Assistant Add On? Can you stop that add von 5 minutes and try the group.play.notification?

@gourdo1
Copy link
Author

gourdo1 commented Dec 18, 2023

Thanks for testing that.

1. Lets verify the mp3 file. Please unzip and copy the doorbell.mp3 to the www directory and check that. This file works on many installation and should also work on yours (play notification, in queue).
   [doorbell.zip](https://github.com/hklages/node-red-contrib-sonos-plus/files/13700574/doorbell.zip)

I assume that file also results in a "connection .... was lost" error.

Yes. 'Unable to play 'doorbell.mp3' - the connection to 192.168.2.4:9123 was lost'

I hear a doorbell sound when I use the duckdns URL and no error message in the Sonos app.

2. Do you have installed duckdns as Home Assistant Add On? Can you stop that add von 5 minutes and try the group.play.notification?

Yes duckdns is installed as an add-on in HA. I stopped the add-on and there's no difference even after 10 minutes -- the doorbell sound still plays when using duckdns.org URL. However, when I ping my duckdns dnsname, it still properly resolves to my external WAN IP, so not sure how long it would have to be disabled for the hostname association to time out, if that's what you're trying to get at...

@gourdo1
Copy link
Author

gourdo1 commented Dec 18, 2023

So I just installed the Sonos integration in Home Assistant. Not sure why I didn't try before, but it exposes a media player entity that I can use to theoretically play audio files in NodeRED similar to your integration.

... and it faces the same issue of only playing against my duckdns hostname, and not an internal IP.

At this point, I'm guessing the issue has more to do with Sonos itself not accepting a local file to play. Maybe they just don't like the idea of someone playing their own local files as opposed to paid or at least integrated services so they block IP addresses? Dunno, but I guess it's not a limitation of your implementation after all.

@hklages
Copy link
Owner

hklages commented Dec 18, 2023

Agree - it is not a limitation of my implementation.

I am able to play local files on Home Assistant, from Synology NAS, from other file server. So in general SONOS accepts these local files (even only http instead of https)

Something in the DuckDNS / Home Assistant combination is not supported from SONOS but I have no idea how to overcome that.

If you have another server you could put your files on that server. Maybe that works.

Another idea is to use the SONOS app and add the www directory as "library" and then select it as an library item. There are several commands to do ti.

@gourdo1
Copy link
Author

gourdo1 commented Dec 18, 2023

I even went a step further and went to the builtin web UI for my Sonos Arc... which has a ping utility as well as tracert. (http://192.168.2.225:1400/tools.htm) and not only can it ping the HA server's IP, but it can tracert and determine the local hostname for the server from its perspective:

running /usr/bin/traceroute 192.168.2.4
traceroute to 192.168.2.4 (192.168.2.4), 30 hops max, 46 byte packets
 1  homeassistant.localdomain (192.168.2.4)  0.941 ms  0.821 ms  0.380 ms

Yet again, using that as the hostname utterly fails. Sonos doesn't like using IPs/names it thinks are local.

The reaosn i want to use the HA server to host the file is that everything is self-contained. I don't have to worry about yet another device being available as long as HA is up. I didn't want to rely on the duckdns because that's another potential point of failure when my HA server's static IP would be more reliable long-term. In any case, for now, I'll stick to the duckdns name and see if I can find out more about the Sonos limitations.

@gourdo1
Copy link
Author

gourdo1 commented Dec 18, 2023

Ok, so I think I know what's going on. I tried a different dynamic DNS service for my HA server and oddly, it failed to work...

Then I found a thread here, which hints at the issue:
home-assistant/core#55223

Basically a couple years ago, it seems Sonos added more stringent TLS certificate checking to the system, I assume for security purposes. Since I'm using https for my HA server and the certificate is literally for the duckdns name, it plays just fine for that DNS name, but any other IP address or hostname I try that references the same server results in a mismatched SSL certificate hostname(!) and SOnos refuses to play... albeit with a cryptic error message that doesn't tell you what the actual problem is.

So I think I could either turn off SSL (not the best idea) or create a new certificate to include the internal IP or alternate internal hostname, etc.

I think the mystery is finally solved!

@hklages hklages added the solved label Dec 18, 2023
@hklages
Copy link
Owner

hklages commented Dec 18, 2023

Thanks for solving the "mystery".

@hklages hklages closed this as completed Dec 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants