Issue with Russound RNET Component after 39.3

Hi everyone - I’ve run into an issue with the Russound RNET component and wanted to see if others had similar problems.

The amplifier is a Russound CAA66 and it is connected to the network via a Raspberry Pi and a serial-to-USB cable. The ser2net package is installed and used to allow Home Assistant to connect to the amp.

On initial startup, the component appears to initially load, but then fails due to:
Unsupported operand type(s) for /: 'Nonetype' and 'float'
and none of the individual media_player entity_ids are loaded.

This component last worked in version 39.3 with the same set up and configuration.

I’ve pasted the interesting bits from the log file below. Has anyone seen the same issue or have any suggestions to get it back up and running?

Thanks!

17-04-10 12:02:23 INFO (Thread-1) [russound.russound] Successfully connected to Russound on 10.99.1.87:6271
17-04-10 12:02:25 WARNING (Thread-8) [russound.russound] Error obtaining Russound power state for controller 1 and zone 1.
17-04-10 12:02:25 WARNING (Thread-4) [russound.russound] Error obtaining Russound power state for controller 1 and zone 3.
17-04-10 12:02:25 WARNING (Thread-8) [russound.russound] Did not receive expected response message from Russound controller.
17-04-10 12:02:25 WARNING (Thread-4) [russound.russound] Did not receive expected response message from Russound controller.
17-04-10 12:02:25 WARNING (Thread-5) [russound.russound] Error obtaining Russound power state for controller 1 and zone 2.
17-04-10 12:02:25 WARNING (Thread-7) [russound.russound] Error obtaining Russound power state for controller 1 and zone 4.
17-04-10 12:02:25 WARNING (Thread-5) [russound.russound] Did not receive expected response message from Russound controller.
17-04-10 12:02:25 WARNING (Thread-7) [russound.russound] Did not receive expected response message from Russound controller.
17-04-10 12:02:25 WARNING (Thread-11) [russound.russound] Error obtaining Russound power state for controller 1 and zone 5.
17-04-10 12:02:25 WARNING (Thread-11) [russound.russound] Did not receive expected response message from Russound controller.
17-04-10 12:02:25 WARNING (Thread-12) [russound.russound] Error obtaining Russound power state for controller 1 and zone 6.
17-04-10 12:02:25 WARNING (Thread-12) [russound.russound] Did not receive expected response message from Russound controller.
17-04-10 12:02:26 WARNING (Thread-8) [russound.russound] Error obtaining Russound power state for controller 1 and zone 1.
17-04-10 12:02:26 WARNING (Thread-8) [russound.russound] Did not receive expected response message from Russound controller.
17-04-10 12:02:26 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/lib/python3.4/asyncio/tasks.py", line 233, in _step
    result = coro.throw(exc)
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/helpers/entity_component.py", line 359, in async_process_entity
    new_entity, self, update_before_add=update_before_add
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/helpers/entity_component.py", line 189, in async_add_entity
    yield from self.hass.loop.run_in_executor(None, entity.update)
  File "/usr/lib/python3.4/asyncio/futures.py", line 388, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.4/asyncio/tasks.py", line 286, in _wakeup
    value = future.result()
  File "/usr/lib/python3.4/asyncio/futures.py", line 277, in result
    raise self._exception
  File "/usr/lib/python3.4/concurrent/futures/thread.py", line 54, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/components/media_player/russound_rnet.py", line 95, in update
    self._volume = self._russ.get_volume('1', self._zone_id) / 100.0
TypeError: unsupported operand type(s) for /: 'NoneType' and 'float'
17-04-10 12:02:26 WARNING (Thread-4) [russound.russound] Error obtaining Russound power state for controller 1 and zone 3.
17-04-10 12:02:26 WARNING (Thread-4) [russound.russound] Did not receive expected response message from Russound controller.
17-04-10 12:02:26 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/lib/python3.4/asyncio/tasks.py", line 233, in _step
    result = coro.throw(exc)
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/helpers/entity_component.py", line 359, in async_process_entity
    new_entity, self, update_before_add=update_before_add
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/helpers/entity_component.py", line 189, in async_add_entity
    yield from self.hass.loop.run_in_executor(None, entity.update)
  File "/usr/lib/python3.4/asyncio/futures.py", line 388, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.4/asyncio/tasks.py", line 286, in _wakeup
    value = future.result()
  File "/usr/lib/python3.4/asyncio/futures.py", line 277, in result
    raise self._exception
  File "/usr/lib/python3.4/concurrent/futures/thread.py", line 54, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/components/media_player/russound_rnet.py", line 95, in update
    self._volume = self._russ.get_volume('1', self._zone_id) / 100.0
TypeError: unsupported operand type(s) for /: 'NoneType' and 'float'
17-04-10 12:02:26 WARNING (Thread-12) [russound.russound] Error obtaining Russound power state for controller 1 and zone 6.
17-04-10 12:02:26 WARNING (Thread-12) [russound.russound] Did not receive expected response message from Russound controller.
17-04-10 12:02:26 WARNING (Thread-11) [russound.russound] Error obtaining Russound power state for controller 1 and zone 5.
17-04-10 12:02:26 WARNING (Thread-5) [russound.russound] Error obtaining Russound power state for controller 1 and zone 2.
17-04-10 12:02:26 WARNING (Thread-11) [russound.russound] Did not receive expected response message from Russound controller.
17-04-10 12:02:26 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/lib/python3.4/asyncio/tasks.py", line 233, in _step
    result = coro.throw(exc)
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/helpers/entity_component.py", line 359, in async_process_entity
    new_entity, self, update_before_add=update_before_add
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/helpers/entity_component.py", line 189, in async_add_entity
    yield from self.hass.loop.run_in_executor(None, entity.update)
  File "/usr/lib/python3.4/asyncio/futures.py", line 388, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.4/asyncio/tasks.py", line 286, in _wakeup
    value = future.result()
  File "/usr/lib/python3.4/asyncio/futures.py", line 277, in result
    raise self._exception
  File "/usr/lib/python3.4/concurrent/futures/thread.py", line 54, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/components/media_player/russound_rnet.py", line 95, in update
    self._volume = self._russ.get_volume('1', self._zone_id) / 100.0
TypeError: unsupported operand type(s) for /: 'NoneType' and 'float'
17-04-10 12:02:26 WARNING (Thread-5) [russound.russound] Did not receive expected response message from Russound controller.
17-04-10 12:02:26 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/lib/python3.4/asyncio/tasks.py", line 233, in _step
    result = coro.throw(exc)
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/helpers/entity_component.py", line 359, in async_process_entity
    new_entity, self, update_before_add=update_before_add
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/helpers/entity_component.py", line 189, in async_add_entity
    yield from self.hass.loop.run_in_executor(None, entity.update)
  File "/usr/lib/python3.4/asyncio/futures.py", line 388, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.4/asyncio/tasks.py", line 286, in _wakeup
    value = future.result()
  File "/usr/lib/python3.4/asyncio/futures.py", line 277, in result
    raise self._exception
  File "/usr/lib/python3.4/concurrent/futures/thread.py", line 54, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/components/media_player/russound_rnet.py", line 95, in update
    self._volume = self._russ.get_volume('1', self._zone_id) / 100.0
TypeError: unsupported operand type(s) for /: 'NoneType' and 'float'
17-04-10 12:02:26 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/lib/python3.4/asyncio/tasks.py", line 233, in _step
    result = coro.throw(exc)
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/helpers/entity_component.py", line 359, in async_process_entity
    new_entity, self, update_before_add=update_before_add
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/helpers/entity_component.py", line 189, in async_add_entity
    yield from self.hass.loop.run_in_executor(None, entity.update)
  File "/usr/lib/python3.4/asyncio/futures.py", line 388, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.4/asyncio/tasks.py", line 286, in _wakeup
    value = future.result()
  File "/usr/lib/python3.4/asyncio/futures.py", line 277, in result
    raise self._exception
  File "/usr/lib/python3.4/concurrent/futures/thread.py", line 54, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/components/media_player/russound_rnet.py", line 95, in update
    self._volume = self._russ.get_volume('1', self._zone_id) / 100.0
TypeError: unsupported operand type(s) for /: 'NoneType' and 'float'
17-04-10 12:02:26 WARNING (Thread-7) [russound.russound] Error obtaining Russound power state for controller 1 and zone 4.
17-04-10 12:02:26 WARNING (Thread-7) [russound.russound] Did not receive expected response message from Russound controller.
17-04-10 12:02:26 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/lib/python3.4/asyncio/tasks.py", line 233, in _step
    result = coro.throw(exc)
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/helpers/entity_component.py", line 359, in async_process_entity
    new_entity, self, update_before_add=update_before_add
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/helpers/entity_component.py", line 189, in async_add_entity
    yield from self.hass.loop.run_in_executor(None, entity.update)
  File "/usr/lib/python3.4/asyncio/futures.py", line 388, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.4/asyncio/tasks.py", line 286, in _wakeup
    value = future.result()
  File "/usr/lib/python3.4/asyncio/futures.py", line 277, in result
    raise self._exception
  File "/usr/lib/python3.4/concurrent/futures/thread.py", line 54, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/components/media_player/russound_rnet.py", line 104, in update
    self._source = self._sources[index]
TypeError: list indices must be integers, not NoneType

Finally had a bit of time to do some troubleshooting.

I was able to successfully control the unit by sending hex commands through a generic packet sender. This leads me to believe the problem is with my configuration or, since the log initially gives a ‘successfully connected’ message before failing, one of the HASS dependencies.

The error also occurs now when reverting back to 39.3 – the last version that it previously worked on. I imagine this means that one of the updated dependencies is probably causing the issue – not HASS itself.

Anyone have any ideas on where I could continue troubleshooting? @laf or @acambitsis – have either of you noticed the same issue?

Thanks!

I’ve managed to replicate this now. I can get my devices to show up by fudging some code, will need to find out why.

Okay great! Let me know if you need any data from me. I’m happy to help troubleshoot

Ok I can see why, it’s due to the return response from a call being None (for me at least). I’ve fudged it on my side to return 1 instead of None. To do the same edit:

.homeassistant/deps/russound/russound.py

Find the line: def get_zone_info(self, controller, zone, return_variable):

In that function you will see: return_value = None, change it for return_value = 1

Restart hass. Let me know if it works ok and I’ll patch the source (this will break if you update hass I think)

@acambitsis Don’t know if you’ve got 5 mins to check what I’ve proposed is sane. I think it’s because the russounds don’t always return the info we need at which point we mark it as None. It might be better to handle that in the hass russound plugin but I’m not sure.

1 Like

That worked for me! Thanks!! :grinning:

Hey @gth758y, @laf - sorry only got round to this now. My system was dormant, and I have just got it back up and running and installed latest HA. Issue happens on my side too.

@laf thanks for figuring out the problem. I’ll try spend some tomorrow to checkout your fix.

@acambitsis The initial stab was just a bodge.

I think it might be better to do some validation within the hass russound code and set the defaults.

@armills I was hoping you can help out here so we can fix this issue the right way. You may recall you helped with the pull request https://github.com/home-assistant/home-assistant/pull/5756 re the changes @laf and I made on improving russound support. Subsequently after v 39.3 of HA the error above is showing up when the component first starts up. Its occurring because when we cannot determine the state of a variable from russound we return None. It seems HA is not happy with that. @laf has proposed a workaround, but wanted to confirm with you what is the best way to handle an unknown state. Thanks.

Read through this here. I think the problem isn’t necessarily that hass is getting a None, but it’s that we’re trying to do math on it.

I’d change this line to something like what’s shown below, at least for a start.
Old:

self._volume = self._russ.get_volume('1', self._zone_id) / 100.0

New:

self._volume = self._russ.get_volume('1', self._zone_id)
if self._volume is not None:
    self._volume /= 100

Thanks @armills. Totally makes sense that that would be an issue - sloppy on my part. Changing the above and also explicitly handling a None on ‘index’ on line 104 (self._source = self._sources[index]) was also required.
What is bothering me is why this didn’t show up as an issue from the start?

Hi there. I finally had a chance to learn python and find a stable solution for this issue. From the time that I invested, I found that the errors we were getting are derived from the following:

  1. The original code did not take into consideration that multiple instances of it will be running under different threads to update each zone independently. I could see multiple threads sending requests at the same time, which made the requests send garbage to the russound. Added code to synchronize access to the tcp sockets, and that got rid of most of the problem.
  2. The original code was incorrectly setting one byte of the request to get all data from a zone, and that made the russound send back a bunch of stuff we did not want to get. The code is just asking for what it needs now.
  3. The code was making three calls to the same function to get the status of a zone, I changed it to get all parameters in a single call.

I can send you the files if you contact me, I’m still learning how to submit the changes, so it will probably take a while to see these reflected in an official release.

cheers!

Hi Gerado - sounds like you have progressed things nicely - very happy help get this submitted. I’ll try contact you directly.