Problem with RoonCommandLine

Hi @Ronald_Record, I’m getting in touch as I seem to have run into a problem with RoomCommandLine. Specifically, the volume commands seem to have stopped working.

For example, if I use roon in the terminal app I get the following error:

/usr/local/bin/roon: /usr/local/Roon/venv/bin/rich: /usr/local/Roon/venv/bin/python: bad interpreter: No such file or directory

And when I try to change the volume nothing happens. Other commands still work (e.g. play/pause, next track etc.

Likewise, if I run roon -v g:r:5 -z “Kef LSX” in BetterTouchTool it reports the following:

Traceback (most recent call last):
  File "/usr/local/Roon/api/set_volume.py", line 149, in <module>
    roonapi.change_volume_raw(output_id, zone_volume,
AttributeError: 'RoonApi' object has no attribute 'change_volume_raw'. Did you mean: 'change_volume'?

Let me know if you need any more information.

Hi @DaveN , it looks like your Python installation may be the problem. The first error you report:

/usr/local/Roon/venv/bin/python: bad interpreter: No such file or directory

seems to indicate the RoonCommandLine Python virtual environment was not setup correctly. The second error:

AttributeError: 'RoonApi' object has no attribute 'change_volume_raw'.

is likely a result of the first error, the roonapi Python module was not loaded because python could not be found.

What do you see with the command:

ls -l /usr/local/Roon/venv/bin/python

Then follow that up with ls -l /path/to/symlinked/python. Keep listing whatever python points to until you get to the actual python executable. On my Ubuntu 20.04 system with Python 3.8 installed this looks like the following:

ls -l /usr/local/Roon/venv/bin/python
lrwxrwxrwx root root 7 B Sun Aug 18 08:36:01 2024  /usr/local/Roon/venv/bin/python ⇒ python3
ls -l /usr/local/Roon/venv/bin/python3
lrwxrwxrwx root root 16 B Sun Aug 18 08:36:01 2024  /usr/local/Roon/venv/bin/python3 ⇒ /usr/bin/python3
ls -l /usr/bin/python3
lrwxrwxrwx root root 9 B Fri Mar 13 05:20:20 2020  /usr/bin/python3 ⇒ python3.8
ls -l /usr/bin/python3.8
.rwxr-xr-x root root 5.2 MB Wed Sep 11 09:02:53 2024  /usr/bin/python3.8

Also, let’s see what your RoonCommandLine Python virtual environment looks like:

source /usr/local/Roon/venv/bin/activate
type python
python -c 'import site; print(site.getsitepackages())' | tr -d '[],'

This last command, showing where the Python site packages are installed in the virtual environment, may not work since it appears your Python executable is not found. If it does work, verify that the roonapi package is in one of the directories in your site packages path.

This may provide some info on what is missing or misinstalled. We can go from there.

1 Like

Hi Ronald, thanks for your swift response.

lrwxr-xr-x  1 root  wheel  10  1 Jun 21:33 /usr/local/Roon/venv/bin/python -> python3.12
djn@trinity ~ % ls -l /usr/local/Roon/venv/bin/python3.12
lrwxr-xr-x  1 root  wheel  44  1 Jun 21:33 /usr/local/Roon/venv/bin/python3.12 -> /opt/homebrew/opt/python@3.12/bin/python3.12
djn@trinity ~ % ls -l /opt/homebrew/opt/python@3.12/bin/python3.12
ls: /opt/homebrew/opt/python@3.12/bin/python3.12: No such file or directory
djn@trinity ~ % source /usr/local/Roon/venv/bin/activate
(venv) djn@trinity ~ % type python
python is an alias for /usr/bin/python3
(venv) djn@trinity ~ % python -c 'import site; print(site.getsitepackages())' | tr -d '[],'
'/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/site-packages' '/Library/Python/3.9/site-packages' '/AppleInternal/Library/Python/3.9/site-packages' '/AppleInternal/Tests/Python/3.9/site-packages'

Hopefully the above will shed some light :slight_smile:
Thanks again for you help.

That seems to indicate that the RoonCommandLine Python virtual environment on your system is referencing a Python that is no longer installed. What version of Python is installed in /opt/homebrew/opt/ ? You may need to upgrade the virtual environment to point to a newer version. This can happen if:

  1. You install Python
  2. You create a Python virtual environment (e.g. install RoonCommandLine)
  3. You upgrade your system Python to a newer version
  4. Now your virtual environment is pointing to a non-existent Python

I think you can upgrade your RoonCommandLine Python virtual environment with something like venv --upgrade --upgrade-deps but let’s first determine what version of Python you have installed and exactly how to upgrade a virtual environment.

In opt/homebrew/opt/ I have the following:

Screenshot 2024-10-22 at 18.49.41

Oddly, most of the folders have the same set of files, i.e.

However, the folder called python@3.12 has less files …

Screenshot 2024-10-22 at 18.51.03

In a bid to not waste your time I thought I’d try a complete reinstall, so I updated Python, deleted usr/local/Roon/ and the RoonCommandLine folder, and attempted to reinstall from scratch. It didn’t go well …

djn@trinity ~ % git clone 'https://github.com/doctorfree/RoonCommandLine.git'
Cloning into 'RoonCommandLine'...
remote: Enumerating objects: 4411, done.
remote: Counting objects: 100% (694/694), done.
remote: Compressing objects: 100% (232/232), done.
remote: Total 4411 (delta 506), reused 641 (delta 455), pack-reused 3717 (from 1)
Receiving objects: 100% (4411/4411), 4.25 MiB | 10.57 MiB/s, done.
Resolving deltas: 100% (3297/3297), done.
djn@trinity ~ % cd RoonCommandLine                                           
djn@trinity RoonCommandLine % ./Install                                                    
Password:
Install RoonCommandLine version 2.1.3r2 ? ('Y'/'N'): y
Using djn as the Roon user. 'Y' for OK, 'N' to select a different user: y
Setting the Python Roon API server IP address to 192.168.68.50
Enabling local access in /usr/local/Roon/etc/pyroonconf

In order to configure the Python Roon API we must set the IP address
of the Roon Core. Discovery will be used to determine the Roon Core IP.
When prompted for authorization, go to a Roon Remote window and click
    Settings -> Extensions -> Enable
to authorize discovery

Traceback (most recent call last):
  File "/usr/local/Roon/api/get_core_ip.py", line 26, in <module>
    apis = [RoonApi(app, None, server[0], server[1], False)]
            ~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/Roon/venv/lib/python3.13/site-packages/roonapi/roonapi.py", line 798, in __init__
    raise RoonApiException("Host and port of the roon core must be specified!")
roonapi.roonapi.RoonApiException: Host and port of the roon core must be specified!
Approval granted, retrieving zones and zone info ...
Traceback (most recent call last):
  File "/usr/local/Roon/api/list_zones.py", line 65, in <module>
    roonapi = RoonApi(appinfo, token, server, port)
  File "/usr/local/Roon/venv/lib/python3.13/site-packages/roonapi/roonapi.py", line 798, in __init__
    raise RoonApiException("Host and port of the roon core must be specified!")
roonapi.roonapi.RoonApiException: Host and port of the roon core must be specified!

Verify the 'server' and 'user' settings in the roon script are correct.
If you wish to deploy RoonCommandLine on other systems, install the package
there or copy the 'roon' frontend shell script to a location in your execution
PATH on those systems from which you wish to control Roon via SSH.

Edit the Roon Command Line configuration settings at:
/usr/local/Roon/etc/roon_api.ini
and verify the settings in the configuration file /usr/local/Roon/etc/pyroonconf

I’ve checked roon_api.ini and it’s missing RoonCoreIP and RoonCorePort.

pyroonconf contains the following:

LOCAL=true
export PYTHONUSERBASE=/usr/local/Roon/venv
ROONAPIPATCHED=true
ROON_ZONE=""

@DaveN now look at the mess you’ve gotten us into :slight_smile:

I think you could have just done something like:

sudo /opt/homebrew/opt/python@3.13/bin/python3.13 -m venv --upgrade /usr/local/Roon/venv

Let’s start over. Uninstall and reinstall RoonCommandLine with:

# Remove previously cloned repository
rm -rf RoonCommandLine
# Clone RoonCommandLine repository
git clone https://github.com/doctorfree/RoonCommandLine.git
cd RoonCommandLine
# Uninstall any previously installed RoonCommandLine and remnants
./Uninstall
rm -f /tmp/_roon_api_ini_.save
rm -f /tmp/_pyroonconf_.save
# Deactivate any Python virtual environment
deactivate
# Install RoonCommandLine
./Install

Some of the above steps are not needed but I threw them in to be safe.

Do you still get the exceptions caused by missing IP and port settings in roon_api.ini ?

I followed all the steps, as you’ll see below. The only step that didn’t work is that my shell didn’t recognise the deactivate command.

djn@trinity ~ % rm -rf RoonCommandLine
djn@trinity ~ % git clone https://github.com/doctorfree/RoonCommandLine.git
Cloning into 'RoonCommandLine'...
remote: Enumerating objects: 4411, done.
remote: Counting objects: 100% (694/694), done.
remote: Compressing objects: 100% (232/232), done.
remote: Total 4411 (delta 506), reused 641 (delta 455), pack-reused 3717 (from 1)
Receiving objects: 100% (4411/4411), 4.25 MiB | 14.97 MiB/s, done.
Resolving deltas: 100% (3297/3297), done.
djn@trinity ~ % cd RoonCommandLine
djn@trinity RoonCommandLine % ./Uninstall
Password:

RoonCommandLine uninstalled
djn@trinity RoonCommandLine % rm -f /tmp/_roon_api_ini_.save
djn@trinity RoonCommandLine % rm -f /tmp/_pyroonconf_.save
djn@trinity RoonCommandLine % deactivate
zsh: command not found: deactivate
djn@trinity RoonCommandLine % ./Install
Password:
Install RoonCommandLine version 2.1.3r2 ? ('Y'/'N'): y
Using djn as the Roon user. 'Y' for OK, 'N' to select a different user: y
Setting the Python Roon API server IP address to 192.168.68.50
Enabling local access in /usr/local/Roon/etc/pyroonconf

In order to configure the Python Roon API we must set the IP address
of the Roon Core. Discovery will be used to determine the Roon Core IP.
When prompted for authorization, go to a Roon Remote window and click
    Settings -> Extensions -> Enable
to authorize discovery

Traceback (most recent call last):
  File "/usr/local/Roon/api/get_core_ip.py", line 26, in <module>
    apis = [RoonApi(app, None, server[0], server[1], False)]
            ~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/Roon/venv/lib/python3.13/site-packages/roonapi/roonapi.py", line 798, in __init__
    raise RoonApiException("Host and port of the roon core must be specified!")
roonapi.roonapi.RoonApiException: Host and port of the roon core must be specified!
Approval granted, retrieving zones and zone info ...
Traceback (most recent call last):
  File "/usr/local/Roon/api/list_zones.py", line 65, in <module>
    roonapi = RoonApi(appinfo, token, server, port)
  File "/usr/local/Roon/venv/lib/python3.13/site-packages/roonapi/roonapi.py", line 798, in __init__
    raise RoonApiException("Host and port of the roon core must be specified!")
roonapi.roonapi.RoonApiException: Host and port of the roon core must be specified!

Verify the 'server' and 'user' settings in the roon script are correct.
If you wish to deploy RoonCommandLine on other systems, install the package
there or copy the 'roon' frontend shell script to a location in your execution
PATH on those systems from which you wish to control Roon via SSH.

Edit the Roon Command Line configuration settings at:
/usr/local/Roon/etc/roon_api.ini
and verify the settings in the configuration file /usr/local/Roon/etc/pyroonconf

Yep. Sorry about that :frowning:

I manually edited pyroconf and roon_api.ini to include the core IP, port and default zone, and everything seems to be working again. That doesn’t explain why it wouldn’t install correctly though so let me know if you’d like me to try/change anything.

@DaveN I need to replicate this on my Mac or dig a little deeper to see why the IP and port are not getting set correctly. Unfortunately, I have a day job so it may take me a little while to find the time. I will try to get to this as soon as possible.

No worries, everything seems to be working as expected now, so there’s no rush. If I come across any problems I’ll update you here.

Thanks again.

@DaveN so far I have been unable to reproduce your issue with Python versioning and the RoonCommandLine Python virtual environment. On my Mac when I install a newer version of Python it leaves the older ones installed so my virtual environment still points to a valid Python.

Homebrew has a number of problems with Python. See Brew Install Python · Mac Install Guide · 2024 for a pretty good overview and some tips for maintaining Python with Homebrew. One thing you can do is pin the version of Python so it does not get automatically updated by Homebrew:

brew pin python

Linux doesn’t have this problem, it’s smarter about creating a Python virtual environment.

I am looking into implementing some kind of failsafe for Python, checking if the virtual environment still points to a valid Python executable and updating the venv if not. I haven’t got that worked out to my satisfaction yet.

1 Like

I published a new release this morning which includes a check in the roon command for a non-existent Python symlink in the RoonCommandLine Python virtual environment and re-initializes the venv if it’s pointing to nowhere. This is just a workaround for the larger problem of Python virtual environments getting out of sync with their underlying Python executable but may suffice for now.

See Release RoonCommandLine Version 2.1.4 Release 1 · doctorfree/RoonCommandLine · GitHub

1 Like