Creating a sunrise alarm with the LIFX lightbulb

If you’re unfamiliar with LIFX it’s basically a smart wifi enabled led lightbulb. Lifx recently released a Ruby gem to communicate with it and give it instructions. With winter looming in the southern hemisphere and the sun being up for what feels like 4 seconds at that time of year it’s really hard to get up in the morning so I investigated using their gem to simulate a sunrise effect in time with my alarm on my phone.

TL;DR

I have a cronjob on my raspberry pi that triggers 2 mins before my alarm to run some ruby code that’ll trigger a slow fade in of colours to simulate a sunrise. The light will go from a very dim red all the way through until a bright yellow almost white light. Code is on github.

What you’ll need

  • Lifx bulb
  • A server or computer that is always on. I have a raspberry pi
  • Any alarm, I use the rise app that plays nice bird chirping sounds.

The code

At the moment lifx only has official libraries for Java, Objective-C & Ruby. Being that I’m diving into ruby at the moment this was perfect. There is a unofficial node library that you could use too if you’re afraid of anything that’s not JavaScript.

require 'lifx'

label = ARGV[0]
time = ARVG[1] ||= 120

client = LIFX::Client.lan
client.discover! do |c|
    c.lights.with_label(label)
end

client.lights.turn_on
light = client.lights.with_label(label)

fade_time = time # time in seconds
interval = 6 # run every 6 seconds
increment = fade_time/interval
luminence = 0.01
luminence_increment = 1/increment.to_f
hue_increment = 60/increment # Fade from red to bright yellow 0 to 60
hue = hue_increment

light.set_color(LIFX::Color.hsl(0, 1, luminence), duration: interval)

def set_interval(delay)
    Thread.new do
        loop do
            sleep delay
            yield
        end
    end
end

sunrise = set_interval(interval) do
    if luminence >= 1
        sunrise.kill
    end

    light.set_color(LIFX::Color.hsl(hue, 1, luminence), duration: interval)
    luminence = luminence + luminence_increment
    hue = hue + hue_increment
end

sunrise.join

The code is pretty simple I setup a thread to run every 6 seconds and slowly increase the hue and luminance values over a 2 minute period.

The Lifx gem API is pretty simple I would suggest going over to their docs to learn more about specifics. Basically my code is just discovering my one and only light that has the label that I passed in as an argument and then I just increment the HSL colour values.

Hooking up the cronjob

On the server side of things in my raspberry pi I register this shell script to run.

#!/bin/bash

source ~/.rvm/scripts/rvm
cd ~/sunrise-lifx
bundle exec ruby ~/sunrise-lifx/sunrise.rb "Bedroom"

The reason I do this is because I need to source in the rvm scripts so I can run my ruby code. Cron starts a bare bones shell so even if you already source in stuff in a .bash_profile you’ll still need to manually source in the stuff you need when executing as a cron job.

The cronjob runs two scripts, one to trigger the sunrise simulation on weekdays at 6:28am and another that runs 15 minutes later to turn the light off as I should be up by then.

28 6 * * 1-5 ~/sunrise-lifx/sunrise.sh >> ~/sunrise-lifx/cronOutput.txt 2>&1
45 6 * * 1-5 ~/sunrise-lifx/turn-off.sh >> ~/sunrise-lifx/cronOutput.txt 2>&1

That’s it. Super simple setup and seems to work pretty well so far.