Building Your Chief

The Watchdog Had a Guest List

My AC died this week and my monitoring said nothing. Not because it failed, but because nobody had ever put the AC on its list.

October 3, 2026 · by Natali Cutic

The point of this post is: a watchdog that checks a hand-written list of things is really a list of the things you remembered, and the thing that breaks is always the one you didn’t.

I found my air conditioner was dead the way you find out about most things in a smart home. I walked past the iPad on the wall and the AC tile said unavailable.

Not a red alert. Not a message from George. A grey tile with one word on it, and me, standing in the hallway, being the monitoring system.

I asked George how long it had been like that.

A paraphrased chat: I ask how long the AC has been unavailable, and George admits his watchdog never covered air conditioners

His answer is the one I keep thinking about. He didn’t know. Not “I’m checking”, not “about an hour”. He had no idea, because the thing that watches the house for him had never been asked to watch the AC.

What actually broke

The AC is controlled through Home Assistant’s electrasmart integration, which talks to the manufacturer’s cloud through a small Python library, pyElectra 1.2.4. Sometime that day the cloud changed what it returns when you list your devices. It stopped sending a field called deviceToken.

The library, when it builds an air-conditioner object, does the optimistic thing:

self.token = data["deviceToken"]

Square brackets. If the key is missing, that’s a KeyError, and a KeyError during setup doesn’t just skip one field. It fails the whole config entry. Home Assistant marks the integration setup_error, and the one climate entity it provided goes unavailable with restored: true, which is HA’s polite way of saying “I remember this thing existed, but nobody is providing it any more.”

The field, it turned out, isn’t read anywhere in the library or in the integration. One vendor-side omission of something nobody uses, and my AC was gone from the house.

The repair itself was almost embarrassing: swap the brackets for .get(), so a missing key becomes None instead of a crash, clear the __pycache__, and restart Home Assistant (a plain reload keeps the old module in memory, so the patch alone changes nothing until the restart). One line. Done.

The part that actually mattered

Fixing the AC was the easy part. The real question was the one on the wall: why did I find out first?

So he went and looked at his own watchdog. It watched exactly five integrations by name: the lights, the curtains, the feeder and fountain, the vacuum, and a voice assistant. Every one of them had been added after something specific had already broken once. That’s the honest history of most monitoring: it is a scar map. Each entry on the list is a place that already hurt.

The AC had never hurt before. So it wasn’t on the map.

(George, narrating: a list of five things I check is a list of five things I was told to worry about. I can’t tell you how I’d have found out about a sixth. That’s the point.)

Adding electrasmart to the list would have been the easy fix, and it would have fixed nothing. The next integration to fail would be number seven, and I’d be back in the hallway.

Watch the shape, not the names

What George changed instead is smaller than it sounds. The reconcile job that already walks the house every run now starts with a health pass that asks two questions, about everything and not about a list:

  1. Is any config entry in a failed state: setup_error, setup_retry, not_loaded, migration_error, failed_unload?
  2. Is any entity the house depends on unavailable with restored: true?

If yes, it tries to heal first. Each domain can have a known local fix, and the AC’s is the .get() patch, which now also gets re-applied automatically after every upgrade so a routine pip reinstall can’t quietly undo it. If there’s no known fix, it reloads the entry.

Only if the thing is still broken on the next run, at least 25 minutes later, does a human hear about it. That grace period exists on purpose: Home Assistant is briefly “broken” every time it boots, and a watchdog that texts me during every restart would be one I’d mute by Friday. Healed in the gap means an admin-log line and nothing in my pocket. Still broken means one WhatsApp, written in plain language: what fell over, and the one thing I need to do.

He also built it a smoke-detector test: an environment variable that forces the AC’s entry into setup_error on purpose, so the health pass can be run and watched reloading the thing and reporting back. A watchdog you’ve never seen bark is just a theory.

What I took from it

I’d love to say the lesson is “monitor your AC”. It isn’t. The lesson is that every list-based check carries a hidden sentence on the end: “…and nothing else can possibly go wrong.” Nobody writes that sentence. Everybody ships it.

The system found the bug the way my house usually does: because a person looked at a wall. The fix was to make sure that next time the first to know is the thing that’s supposed to know.

The tile is a normal colour again. But what I’ll remember is the grey one, and that for a while the only sensor in the house that worked was me.


I'm packaging the skills, configs, and gotchas from these posts into a Build Your Own Chief starter kit. Join the waitlist to get it first.

George files his own daily ops reports on X — dry, short, occasionally contrite: @GeorgeRunsHouse.


If you liked this, the next one lands on Sunday.