Maintaining a smart home

It turns out you can’t just set up a smart home and expect everything to keep running smoothly. A certain amount of routine maintenance is essential.

If you have automations that don’t run very often, it’s worth triggering them from time to time to ensure that they’re still working. Cameras are a good example. I’ve written about my convoluted camera setup, and it’s definitely something that needs the occasional test. I tend to keep quite a close eye on the cameras themselves, as they can be the weakest link – Wifi IP cameras having a tendency to occasionally drop offline.

One of my cameras is set to send notifications whenever it detects a person, even when I’m home and that person is likely to be me. Due to its position, it gets triggered every week when it’s time to put the bins out, but the false alarms are worth it as a sanity check that the full stack of Zoneminder -> zmEventNotification -> Home Assistant -> AppDaemon -> Pushover is working as intended.

Battery operated devices are often the weakest link. When I was a Samsung SmartThings user, sensors would occasionally drop offline. So far I’ve been reasonably lucky with my ZWave sensors, although one of my door contact sensors did stop working. It was a multipurpose sensor, and was still reporting temperature correctly, so I didn’t suspect anything was wrong. Since it was on a door I rarely use, it could’ve been out of action for months before I finally noticed. I now make a point of checking the sensors periodically if they’re not associated with automations that I see working regularly.

I’ve also found that some of my ZWave battery sensors constantly report the battery level as 100%. This is, apparently, not uncommon. It’s another reason to keep an eye on the sensors.

It got me thinking about how I can automate some of these checks. Obviously I can’t automate opening a door to see if the sensor is working correctly, but I can automate a check to see if the sensor is alive. ZWave entities in Home Assistant have an attribute called ReceivedTS that is the timestamp of the last received signal from the entity. For those entities that should be reporting regularly, it’s fairly trivial to write a small AppDaemon program to check that a signal has been received within a given time frame. I can set AppDaemon to run the code on a regular interval and send out a notification if a signal has not been received for a given length of time.

Except it’s not that easy. That only works for certain types of ZWave device. For example, I have a ZWave power outlet, and that only updates when it is switched on or off. That means that it’s not as simple as checking all ZWave devices – I’d have to maintain a list of entities or put some convoluted logic in to determine which ones are relevant. For my current purposes, I’m interested in any sensor with a battery level attribute – all of my battery sensors should be reporting regularly.

Then there’s the question of how often to check and how often to send notifications. If there’s a problem and I know it’s going to persist for a while until I get round to fixing it, I don’t want to get a notification every hour. Daily is probably OK – it would act as a reminder, if nothing else.

I put together a quick check in AppDaemon that does the job, checking once a day to confirm that the sensors have reported within the last 12 hours:

import appdaemon.plugins.hass.hassapi as hass

from datetime import datetime, timedelta, time

class ZwaveMonitor(hass.Hass):
    def initialize(self):

        self.log('ZWave Monitor app initialising')
        self.handle = self.run_daily(self.check_zwave, time(7,0,0))

    def check_zwave(self, kwargs):
        results = self.get_state('zwave')

        for sensor in results:

            if 'battery_level' in results[sensor]['attributes']:
                received = results[sensor]['attributes']['receivedTS']
                receivedtime = datetime.strptime(received[0:19], '%Y-%m-%d %H:%M:%S')

                if receivedtime < datetime.now() - timedelta(hours=12):
                    detail = "{} last received at: {}".format(sensor, received)
                    self.call_service('notify/pushover', message = detail, title = 'ZWave Sensor Issue')

There is another problem sensor though, and that’s my outdoor RF temperature sensor. For that one I’d need the last_updated property of the entity, which can also be read by AppDaemon. However, rather than simply change my quick and dirty script I’m thinking about ways to build a more generic monitoring system.

At this stage I’m not sure whether to attempt to build it all within Home Assistant itself or send data out to a specialised monitoring tool. The advantage of HA is that it already knows how to send the notifications I need, but on the other hand, a proper monitoring tool could also be used beyond HA.

Food for thought, and another project to go onto the list…

in Home Automation

Related Posts