In many home automation scenarios we have an input and we want to act on it. Rarely is it a simple if-this-do-that scenario. It may be so complex that we need a state machine or some sequential logic blocks.
Over time I've evolved both of these approaches and now have a full hierarchical state machine available on Github and a more advanced approach to logic blocks that can chain back and forth within the graph to explain why any action fired upstream and what it will affect downstream.
Let's take a look at all the logic blocks I find useful.
Converting from real-valued inputs to real-valued inputs
Any time series in my system can be transformed to a new time series by an arbitrary conversion function (e.g. degrees C to degrees F), by addition or subtraction from another time series, by summarization (e.g. daily power consumption) or by differentiation (e.g. rate of change of humidity). Some of these calculations are performed on the fly which can be complex because time series are all stored in a compressed form with changes recorded only when necessary not on equal or predictable intervals. This requires interpolation to find values at the corresponding times between two series. Some are simply calculated as their inputs change and the value is recorded allowing rapid lookup later (e.g. power consumption summaries for a room or floor).
Converting from real-valued inputs to binary inputs
We might want to turn a light on when it gets dark outside, or a fan when the humidity goes up. Naively we might say light_state = outside_brightness < 80%. This is never the right approach because all analog signals have noise and may oscillate around any particular value before moving to consistently above or below. We always need to apply hysteresis with two values: an on value and an off value and there needs to be some gap between them to prevent rapid on-offs on the output.
Handling binary inputs
Having converted our analog values and applied hysteresis to get a digital value we are still not quite ready to control a device. An A/C compressor for example cannot be cycled quickly without damaging it. A light may linger on for a while after a room goes not occupied in case the occupant returns quickly. These temporal logic blocks are closely related to the old-fashioned timing relays you can still find in many industrial applications. They include:
Pulse stretch / delay-off
Pulse limit
Delay
Repeat
Actions
Finally we are ready to do something so a command block runs. Most home automation systems have actions like light on, light off, light to x%. These are OK but there is a better way, and I wish light switches implemented this interface directly ... The problem comes when two events both want to control a light and one wants 50% brightness and the other wants 75% brightness. If they keep firing alternately, the light might flick back and forth between the two brightness values. A better API for lighting control, and the one I use throughout my system is BrightnessAtLeast(x%) and BrightnessAtMost(x%). This API is commutative and idempotent.
Logging
Another critical part of an event system is logging. By using chained logic blocks defined with my fluent Rx-like syntax I can capture the sequence that actually triggered the event and log that. A log for a light coming on might note that it came on because (i) it's after 5pm; (ii) it's dark; and (iii) a car came down the drive. This makes it much easier to figure out what went wrong. Any complex system will eventually exhibit unexpected behavior, but logging like this has helped find and fix issues quickly when it does.
I've been working on home automation for over 15 years and I'm close to achieving my goal which is a house that understands where everyone is at all times, can predict where you are going next and can control lighting, heating and other systems without you having to do or say anything. That's a true "smart home".
My year long Bluetooth project that won the $20,000 HCI and Microsoft competition during lockdown has continued to grow and now reliably tracks how many people are in the house and outside and can locate any device down to room level.
Digital Twin are an online representation of a real world object, a copy of its properties in the digital world and a way to send updated and commands to it. In effect I've been making them for years but now they have a trendy name.
An overview of the many sensors I've experimented with for home automation including my favorite under-floor strain gauge, through all the usual PIR, beam and contact sensors to some more esoteric devices like an 8x8 thermal camera.
Why automated learning is hard for a smart home. The perils of over-fitting, under-fitting and how the general unpredictable nature of life makes it hard to build a system that learns your behavior.
One way to reduce the volume of sensor data is to remove redundant points. In a system with timestamped data recorded on an irregular interval we can achieve this by removing co-linear points.
ESP32 provides a great platform for sensors around the house but by the time you've added a USB power brick, cable and enclosure it's quite messy. I wanted a device that I could just plug in with no exposed wires and no mounting needed so I designed one in OpenSCAD.
Bluetooth sensing for home automation is a great proxy for people counting as it can detect and locate each cellphone in the house. iBeacons attached to tools, cars and pets can provide a 'find my anything' feature too.
Having at least one light sensor is critical for any home automation system that controls lightng. Lights need to be turned on when it's dark not at specific times of day, especially here in Seattle when it can be dark and cloudy at any time of day.
Microwave doppler sensors can be found in some alarm sensors but there are also available very cheaply as a separate component. They offer exceptional range but suffer from false triggers requiring a probailistic approach to people sensing.
Optical-beam sensors are reliable and can cover a long-distance such as across a garage or aisle-way. When they include multiple-beams they have good false-trigger rejection.
Another super useful function for handling sensor data and converting to probabilities is the logistic function 1/(1+e^-x). Using this you can easily map values onto a 0.0-1.0 probability range.
In a home automation system we often want to convert a measurement into a probability. The ATAN curve is one of my favorite curves for this as it's easy to map overything onto a 0.0-1.0 range.
Several years ago we did a major remodel. I did all of the finish electrical myself and supervised all of the rough-in electrical. I also put in all of the electrical system and water in our barn. I have opinions ...
An if-this-then-that style rules machine is insufficient for lighting control. This state machine accomplishes 90% of the correct behavior for a light that is controlled automatically and manually in a home automation system.