My previous post, Making the Little Lights Twinkle, covered my coding of the NodeJS server that could take simply relay numbers and command (on|off) and put them to use. Now that I have a server/service up and running, it was time for me to be able to control the lights. I removed my Orchestra of Lights and put my new Raspberry Pi hardware device in its place. The only downside is that my setup has 8 outlets and the Orchestra of Lights only had 6. As I built out some of my light sequences, I noticed there’s a delay due to relays 7 and 8 being triggered but nothing being connected to them. Maybe that’s something I can do for next year. I’ll plan for 8 lighting areas instead of just 6.
In addition to needing to be able to plan for two more strands of lights, I still hadn’t figured out my audio configuration yet. I’ve only had the time to focus on the lights themselves. For the time being, I’ve got a weatherproof bluetooth speaker outside that I sync my iPad to for music. I just tell my iPad to loop through a playlist that my wonderful wife has put together. Thank you deer!
The Initial Script
While I still struggled to find some time to continue to research making the lights dance to music, I figured it was a really good idea to get something up and running. I thought randomness was key. I wanted it to be random because I was sick of the Orchestra of lights running through the same/similar light pattern over and over and over and over…..and over. With that, I built the initial script control my lights:
#!/bin/bash
COMMANDS=("off" "on")
i=0
trap exitout SIGINT
exitout() {
echo "We Are Done Here!"
exit
}
while :
do
CMD=$(( ${RANDOM} % 2 ))
RELAY=$(( ${RANDOM} % 8 + 1 ))
curl 127.0.0.1:8080/light/$RELAY/${COMMANDS[$CMD]}
echo $RELAY ${COMMANDS[$CMD]}
sleep 0.2
done
Obviously, this is a really quick hack of a script but it works. It’s also obvious that it is a simple shell script. I created the array “COMMANDS” with two elements “off” and “on”. I ended up not using “i” but oh well it’s still here. I have the script setup to exit “cleanly” by calling exitout whenever someone presses CTRL+C on the keyboard. You need this because as you can tell the script is created with a while loop that never exits.
Let’s talk about what is going on inside that while loop. With each iteration, I’m setting CMD to a random number modulo 2 which gives us either 0 or 1. I’m also setting RELAY to a random number modulo 8 which gives us something 0 – 7 on each iteration. You’ll notice I add +1 so that I actually make RELAY be 1 – 8. Next, I run a curl command with my relay number and the element 0 or 1 aka off on from the COMMANDS array. From there, I just echo out what I sent to the server and then sleep for 0.2 seconds. This loop runs forever until something crashes or the user does CTRL+C.
Oh My Goodness This is Ok
The above simple script did the trick. This made my lights randomly turn on and off. I was quite happy with the results we got with this. I had light strands turning on and off. Sometimes, the lights were doing something that appeared like it was in tune with the music. There was one little flaw in this. The flaw was that because it was random, you could have the same relay being given the same command or the randomness would focus on a single light strand turning on and off.
Ultimately, my major concern was that we had too many lights out at the same time. So, this was a really good initial step and worked well for my immediate wants and needs. I wanted more. I got bored with random and put a little time into something a little more.
Building the More Interesting Client
Ok like I said before, I was getting bored with the original client script. I wanted to be able to do just a little bit more. I built a script that does a few sequences as you can see below.
#!/bin/bash
COMMANDS=("blinkUp" "blinkDown" "danceUp" "danceDown" "blinkAll" "crazyRun")
i=0
trap exitout SIGINT
exitout() {
echo "We Are Done Here!"
exit
}
allLights() {
a=1
while [ $a -le 8 ]
do
curl 127.0.0.1:8080/light/$a/$1
echo ""
a=$(( a + 1 ))
done
}
blinkUp() {
echo "Blinking Up"
allLights on
a=1
while [ $a -le 8 ]
do
curl 127.0.0.1:8080/lights/$a/off
echo ""
sleep 0.5
curl 127.0.0.1:8080/lights/$a/on
echo ""
sleep 1
a=$(( a + 1 ))
done
}
blinkDown() {
echo "Blinking Down"
allLights on
a=8
while [ $a -ge 1 ]
do
curl 127.0.0.1:8080/lights/$a/off
echo ""
sleep 0.5
curl 127.0.0.1:8080/lights/$a/on
echo ""
sleep 1
a=$(( a - 1 ))
done
}
danceUp() {
echo "Dancing Up"
allLights off
a=1
while [ $a -le 8 ]
do
curl 127.0.0.1:8080/lights/$a/on
echo ""
sleep 0.5
curl 127.0.0.1:8080/lights/$a/off
echo ""
a=$(( a + 1 ))
done
}
danceDown() {
echo "Dancing Down"
allLights off
a=8
while [ $a -ge 1 ]
do
curl 127.0.0.1:8080/lights/$a/on
echo ""
sleep 0.5
curl 127.0.0.1:8080/lights/$a/off
echo ""
a=$(( a - 1 ))
done
}
blinkAll() {
echo "Blinking All"
allLights on
allLights off
allLights on
allLights off
allLights on
allLights off
}
crazyRun() {
echo "Doing Crazy Shit"
danceUp
danceDown
allLights off
sleep 0.5
allLights on
sleep 0.5
danceDown
danceUp
blinkAll
danceUp
danceDown
danceUp
danceDown
}
while :
do
CMD=$(( ${RANDOM} % 6 ))
${COMMANDS[$CMD]}
sleep 0.2
done
I’ve added a bunch of different functions to this new script: