Posts tagged Home Automation

VariableWithHistory – making persistence invisible, making history visible

In a typical .NET application variables have a short lifetime. When they go out of scope or the application ends their value is lost. Also, you cannot ask a variable what its value was 1 hour ago, or what its average, maximum or minimum value was yesterday.

Yet, such a variable would be extremely useful when writing a Home Automation System because you often need to make comparisons between a current value and some historical average, or between two ranges (e.g. was the kitchen more or less occupied than yesterday). Now, normally you wouldn’t want to mix persistence up with the representation of a value in your code (see ‘Separation of Concerns’), but in this case I decided that it was worth mixing the two concepts because the benefits of doing so were so great.

So I created a class called VariableWithHistory<T> which is the abstract base class for IntegerWithHistory, DoubleWithHistory, BoolWithHistory, StringWithHistory and a number of others.  The first property worth noting on these classes is the .Current property.  This always gives you the latest value that has been set.  Setting the .Current value stores both the value and the DateTime (Utc of course) at which the value became current.  A history of all past values is maintained in MongoDB up to some suitable limit per variable (each variable can have its own adjustable history size in bytes by using MongoDB’s capped collections).  If the new value is the same as the old one no update is made, the implicit behavior being that the value changed and stayed there until it changes again, so if you want to know what the value is now it is the same as the last change recorded.

With this new variable type in place any object in the house can have any number of persistent fields on it (bool occupied, double temperature, string triggeredBy, …).  Updating these values is as simple as assigning to their .Current property.  When the system loads, each value comes back with the value it had when the system was shut down.  To accomplish this every VariableWithHistory is given a unique id (based on the unique id of it’s parent, e.g. a room).

So far so good, shut down, restart and the house doesn’t need to query a device to know if it’s on or off and all the long running Sequential Logic Blocks I use for rules (e.g. .Delay(days:2)) carry on running as if nothing happened.  This is particularly useful since I typically deploy a new version almost every day and some logic blocks have long delays built into them.

But besides providing simple recovery from a reboot, these persistent variables allow me to do some much more interesting things.

int CountTransitions(DateTimeRange range, T direction);
Counts how many transitions there have been to the value T in a given time range, e.g. how many times did the driveway alarm go ‘true’ this evening?

Dictionary<T, double> Fractional(DateTimeRange range);
Builds a histogram of all the values seen in the time range, e.g. 50% hot, 20% cold, 30% warm for a string variable that tracks temperature

DateTimeOffset LastChangedState
e.g. when was this sensor last triggered?

TimedValue<T> ValueAtTime(DateTimeOffset dt)
What was the value at a given time in the past, e.g. what was the temperature at the same time yesterday?

Each specific type of VariableWithHistory<T> may also have additional methods relevant to the type T.  For example, on DoubleWithHistory there is a method double Average(DateTimeOffset minValue, DateTimeOffset maxValue) which gets the average value over the specified time range.  On BoolWithHistory there is a method double PercentageTrue(DateTimeRange range) which you could use to find the average occupancy for a room yesterday.

 

My initial implementation waited for the database to write each update before allowing any queries but now I simply cache the Current value and assume that queries will probably get executed after updates and that the average temperature yesterday is close enough with or without the last 100ms of updates.  I did try to keep this class isolated from MongoDB but in the end the benefit of some of the atomic update capabilities in MongoDB made it easier to just take the dependency.

My previous implementation of this feature used my own in-memory database, MongoDB has slowed it down a bit but I’ve gained the ability to archive terabytes of sensor data which should prove useful for my next project which is to add some machine learning to the system.

 

 

 

 

 

 

 

Updated Release of the Abodit State Machine

I published a new version of the Abodit State Machine to Nuget this evening. You can find it here.

One breaking change in this version is that the state machine is now specified using three Type parameters instead of two:

public class OccupancyStateMachine : 
          StateMachine<OccupancyStateMachine, Event, BuildingArea>

The third type parameter, TContext, is a context object that can be passed in with every event occurrence or tick. This means that you don’t need to store any extraneous data in the state machine itself and can keep it as a pure representation of the state of the system.

In the example above I have an OccupancyStateMachine and the context is a BuildingArea. Each call to EventHappens now takes the event that happened and a BuildingArea object.

When you define your state machine you will need to include 4 parameters in each lambda expression.

Here, for example, is the current state machine for a BuildingArea in my home automation. It uses a hierarchy of states with two base states: Not Occupied and Occupied. It has timers for activity within a room or for occupancy within rooms that are contained by a floor. Note how it also exposes an IObservable<State> so that other objects can subscribe to state machine changes. I didn’t want to take the Rx dependency in the state machine class itself but you can see how easy it is to hook it up.

Of interest also is the way I represent occupancy as three distinct states, the extra one ‘Asleep’ represents a room that is not-occupied in the sense that there is no motion there now but there was at some point during the evening before.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Abodit.StateMachine;
using log4net;
using Abodit.Units;
using AboditUnits.Units;
using System.Reactive.Subjects;
using System.Reactive.Linq;

namespace Abodit
{
    /// <summary>
    /// An Occupancy State machine handles not occupied, occupied, asleep
    /// </summary>
    [Serializable]
    public class OccupancyStateMachine : StateMachine<OccupancyStateMachine, Event, BuildingArea>
    {
        private readonly Subject<State> watch = new Subject<State>();
        public IObservable<State> Watch { get { return watch.AsObservable(); } }

        public override void OnStateChanging(StateMachine<OccupancyStateMachine, Event, BuildingArea>.State newState, BuildingArea context)
        {
            watch.OnNext(newState);
        }

        public static readonly State Starting = AddState("Starting");

        public static readonly State NotOccupied = AddState("Not occupied",
                (m, e, s, c) => { 
                                m.CancelScheduledEvent(eTick);          // Stop the clock
                                m.IsTimerRunning = false;
                                m.IsRecentlyOccupied = false;
                                m.IsHeavilyOccupied = false;
                                m.After(new TimeSpan(hours:0, minutes:5, seconds:0), e5MinutesSinceOccupied);
                                m.After(new TimeSpan(hours:24, minutes:0, seconds:0), e24hoursSinceOccupied);
                                m.After(new TimeSpan(hours:48, minutes:0, seconds:0), e48hoursSinceOccupied);
                             },
                (m, e, s, c) => { });

        public static readonly State NotOccupiedIn5Minutes = AddState("Not occupied in over 5 minutes",
                (m, e, s, c) => { },
                (m, e, s, c) => { }, NotOccupied);

        public static readonly State NotOccupiedInOver24Hours = AddState("Not occupied in over 24 hours",
                (m, e, s, c) => { },
                (m, e, s, c) => { }, NotOccupiedIn5Minutes);

        public static readonly State NotOccupiedInOver48Hours = AddState("Not occupied in over 48 hours",
                (m, e, s, c) => { },
                (m, e, s, c) => { }, NotOccupiedInOver24Hours);

        public static readonly State NotOccupiedInOver1Week = AddState("Not occupied in over 1 week",
                (m, e, s, c) => { },
                (m, e, s, c) => { }, NotOccupiedInOver48Hours);

        public static readonly State Asleep = AddState("Asleep",
                (m, e, s, c) =>
                {
                    // Set a timer going for morning
                    var now = TimeProvider.Current.Now.LocalDateTime;
                    var morning = now.Hour < 8 ? now.AddHours(-now.Hour + 8) : now.AddHours(24 - now.Hour + 8);
                    m.At(morning.ToUniversalTime(), eMorning);
                },
                (m, e, s, c) => { },
                parent:NotOccupied);

        public static readonly State Occupied = AddState("Occupied",
                (m, e, s, c) =>
                {
                    m.IsRecentlyOccupied = true;
                    // Add a timer that runs while we are occupied
                    m.Every(new TimeSpan(hours:0, minutes:0, seconds:10), eTick);
                    // And set a timer going to mark 5 minutes since occupied
                    m.After(new TimeSpan(hours:0, minutes:5, seconds:0), e5MinutesAfterBecomingOccupied);
                    m.CancelScheduledEvent(e5MinutesSinceOccupied);
                    m.CancelScheduledEvent(e24hoursSinceOccupied);
                    m.CancelScheduledEvent(e48hoursSinceOccupied);
                },
                (m, e, s, c) => { });

        public static readonly State HeavilyOccupied = AddState("Heavily occupied",
                (m, e, s, c) => { },
                (m, e, s, c) => { },
                parent:Occupied);

        private static readonly Event eStart = new Event("Starts");
        private static readonly Event eUserActivity = new Event("User activity");
        private static readonly Event eTick = new Event("Tick");
        private static readonly Event eTimeout = new Event("Timeout");
        private static readonly Event eMorning = new Event("Morning");
        private static readonly Event e5MinutesAfterBecomingOccupied = new Event("5 minutes after becoming occupied");
        private static readonly Event e5MinutesSinceOccupied = new Event("5 minutes since occupied");
        private static readonly Event e24hoursSinceOccupied = new Event("24 hours since occupied");
        private static readonly Event e48hoursSinceOccupied = new Event("48 hours since occupied");

        private static readonly Event eAllChildrenNotOccupied = new Event("No child occupied");
        private static readonly Event eAtLeastOneChildOccupied = new Event("At least one child occupied");

        private double decliningActivity = 0.0;         // Up 1000 every UserInput, down x0.9 every n seconds
        private const int ActivityPerUserInput = 1000;
        private const double rateOfDecline = 0.92;

        public bool IsTimerRunning { get; set; }
        public bool IsRecentlyOccupied { get; set; }
        public bool IsHeavilyOccupied { get; set; }

        static OccupancyStateMachine()
        {
            // On startup we transition immediately to starting
            // but we want an event call to do this so we aren't doing any work
            // in the constructor, and so the initialization only happens when it's
            // a true 'cold start' not a 'warm start' from some database state
            Starting
                .When(eStart, (m, s, e, c) => { return NotOccupied; });

            // Note: This is a hierarchical state machine so NotOccupied includes Asleep
            NotOccupied
                .When(eAtLeastOneChildOccupied, (m, s, e, c) => 
                {
                    return Occupied;
                })
                .When(e5MinutesSinceOccupied, (m, s, e, c) =>
                {
                    // Could signal something??
                    return s;
                })
                .When(e24hoursSinceOccupied, (m, s, e, c) =>
                {
                    // Could signal something??
                    return s;
                })
                .When(e48hoursSinceOccupied, (m, s, e, c) =>
                {
                    // Could signal something??
                    return s;
                })
                .When(eUserActivity, (m, s, e, c) =>
                {
                    m.After(c.OccupancyTimeout, eTimeout);                // start a new timeout
                    m.IsTimerRunning = true;
                    return Occupied;
                });

            // Asleep is a substate of not occupied so no need for more logic on becoming occupied ...
            Asleep
                .When(eMorning, (m, s, e, c) =>
                {
                    // Eliminate Asleep if appropriate
                    return NotOccupied;
                });

            // Occupied includes recently occupied and heavily occupied ...
            Occupied
                .When(e5MinutesAfterBecomingOccupied, (m, s, e, c) => 
                {
                    m.IsRecentlyOccupied = false;
                    return s;
                })
                .When(eUserActivity, (m, s, e, c) =>
                {
                    // Accumulate activity ...
                    m.decliningActivity += ActivityPerUserInput;

                    m.CancelScheduledEvent(eTimeout);               // cancel the old timeout

                    m.After(c.OccupancyTimeout, eTimeout);                // start a new timeout
                    m.IsTimerRunning = true;

                    if (m.decliningActivity > 20 * ActivityPerUserInput)
                        return HeavilyOccupied;
                    else
                        return s;
                })
                .When(eAllChildrenNotOccupied, (m, s, e, c) =>
                    {
                        if (m.IsTimerRunning)
                        {
                            // If the timer is running ... wait until it runs out
                            return s;
                        }
                        else
                        {
                            DateTime nowLocal = TimeProvider.Current.Now.LocalDateTime;
                            if (nowLocal.Hour > 17)
                                return Asleep;
                            else
                                return NotOccupied;
                        }
                    })
                .When(eTick, (m, s, e, c) =>
                    {
                        m.decliningActivity *= rateOfDecline;
                        return s;
                    })
                .When(eTimeout, (m, s, e, c) =>
                    {
                        DateTime nowLocal = TimeProvider.Current.Now.LocalDateTime;
                        if (nowLocal.Hour > 17)
                            return Asleep;
                        else
                            return NotOccupied;
                    });

            HeavilyOccupied.When(eTick, (m, s, e, c) =>
            {
                // Same code as Occupied but this one will override if we are in HeavilyOccupied mode
                m.decliningActivity *= rateOfDecline;
                // Fall back to just occupied when ...
                if (m.decliningActivity < 0.2 * ActivityPerUserInput)
                    return Occupied;
                else
                    return s;

            });


        }

        public OccupancyStateMachine()
            : base(Starting)
        {
        }

        public OccupancyStateMachine(State initialState)
            : base(initialState)
        {
        }

        public override void Start()
        {
            this.EventHappens(eStart, null);
        }

        public void UserActivity(BuildingArea ba)
        {
            this.EventHappens(eUserActivity, ba);
        }

        public void AllChildrenNotOccupied(BuildingArea ba)
        {
            this.EventHappens(eAllChildrenNotOccupied, ba);
        }

        public void AtLeastOneChildOccupied(BuildingArea ba)
        {
            this.EventHappens(eAtLeastOneChildOccupied, ba);
        }
    }
}

GreenGoose Review

GreenGoose Hardware
One of the conclusions I’ve reached from my many years experimenting with home automation is that one of the missing ingredients is affordable, wireless sensors with long battery life. One of the best solutions I’ve found so far is to use CADDX alarm sensors because they are wireless, have exceptionally long battery life and can be connected to a PC using a reliable serial connection. Proponents of the Internet of Things talk about every device having an IP address and recently some wifi-connected sensors have appeared. I’m skeptical of that approach: it seems unlikely however that they will get the kind of battery life you need to be practical and you really don’t need a separate IP address for every single sensor.

What I believe we need is a hub device that connects to the internet and then really cheap wireless sensors that communicate back through it using a connection technology that requires much less power than wifi. So when GreenGoose recently announced their sensors I was one of the first to place a pre-order and this week I received one of their first device shipments. This blog post discusses some of my initial impressions.

First off I have to say I don’t like the egg shape or the color of the hub. Fortunately it’s in the wiring closet next to the router so I don’t need to see it.

GreenGoose Mounting on food containerThe sensors themselves are remarkably small considering they claim a battery life of 1.5 years and the fact that they include both a sensor, some intelligence and a wireless transmitter. Two of the sensors were stick-on devices which I stuck on the dog and cat food containers respectively even though one was labelled food and the other treats. The other two were shaped like dog tags. Here you can see one of the stick-on sensors mounted inside the lid of a dog food container.  You can view a teardown of the GreenGoose sensors and hub on this Flickr page.

Connecting the sensors up to my account took two attempts, three sensors were found on the first try and the remaining sensor on the second try. That’s apparently fairly normal. There were a few configuration problems with my account and the iPad software (actually iPhone software in 2x mode) and the web site is clearly still under development with daily bug fixes and improvements happening each time I try it. But, I have to say the folks at GreenGoose have been incredibly responsive to my every comment or bug report.

GreenGoose User Interface
So now I’m getting reports from the sensors on their web site and overall things seem to be working quite well. It’s certainly not 100% reliable yet in terms of capturing every event so I don’t think these are going to be the perfect home automation sensor that I’m still waiting and hoping for, but, in all fairness, the folks at GreenGoose aren’t selling these sensors as alarm panel sensors, but as more of a fun game tracking activity and reminding people to go walk the dog. I’ll update this blog when I have a better idea exactly how accurate they are at capturing activity.

The biggest gotcha however is that my original plan to use the sensors on different devices has been somewhat thwarted by the realization that each different sensor type is calibrated to detect a specific kind of motion. You cannot re-purpose them like you would a normal motion or contact sensor. So putting the dog collar sensor on my key chain isn’t producing the results I’d expected. We will have to wait for GreenGoose to come out with sensors to put on doors, cars, shoes, cellphones, iPads and whatever else we want to track. I’ve suggested to GreenGoose that they explain this better on their web site as many hobbyists will try to repurpose the sensors for applications other than the ones for which they were designed.

Another issue at the moment is that the web site forces you to assign the sensors to a specific pet and they only support one pet name. They say they’ll add multiple-pet support soon.

Next I plan to try their API and will report back on how that goes.

Bottom line: this is remarkable technology – a mems accelerometer, some computing power, a radio transmitter and a 1.5 year battery in a package the size of a stick of gum is quite a feat of engineering. Some of the software is a bit ‘immature’ but it’s improving daily. Overall this is a very affordable way to try out some ‘quantified self’ ideas for yourself, it might help you walk the dog more often (our dogs wouldn’t let you forget to do that, but maybe yours would!), and the support from GreenGoose has been great.

Home Automation Calendar Integration

Calendar Home Automation Integration One feature of my home automation system is Google Calendar integration. What this enables is two things: (i) the house can record what happened on the calendar so I can see at a glance what’s been going on back home and (ii) the ability to put events on the calendar for the house to do certain things.

For example, we recently bought some new baby chicks and they need to be kept warm at light. An infra-red lamp in the chicken house is connected to an X-10 controlled outlet (behind a GFCI, of course since this is outdoors). The device that controls that outlet is called “Chicken lights” but also has several shorter aliases (e.g. “Chickens”). Using the home’s natural language engine that outlet can be controlled remotely by the chat interface, by the email interface, by the voice interface or by the calendar interface.

In this case, a simple recurring event on the calendar to turn the light on every night for 9 hours is sufficient and I can set the recurring event to stop after a few weeks because by then the chicks will no longer need it.

This complete integration of Calendar and Natural Language Engine functionality certainly makes for a very easy way to control and monitor a smart home!

Net result … happy chicks:

Smart home energy savings – update for 2010

Smart home energy savings 2010

Here’s an updated graph showing the ongoing reduction in energy for our smart home. Driven mainly by continual improvement in the algorithms that control the heating, air conditioning and lighting the overall consumption of gas and electricity has continued to decline throughout 2010. It appears however that I am approaching the limit as to what is possible as the trend lines are beginning to flatten out. Going forward I’ll continue to try to improve the algorithms but I’ll also be on the lookout for any parasitic power-consuming devices and I’ll be dealing with them using techniques like the smart power strip I mentioned here.

A smart power strip

Smart power strips to save energy

Recently I added a smart power strip to the TV/Amplifier setup in the living room. My main aim was convenience – to make it easier to turn everything off all at once. But I also wanted to see how much power I could save by eliminating the parasitic power drain that a TV, amplifier and two DVD players have when in the ‘off’ state.

The power strip I bought is the one featured to the right here and to date I’m pretty happy with how it’s working. The power strip has one ‘blue’ outlet that senses when a single device goes on or off and then several ‘green’ outlets that switch accordingly. Initially I plugged the amplifier into the sensing output and everything else into the green outlets. That worked great and when the amplifier goes off so does the TV, the DVD player and the DVD changer. Since the amplifier is a Denon -CI model I can also control it remotely and since everything else switches on and off with it I can remotely shut down the whole stack from my home automation software.

The only problem with that approach is that in the ‘off’ mode the Denon -CI still consumes about 5W whereas the TV consumes 0W when off. The TV is one of the earliest HD TVs, a Panasonic Tau CRT TV so it’s fairly power hungry when on but it has a ‘real’ on/off switch so when it’s off there is no power draw at all. [Until recently the picture on that CRT beat nearly every flat panel TV on the market, but with recent LED LCD TVs I think I may finally be willing to part with it. It's old technology, but still an awesome HD picture.] So now I have to chose between remote power-off control and a 5W constant draw or no remote control and 0W consumption.

When I purchased the smart power strip I was concerned that it might itself have a phantom power drain equivalent to one of the other devices but it appears to be relatively harmless consuming hardly any current for itself.

The one adjustment you need to make on the smart power strip is to set the sensitivity so it can turn on and off at the right point.

Overall, definitely a recommended buy on this one.

Holiday Season (Christmas) in our Smart Home

Smart Home lighting for the Christmas Tree

So what does a smart home do at Christmas time?

Well, obviously it controls the Christmas lights, both the ones on the exterior and the ones on the Christmas tree and around the house. The indoor lights come on automatically at dusk and stay on provided the room they are in is occupied. Leave the house and they go off automatically. Walk back in and a strain-gauge under the living room floor detects your arrival and the tree lights and rope lights come right back on. Why waste energy lighting your Christmas tree if nobody can see it and why press light switches if you don’t need to?

The exterior lights come on at dusk and go off around 9PM. During holiday seasons the permanent Christmas lights along the eaves of the house come on automatically too. But the house also understands whether it has visitors. This isn’t something you need to tell it, it just figures it out by counting cars arriving and people coming in through the front door. If the house thinks it has visitors it will leave all the outside and Christmas lights on until the visitors have left. Again, there’s nothing you need to tell it, this is a ‘smart’ home not a ‘dumb’ home, and this is real ‘home automation’ not ‘home control’.

Another change that happens automatically during the holiday season is that the alert for a car coming down the drive changes to a subtle jingle bells sound. Normally the sound is the distant tweeting of birds and it’s played quietly so that visitors don’t even notice it. The residents of course know that there isn’t some bird tweeting outside but that a car is approaching the house. The dogs know the sound too and go running to the door barking. With the change to jingle bells sound the dogs quickly figure that one out too. The only problem is that now, when jingle bells are heard on TV they both run off barking to the front door! If only home automation systems were as easy to train as dogs! The driveway sensor by the way is one of those magnetic detectors buried about 120′ away to the side of the drive. It gives sufficient warning to prepare for a visitor before they even get to the front door.

One final change that happens automatically at this time of year concerns the music system in our house. My home automation software includes multi-channel audio playback through a zoned-audio switch. This allows any one of three sound cards to be connected to any set of speakers in the home. This means you can have exactly the same music playing across a whole floor, or indeed throughout the house, without any lag between rooms. In effect this is a poor man’s Sonos as the cost of each additional source is about $7.50 for a USB sound card plus about $150 for a single zone amplifier. You instruct the music system to play back music either by chatting to it on Instant Messenger (it has its own XMPP address), by emailing it, or by putting an entry on the house’s own Google calendar telling it when to start playback. For example, ‘play songs added this week in office’ would begin playback of any new music added to the system this week. And, the change that happens at this time of year is that the music playback subsystem allows Christmas music to play. That’s right, for the rest of the year, no matter what random selection of music you ask it to play (e.g. every song with the word ‘Bing’ in the title, artist or album) you will not hear any Christmas music. This is one feature iTunes and every other music player should adopt!

What does a Smart House do at Halloween?

Pumpkins_2010-7
Creative Commons License photo credit: madmarv00

At Halloween our home automation system has a few additional and changed behaviors.  Here are some of them …

1. When a visiting car comes down the drive the usual alert in the house is replaced with a spooky noise.  (Normally the driveway alarm is the gentle tweeting of birds — something that could easily be mistaken for an ambient noise if you didn’t live here and know what it means.)

2. When you approach the front door there’s an alarming shuffling and scratching sound from the bushes in front of the garage.

3. When you open the front door to visitors it plays another Halloween clip “Hello Children … ” in a spooky voice.

4. The media player automatically allows any Halloween-appropriate songs to play when on random play.  Normally such songs are skipped automatically.  So you just might hear the Monster Mash, for example, mixed into the normal random rotation.

If your house could talk to you, what would it say?

IMG_5300.jpg
Creative Commons License photo credit: tompagenet

Suppose for a minute that your house could talk.  What would you want it to tell you?

That’s a question I’ve been considering over the past few years because unlike most of you, my house can talk!  There are ceiling speakers in many rooms, the house knows which rooms are occupied, and it talks to you when it has information it needs to communicate.

I’ve experimented with many different announcements over the years, some of which turned out to be useless, some which just became annoying after too many repetitions, and a few that withstood the test of time and daily usage to become fixtures in my smart home.

Here’s a list of some of the current announcements my house makes:-

1. It announces who is calling.  “Talking Caller ID” if you will, except this one has a database behind it and whenever it sees a number it doesn’t recognize it will ask you who it is so it knows how to speak their name next time.  (The asking is done over instant messenger or email, a separate topic I’ll write about soon.)

2. It announces that you have missed phone calls.  It does this when the house has been unoccupied for a while and you walk back in.  It doesn’t do it right away because you are probably carrying stuff and banging doors.  Instead, it waits a moment and then when it detects you moving again in the house it announces all the calls you missed while you were away.

3. It announces the weather for the day in the morning when you get up and head into the bathroom.

4. It announces the weather for tomorrow if it’s already afternoon time today and you turn on any media zone.  But, of course, only if it hasn’t announced it for a while (repetition gets boring fast!).

5. It can announce the artist and title of each song as it is playing.  A simple chat command ‘dj on’ enables this feature.  At the start of every song it ‘ducks’ the music, announces the song, and then brings the volume back up, just like a professional voice-over announcement.

6. It tells you if the traffic is bad on the way into Bellevue this morning, where ‘bad’ is defined as more than seven minutes above the average for this day of the week.  Knowing that it’s bad on Monday morning isn’t useful.  Knowing that it’s much worse than normal is.

7. It announces the time every 10 minutes in the bathroom in the morning rush helping everyone stay on track.

8. It announces when it’s time to wake up using a schedule defined on Google calendar.  This means you can adjust the alarm clock as easily as you can change an appointment, no fiddly black on black buttons under an alarm clock to push.  It also means that the alarm can handle weekdays vs weekends and holidays.

9. It announces if there has been fresh snow overnight at the local ski resort: time to go skiing!  But it also warns you if the pass is closed as it sometimes is in winter after a heavy snowfall overnight.

10. It announces that it’s garbage collection day if it thinks you haven’t taken the trash out.

11. It warns you that the garage doors are open if you try to go upstairs in the evening leaving them open.  That’s a bit like HAL controlling the pod bar doors but in reverse: it tells you to close them!

12. It complains that the fish are hungry if nobody has opened the door to their tank for 24 hours.  Each 6 hours after that the announcements become more urgent, culminating in a “mine mine mine” audio clip from Finding Nemo.  (All our other pets do a fine job at indicating their hunger but the fish lacked this ability until now).

13. It says “good night” when you turn the lights off at the end of the day :)

14. You can also ask it to remind you of anything with a verbal reminder, e.g. the command ‘remind me in 15 minutes say “Turn oven on” in study’ does exactly what it says.

15. It tells us if anyone goes into our barn unexpectedly.

16. It can also scare intruders when it detects unusual motion that doesn’t fit the normal pattern – nobody expects a house to talk to them when they are burglarizing it!  Fortunately I’ve never had to test this feature.

Crucially it does very few of these announcements when it detects that we have visitors.  Party music should not be interrupted by home automation announcements!  It also learned early on that any announcement in a bedroom when the owners were asleep was a very, very bad idea punishable by instant termination and recompilation!

If you have any questions about these or other features of what I believe is the “World’s Smartest House” please feel free to comment below or on the relevant page.

Home Automation Top Features

Home lighting

Lighting probably uses more electricity than anything else in your home

Someone recently asked me what the top features are in my home automation system. That’s a tough question, I have several favorites and there are so many features in there already or under development. But, here’s a current list of some of my favorites:

  • Lights turn themselves off automatically – saves 40% on electricity usage
  • Lights turn on ahead of you at night as you walk around
  • Intelligent heating and A/C control (based on actual and expected occupancy, ‘optimum start’, weather forecast and local thermostat control)
  • Monitor house from anywhere, see at a glance what’s happening
  • Play music, news, podcasts, … in any room or zone
  • House speaks: caller ID, alarm clock, reminders, missed calls, weather forecast, … with professional quality ducking of background music
  • Automatic phone book learns the name of everyone who calls
  • Chat interface with natural language control: understands complex sentences like “who called last week on Friday after 4pm”, tells you what’s happening (calls, cars, …)
  • Calendar integration to record what happened and accept future instructions
  • Turn TV down or off remotely (“dinner’s ready” feature)
  • House can sense what’s happening and act accordingly: different behavior for away on vacation, not-occupied, occupied, visitors staying over, party
  • House generates a local, sports-specific weather forecast and alerts when there’s fresh snow, pass closures, really bad traffic
  • House can explain what it did and why it did it
  • Programming features for defining new behavior based on events, times, past history, forecasts, …