svrooij / node-sonos-ts

:speaker: Sonos control library, use this library in your own appliction.
https://sonos-ts.svrooij.io/
MIT License
81 stars 18 forks source link

feature: Support for resolving hostname on creating sonos device #151

Closed hklages closed 2 years ago

hklages commented 2 years ago

What happened

When using a DNS name such as sonosplay5.fritz.box instead of 192.168.178.37 the library throws an error (see debug logging). The name is assigned by my router (fritzbox) and ping, nslookup confirms, that this name is assigned to the above ip address.

2022-01-04T1733: Using the browser for a simple http://..../status also doesn not work and causes a "bad request" error. So SONOS is rejecting all DNS names 😞.

What did you expect to happen

I hoped that I could use the DNS names without using nodeJS DNS Preparing a work around to use 2 regex (ip-format, dns format) and in case of dns format, resolve the ip address and use that in the following code.

How to reproduce it (minimal and precise)

Just use the DNS name of your SONOS player instead of the IP address.

Debug logging

group.get.state:Cannot read properties of undefined (reading 's:Body') :: Details: {"stack":"TypeError: Cannot read properties of undefined (reading 's:Body')
    at ZoneGroupTopologyService.handleErrorResponse (/config/node-red/node_modules/node-red-contrib-sonos-plus/node_modules/@svrooij/sonos/lib/services/base-service.js:226:51)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async ZoneGroupTopologyService.handleRequestAndParseResponse (/config/node-red/node_modules/node-red-contrib-sonos-plus/node_modules/@svrooij/sonos/lib/services/base-service.js:204:15)
    at async ZoneGroupTopologyService.SoapRequest (/config/node-red/node_modules/node-red-contrib-sonos-plus/node_modules/@svrooij/sonos/lib/services/base-service.js:82:16)
    at async ZoneGroupTopologyService.GetZoneGroupState (/config/node-red/node_modules/node-red-contrib-sonos-plus/node_modules/@svrooij/sonos/lib/services/zone-group-topology.service.js:44:40)
    at async Object.getGro...

Environment

svrooij commented 2 years ago

I’m using node-fetch to do all the requests. I’m sure it would resolve a hostname to an ip without doing anything to it. What happens if you execute ping sonosplay5.fritz.box?

Did you change the dns server on the device running node red?

svrooij commented 2 years ago

Tried the following:

  1. Setup name for sonos speaker in router
  2. Tried calling http://192.168.1.30:1400/xml/device_description.xml (works)
  3. Tried calling http://sonos-kantoor:1400/xml/device_description.xml (broken)

Each call you do to a speaker with the name instead of the IP, you'll get this response:

<HTML><HEAD><TITLE>Error 400</TITLE></HEAD><BODY><H1>Error 400</H1><P>Bad Request</P></BODY></HTML>

That means we cannot use the regular way of doing things and it we want this we need to do a lookup by name before we can continue. But then how often do we need to refresh? What happens on changes? Is this something this library should do, or should this be done in your node-red module?

hklages commented 2 years ago

That's, what I tried to explain you in my previous comment:

SONOS is rejecting all DNS names.

Hmmmm - I should be more precise next time.

That means we cannot use the regular way of doing things and it we want this we need to do a lookup by name before we can continue. But then how often do we need to refresh? What happens on changes? Is this something this library should do, or should this be done in your node-red module?

Fully agree.

For node-red I will use dns.resolve() . If the ip address changes, you also have to enter the new ip address. So it is ok for me.

svrooij commented 2 years ago

Are you ok with closing this issue because Sonos seems to refuse hostnames. Maybe I have to add it to the docs.

hklages commented 2 years ago

Sure. I like the idea to use DNS names and migrated my small network to DNS names. It is a pity that SONOS player refuse DNS name requests. Hope that the dns.resolve will work.