Control Philips Hue lights automatically with Enviro pHAT

This tutorial will show you how to install the Enviro pHAT Python library, and then utilise the advanced pi-lluminate.py example. You'll learn how the Enviro pHAT can be used to sense the ambient light level in a room, and then turn your Philips Hue lights on or off depending on how dark it is.

If you haven't already soldered the header to your Enviro pHAT, then you can follow the guide to soldering pHATs here, or you can use our GPIO Hammer Headers instead.

Installing the software

It's always recommended to use the most up-to-date version of Raspbian, as this is what boards and software are tested against, and it often helps to start with a completely fresh install of Raspbian, although this isn't necessary.

As with most of the Pimoroni boards, there's a really quick and easy one-line-installer to get your Enviro pHAT set up. It's suggested that you use this method to install the Enviro pHAT software.

Open a new terminal, and type the following, making sure to type y or n when prompted:

curl https://get.pimoroni.com/envirophat  | bash

Once that's done, it probably a good idea to reboot your Pi to let the changes propagate, if the installer doesn't prompt you to reboot.

Configuring IFTTT

IFTTT (If This, Then That) is extremely useful. It allows you to create a wide range of applets to trigger a variety of actions (i.e. if this happens, then that should happen). For our pi-lluminate.py script to work properly, we'll need to ensure our Philips Hue account is connected to our IFTTT account and then we'll need to create an applet using the webhooks service.

Once you have created an IFTTT account and connected your Philips Hue account, you'll want to create two new applets: one for when it's dark ,and one for when it's light. Select the this and then choose webhooks, then select "Receive a web request". You'll be asked for an "Event Name", so pick something appropriate such as dark. Then select the that option and choose Philips Hue and finally "Turn on lights". You'll then be able to select which lights you want to control from the drop-down menu.

Repeat this again, but this time set the "Event Name" to light and then select "Turn off lights" in the "that" part. Once you have done this, you'll have two webhook applets.

Get your webhooks

Now, you'll need to get the webhooks that will be included in our pi-lluminate.py example. To find these, go to your IFTTT account and select "Services" from the menu and search for webhooks, or click here. You'll' see a button called "Documentation" - click that and you'll see a screen similar to this:

In the example above, we've blurred out our key, as anybody who knows this could control your lights! The part to make note of is the URL that looks like: https://maker.ifttt.com/trigger/{event}/with/key/YOURKEYISHERE as we'll need to substitue the {event} with our "Event Name", i.e. dark and light, so your webhooks will look like https://maker.ifttt.com/trigger/dark/with/key/YOURKEYISHERE and https://maker.ifttt.com/trigger/light/with/key/YOURKEYISHERE.

Make note of your key and the two "Event Names" (dark and light) as we'll need them later. If you wanted to, you could test that they worked by running the example shown at the bottom, via the command line on your Raspberry Pi:

curl -X POST https://maker.ifttt.com/trigger/dark/with/key/YOURKEYISHERE

Hopefully, your Philips Hue lights just turned on! If not, double check that you've connected your account correctly and check the applets are configured properly.

Using the software

In order to use the pi-lluminate.py example, you'll need to make a few changes to the bundled example to include the webhooks that we just created. The easiest way to do this is by running the following inside the advanced folder (assuming it is in /home/pi/Pimoroni/enviro-phat/examples/advanced):

nano /home/pi/Pimoroni/enviro-phat/examples/advanced/pi-lluminate.py

Find the line that starts with def turn_off(): and you should see there are two variables called TRIGGER_WORD and TOKEN. Replace the "YOUR CHOSEN TRIGGER WORD GOES HERE" in this section with light (or the "Event Name" that you used to trigger the action to turn off your lights) and then replace "YOUR IFTTT TOKEN GOES HERE" with the key that we made note of previously:

def turn_off():
    # Set your trigger word - e.g. "light" - and the IFTTT Webhook token below.
    TRIGGER_WORD = "light"
    TOKEN = "YOURKEYISHERE"

Do the same for the def turn_on():, except this time "YOUR CHOSEN TRIGGER WORD GOES HERE" will be dark (or the "Event Name" that you used to trigger the action to turn on your lights):

def turn_on():
    # Set your trigger word - e.g. "dark" - and the IFTTT Webhook token below.
    TRIGGER_WORD = "dark"
    TOKEN = "YOURKEYISHERE"

These variables are baked into the webhook commands within our script, so you should not need to make any changes to the actual URL that is called. Handy!

Adjusting the sensitivity

The Enviro pHAT measures the amount of light, in units called Lux, using the light sensor and we'll take advantage of this to measure the ambient light level in the room and then trigger either the turn_on() function or the turn_off() fucntion depending on the value.

We've chosen a low and high value in our code, but you if you find that your lights are not turning on soon enough, or are turning off when it is still too dark, you can tweak the values:

try:
    # Local variables.
    state = 0   # Sets the state for the lights.
    low = 260   # Low value for light level (lux).
    high = 300  # High value for light level (lux).
    period = 90 # Delay, in seconds, between calls.
    while True:
    # Get the average lux level first,
    room_light = average_lux()
    # Now check if the room is dark enough then turn on the lights.
    if room_light < low and not lights_on:
        turn_on()
        lights_on = True
    elif room_light > high and lights_on:
        turn_off()
        lights_on = False
    print("Waiting {} seconds before trying again".format(period))
    time.sleep(period)
except KeyboardInterrupt:
    pass

As you can see above, the low value is set to 260 Lux and the high value is set to 300 Lux. We've set a state variable so that our code knows whether the lights are on or off, to prevent the functions from being triggered constantly. The period variable is the time, in seconds, between calls and we found that 90 is a suitable number, but you can tweak this if you need to as well.

How it works

Put simply, the pi-lluminate.py script uses the Enviro pHAT to measure the ambient light level (in Lux) and calculates and average value over 60 seconds. If the average value is below the low variable, the turn_on() function is triggered, which sends a webhook to IFTTT that triggers the Philips Hue lights to turn on.

Likewise, if the Enviro pHAT measures the ambient light level and is it above the high variable, the turn_off() fucntion is triggered, which sends a webhook to IFTTT that triggers the Philips Hue lights to turn off:

def average_lux():
    # Variables for calculating the average Lux levels
    start_time = time.time()
    curr_time = time.time()
    collect_light_time = 60
    collect_light_data = []

    # Calculate the average Lux level over 60 seconds
    print("Calculating average light level...")
    while curr_time - start_time < collect_light_time:
          curr_time = time.time()
          avg = light.light()
          collect_light_data.append(avg)
      time.sleep(1)
    # Take the last 45 data points taken over 60 seconds to calculate the average
    average_light = sum(collect_light_data[-45:]) / 45.0
    now = whats_the_time()
    print("Average over {collect_time} seconds is: {average} Lux. Last checked at {time}".format(
        collect_time=collect_light_time,
        average=average_light,
        time=now
    ))
    return average_light

Testing it out

The easiest way to test this out is either to block the light sensor on the Enviro pHAT with your hand, or to use a torch to shine more light on the Enviro pHAT and see if your Philips Hue lights react by turning on or off. To test, run the following command in your Raspberry Pi's terminal:

python /home/pi/Pimoroni/enviro-phat/examples/advanced/pi-lluminate.py

You should see a printout that says Calculating average light level... followed shortly by Average over 60 seconds is: 255 Lux. Last checked at 13:43, but your values may vary depending on what the Lux level is and what time it was recorded.

In theory, when the Enviro pHAT is covered with your hand, the lights should come on in about a minute, and then should turn off again if you shine a torch on the Enviro pHAT for about a minute. We found that without taking an average reading, our lights were being triggered quite frequently, especially on days where it was sunny then cloudy, then sunny again (i.e. typical British weather!)

Taking it further

You could automate when the script runs using a cron job, which is handy if you want to control your lights at specific times of the day - i.e. during the late afternoon / early evening. Alternatively, you could create a service that runs when your Raspberry Pi boots and it'll control your lights whenever you need.

That's all folks!

Search above to find more great tutorials and guides.

Plasma 2040

Swathe everything in rainbows with this all-in-one, USB-C powered controller for WS2812/Neopixel and APA102/Dotstar addressable LED strip.