Tuesday, December 12, 2017

Raspberry Pi Music Player Feedback Light

I have a pretty simple setup of a Pi that plays an internet radio stream. One of the problems was that we were constantly turning off the stereo but leaving the Pi playing the stream and we had no feedback that it was still on and consuming bandwidth.

So a simple LED light when MPC was playing should fix that.

After installing a base image of DietPi installed all the mpc and mpd components and got the radio stream going. I installed WiringPi in order to control the GPIO pins.

So, now - how to get the LED to light up with MPC was playing? There are a few approaches such as starting MPC from a script that also lights the LED, but as I sometimes start MPC from the command line, sometime from a custom webpage, I didn't want to remember to run a special script to start it up. I wanted it to be monitoring if MPC was playing and light up no matter the method of starting.

Since cron only runs at 1 minute intervals, I had a problem. I didn't want to wait 1 minute to get feedback to turn the LED on or off. I wanted a smaller resolution than 1 minute intervals, but 1 second was okay. So I settled on cron starting a script every minute, and the script checking MPC each second to see if it was playing or not.

If the length of the string returned was 68 characters, it meant that MPC wasn't playing as it was the general MPC info returned. If MPC was playing it would included the song details, and therefor be greater than 68 characters, so we assume it's playing and light the LED.

First I need to set up the pin at boot time, so I saved this in a startup script located in /etc/init.d/startupscript.sh


#register GPIO 4 for input and output
gpio -g mode 4 out

I had this code saved a script that cron called every minute:


#This file is used in a cron job to test if mpc is playing or not.
for i in `seq 1 60`;
sleep 1

PLAYING=$( mpc status )

#Test the length, check the staus, then
#if mpc is not playing then the string length is 68 char long
#if mpc is playing, string length is longer
if [ ${#PLAYING} -gt 68 ]; then
#echo "MPC is playing";
#turn LED on
gpio -g write 4 1
#turn LED off
gpio -g write 4 0


And I tested it out by wiring up the LED to the right GPIO pin, SSH to the Pi and issue the command 'mpc play' and watch the LED light up almost straight away (max 1 sec), then 'mpc stop' and the LED switched off.

Saturday, March 25, 2017


When using Busybox TFTP client

get file:
tftp -g -r filename.txt tftpserverip_or_hostname

put file:
tftp -p -l filename.txt tftpserverip_or_hostname

Getting a file not found error? It seems that the file must exist on the server first, so if you want to upload a new file, first go to the server via SSH or something and create a dummy file of the same name.

Getting permission denied error? You don't have enough permissions on the dummy file you are trying to upload over. SSH to the TFTP server and chmod 777 the file. Upload it. Then change the permissions back to 644 or something.

When using OSX
get file, launch Terminal and type these commands:
connect tftpserverip_or_hostname
get filename.txt

put file, launch Terminal and type these commands:
connect tftpserverip_or_hostname
put filename.txt

Thursday, August 11, 2016

After having a bit of trouble installing my own certificate on Ubiquiti's Unifi software on Linux, I though I would let you know the process I went through.

First up, in my case I had my CA Certificate + User Certificate + User Key in .p12 format.

If you have already installed the Unifi software then please, please, please make a config backup.

Install the Unifi software on your server and make sure you can get to the Management page where it will be using an untrusted certificate from ubnt.com

Download Keystore Explorer for your OS from http://www.keystore-explorer.org/ which is a GUI for some java command line tools to deal with keystores.

Create a new keystore of type JKS

Import key pair, and select your .p12 certificate.

give it password 'aircontrolenterprise' (This is the ubiquity set password on the existing keystore that we are going to replace)

When requested to give it an alias, give it an alias 'unifi'

Save it.

SSH back to the server running your Unifi.

Stop the unifi service by running the command 'sudo service unifi stop'

move the existing keystore that we are going to replace by running 'sudo mv /var/lib/unifi/keystore /var/lib/unifi/keystore.original'

Use FTP or another method to copy the keystore you created with Keystore Explorer into the same location /var/lib/unifi/keystore

restart the service by running 'sudo service unifi start'

Back on your client machine, browse to the Unifi Management to test.
You should now have your own trusted certificate and can start restoring your saved config or starting with your fresh Unifi install.

Wednesday, February 24, 2016

Resize Linux Partition

I had the case of wanting to resize a linux partition for my Raspberry pi without access to the usual raspi-config tool so had to do it manually.
The raspi-config tool doesn't require a reboot, so there are probably other ways to achieve it as well, but this way works for me.

First I had a full disk. Which you can see by running the df command with -h for human readable output.

I want to expand the space for the / mount point that is at 100%
You can see that there is a partition at /dev/mmcblk0p1 , the p1 refers to partition 1 so that is device /dev/mmcblk0 but what partition is the / mount point?

You can check the partitions on the device with the fdisk -l command which lists them. 

So you can see that we want to expand the partition /dev/mmblk0p2 on device /dev/mmblk0

You also use fdisk on the device to delete and recreate the partition, then write the results back. This is done on partition 2 even though partition 2 is the linux partition on the running system.

It says the partition was altered, but the device is busy. It also says the device is busy for the next commands so the next step was to reboot.

After the reboot, run resize2fs on the partition that changed size.

If it ran successfully, you can df -h again to see the new space that is now available.

The space is now available for you to use.

Wednesday, October 28, 2015

Mac OS X Automator - Convert .m4a to .mp3

I had a problem that my car stereo only plays MP3 files, but I have some music in M4A format that I wanted to listen to for a road trip.

So I wanted to convert it, and as I had a few files to do, I decided that Automator could help me out in order to repeat it.

In the end it was pretty simple.
I created a new Automator application in case I wanted to have it as an application in the future. You could do it as a workflow as well, since if you compile it as an application the paths will be set inside it and you will have to open it in Automator again to change it.

I already had ffmpeg on my system so I tested it on the command line first.

If you don't have ffmpeg installed you can install it with Macports using the command:

sudo port install ffmpeg 

Once you have the ffmpeg installed, play around with for a bit to get it converting the audio file on the command line. Once that was working all you needed to do was have your Automator application get a finder object and run a shell script using the ffmpeg command line options with a few adjustments (such as needing the ffmpeg complete path in Automator)

Here is the code:

for f in "$@"
b=$(basename -s .m4a "$f")
/opt/local/bin/ffmpeg -i "$f" -codec:a libmp3lame -ab 256k /Users/username/Desktop/"$b".mp3

(If you copy the above code, don't forget to change the output directory to the one you want)

That basically creates a loop that goes through all of your input files. The screenshot only had one input, but you can drag multiple files into the "get specified finder items" section. Each time the loop runs the current file it is working on gets saved into variable 'f'.

b=$(basename -s .m4a "$f") -> creates a variable 'b' and saves into it, the filename of the current file we are working on (that is "$f" dont forget) without the .m4a extension. So if you pass it '/path/to/file/music.m4a' variable 'b' will contain 'music'

Then run the ffmpeg command line. In my case I knew the input bitrate was 256kbps, so I forced ffmpeg to save in that bitrate too. Check the ffmpeg documentation for what you can do with it.

Thursday, September 17, 2015

Raspberry Pi Touchscreen Display Unboxing

I stumped up and bought a Raspbeery Pi 7" Touchscreen Display as I am planning on using it as a start/stop, status display for my radio streaming pi.

All the components it came with.

Attach the white display cable that is going to connect to the pi, attach the large screen cable to the connector on the underside of the display board. Attach the smaller ribbon to the small connector on the top of the display board (not shown)

Use the spreaders to attach the display board to the display.

Attach the pi, attach the power and boot up. (photo to come)

Tuesday, December 2, 2014

pfsense load balancing

I had the case where I wanted to access my server remotely via SSH when my server was behind my pfsense firewall.
The problem was, I often swap between a wired and wireless connection. I could port forward two different ports, one to the wired network and one to the wireless, but that is one more thing to remember. So I thought I would investigate pfsense load balancing functions so I wouldn't have to remember if I left it on wired or wireless.

First is to set static IPs for the servers wireless and wired connections so I could reference them later. You can do this in the Status > DHCP leases menu.

Second I needed to allow SSH from the WAN to the LAN network. I created a Firewall rule to allow this. You could create two rules to allow SSH to each static IP, but I have other devices on my network, so I just opened it from the WAN port to the whole network. by using the /24 address of the destination.

Now to the fun stuff, load balancing.

You need to create a pool containing the servers you want to load balance to, and a virtual server to forward a port to and use the pool.

In Services > Load Balancer > Pool, click the plus to create a new pool.
Since you wanted pfsense to know what is available, wired or wireless, and send traffic to whatever is available we want to select 'Load Balance'. Give it a description. The servers are listening on port 22 for SSH so we want to balance across that port. Add the static IPs that you set earlier and save.

Now in Services > Load Balancer > Virtual Server, click the plus to create a new virtual server.
Give it a name, the IP address is your WAN IP (or alias for the WAN IP) I wanted to use a non standard port, so chose port 1023, and you select the pool to use, in my case 'Server_SSH_Pool' and save,

Apply changes. I rebooted the server to be sure.

Now get onto the same network that your WAN connects to and try to SSH.


where username is the username of an SSH user on the two servers in the load balancer pool.

It should ask you for the password and you should be in.
log out, change the server to connect to the LAN via its other network interface wired or wireless. Then back on machine on your WAN try to SSH again to the same address.

You should now be able to get in from your WAN by using the one IP address and port 1023, no matter if your server is connected to the LAN via wired or wireless. (or a second NIC, it doesn't have to be wired and wireless) You are just load balancing across two different IPs so those could be different servers as well - that's how you load balance HTTP web requests to different web servers to handle load, my case just needed SSH instead.