Combine RS232 Volume Control with Hifiberry Digi

I run music from an RPi with Hifiberry Digi into a Rotel A12 Amplifier with integrated DAC via SP-DIF.
The optical connection does not allow volume control, so I was wondering, if I could use the RS232 control-interface of the amp to control the volume.
A short test with a USB-to-Serial adapter works from the shell, letting me remote control functions of the amp.
I was wondering, what the best way of integration would be: I would like the volume slider on the GUI to control the volume of the amp. However, a quick look into the code showed me, that the volume controls (mixer with hardware, software, none) are pretty tied to the DACs configurations and I would probably need to start messing with those.
Is there an easier way to allow e.g. a plugin to read the slider and then send RS232 commands without having to add new functions to the mixer setup? Currently the slider is fixed at 100% with the default setting for the Digi.

My current idea would be a new mixer type “Websock” that would just broadcast any movement of the slider as a websocket message and each plugin wanting to act upon that info would just subscribe to the messages. Other suggestions how it could be implemented? I basically need to untie the slider from the hardware and sound processing and just be able to use it as a pure input device.


Volumio also has the ability to call a shell script on volume actions - for similar use cases. I don’t believe it is thoroughly documented though. Look at volumescript in the volumecontrol.js code to get some ideas!

Hi, thanks for the hint, looks like it could be easier than expected. Will look into it a bit more and see, if I can use it. Would really be great to control the volume from the GUI and not having to use the remote control all the time.
Currently still some issues with the serial - all commands like mute, change input and switch speakers are working except the volume setting :confused: - have to figure out why before trying to integrate it into volumio.

Keep us posted! I have a plugin template that does exactly that :wink:

I looked into the volumecontrol.js code and I think I understand the idea. I also have found and fixed my issue with communication over the serial interface.
I have already programmed 4 simple scripts,,, and confirmed they are working. The command line arguments and response should match with the volumecontrol.js code.
I integrated the scripts into a simple plugin and can successfully load them using
self.commandRouter.updateVolumeScripts(data), which gives me a positive response in the log:
Updating Volume script: {"enabled":true,"setvolumescript":"/data/plugins/miscellanea/rotelampcontrol/rotelscripts/ /dev/ttyUSB0 ","getvolumescript":"/data/plugins/miscellanea/rotelampcontrol/rotelscripts/ /dev/ttyUSB0","setmutescript":"/data/plugins/miscellanea/rotelampcontrol/rotelscripts/ /dev/ttyUSB0 ","getmutescript":"/data/plugins/miscellanea/rotelampcontrol/rotelscripts/ /dev/ttyUSB0","minVol":0,"maxVol":50,"mapTo100":true}

Since the mixer slider was still disabled, I have enabled Software Volume Control in the settings. If I move the slider, it seems to trigger the scripts, but I realize now, that they are called with a POSIX shell /bin/sh and that ignores the #!/bin/bash shebang in my scripts and thus throws an error, because I use bashisms: 10: read: Illegal option -n

Unfortunately, I have quite some difficulties converting my bash scripts to POSIX compatible syntax - could I also use a js-script instead or is there any “trick” to still use bash? Hints welcome.

Below is one of my scripts as example + the object configuration that would need to overwrite the default. Let me know if this looks reasonable (did not try to call it from Volumio code yet). takes serial device ID as command-line argument:

# Start read command in the background to wait for the return from the amp
# -d: Read up to '$' which is the end character of Amp messages
#Convert the response to either 0 or 1 as expected by Volumio
(read -n 60 -t 5 -d \$ RESP < $1; RET=$(echo $RESP | sed 's/mute=//g' | sed 's/on/1/g' | sed 's/off/0/g');echo $

sleep 0.2

# Send command to request mute state
echo -e -n mute?  > $1

# Wait for background read to complete

I ran into the same issues, this is my workaround…

I recall vaguely trying to fix things to respect the shebang in other parts of volumio, but I think the PR slipped through…

Edit: Yep

1 Like

Thanks for the hint - simple and effective. I was still trying to force it into POSIX compatible format.
Works now will add some more features and share once it is working.

…as time went by…

I was not so happy with the solution and finally chose to make a small plugin.
It is implemented as an override plugin now instead of the volumescripts and stores the serial commands supported in a JSON file. That way it may even be possible to extend it to support other brands and models.
Works nice with my Rotel so far - so I’ll publish it… watch out for a PR.
Created a PLUGIN thread here.

1 Like