Siri, let there be light.
I built a smart lighting system for my room with Siri and web controls for a fun DIY school-break project.
One day, I woke up to an aspiration of wanting to build a bit of a smart home project for my semester break––and so, I started off with my lights.
“For most people interested in living in a smart home, lighting is the entry point.”
– Christopher Null, TechHive.
While the costs of implementing for my entire house could be prohibitive, I’d figured that I could, at least, try it out with my own room first.
Preparations
Firstly, I drafted the following high-level use-cases:
- Automate lighting controls with emphasis on human-centric lighting––cool whites for day time, warm (yellowish) lights for evening until night.
- Save energy through daylight harvesting and occupancy detection.
- Override automated lighting controls through a mobile-first web app.
Requirements
I’ve set for the following as my objectives for the project:
- Change lighting from cool to warm at set timings of the day according to circadian rhythms.
- Ramp up/down on sunrise, noon, and sunset.
- Detect presence of people (motion) in the room to turn lights on/off.
- Automatically adjust light levels based on ambient light (daylight harvesting).
- Control using my MacBook, iPhone, iPad and/or Apple Watch via web — and Siri.
Implementation Phases
Now that I’ve set the requirements, I think it’s best to break down the project into key phases (for the small wins, of course!):
- Programatically tune colour levels and brightness
- Occupancy sensing
- Daylight harvesting
- Control via app/wearable + Siri integration
- Installation on ceiling, calibration and user testing
Lighting Control Limitations
It was difficult to search for affordable LED drivers from Chinese suppliers that comes with full English documentation, so I decided on a simple hack to control the lights: reverse-engineer the remote controllers of off-the-shelf LED light modules and use an IR transmitter connected to an Arduino to send the programmed logic instead.
Essentially, I’m limited to the capabilities of predefined light controls of the light module, but the time-savings from this implementation is a great tradeoff.
I could always improve the project to use LED drivers next time anyway.
Off-the-Shelf Remote-Controlled LED Light Module
The LED light module I purchased (S$ 16.80) has the following light-control functions enabled via the remote controller:
- Adjust brightness — however increment/decrement levels are not constant
- Adjust colour temperature (from Warm to Cool White)
- Change colour temperature (Warm, Neutral or Cool White)
- Set “evening lights”––warm white setting
IoT System Parts
To make the lighting controls, I needed the following parts to build my solution:
- Ambient light sensor (S$ 9)
- IR Transmitter (S$ 1)
- Motion detector: HC-SR501 PIR sensor ($5 at Continental)
- Logic board — ESP8266 (S$ 8.40 on Shopee/S$ 15 from Continental at Sim Lim Tower; reused an old board so I forgot the price!)
…and also, an TSOP38238 IR receiver (S$ 3) to decode the remote controller’s IR signals.
Quick maths? Costs about $45, possibly cheaper if you were to buy the IoT parts online (I didn’t!).
Implementation
Initialising lighting
Some sort of calibration must be made to store the lighting states on my light-control program since I’m not able to manipulate the light state directly via an LED driver.
I implemented a function called initialiseLighting()
that sets up the light fixture upon power up. It goes by the following sequence:
- Since there is no indication on the previous state, reset any previous state by choosing the “Evening Light” option. Then, turn it off. This way, my program can track the current state.
- Turn on lights to Cool White at full brightness, and measure the light reading at this peak brightness:
ambientWithMaxLightReading
via the light sensor readings. Once done, turn off. - Turn on lights to “Evening Light” again to measure the
ambientWithEveningLightReading
. Once done, turn off. - Measure the
ambientLightReading
when the lights are fully off: since there is no way for my program to confirm whether the lights are actually on or off, this reading becomes another data point for that.
Light Controller
The runLightController()
function does the following:
- Retrieves the current time.
- Controls the light temperature (warm, neutral or cool) according to the time of the day.
- Adjusts the brightness based on ambient lighting and time of day.
- Expose APIs for Siri Homekit-Homebridge control integration.
Web UI
The UI is built simply with HTML and Bulma as the CSS framework — allowing me to override the light controls through my laptop, tablet or smartphone, or set it back to automatic controls.
Siri integration
Siri helps me to override the light fixture controls through any of my Apple devices. Since it’s a custom IoT setup, I needed Homebridge to integrate my setup to Apple’s HomeKit.
I didn’t have a Raspberry Pi at home as a dedicated server, so I figured that my laptop will be sufficient as my Homebridge server––since I’ll likely be at home when I need Siri to control my lights.
Maybe a dedicated Pi next time.
With HomeKit, I’m able to set lighting scenes based on my definitions of brightness and colour temperatures — including adding my family members to control via Siri on their devices.
Installation
The installation was not as straightforward; I needed to use an existing light cable to install a power socket for powering my ESP8266 board on the ceiling.
It wasn’t easy––especially with a short ladder and a tall apartment ceiling height that made me stretch up often, but here’s how the final setup looks like:
Final Thoughts
I haven’t fully completed calibrating the system due to other commitments, but so far, it’s looking good.
Just wanna say that I really, really(!) love how accessible and cheap-ish IoT peripherals are to ordinary folks. It allowed me to toy around with this DIY project with so much fun and quite possibly continue building an ecosystem around it in the near future.