For a while now I’ve been relying on my outdoor Aqara motion sensor to additionally report light levels. However, whilst it has coped with the outside Scottish weather admirably for two winters now, it is very slow to report changes in luminosity when there is no motion to trigger it, and it also just reports on a scale of 0 to 1000.
Additionally, the sensor has been mounted at the most sheltered location, and the majority of the sun comes from the most exposed location. This coupled with cloud shade and generally overcast days, means the system often underreads, and Home-Assistant turns on the lights when there’s really no need.
I need to fix this.
I’m a big fan of Wemos D1 Minis, and ESPHome, so the use of those two items is a requirement.
I now have three sensors around the house, using suction cups to hold them onto a window on each wall (one wall faces the garage and has no decent light), with a USB power feed. Small enough to snugly fit down in the corner of the window. The data is reported to Home-Assistant.
In order to measure light level, most people have been relying on a light dependent resistor, or LDR. I’ve tried this before and whilst it works it takes a lot of calibration and trial and error, and you’re still left with something that has no real reference points.
Instead, I’ve picked the OPT3001 “Digital ambient light sensor (ALS) with high-precision human-eye response” from TI, and it helpfully comes on a little breakout board too. It’s small, it communicates over I2C, and already has some example code by ClosedCube Ltd. The OPT3002 is also available, but it is designed to measure wavelengths beyond what the human eye can see. I feel that the OPT3001 is more suited for this job.
First task was to make it work with ESPHome, since it’s not supported natively. Thankfully there were some helpful tutorials available, and I’ve written some very bad C++ which allows ESPHome to use the CloseCube code withouth modification.
In essence, OPT3000.h will be needed, along with an ESPHome config file, and the ClosedCube code copied into a neighbouring directory
Modifications and improvements to my own OPT3001.h will be gladly received. It has no error checking, sanity, good habits, etc.
Once the code was made ready, it was turned from a breadboard project into 3 protoboard assemblies. All this did was hard mount the OPT3001 sensor in front of the Wemos and make it suitable for mounting into a 3D printed case.
The 3D printed case is available at https://www.tinkercad.com/things/21nBukc8C9o-wemos-light-sensor and as an object at https://www.thingiverse.com/thing:4714696
Sadly because I edited it on TinkerCad it can only be downloaded as a complete STL. If editing is desired it’ll have to be done on TinkerCad.
To mount it on the window, I obtained some mushroom head suction cups, used the 3D printer to spit it the modified case, and stuck it various windows. The case snugly holds onto the suction cups by gravity alone.
The end result has been a drastic improvement in outside light measurement. It’s quite evident from the graph below that the Aqara sensor is lagging behind and not reporting the decrease in light intensity that comes from minor cloud cover. What can be seen, though, are the better readings throughout the cloud cover changes. Yet there is still more than enough granularity in the scale to permit intelligent lighting choices by Home-Assistant.
I still have some tweaks to make to the home automation system so that I can adjust for overcast days in the early evening and other such marginal situations, but overall I now have a much more responsive and accurate system for measuring the light level coming in to the house.