Programming a LIFX lightbulb
By: Claire Tran
Tags: Internet of Things, Smart Lighting, Engineering, Lifx, IoT

It’s Christmas and at the end of every year, I do a few things — revisiting goals, learning, relaxing, seeing family and friends and making something fun.

For this year, I’ve chosen to dive into an IoT project, to program my LIFX lightbulb. I’ve been eyeing the smart light for many months, and decided to use this project as an excuse to experiment.

The Idea

I find that I often fall asleep reading, so I wanted to automatically switch off my light at a particular time everyday.

I’ll be using Python to code a simple example and deploy the solution to Heroku.

In a nutshell, this is how I wanted the light to behave:

At 10PM: switch on the light at a specific brightness level

At 12PM: dim the lightbulb

At 1AM: switch off the light

Testing the light

Setup

The first thing you will need to do, is setup the lightbulb with the App.

Once you’ve set up, you can adjust settings of your lightbulb, for example the colour and brightness, as well as switching the device on and off.

Changing device settings

Understanding the API

You will need to log in to LIFX and generate a token to be used with the API.

Head over to https://cloud.lifx.com/settings to create a token.

Try It Out

The API https://api.developer.lifx.com/ lists the API requests available to test the lightbulb

Example:

List lights you have: https://api.developer.lifx.com/docs/list-lights

Setting light states: https://api.developer.lifx.com/docs/set-states

Toggling the device on and off: https://api.developer.lifx.com/docs/toggle-power

You can test out the API on the page or via the example cURL/code that is provided

Step 1: Finding the light ID

First thing we need to is find the light id so we can target the light

API to use: https://api.developer.lifx.com/docs/list-lights

Let’s make a cURL request to find the device id.

In the docs, the id field in the response is the device id to reference.

Step 2: Request the current state of the device

Let’s add some code.

Create a project e.g. light and add a file called main.py

import enum

import json

import requests

import os class State(enum.Enum):

Off = 'off'

On = 'on' def updateState():

print ("Running cron job") token = os.getenv('LIFX_TOKEN')

lightId = os.getenv('LIGHT_ID')

headers = {

"Authorization": "Bearer %s" % token,

}

lights = json.loads(response.text)

currentState = lights[0]['power']

currentBrightness= lights[0]['brightness'] response = requests.get(' https://api.lifx.com/v1/lights/' + lightId, headers=headers)lights = json.loads(response.text)currentState = lights[0]['power']currentBrightness= lights[0]['brightness'] print ("Current state and brightness: [" + str(currentState) + ", " + str(currentBrightness) + "]") updateState()

Next, set environment variables for LIFX_TOKEN and LIGHT_ID

export LIFX_TOKEN=XXX

export LIGHT_ID=YYY

Install the required dependencies (using pip or pip3 )

pip install requests

Then run the code:

python main.py

(if you are running Python3, you may need to run this via python3 main.py)

This will print something like

$ Current state and brightness: [on, 0.3]

Step 3: Check the time

The next part of the logic is to check the time so the light can switch on, dim and switch off at the right time.

Time is usually in UTC, but if you wanted to, you can also convert the time to your timezone.

First, add the following imports

import time

from datetime import datetime

import pytz

Then install required dependencies using pip or pip3

Next, under the code that printed the current state of the device, convert the time to your timezone, example:

tz = pytz.timezone('Europe/Vienna')

now = datetime.now(tz)

print ("Current hour: " + str(now.hour))

Now run the code python main.py , you should get something like:

$ Current hour: 11

$ Current state and brightness: [on, 0.3]

Next, let’s check the time. For brevity, I’ll demonstrate with a couple of conditions

if now.hour == 22:

power = State.On.value

brightness = 0.7

elif now.hour == 0:

power = State.On.value

brightness = 0.3

else:

power = State.Off.value

brightness = 0.1

Then add payload information for the request.

payload = {

"power": power,

"brightness": brightness

}

response = requests.put(' print ("Updating state to: " + power)response = requests.put(' https://api.lifx.com/v1/lights/d073d5627d36/state' , data=payload, headers=headers)

Putting that together, this looks like

For testing purposes, you can update the “hour” in the conditions to turn the light off and on.

Step 4: Setting up Scheduling

We next want to schedule the code to run in certain hours of the day

Add another file called toggle.py .

For this example, I’ve set this to run every hour, but you can set this to run at specific times (check https://crontab.guru/ for examples).

from main import toggle

from apscheduler.schedulers.blocking import BlockingScheduler print("Running scheduler")

scheduler = BlockingScheduler()

scheduler.add_job(updateState, 'cron', day_of_week = '*', hour='*', minute='0')

scheduler.start()

Next, remove the last line updateState() in main.py

I’ve chosen to deploy the project to Heroku, so we need to setup other files

In the same project, create requirements.txt and add

requests

pytz

apscheduler

Then create Procfile with the following contents

clock: python toggle.py

Lastly, create runtime.txt to set the python version. In my example, the file contents:

python-3.9.0

Step 5: Push your code to Github

In the project, initialise the project

git init

Then add and commit your files

git add .

git commit -m "Adding project"

In Github, create your repository (see: https://docs.github.com/en/free-pro-team@latest/github/getting-started-with-github/create-a-repo)

After you’re done, add the remote to your project on the command line

git remote add origin <git repo url>

Then push the code to the repository

git push origin master

Step 6: Heroku Setup

Set up the Heroku CLI

See: https://devcenter.heroku.com/articles/heroku-cli

2. Create an app and pipeline

Go to: https://dashboard.heroku.com/ to add the project in the UI and connect to your Github repository.

To create a pipeline, refer to this page on how- https://devcenter.heroku.com/articles/pipelines

Example pipeline I have set up (only production for now):

Then add the environment variables under project settings (go to project name > Settings )

Then enable automatic deploys for your project (i.e. every time you add code, this will automatically deploy)

You should see this section from the Deploy tab: your project > Deploy

3. Add a Scheduler

See this guide as a reference: https://devcenter.heroku.com/articles/clock-processes-python

On the command line, type and run

heroku addons:create scheduler:standard

Then add a dyno

heroku ps:scale clock=1 --app <your app name>

Check the resources tab your project > Resources , you should see something like the following

Step 7: Check Logs

You should be setup now. To check if the app is running as expected:

heroku logs -t -a your-app

Here is an example run:

2020-12-30T11:00:00.836778+00:00 app[clock.1]: Current hour: 22

2020-12-30T11:00:00.836804+00:00 app[clock.1]: Current state and brightness: [off, 0.1]

2020-12-30T12:00:00.721686+00:00 app[clock.1]: Updating state to: on

2020-12-30T13:00:00.007372+00:00 app[clock.1]: Running cron job

2020-12-30T13:00:00.603605+00:00 app[clock.1]: Current hour: 0

2020-12-30T13:00:00.603733+00:00 app[clock.1]: Current state and brightness: [on, 0.5]

2020-12-30T13:00:00.603833+00:00 app[clock.1]: Updating state to: on

2020-12-30T14:00:00.007353+00:00 app[clock.1]: Running cron job

2020-12-30T14:00:00.789883+00:00 app[clock.1]: Current hour: 1

2020-12-30T14:00:00.790068+00:00 app[clock.1]: Current state and brightness: [on, 0.3]

2020-12-30T14:00:00.790171+00:00 app[clock.1]: Updating state to: off

That’s it. Happy coding, enjoy your LIFX light!