.. figure:: logo.png :align: center http://www.bardolph.org .. index:: projects .. _webserver_setup_casual: =========================================================================================================== Using LIFX Color LED Strips and the Bardolph Scripting Language to Create Holiday-Themed Window Shows =========================================================================================================== *By Perry Piazza* *Hi. My name is Perry and I am helping Al with the Bardolph project. Articles that I write will cover my experiences with Bardolph.* I recently picked up two open-box LIFX 40" inch Multicolor LED Strips for about $25 each on eBay. This is a pretty good deal since they normally retail for about $50 each. Good news! They both worked perfectly and looked unused. LIFX uses premium LEDs and components in their strips, and it really shows in terms of color and brightness. The strips arrived in early April and Easter was coming up, so I thought I'd create an Easter-themed display for one of the windows in our home that could be seen from either inside or outside. A basic "show" was easy enough to conjure using the LIFX app on my iPhone, but in order to turn it up a couple of notches I used Bardolph. As I was creating the Easter scripts, I got to thinking, why don't I create light shows for other holidays as well so that I have them at the ready for all of my favorite holidays. So I did just that. And here's how you can replicate this project and make it your own. If you'd really like to master the Bardolph scripting language, a good first step would be to acquaint yourself with the extensive, well-written language documentation which can be found `here `_ (a google search of "LIFX Bardolph" will find it quickly as well). Bardolph is implemented in Python and will require your computer to have both Python and Bardolph installed. And if you plan on running scripts regularly or via a web server, you'll want to do so via an "always on" computer. This can be a low-powered SBC (single board computer) like a Raspberry Pi (the "Pi") running a Linux Distro, which is what I used. A Pi has the advantage of consuming very little electricity and can serve as a smart home hub to control other smart devices as well. ------------- Project Setup ------------- First I upgraded Python and installed Bardolph. After installation, I created a virtual environment (using the terminal). I next plugged the two light strips into a wall outlet and connected them to my network using my iPhone and the LIFX app. Note that you may need to switch from your home's 5.0 Ghz WiFi network to the 2.4 Ghz network or set one up if needed. After setting up the strips I ran Bardolph's 'lscap' command from the terminal to make sure that the LIFX light strips were connected to the network and could be recognized by Bardolph. I was pleased to see LS1 and LS2 show up in the list (along with "current state" information for each strip's 8 "zones"). Next, I decided what I wanted my light show to do. If you're doing your own project at home, you'll want to do the same, keeping in mind how many LIFX devices you have and the types of bulbs, strips, or tubes that you'll be using, For this project, I decided to use the two 40" strips positioned at the sides (on the inside casing) of a window so that the effect could be seen from both inside and outside of the house and then creating three different routines for each holiday. The three routines I chose to create are: 1. The first routine consists of two-or-three holiday-related colors per strip blinking on and off. For Christmas, I chose green in the top half of Strip 1 and red in the bottom half of LS1, with the colors reversed on LS2. The colors that I chose for Halloween were Orange and Deep Red. 2. My second routine has the holiday theme colors, for example, red, white, and blue in the case of the 4th of July, following one another up LS1 and then down LS2 in a chase pattern. 3. The third routine consists of the holiday-theme colors flickering on and off in random spots across the two strips and then dimming to dark. This pattern was the most difficult to "code" as it required generating random numbers and using more complex "conditionals". Next, I skimmed through the Bardolph documentation to re-familiarize myself with the syntax and commands of the language. If you've had any rudimentary experience with programming (say, with Python), you should be fine programming using Bardolph. Bardolph scripts are text files with a .ls suffix (in the same way that Python scripts use a .py suffix). Spaces and tabs (so called, "white space") are ignored and no indenting is required, but you'll probably want to structure your scripts with indents to be more readable. For this reason I decided to use a lightweight code editor. Comments (sometimes called remarks) can be inserted into the script easily using hashes. Next, I decided how I wanted to name and save my scripts. I chose to have a folder structure as follows: bardolph_scripts > holidays. Inside of the holidays folder I used a naming convention for my scripts that made it easy to distinguish between them. I went with this syntax: holiday_routine_num_outine_version_(holiday#_holiday).ls. So, for example, one was named holiday_routine_2_v1_(3_fourth_of_july).ls and another was named holiday_routine_1_v1_(1_christmas).ls I kept the light strips near my desk for testing during coding, but eventually moved them to the window when I was satisfied with the scripts. Beyond having a preplanned naming convention for your scripts during a project, it's probably also a good idea to have a naming convention for naming individual devices so that as your collection grows, the names are easy to remember. For example, you could use something like model_number-item_number-location or device-type-item_number. A19_1_endTableLR, could, for example, be your first A19 bulb in the end table lamp in the living room. ----------------- Coding My Project ----------------- I've included sample code for each of my holiday routines below, so feel free to copy these and modify them for your own use. After each code block I'll make a few comments, but of course this article isn't intended to be a comprehensive explanation of how to code using Bardolph. ----------------------------------------------------------------- Routine 1 Sample Code, Comments, and Additional Coding Challenges ----------------------------------------------------------------- .. code-block:: lightbulb # Colors blink on and off # Easter # hue 267 sat 33 purple # hue 336 sat 80 pink/red # hue 105 sat 80 lime green on "LS1" and "LS2" repeat 20 begin hue 267 saturation 33 brightness 68 kelvin 2700 set "LS1" zone 0 2 and "LS2" zone 5 7 hue 336 saturation 80 brightness 79 kelvin 2700 set "LS1" zone 3 4 and "LS2" zone 3 4 hue 105 saturation 80 brightness 40 kelvin 2700 set "LS1" zone 5 7 and "LS2" zone 0 2 time 0.2 hue 105 saturation 80 brightness 40 kelvin 2700 set "LS1" zone 0 2 and "LS2" zone 5 7 hue 267 saturation 33 brightness 68 kelvin 2700 set "LS1" zone 3 4 and "LS2" zone 3 4 hue 336 saturation 80 brightness 79 kelvin 2700 set "LS1" zone 5 7 and "LS2" zone 0 2 time 0.2 end off "LS1" and "LS2" The script above is relatively simple. It makes use of a simple counting loop to repeat the sequence 20 times; uses 'and' to apply the 'on', 'off', and 'set' commands to more than one device; uses the 'set' command additionally to apply state settings to specific zones of the strip; includes comments; and makes use of delays via the TIME function. Some "try at home" programming challenges that you could make to this script could be: 1. Switch this to a two-color routine, 2. Assign a different color to every zone in the strip, 3. Change the script so that it starts at a specific time of day and stops at a specific time of day. 4. Modify the script for other holidays / occasions. ----------------------------------------------------------------- Routine 2 Sample Code, Comments, and Additional Coding Challenges ----------------------------------------------------------------- .. code-block:: # Colors race up one strip and down the other # July 4th # hue 0 sat 80 deep red # sat 0 brightness 50 kelvin 5000 white # hue 230 sat 80 blue on "LS1" and "LS2" # Assign up and down zone counter variables assign up 0 assign down 7 # routine runs for n runs repeat 10 begin # each of these strips has 8 zones repeat 8 begin hue 0 saturation 0 brightness 50 kelvin 5000 # Set the background as white set "LS1" and "LS2" if up < 8 && down > -1 begin # strip zones run from 0 to 7, so keep going until # we exhaust all zones hue 0 saturation 80 brightness 50 kelvin 2700 # holiday color 1 ... # gets set on strip 1 at zone up set "LS1" zone up # holiday color 2 ... hue 230 saturation 80 brightness 60 # gets set on strip 1 at zone down set "LS2" zone down assign up up + 1 assign down down - 1 end else begin # once we exceed the zone thresholds ... assign up 0 # reset the counter variables assign down 7 end time 0.1 end # repeat with the colors swapped assign up 0 assign down 7 repeat 8 begin hue 0 saturation 0 brightness 50 kelvin 5000 set "LS1" and "LS2" if up < 8 && down > -1 begin saturation 80 kelvin 2700 hue 230 brightness 60 set "LS1" zone up hue 0 brightness 50 set "LS2" zone down assign up up + 1 assign down down - 1 end else begin assign up 0 assign down 7 end time 0.1 end end off "LS1" and "LS2" This script is more complex than Script 1 and makes use of a few new code concepts. For example, it uses the 'assign' command to create variables (in this case the variables 'up' and 'down') and change their values. It includes arithemetic (in this case addition abd subtraction to modify the counters). It uses abstractions such as a variable plus a number (u + 1). Finally it uses conditional statements (the ones that starts with "if"). In this case we're checking to make sure that our count hasn't taken us out of the range of available zones on our device. Some "try at home" programming challenges that you could make to this script could be: 1. Randomize which color acts as the background color, or change the background to an off state. 2. Speed up or slow down the "movement" of the racing colors. 3. Have the racing color "bounce" off of the top and bottom of a strip and change directions. ----------------------------------------------------------------- Routine 3 Sample Code, Comments, and Additional Coding Challenges ----------------------------------------------------------------- .. code-block:: # Random zones brighten and darken in holiday colors # Christmas # hue 120 green # hue 0 red on "LS1" and "LS2" hue 0 saturation 0 brightness 0 kelvin 2700 set "LS1" and "LS2" # how long it takes to brighten and darken assign ramp_time 0.4 repeat 20 begin # Randomize strip, zone, and color. assign strip_num [random 1 2] assign zone_num [random 0 7] assign color_num [random 1 2] # random zone A # if random number chooses strip 1 if strip_num == 1 begin # if random number chooses color 1 if color_num == 1 begin # holiday color 1 hue 120 saturation 100 brightness 50 kelvin 2700 # to strip #1 random zone ramped up over time set "LS1" zone zone_num duration ramp_time # now dim the strip over time hue 0 saturation 0 brightness 0 kelvin 2700 set "LS1" duration ramp_time time ramp_time * 2 end else begin # if random number chooses color 2, use holiday color 2 hue 0 saturation 100 brightness 50 kelvin 2700 # to strip #1 random zone ramped up over time set "LS1" zone zone_num duration ramp_time # now dim the strip over time hue 0 saturation 0 brightness 0 kelvin 2700 set "LS1" duration ramp_time time ramp_time * 2 # wait for all of the ramps end end else # random number chose strip 2 begin # if random number chose color 1 if color_num == 1 begin # holiday color 1 ... hue 120 saturation 100 brightness 50 kelvin 2700 # to strip #1 random zone ramped up over time set "LS2" zone zone_num duration ramp_time # now dim the strip over time hue 0 saturation 0 brightness 0 kelvin 2700 set "LS2" duration ramp_time time ramp_time * 2 end else # random number chose color 2 begin # holiday color 2 ... hue 0 saturation 100 brightness 50 kelvin 2700 # to strip #1 random zone ramped up over time set "LS2" zone zone_num duration ramp_time # now dim the strip over time hue 0 saturation 0 brightness 0 kelvin 2700 set "LS2" duration ramp_time # wait for all of the ramps time ramp_time * 2 end end end off "LS1" and "LS2" This script is arguably the most complex of the three. It uses the built-in 'random' function (which must be "called" from within square braces) which returns a random integer n such that min ≤ n ≤ max. Introducing randomness forces you to think more about code structure; for example, where in the code do you need to call the function. For example, if the random integer call was made outside of the loop there wouldn't be any randomization. This script also introduces another time-related command 'duration'. Duration is used to change the state of a device (from one state to another) gradually over a period of time specified. An 'else' statement also finds its way into this script. Here, we use it as a convenience to create a path to a set of commands for the other of two random states. Because we are randomizing multiple things (strips, colors) we introduce "nested" paths here (one "if then" statement inside of another "if then" statement"). Finally, we use the 'time' command in a different way: because we know that we'll need to wait for the lights to ramp to a new state (since we used 'duration'), we have to wait for this to finish before we continue the loop. Some "try at home" programming challenges that you could make to this script could be: 1. Switch this to a randomized three-color routine - for example, red, white, and blue. 2. Randomize the brightness (say, a number from 50% to 100") and/or the duration "ramp time". 3. Tighten the code up by using just one random number range but scaling the random number to fit different variable needs. 4. Speed up or slow down this routine. 5. Condense the code! Al and I have created a version of this script that condenses the code down to 33 lines. Can you beat us? I'll present that code in a follow-up article. Summary Though I've only provided three scripts here, I actually created versions of each of these for Christmas, Halloween, the Fourth of July, and Easter; so twelve scripts in all. For a given holiday or event, scripts can be combined and/or sequenced as well, of course, either by concatenating scripts and creating a master loop, or by creating a small helper script (say, in Python) to call scripts and run them. Gallery ------- .. image:: christmas_strip.mp4 :alt: Christmas Light Show :width: 200px