Controlling mpd using the SES/AOSS/EZ-SETUP button

Discussion about my Wifi Radio project at http://mightyohm.com/wifiradio/ or my WL-520gU talk at NOTACON.
User avatar
gerben
Posts: 164
Joined: Sat Oct 16, 2010 8:41 am
Location: Netherlands

Controlling mpd using the SES/AOSS/EZ-SETUP button

Post by gerben »

I thought I would share my radio project here. I was looking into having internetradio in my bedroom for a very long time, and then I saw this solution on MakeMagazin. I have no experience with micro controllers and soldering, so I set out to use the the only button on the router to control the radio.

So I created some kind of morse code to control the radio (code below).
Pressing one and releasing makes it start playing, or when already playing select the next station in the playlist. Pressing twice plays the previous station. Pressing and holding stops playback. Pressing twice but holding the second time makes it jump back to the first station on the playlist.

Second thing was showing what station was playing. For this I use the power led (code below). Where changing songs it will flash x times where x is the index in the playlist. To make it usable for big numbers, 4 short flashes are replaced by one long one. Seems to be working ok. The only minor problem is that you can only the this when you change stations, so you have to memorize the index. Maybe I'll change this later. I have the list of stations, printed out, laying next to the radio.

Third thing was a sleep function. Whenever I send an mpc playback command I also 'touch' a file. A cronjob running every 5 min checks to see if this file is modified more than 30 minutes ago. If so it stops playback. As a nice feature I first bring down the volume slowly first. The minor problem is that it is almost indistinguishable from my radio's sleep function :-)

Fourth thing was start playing when the my radio alarm goes off. A simple cronjob that starts playback on working days at 7:59AM. I needed to install ntpclient to get the date and time correct. Still has some bugs, because sometimes the clock is behind a few hours. Probably the fault of the 200mhz broadcom chip, while set in the kernel as being a 240mhz, ntp not being able to get a new time.

Fifth thing was lowering the volume when ads are playing. Quite a bit of work fiddling around with code and bugs, but I is a very very nice feature. It still makes me smile whenever it detects an ad.

The the 'hardware' side. The ez-setup button is at the backside, and the leds are at the front, so this posed a problem. I first wanted to solder some wires and an external button to the ez-setup button contact, but when I open the router up, I saw 4 (?) tiny solder points and ditched the idea. So I build a jig out of Plexiglas, with a lever thingy, so now I can press the button from the front. And it also looks cool. I used a black marker to dim the red light coming from the soundcard.

That kind of sums it up. I flashed the router using Jeff's instructions (except for the serial connection). Thank you very much Jeff for sharing all the hard work. We share the same lastname by the way.

So here is a photo of the setup. Router on top of my stereo set. Router is hardwired to the internet. Router is also used for wifi, and my network printer is connected to it.
Image
I've put the code in the next post, below.
User avatar
gerben
Posts: 164
Joined: Sat Oct 16, 2010 8:41 am
Location: Netherlands

code for: Controlling mpd using the SES/AOSS/EZ-SETUP button

Post by gerben »

In no specific order:
PS. does anyone know of a way to get usleep on openwrt. Busybox doesn't include it in Jeffs version.

Code: Select all

============================================
/root/add-ad.sh
note: not used yet. has to be connected to pressing the button trice.
::::::::::::::::::::::::::::::::::::::::::::
#!/bin/sh
title=`echo "currentsong" | nc 127.0.0.1 6600 | grep -e "^Title: "`
title=${title:7}
if [ -z "$title" ];then
	exit
fi
echo "$title">>/root/ads.txt

Code: Select all

============================================
/root/ads.txt
::::::::::::::::::::::::::::::::::::::::::::
Sponsored Message
Get DI.fm Premium!
Cut Your Mortgage Interest Rates! Free Consult. Call: 1-800-398-8869
You are listening to DI radio, the best of trance on the net
Ultramax Ultimate CD+DVD collection - http://www.ultramaxmusic.com
Brought to you by Santrex.net - Affordable Off Shore Hosting

Code: Select all

============================================
/root/buttonpressed.sh
note: when button is pressed this is written to a file. It will sleep for 1 sec. to see if there are any more presses coming. If another press comes this press will killall sleep, and first press's script detects it and exits
note2: pressed and released scripts are not always called in the right order, so it can happen that press-release-press-release, becomes press-release-release-press.
note3: if playing the power led flashes, if stopped the power led is off
::::::::::::::::::::::::::::::::::::::::::::
#!/bin/sh
exec 1>/dev/null

echo 0 > /proc/diag/led/power

echo -n "p">>/tmp/buttonstates

killall sleep
sleep 1
if [ "$?" != "0" ]
then
	#echo "second click occured"
	exit
fi

#read state history e.g. prpr
states=`cat /tmp/buttonstates`
#clear
echo -n "">/tmp/buttonstates
echo "$states">/tmp/oldbuttonstates

if [ "$states" = "p" ];then
	/root/mympc.sh stop
	exit
fi
if [ "$states" = pr ];then
	/root/mympc.sh playnext
	exit
fi
if [ "$states" = "prpr" -o "$states" = "prrp" ];then
	/root/mympc.sh playprev
	exit
fi
if [ "${#states}" = "6" ];then
	/root/mympc.sh play 1
	exit
fi

#invalid input
echo 1 > /proc/diag/led/power

Code: Select all

============================================
/root/buttonreleased.sh
::::::::::::::::::::::::::::::::::::::::::::
#!/bin/sh
if [ -s /tmp/buttonstates ]
then
	echo -n "r">>/tmp/buttonstates
fi

Code: Select all

============================================
/root/check-sleep.sh
::::::::::::::::::::::::::::::::::::::::::::
#!/bin/sh

secpassed=`expr $(date +%s) - $(date -r /tmp/lastradioinput +%s)`
echo "$secpassed"

mysleep() { ping -c 1 127.0.0.1>/dev/null; }

# 30min: 1800sec
if [ $secpassed -gt 1800 ];then
	for i in 45 40 35 30 25 20 15 10 5
	do
		mpc volume -5
		mysleep;mysleep;mysleep;mysleep
	done
	/root/mympc.sh stop
	#reset volume
	mpc volume 50
	touch /tmp/lastradioinput
fi

Code: Select all

============================================
/root/detect-ad.sh
::::::::::::::::::::::::::::::::::::::::::::
#!/bin/sh
trap 'exit 1' SIGINT
echo "PID:$$"

muted=2

while true
do
	i=$(( $i + 1 ))
	sleep 1
	#detect if sleep was killed
	while [ "$?" != "0" ]
	do
		sleep 1
	done
	
	title=`echo "currentsong" | nc 127.0.0.1 6600 | grep -e "^Title: "`
	title=${title:7}
	if [ -z "$title" ];then
		continue
	fi
	
	adfound=`echo "$title" | grep -F -i -c -f /root/ads.txt`
	
	if [ "$adfound" = "0" ];then
		if [ "$muted" != "0" ];then
			echo "ad stopped"
			mpc volume 50
			muted=0
		fi
	else
		if [ "$muted" != "1" ];then
			echo "ad started"
			mpc volume 20
			muted=1
		fi
	fi
done
echo "detect-ads stopped!!!"

Code: Select all

============================================
/root/flash-led.sh
::::::::::::::::::::::::::::::::::::::::::::
#!/bin/sh
on=1
off=0
count=$1

#check if led already off
current=`cat /proc/diag/led/power`
if [ "$current" != "0" ];then
	echo $off > /proc/diag/led/power
	sleep 1
fi

i=$count
pattern=""
while [ $i -gt 0 ]; do
	if [ $i -ge 4 ]; then
		pattern="$pattern$on$on$on$on$off$off"
		i=`expr $i - 4`
	else
		pattern="$pattern$on$off$off"
		i=`expr $i - 1`
	fi
done
pattern="$pattern$off"

#echo $pattern
mysleep() { ping -c 1 127.0.0.1>/dev/null;ping -c 1 127.0.0.1>/dev/null ; }

while [ ${#pattern} -gt 1 ]; do
	val=${pattern:0:1}
	pattern=${pattern:1}
	echo $val > /proc/diag/led/power
	#sleep "$val sleep"
	mysleep
done
					
sleep 2
#echo 1 > /proc/diag/led/power
echo "flash" > /proc/diag/led/power

Code: Select all

============================================
/root/mympc.sh
::::::::::::::::::::::::::::::::::::::::::::
#!/bin/sh

if [ "$1" != "stop" ];then
	touch /tmp/lastradioinput
fi

#custom commands
if [ "$1" = "playnext" ];then
	mpc next;mpc play;
	/root/show-preset.sh &
	exit
fi
if [ "$1" = "playprev" ];then
	mpc stop;mpc play;mpc prev;
	/root/show-preset.sh &
	exit
fi

mpc $1 $2 $3
/root/show-preset.sh &

Code: Select all

============================================
/root/radio-init.sh
::::::::::::::::::::::::::::::::::::::::::::
#!/bin/sh
mpc repeat on
mpc volume 50
mpc load difm

sleep 10
/root/detect-ad.sh &

Code: Select all

============================================
/root/show-preset.sh
::::::::::::::::::::::::::::::::::::::::::::
#!/bin/sh
state=`echo "status" | nc 127.0.0.1 6600 | grep -e "^state: "`
if [ "$state" != "state: play" ];then
	echo 0 > /proc/diag/led/power
	exit
fi

num=`echo "status" | nc 127.0.0.1 6600 | grep -e "^song: " | grep -oe "[0-9]"`
num=`expr $num + 1`
echo $num
/root/flash-led.sh $num

Code: Select all

============================================
/etc/hotplug.d/button/01-radio-control
note: create this file to detect the button clicks
::::::::::::::::::::::::::::::::::::::::::::
#!/bin/sh
if [ "$BUTTON"="ses" ]
then
	if [ "$ACTION" = "pressed" ]
	then
		/root/buttonpressed.sh
	fi
	if [ "$ACTION" = "released" ]
	then
		/root/buttonreleased.sh
	fi
fi

Code: Select all

============================================
/etc/init.d/myradio
::::::::::::::::::::::::::::::::::::::::::::
#!/bin/sh /etc/rc.common

START=99
start() {
sleep 5
/root/radio-init.sh
}

##
### todo: add symlink to /etc/rd.d/ or something (can;t remember)
##

Code: Select all

============================================
crontab -e
::::::::::::::::::::::::::::::::::::::::::::
# minute (0 - 59)	hour (0 - 23)	day of month (1 - 31)	month (1 - 12)	day of week (0 - 6) (Sunday=0)

*/5 * * * * /root/check-sleep.sh

# play music at 8am; sleep should stop music after 30min
59 7 * * 1,2,4,5 /root/mympc.sh play

Code: Select all

============================================
various other info
::::::::::::::::::::::::::::::::::::::::::::

 - install ntpclient
 - /etc/config/system
     - option timezone CET-1CEST,M3.5.0,M10.5.0/3
      (= Amsterdam)

============================================
::::::::::::::::::::::::::::::::::::::::::::
WTFPL licence. Us at own risk
mtennant
Posts: 27
Joined: Sun Jul 04, 2010 9:46 am

Re: Controlling mpd using the SES/AOSS/EZ-SETUP button

Post by mtennant »

"Router is hardwired to the internet. Router is also used for wifi, and my network printer is connected to it."

Very cool. Wish something like this could be incorporated into a standard build/flash.

How do you find the WL-520GU does as an Internet radio player, access point, router and print server?

If all are active at one time with lots of traffic from wired and wireless users, does the system choke?
User avatar
gerben
Posts: 164
Joined: Sat Oct 16, 2010 8:41 am
Location: Netherlands

Re: Controlling mpd using the SES/AOSS/EZ-SETUP button

Post by gerben »

How do you find the WL-520GU does as an Internet radio player, access point, router and print server?
Router is in my bedroom, so it's only doing one thing at a time. While debugging it I had it in the living room, and had no problem surfing the web while playing internet radio. Only a few times did the music stop playing for a moment. 'opkg update' isn't advisable while playing radio though.
The printer is like i said a network printer, so the printerserver is running on the printer, not the router. Sorry to get your hopes up. Would be nice though.
From my experience the router is very stable running both mpd and wifi.
Balthasar
Posts: 5
Joined: Tue Mar 29, 2011 7:15 am

Re: Controlling mpd using the SES/AOSS/EZ-SETUP button

Post by Balthasar »

Hi gerben, I am very interested in this kind of UI setup.

Currently, I am using an old WinMo device with an Android SD card to remote my radio but the battery gets flat in a matter of hours.

I downloaded all the scripts, copied them over to their place using WinSCP, just to be sure I specified rwxrwxrwx permission but SES still acts as a Reset button. Device reboots sooner or later, upon pressing the SES button. I suppose /etc/hotplug.d/button/01-radio-control is not launched.

Any suggestion on how to debug these scripts?
Furthermore, could you pls. post a photo on the back of your device to find out how the red button is pressed by that lever?

Anyway, congrats for your great work! Thanks in advance, Balthasar
Balthasar
Posts: 5
Joined: Tue Mar 29, 2011 7:15 am

Re: Controlling mpd using the SES/AOSS/EZ-SETUP button

Post by Balthasar »

Nevermind, got it working. One of my scripts contained your comment lines without preceding '#' signs so it caused a syntax error.

I modified flash-led.sh so that it sens a long flash for 5 instead of 4, a bit easier for me to interpret (e.g.: 8 = long, short, short, short).

I am still interested in that plastic lever though.

Thanks,
Balthasar
User avatar
gerben
Posts: 164
Joined: Sat Oct 16, 2010 8:41 am
Location: Netherlands

Re: Controlling mpd using the SES/AOSS/EZ-SETUP button

Post by gerben »

I'm glad you found it useful.
As for the lever. I quickly scribbled something for you
Image
green is the push-pin. Red is the pivot with the top side pressing against the SES button. The small dot in my case is a nail. The green push pin is held in place by two holes in the two (gray) perpendicular supports.
I'm not sure if this is at all helpful. Good luck.
Balthasar
Posts: 5
Joined: Tue Mar 29, 2011 7:15 am

Re: Controlling mpd using the SES/AOSS/EZ-SETUP button

Post by Balthasar »

Hi gerben, thanks for the drawing! Everything is clear now.

Happy Easter,
Z
tero
Posts: 5
Joined: Wed Apr 27, 2011 12:10 pm

Re: Controlling mpd using the SES/AOSS/EZ-SETUP button

Post by tero »

Hi. I am a litle confused when it comes to shell scripts(i only know basic commands) but this looks awesome. So if you don't mind I have a few noob questions. What files do i exactly need to play and stop and go to next station with external button? And are this scipts loaded while booting up?
Thanx.
User avatar
gerben
Posts: 164
Joined: Sat Oct 16, 2010 8:41 am
Location: Netherlands

Re: Controlling mpd using the SES/AOSS/EZ-SETUP button

Post by gerben »

The most important one is /etc/hotplug.d/button/01-radio-control. This one will be executed every time you press or release the button. This script will call either buttonpressed or buttonreleased. Button pressed depends on mympc.sh, but if you replace every "/root/mympc.sh XXX" by "mpc XXX". So these 3 are the ones you need for basic playback control.
Just create those 3 files and set the correct permissions, and you are good to go

As for the other script. check-sleep.sh is run by a cronjob every 5 minutes. detect-ad.sh is run continuously. radio-init runs at boot.

But why not use the whole package? The flashing leds at least give you an idea of what station is playing, and also if it's playing. The ad detection I think is absolutely great. No more annoying loud messages. Sleep might be useful.

Good luck and please ask any questions if you have them.
Post Reply