Replacing my Sonos Port...

After my Sonos Port (old gen) stopped working, the second one in a couple of years, I thought I should be able to build something better myself.
I usually stream my music from Spotify nowadays, but my Sonos  setup was a bit of a hassle to use. I have a Cambridge Audio Azur 851A amplifier with Bower & Wilkins 702 speakers, and a Sonos Port connected to the amplifier. To play music on the stereo I had to:
  1. 1. Start the Sonos app
  2. 2. Select track from Spotify source in Sonos
  3. 3. Start amplifier using remote control (with limited range so I often had to get up from the sofa to get closer to the amplifier - lazy? why yes! :-)
  4. 4. Anytime I wanted to change volume I had to use the remote rather than Sonos - I used fixed line-out rather than volume on Sonos as setting it was hard getting a balance of volumes across rooms. Often resulting in way-to-high volume (initially) on the amplifier, especially with using multiple sources to the amplifier.
The new build uses Raspberry Pi with HiFiBerry DAC2 HD and a serial cable to control the amplifier (the amplifier has a serial port - RS232 / DB9 - that can be used to control it).
By using Raspotify I can use Spotify Connect to send music directly from my mobile to Raspberry Pi - and also control the volume of the amplifier with a bit of code. Besides volume control, the code would automatically turn the amplifier on and off. This would completely eliminate the need for a remote control.
Spotify screenshot. Any volume change is captured and commands sent to amplifier. Selecting the Rasperry Pi (Vardagsrum) will power on the amplifier. Selecting another playback device will stop (standby) amplifier.
Raspberry Pi with HiFiBerry DAC2 HD in the Steel Case (v2). Besides power and audio cable, I have a HDMI dummy plug to emulate HDMI connected (makes VNC work better). In the back you can see the RS232 cable (DB9) that connected to the Azur 851A amplifier
And here is the complete setup, with the retired and non-working Sonos Port on the right hand side.
Here are the installation steps and code for Raspberry Pi
Bill of materials:
- Raspberry Pi 4
- HiFiBerry DAC2 HD
- Steel case for HiFiBerry DAC+/ADC, Pi 4, V2
- USB-to-RS232 (DB9) cable (incl. female-to-female DB9 cable)
- (HDMI Dummy Plug Headless, if accessing Raspberry Pi remotely using VNC (with GUI)

1. Install Raspberry Pi in case with HifiBerry DAC2 HD card. Description link: -> https://www.hifiberry.com/docs/hardware/steel-case-assembly-new/

2. Install raspotify. Description link -> https://pimylifeup.com/raspberry-pi-spotify/
	a. Get access to config file:
	    chmod 777 /etc/default/raspotify
	b. Configure raspotify (Spotify Connect Service):
		OPTIONS="--onevent /etc/default/raspotify-events.py"
	c. Optional: Restart raspotify after config change:
		sudo systemctl restart raspotify

3.	Configure HifiBerry DAC2 HD. Description link -> https://www.hifiberry.com/docs/software/configuring-linux-3-18-x/
	a. Edit /bot/config.txt
		sudo nano /boot/config.txt
	b. Remove (or comment out):
	b. Add:

4. Create raspotify event script
	a. create new file
		touch /etc/default/raspotify-events.py
	b. get access to new file
		chmod 777 /etc/default/raspotify-events.py
	c. provide raspotify user with access to dialout (a.k.a serial port)
		sudo usermod -a -G dialout raspotify
	d. copy code below into /etc/default/raspotify-events.py:
		#! /usr/bin/env python
		# raspotify script to control Cambridge Audio Azur 851A amplifier through RS232 interface
		# Add this script to raspotify config file (/etc/default/raspotify):
		#    DEVICE_NAME="Vardagsrum"
		#    BITRATE="320"
		#    OPTIONS="--onevent /etc/default/raspotify-events.py"     Run this script on events
		#    VOLUME_ARGS="--initial-volume=50"                        Start from low volume
		# Ensure script is editable & executable:
		#    chmod 777 /etc/default/raspotify-events.py
		# Restart raspotify after config change:
		#    sudo systemctl restart raspotify
		# Give user (raspotify) access to dialout (serial port):
		#    sudo usermod -a -G dialout raspotify

		from syslog import syslog
		import os
		import serial
		import sys
		from datetime import datetime, timedelta
		# from time import sleep
		# import codecs      # debug

		# Send commands to Azur 851A
		def send_command(logg, cmd, wait):
				sio = serial.Serial('/dev/ttyUSB0', timeout=wait)

				# Clear buffer from any unread data
				# Send command & wait on confirmation
				start_time = datetime.now()
				sio.write(azur_cmd['command'] + cmd)   
				sio.read_until(azur_cmd['reply'] + cmd)
				time_diff = (datetime.now() - start_time)
			except serial.SerialException as e:
				if e.errno == 13:
					syslog('SerialException[13]: Insuffient access')
					syslog('SerialException[{}]: No USB/RS232 connected?'.format(e.errno))
				# raise e
			exe_time = round(time_diff.total_seconds() * 1000)/1000
			syslog('Azur 851A {}: {}s'.format(logg, exe_time)) 

		azur_cmd = {'command': b'#1,', 'reply': b'#4,', 'on': b'11,1\r', 'standby': b'11,0\r', 'vol': b'13,', 'foot': b'\r'}

		player_event = os.environ.get('PLAYER_EVENT')

		if player_event == 'volume_set':
			volume = os.environ.get('VOLUME')
			target_vol = int(round((float(volume) / 65535) * 96))  # Convert to equivalent azur volume
			cmd = azur_cmd['vol'] + str(target_vol).zfill(2).encode() + azur_cmd['foot']
			send_command('volume {}'.format(target_vol), cmd, 1)
		elif player_event == 'start':
			send_command('on', azur_cmd['on'], 10)
		elif player_event == 'stop':
			send_command('standby', azur_cmd['standby'], 3)

5. Reboot Raspberry Pi:
	sudo reboot

To access Raspberry Pi remotely with GUI:
6. Install VNC on Raspberry Pi

7. Install VNC viewer on remote computer

Or to access it through SSH (headless):
6. Activate SSH in Raspberry Pi. Description link -> https://www.raspberrypi.org/documentation/remote-access/ssh/

7. Activate SSH on Windows computer. Description link -> https://www.raspberrypi.org/documentation/remote-access/ssh/windows10.md

8. Replace IP adress with host definition, add text below to C:\Windows\System32\drivers\etc\hosts file:
	192.168.xxx.xxx   raspberry

9. Activate passwordless SSH use link -> https://www.raspberrypi.org/documentation/remote-access/ssh/passwordless.md

10. Now you can login to Raspberry pi without password using:
	ssh pi@raspberry


Please sign in to leave a comment.