ol-iver / denonavr

Automation Library for Denon AVR receivers.
MIT License
176 stars 67 forks source link

Sometimes Denon and Marantz /description.xml goes skewy #189

Closed sjwright closed 3 years ago

sjwright commented 3 years ago

I was setting up my Denon AVR-X4000 with this library and noticed a strange failure state. After reading your code and investigating what was causing this, I eventually tracked the problem to my device returning a rather weird description.xml file:

<?xml version="1.0"?>
<root ...>
    <device>
...
        <friendlyName></friendlyName>
        <manufacturer>BridgeCo AG, Switzerland</manufacturer>
        <manufacturerURL>http://www.bridgeco.com/</manufacturerURL>
        <modelDescription>BridgeCo Digital Media Adapter with UPnP</modelDescription>
        <modelName>DigitalMediaAdapterUPnP</modelName>
        <modelNumber>03</modelNumber>
        <modelURL>http://www.bridgeco.com/</modelURL>
...
    </device>
</root>

After power cycling the device, the XML now returns correct values:

<?xml version="1.0"?>
<root ...>
    <device>
...
        <friendlyName>lounge-avr</friendlyName>
        <manufacturer>Denon</manufacturer>
        <manufacturerURL>http://www.denon.com</manufacturerURL>
        <modelDescription>AV SURROUND RECEIVER</modelDescription>
        <modelName>*AVR-X4000</modelName>
        <modelNumber>X4000</modelNumber>
        <modelURL>http://www.denon.com</modelURL>
...
    </device>
</root>

(Other than the lines shown above, the XML file was identical.)

I don't know what causes the device to start outputting these wrong values, but it appears I'm not alone in this. Here's the same problem occurring with a Marantz: https://github.com/home-assistant/core/issues/37351

Obviously there's nothing this library can do about the device returning corrupted model data but currently the library returns a generic error message and assigns a generic device state, per /denonavr/denonavr.py:500:

        if device_info is None:
            self._manufacturer = "Denon"
            self._model_name = "Unknown"
            self._serial_number = None
            _LOGGER.error(
                "Unable to get device information of host %s, can not "
                "use the serial number as identification", self._host)

Because a generic device state is being returned, applications aren't able to help their users resolve this problem to get a fully functional experience. I propose that this corrupted state be identified in ssdp.py and a hard failure state (akin to a connection timeout) is triggered in denonavr.py.

        except requests.exceptions.OhNoItsPrentendingToBeSomeBridgeCoDevice:
            _LOGGER.error("Unable to get device information. Device is in a corrupted state. "
                "Disconnect and reconnect power to the device and try again.")
            return
ol-iver commented 3 years ago

That's a good idea 👍 I did a major change in the library and included your proposal there in a slightly different way