How It Works

Here's how the code works.


First, you'll import the libraries needed including time, ssl, socketpool, wifi, and adafruit_requests for creating the connection to the bulb, adafruit_funhouse for all of the convenient functions for using the sensors, display, NeoPixels, and buttons on the FunHouse easily, and the adafruit_lifx library for specific bulb functions.

import time
import ssl
import socketpool
import wifi
import adafruit_requests
from adafruit_funhouse import FunHouse
import adafruit_lifx

WiFi Setup

Next, the code checks the file for the WiFi credentials.

    from secrets import secrets
except ImportError:
    print("WiFi and API secrets are kept in, please add them there!")

Color Variables

You can pick your standby and active (sensor has been "tripped") colors here. Note that these are hexidecimal color values formatted two ways for the bulb, which uses HTML style hex formatting, and the FunHouse DotStars, which use more standard hex code formatting.

default_bulb_color = "#002010"
default_led_color = 0x002010
tripped_bulb_color = "#440044"
tripped_led_color = 0x440044

Requests Session

Here the ESP32-S2 sets up a WiFi HTTP socket session.["ssid"], password=secrets["password"])
pool = socketpool.SocketPool(
http_session = adafruit_requests.Session(pool, ssl.create_default_context())

LIFX Setup

Next you'll set up the LIFX bulb using your token from the file, the bulb name, and the http session. The lights variable is set by querying the LIFX light list.

lifx_token = secrets["lifx_token"]
lifx_light = "label:Lamp"
lifx = adafruit_lifx.LIFX(http_session, lifx_token)
lights = lifx.list_lights()

FunHouse Setup

The FunHouse object is created, setting a background color for the screen and a text scale of 3 and the DotStars are turned on to their default color.

Three variables are created to store the PIR sensor state, the running/paused state, and the initial on timer value.

funhouse = FunHouse(default_bg=0x000F20, scale=3)

pir_state = 0
running_state = False
trip_time = 30  # seconds to stay tripped, adjust this with buttons while running


Text Display

Next the screen labels are set up, including a function for toggling label colors when buttons are pressed.

def set_label_color(conditional, index, on_color):
    if conditional:
        funhouse.set_text_color(on_color, index)
        funhouse.set_text_color(0x606060, index)

# Create the labels
funhouse.display.root_group = CIRCUITPYTHON_TERMINAL
up_label = funhouse.add_text(text="+", text_position=(3, 6), text_color=0x606060)
down_label = funhouse.add_text(text="-", text_position=(3, 40), text_color=0x606060)
running_label = funhouse.add_text(
    text="paused", text_position=(2, 68), text_color=0x606060
time_label = funhouse.add_text(
    text=trip_time, text_scale=2, text_position=(30, 25), text_color=0x606060

funhouse.display.root_group = funhouse.splash

Turn on the Light

The final step of setup is to turn on the LIFX bulb with a brightness of 65% and the default teal color.

light_brightness = 0.65
lifx.set_brightness(lifx_light, light_brightness)
    lifx_light, power="on", color=default_bulb_color, brightness=light_brightness

Main Loop

The main loop of the program does the following:

  • When the top button is pressed, increase the timer variable and highlight the text
  • When the middle button is pressed, decrease the timer variable and highlight the text
  • When the bottom button is pressed toggle the running_state value and swap the text
  • Watch for the PIR sensor value to change -- if the sensor is tripped, set the LIFX set_color and the DotStars to the "tripped" color, and then countdown the timer. When the timer runs down, return to the default color.
while True:

    if funhouse.peripherals.button_up:
        trip_time = trip_time + 1
        funhouse.set_text(trip_time, time_label)
        funhouse.set_text_color(0xFFFFFF, up_label)
        funhouse.set_text_color(0x606060, up_label)

    if funhouse.peripherals.button_sel:
        trip_time = abs(trip_time - 1)
        funhouse.set_text(trip_time, time_label)
        funhouse.set_text_color(0xFFFFFF, down_label)
        funhouse.set_text_color(0x606060, down_label)

    if funhouse.peripherals.button_down:
        if running_state is False:  # it's currently paused, so unpause it
            running_state = True  # flip the state
            funhouse.set_text("..prepping..", running_label)
            time.sleep(6)  # pause to get out of range
            funhouse.set_text("sensing...", running_label)

        else:  # it's currently running, so pause it
            running_state = False
            funhouse.set_text("paused", running_label)

    # when sensor is tripped, set the color x amount of time
    if running_state is True and funhouse.peripherals.pir_sensor and pir_state is 0:
        funhouse.set_text("tripped", running_label)
        prior_trip_time = trip_time  # store the state of the trip time value
        for _ in range(trip_time):
            trip_time = trip_time - 1
            funhouse.set_text(trip_time, time_label)
        pir_state = 1
        trip_time = prior_trip_time  # restore the trip time value

    # return to default color
    elif (
            running_state is True and not funhouse.peripherals.pir_sensor and pir_state is 1
        funhouse.set_text("sensing...", running_label)
        funhouse.set_text(trip_time, time_label)
        pir_state = 0

This guide was first published on Apr 28, 2021. It was last updated on Jun 24, 2024.

This page (Code Walkthrough) was last updated on Mar 08, 2024.

Text editor powered by tinymce.