My R package for controlling the lights in my house from R
Taking alerts to the next level - flashing the house lights!.
Tina and I recently switched some of the lights in our house over to Phillips Hue bulbs. These bulbs have a pretty easy API - so I figured it was time to write some functions to link R and my homes lights.
The plan
Make the lights in my house flash when a piece of code in R finishes running.
What the?
I was running some models that took around 20 hours to converge last year, so I used pushoverr
to send iOS push notifications. This meant if I ran a long model, it would send a notification to my phone when the model finished. I didn’t like the way that package worked, so rewrote it one Sunday using httr
.
The package httr
helps to setup HTTP requests and REST API integration. Learning how to control the interface between systems is getting super important. At home, I need to get everything talking to the home server, and at work, services like github, Jenkins and CI in general make understanding APIs super important.
Which leads me to the logical conclusion that I need to get my R server talking to the lights.
notifyme
notifyme is the R package I wrote to make this work. It’s available on CRAN, or directly from github. It actually also has a new interface to pushover as well, so you can also use it for the slightly more useful task of getting push notifications.
Summary stats
Link info | Link |
---|---|
Link to CRAN entry | http://cran.r-project.org/package=notifyme |
Unix build status of last commit | |
Current version on CRAN | |
Total downloads from CRAN |
Using the package
First you need to know the IP address of your bridge. There are lots of ways to do this, but the easiest is to use the function get_hue_ip()
in my package. This makes use of the the UPNP service provided by Phillips. For the code below to work, you need to be on the same network as your Phillips Hue bridge.
ip_of_my_bridge <- notifyme::get_hue_ip()
Now, you wouldn’t want anyone on your wifi being able to mess with your lights. To try and add a level of protection, you need a valid username to append to the requests. To authenticate and get the username (to me it’s a token..but Phillips calls it a username), you just need to press the link button (the big blue glowing button) on the bridge, then run this code straight away.
my_authenticated_username <- notifyme::create_hue_username(
bridge_ip = ip_of_my_bridge
)
So now I know the IP address of my bridge (ip_of_my_bridge
), and have a username that will act as a key to let me control the lights (my_authenticated_username
).
The following code will flash all the lights in the house three times, then return them to normal. I’m firing off a special alert function with a POST
request behind the scenes.
notifyme::hue_flashlights(
bridge_ip = ip_of_my_bridge,
username = my_authenticated_username
)
I’ve set it to control all the lights by default - but have included the option to allow you to control a single bulb. Say to make just the lamp at your desk flash.
But… just flashing the lights on and off isn’t very dramatic. So I also added the option to turn the lights red as well. If you leave the red light option on, it’s actually first downloading the colour and state (on/off) of your lights. This is because Phillips Hue currently only allows automatic return to last state when using the flashing alert. If I want to make the lights red, I need to save how they were before the alert, then reinstate it after.
To make this happen, when the lights flash red, I’m using another function in the package get_light_info()
. This will return the name, current colour and types of light bulbs in the house as a dataframe, so that after the flash my function knows how to reset the bulbs to how they previously were. This function is exported, so you can also just run get_light_info()
if you want to see some info on your lights.
And, this is what it looks like in action!
But wait, there’s more
I revamped my notification function and added it to this script, and also made a simple key storing function, to automatically pull the api information. I’ll save talking about that for another post.