Cambridge Audio CXN and CXA media_player

Hello there!

I’m soooo interested in getting this add-on working on my setup!! thanks a million for your work!! I tried to install the two flavours and failed miserably in both cases :frowning:

As the the HA connected back2back over serial with the CXA contains “less moving parts”, I think it should be easier to fix this flavour first.

This is the error that I see upon rebooting HA, once I have followed all the steps indicated in GitHub:

Logger: homeassistant.config
Source: custom_components/cambridge_cxa/media_player.py:11 
Integration: cambridge_cxa (documentation, issues) 
First occurred: 10:24:51 PM (1 occurrences) 
Last logged: 10:24:51 PM

Platform error: media_player
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/config.py", line 928, in async_process_component_config
    platform = p_integration.get_platform(domain)
  File "/usr/src/homeassistant/homeassistant/loader.py", line 744, in get_platform
    cache[full_name] = self._import_platform(platform_name)
  File "/usr/src/homeassistant/homeassistant/loader.py", line 761, in _import_platform
    return importlib.import_module(f"{self.pkg_path}.{platform_name}")
  File "/usr/local/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/config/custom_components/cambridge_cxa/media_player.py", line 11, in <module>
    from serial import Serial
ImportError: cannot import name 'Serial' from 'serial' (/usr/local/lib/python3.10/site-packages/serial/__init__.py)

any idea what I should do to fix the error?

cannot import name 'Serial' from 'serial' 

Also, there is something worth noting. As soon as I connected a serial cable to my HA, installed this plugin, included the new media_player code and rebooted HA, I lost all my RFXTRX entities! :frowning:

Logger: homeassistant.config_entries
Source: components/rfxtrx/__init__.py:138 
First occurred: 10:24:51 PM (1 occurrences) 
Last logged: 10:24:51 PM

Error setting up entry RFXTRX for rfxtrx
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/RFXtrx/__init__.py", line 784, in connect
    self.serial = serial.Serial(self.port, 38400, timeout=0.1)
AttributeError: module 'serial' has no attribute 'Serial'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 382, in async_setup
    result = await component.async_setup_entry(hass, self)
  File "/usr/src/homeassistant/homeassistant/components/rfxtrx/__init__.py", line 91, in async_setup_entry
    await async_setup_internal(hass, entry)
  File "/usr/src/homeassistant/homeassistant/components/rfxtrx/__init__.py", line 168, in async_setup_internal
    rfx_object = await hass.async_add_executor_job(_create_rfx, config)
  File "/usr/local/lib/python3.10/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/homeassistant/homeassistant/components/rfxtrx/__init__.py", line 138, in _create_rfx
    rfx = rfxtrxmod.Connect(
  File "/usr/local/lib/python3.10/site-packages/RFXtrx/__init__.py", line 977, in __init__
    self.transport = transport_protocol(device)
  File "/usr/local/lib/python3.10/site-packages/RFXtrx/__init__.py", line 779, in __init__
    self.connect()
  File "/usr/local/lib/python3.10/site-packages/RFXtrx/__init__.py", line 785, in connect
    except serial.serialutil.SerialException:
AttributeError: module 'serial' has no attribute 'serialutil'

thanks!!

and if I now try to reboot HA, this is the error message that I see:

Platform error media_player.cambridge_cxa - cannot import name 'Serial' from 'serial' (/usr/local/lib/python3.10/site-packages/serial/__init__.py) 

Hi ShallonTZ,

Make sure to have a directory structure like this:

<hass root dir>/custom_components/cambridge_cxn/

Put the __init__.py, manifest.json and media_player.py files in there. Should work.
I have just committed version 0.5 of the CXN component to my github. Please try that version.

Thx!

Hi kitus,

Looks like you don’t have the pyserial module installed.

Try following command: pip3 install pyserial and then reboot HA.
No idea about your RFXTRX issue though… You still experience issues with that now?

Yes, my RFXTRX devices are all gone. I guess there is a conflict between the two serial devices. It is very weird. I tried to load a previous snapshot and it did not fix it. Rebooted the host to no avail either.

Try following command: pip3 install pyserial and then reboot HA.

I’m on Debian running HA Supervised. I should install these two components?

python3-serial - pyserial - module encapsulating access for the serial port
python3-serial-asyncio - Async I/O extension package for pyserial

Thanks a million for your work. Is there anyway I can buy you a coffee?

I went ahead and installed python3-serial on my Debian, and it does not change a thing

Logger: homeassistant.config
Source: custom_components/cambridge_cxa/media_player.py:11 
Integration: cambridge_cxa (documentation, issues) 
First occurred: 11:10:59 PM (1 occurrences) 
Last logged: 11:10:59 PM

Platform error: media_player
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/config.py", line 928, in async_process_component_config
    platform = p_integration.get_platform(domain)
  File "/usr/src/homeassistant/homeassistant/loader.py", line 744, in get_platform
    cache[full_name] = self._import_platform(platform_name)
  File "/usr/src/homeassistant/homeassistant/loader.py", line 761, in _import_platform
    return importlib.import_module(f"{self.pkg_path}.{platform_name}")
  File "/usr/local/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/config/custom_components/cambridge_cxa/media_player.py", line 11, in <module>
    from serial import Serial
ImportError: cannot import name 'Serial' from 'serial' (/usr/local/lib/python3.10/site-packages/serial/__init__.py)

Hello,

I went ahead and also tested the raspberry pi option and it worked!!! Man, any chance I could buy you a coffee?

Question: @lievencoghe I’ve read in the official documentation that one cannot adjust the volume through the serial connection, but do you know if one could at least read the current volume on the amp? I Don’t see that documented, but while i could understand Cambridge won’t allow volume adjustments over serial, I don’t see why reading the volume is not an option.

THANKS AGAIN!!!

Hi Kitus,

If I understand correctly, you got the serial module installed, and you no longer see the error message "cannot import name ‘Serial’ from ‘serial’ ? Glad to read that you have it working now!!

To answer your question about volume control, you are right, unfortunately this is not possible with the serial connection. Nor can you read out the current volume level. If you have a CXN, and you have connected the control bus cable between the CXN and CXA, then you can adjust the CXA’s volume.
Let me know if you have a CXN, and need help setting this up.

I never say no to a coffee btw :wink: https://www.buymeacoffee.com/lievencoghe

Hi there!

The integration is working. I can’t comment on the reliability because I’ve not had much time to play around with it, but feels solid.

The issue with my rfxtrx sensors is still present but marginally. Every time my HA instance comes up, all my rfxtrx sensors appear as unavailable. I’ve learnt how to work this around by running

ha core rebuild

not much of an issue but still annoying. Do you know why this may happen?

Also, I discovered this: GitHub - andrew-bolin/pi_hifi_ctrl: Raspberry Pi Hi-Fi Amplifier Control Volume control seems to be possible through that, although it looks like there is no integration with home assistant…

If you own a CXN, I imagine that you are all set. I still have not addressed my primary need, and may continue to look into this in the future (with a bit less of an urgency as I managed to get partial control of the amp thanks to your integration). My main use case is: prevent from any music to be played through my speakers unless I’m sure my toddler has not turned the volume up to the maximum level.

Also, the only version that I see in GitHub is 0.4, right?

Thanks a lot for your terrific job. Coffee is coming (as soon as I get to my computer) :wink:

Hmm, interesting… I also have the RFXTRX integration, but do not experience the behaviour you are seeing. My RFXCOM device however, is connected to a remote Raspberry PI. Other than that, I really have no idea why you need to rebuild every time HA starts…

This repo you’re referring to is most interesting! I will have a deeper look into it. Especially the CEC/ARC part could be very convenient!

I had to laugh… Fearing your toddler has turned up the volume all the way :laughing: This is all temporary, I can tell you. My kids are 6 & 9 now. Can’t imagine them pulling something like that on me anymore. But I feel your pain. Unfortunately there will be no way of telling the current volume level through any integration. The CXA still has a classic volume pot. The volume is not set In the digital domain.

Please let me know how you get on In the future with the component. Ideas/suggestions are most welcome. And cheers! :coffee:

My RFXCOM device however, is connected to a remote Raspberry PI. Other than that, I really have no idea why you need to rebuild every time HA starts…

I guess it depends how the hosts “sees” the rfxtrx device. Are you doing a similar trick that what you do with the /dev/ttyCXA device? My rfxtrx is connected physically to my HA.

This repo you’re referring to is most interesting! I will have a deeper look into it. Especially the CEC/ARC part could be very convenient!

That’s a bonus yes!!

Unfortunately there will be no way of telling the current volume level through any integration. The CXA still has a classic volume pot. The volume is not set In the digital domain.

Wait, what? That integration does allow to access the volume level, doesn’t it? this integration is accessing the cambridge proprietary bus. For sure the volume level is accessible.

I had to laugh… Fearing your toddler has turned up the volume all the way :laughing: This is all temporary, I can tell you. My kids are 6 & 9 now. Can’t imagine them pulling something like that on me anymore

Yeah! I have 3 kids, and the 2 oldest wouldn’t do that either. Still I’m a bit worried that somebody could accidentally turn the volume all the way up and I could ruin my speakers… my toddler is what put this thought in my head but somebody cleaning could do that accidentally.

Please let me know how you get on In the future with the component. Ideas/suggestions are most welcome. And cheers!

If I’m right and that new integration allows accessing the volume, I would be willing to pay more a bunch of coffees or even a complete meal!!!

I also have the RFXTRX integration, but do not experience the behaviour you are seeing. My RFXCOM device however, is connected to a remote Raspberry PI.

I just created this issue with RFXTRX RFXTRX integration inconsistent due to using custom integration · Issue #86382 · home-assistant/core · GitHub

[I have a cambridge CXN V1 streamer.
I managed to integrate it into home assistant.
The commands work well except for the power command which turns off the CXN, but does not allow it to be started.
What did I miss, or is it the CXN that does not allow it???
Thank you for this very nice development.

I have been using @lievencoghe’s repo with my CXNv2 and have had great success. I forked the repo and added a support HACS (just today realized this is pretty much exactly what @rromrrom did). Should I make a pull request?

The two things that I have noticed:

  1. The CXN uses 0-30 for volume. Is is possible to sync this with HA, instead of 0-100? I have been digging into your logic around this, but not quite sure is possible on the HA side.
  2. Is there a way for the device to get unique ID?

Thanks!

Had some issues getting it working, mostly due to the fact that my CXN had decided to switch to DHCP without me knowing instead of fixed IP but working now. Nice to have this so many thanks for your hard work.

I’ve been using this for a while now with an Evo 150, but it wasn’t working great for me as it would hang when turned off: the media player entity in HA would still show as On/Playing, after that only a restart of HA would fix the state. In the python script I noticed that it requires Network Standby to see the correct state, which makes sense as the web server is otherwise not available. As I’m using eco mode it can’t detect the off state so it defaults to ‘On’. I’ve changed this to ‘Off’, and added some extra ‘Idle’ states the Evo uses:

            elif self._state == "stop":
                return STATE_IDLE
            elif self._state == "ready": #state when device is selected as cast output, but nothing is playing yet
                return STATE_IDLE
            elif self._state == "not_ready": #state when Tidal is selected as input but nothing is playing yet
                return STATE_IDLE
            elif self._state == "no_signal": #state when any input doesn't give a signal. Default state for Phono input when the record is not playing
                return STATE_IDLE
            else:
                return STATE_OFF #so the device doesn't stay 'On' when eco-mode is enabled

Something else that was missing for me was to see the speaker output. I’ve changed the script to show this in the ‘Sound_mode’ field in HA, see here, it’s basically a copy of the ‘source_list’ code. Unfortunately I can’t get the command to change the sound mode (output) to work. The error it gives when changing the sound mode (in a browser) is ‘Can’t select Bluetooth output without specifying a device’, and I’m using this link: http://192.x.x.x/smoip/zone/state?audio_output=SPEAKER_A_B changing ‘SPEAKER_A_B’ to a non-existing output gives an error, so the id seems to be correct.

I’ve also decompiled the APK, but can’t find any other action to change audio output. Here’s the relevant file: https://pastebin.com/E667zNFx

If someone can figure out how to change the speaker output I’m very interested. Currently doing it with IR sequences, but it’s not very reliable, hence the need to be able to check it in HA. Perhaps with wireshark or something like that it can be intercepted from the app.

Edit: managed to get the correct link by capturing it on my phone in the StreamMagic app :slight_smile: I’ve added it to my repo. In short the changes I made:

  • Added more Idle states
  • Added output select (speakers A, B etc.) by using Sound_mode in HA
  • Added media_content_type = Music, so HA shows the artist in the media player entity card

Thanks for the original repo Lieven!

I am getting Failed to call service media_player/media_next_track. HTTP Error 400: Request Failed errors (or similar) for Next, Previous, Shuffle, and Repeat. Do these work for others? What do I need to do to debug this issue? Cheers!

This is a fantastic bit of work - let me add my voice to the thanks!

I’d like to find a way to query the CXN to see which source it’s currently set to. At the moment this seems that it’s not possible, though I could be wrong. Am I right, and what would it take to add it? I am new to this kind of coding but will try my best - or pay in coffees…!

Thank you.

Hi everyone,
first of all, thank you so much for this great project. I am trying to make it work with a Cambridge CXA61 using a Serial adapter directly connected to my host (Unraid with HA OS VM).

After setting up the component, the media_player showed up and I was able to turn off and on my receiver. Great!

I then restarted Home Assistant after removing another custom_component (Apple TV) which should not matter actually… but now I am facing this issue:

File "/config/custom_components/cambridge_cxa/media_player.py", line 11, in <module>
    from serial import Serial

ImportError: cannot import name 'Serial' from 'serial' (/usr/local/lib/python3.12/site-packages/serial/__init__.py)

Any idea what to try? Especially since it worked before…

Hi, I just faced the same issue.

I assume you are running in docker? Anyway, I am, and this is how I solved the issue.

Go into the shell of the container:
docker exec -it <container name> /bin/bash

Then uninstall and reinstall pyserial:

pip uninstall pyserial
pip install pyserial

Exit from the container’s shell:
exit

Restart home assistant:
docker restart <container name>

Please let me know if this solves your issue.