Presence Detection for openHAB via Wifi and Geofences

Many home automation task have to be done depending on whether somebody is at home or not. Heating the bathroom up in the morning is a good thing while somebody is at home but should be avoided while we are on a long vacation.

Furthermore, if openHAB knowns that somebody leaves home, it can take care of energy saving actions such as reducing the temperature or switching all lights off.

Other scenarios are imaginable but these two examples are the use cases I have currently implemented in my openHAB rules.

Since we both (my girlfriend and I) have our iPhones with us almost all the time, it should be quite easy to track our presence using these devices.

Prerequisites

Our presence detection mechanism relies on the wifi connection between our iPhones and our router. If an iPhone connects to our Fritz!Box (model 7490) openHAB detects this via the Fritz!Box TR064 binding.

Unfortunately, wifi alone is not reliable enough. In standby, the iPhones may disconnect from the Fritz!Box. This happens quite often during night and leads to a cold bathroom in the morning since openHAB thinks that nobody is present.

Therefore, a second source for presence detection has to be found. Luckily, there exists a free app called OwnTracks in the iOS app store which allows the definition of geo fences and is able to connect to a MQTT broker to inform interested subscribers about state changes. Read more about MQTT here.

Such an MQTT broker is Mosquitto, which is open source and free to use. Mosquitto can be easily installed on a Raspberry PI and integrates well with the MQTT binding and the MQTTitude binding for openHAB.

Setup

Install Required Software

  1. Install the Fritz!Box TR064 binding and configure it according to the binding documentation
  2. Install Mosquitto (see Instructables.com for a tutorial)
  3. Install the MQTT binding as well as the MQTTitude binding

Configure the MQTT Broker

  1. Create users (one for each person and one for openHAB itself) using mosquitto_passwd (Documentation)
  2. Make sure, that your MQTT broker is reachable from outside of your network. Otherwise OwnTracks will not be able to post notifications on a topic while leaving home.
  3. Configure the MQTT binding according to its documentation.

Configure OwnTracks

The configuration of the OwnTracks app is straight-forward. First we need to connect OwnTracks with our MQTT broker.

Configure OwnTracks on each smartphone using the previously defined username and password. OwnTracks lets you specify a DeviceID. This ID is part of the topic on which OwnTracks publishes location change notifications.

For example, if my user is called “Tobi” and my device has the ID “MiniMe”, the MQTT topic is owntracks/Tobi/iPhone. We need this topic later, when defining items in openHAB.

Configure Geofences

There are several possibilities, when it comes to the definition of geofences. We could use the Manual Mode of OwnTracks and specify the regions in the openHAB configuration. The advantage of this approach is, that the devices must not know about the existing locations (fences/ regions) and the entire configuration is done in openHab.

However, in the manual mode, the smartphones need to send every location change over the MQTT broker and OpenHab has to evaluate the GPS coordinates every few seconds or so. This causes a lot of network overhead as well as a higher battery consumption.

Another approach is to switch OwnTracks into Region Mode and to define the regions in the app itself. In this case, regions must be defined and named on every smartphone on its own but only larger movements (i.e entering or leaving a region) are reported via the MQTT topic. This reduces the communication to a few messages per day.

I have chosen this approach and defined a region “Home” in OwnTracks on both iPhones.

Items in openHAB

Persons and the General Presence State

For each person in our household I define a switch in openHAB, i.e.:

Switch Tobi_Present "Tobi @ Home [MAP(presence.map):%s]" <present> (Somebody_Present)

As you can see, this item is part of the group Somebody_Present. This item is a simple OR-group which expresses the fact that at least one person is at home:

Group:Switch:OR(ON, OFF) Somebody_Present "Jemand @ Home [MAP(presence.map):%s]" <present>

This was the easier part of the presence detection.

Device States

For each device, I define two switches in openHAB. One for the wifi state and one for the geofence (i.e. GPS state).

The wifi switch uses the TR 064 binding:

Switch iPhoneTobi_Wifi "Tobi @ Home (iphone, wifi) [MAP(presence.map):%s]" <present> {fritzboxtr064="maconline:<MY-MAC-ADDRESS>"}

Where <MY-MAC-ADDRESS> is the MAC address of my iPhone.

The geofence switch for my iPhone is defined as:

Switch iPhoneTobi_MqttHome "Tobi @ Home (iphone, mqtt) [MAP(presence.map):%s]" <present> {mqttitude="internal:owntracks/Tobi/iPhone/event:Home"}

Here internal is the name of my MQTT broker, as defined in the openHAB configuration file in the MQTT section. The event:Home event is published by OwnTracks whenever my iPhone enters or leaves the Home region. The switch is switched off when leaving the region and switched on, when entering the region.

presence.map and Presence Icon

For better readability in the sitemap, I use a transformation file to map switch states ON and OFF to more appropriate words:

OFF=Nein
ON=Ja
-=Unbekannt
NULL=Unbekannt

The icon part <present> in the item definition yields an icon which comes in two versions, present-on and present-off which are chosen automatically according to the current state.

Presence state in the openHAB sitemap. Text items are used to group the wifi and mqtt items on the next level.

Rules: From Devices To Persons

Why the hell is it not sufficient to use an OR-group to combine the wifi and the geofence state?

As I have stated earlier, the wifi may disconnect while I am at home. Hence relying on the wifi signal alone leads to false negatives: openHAB thinks that I am absent while I am at home.

On the other hand, wifi has no false positives: If my iPhone connects with my home wifi, I am at home (or at least my phone is).

A GPS signal on the other hand may jump a bit. But if I define my home region large enough (currently I have defined a 70m radius), it is quite unlikely, that the signal jumps out of my home region while I am at home. And the same is true for the other direction: If my GPS signal is within my home region, there is a high probability that I am indeed at home.

Therefore, changes of my geofence state are forwarded directly to my personal presence state switch:

rule "Tobi MQTT Presence"
when
    Item iPhoneTobi_MqttHome changed
then
    sendCommand(Tobi_Present, iPhoneTobi_MqttHome.state as StringType)
end

The wifi rule is a little bit more complicated: If wifi changes to OFF, I use the geofence state as last resort to avoid false negatives from the wifi switch:

rule "Tobi Wifi Presence"
when
    Item iPhoneTobi_Wifi changed
then
    switchPresence.apply(Tobi_Present, iPhoneTobi_Wifi, iPhoneTobi_MqttHome
end

where switchPresence is a function defined as

val org.eclipse.xtext.xbase.lib.Functions$Function3 switchPresence = [
    SwitchItem presenceItem,
    SwitchItem wifiItem,
    SwitchItem mqttItem |
    if(wifiItem.state == ON) {
        sendCommand(presenceItem, ON)
    } else if(wifiItem.state == OFF && mqttItem.state != ON) {
        sendCommand(presenceItem, OFF)
    }
]

The mqttItem.state != ON may look awkward but it can happen that the geofence state is undefined when this rule is executed and in this case, the presence must be switched off due to the lack of other information.

I have these two rules defined for each person in our home (makes four rules for my girlfriend and me).

Conclusion and Outlook

While the combination of GPS and Wifi is a bit complicated, I find it to work much better than GPS or Wifi alone. Wifi leads to many false negatives while geofences are relatively slow and require to leave and reenter the home region if openHAB forgets the current state (i.e. through a reboot).

The combination of both states with the rules above leads to a reliable presence detection. I represent the state in our sitemap using Text items, but more important I am using the state for heating automation:

When nobody is at home, the radiators are set to an “ECO” temperature, i.e. 16.5 °C and reset to the previous temperature when somebody is back home again.

Having a reliable presence state makes me think of other use cases. One might be to heat up the living room when I am leaving work or to switch lights off if nobody is at home. Furthermore, openHAB could warn the last person that is leaving our home, if a window is still open. Endless possibilities! 🙂

How does your openHAB detect presence state and what are you doing with this information?

Leave a Reply

Your email address will not be published. Required fields are marked *