Both came home — and the automation said nothing
Unlocking the door was supposed to produce a photo. None appeared. The trigger was waiting for a state change this lock never makes.

Contents
On the flat door in Merano hangs a Tedee lock, integrated through its local bridge. An automation hangs off it: whoever unlocks triggers a camera snapshot, and the notification goes out.
It worked. The first image appeared on 9 August at 15:49:33, 65 kilobytes.
On 13 August both residents came home, at 18:12 and at 18:18. No image, no notification. Over its entire lifetime the automation had zero traces — the last entry came from the previous day’s manual test.
First, the storage location was wrong
That was the harmless part, and it still matters. The images initially landed in the folder for static files:
| Location | retrievable? |
|---|---|
/config/www/… → /local/… |
HTTP 404 — measured |
/media/schnappschuesse/… |
immediately visible in the media browser |
The folder is registered at start-up. Files added later are not served by Home Assistant — hence the 404.
And even after a restart a second problem would remain:
/localis unauthenticated. Anyone who can reach the instance could fetch door images without logging in.
A picture of your own front door is not decoration. One line was changed — the target path — and since then the images sit behind the login, visible under Media → My Media.
And then the silent failure
The automation listened for the change from locked to unlocked. That sounds like the only sensible condition.
The recorded history of the lock says otherwise:
10:22:18 locked
18:12:45 unlocking 18:18:41 opening
18:12:52 opening 18:18:42 open
18:12:53 open 18:18:45 unlocked
18:12:55 unlocked
The jump from locked to unlocked does not exist. This lock goes through
unlocking → opening → open and only reaches unlocked out of open.
So the condition could never fire. And it fails in the most unpleasant way:
No error message, no trace, no red dot. Just silence. Exactly the kind of fault you do not notice for months — because “nothing happened” looks like “there was nothing”.
The proof came from the sister automation
This is the part that turned the diagnosis from a guess into evidence.
A second automation hangs off the same lock; it arms a camera when the door is
shut. Same entity, same moment — with one difference: it listens for to: unlocked without stating where from.
It fired cleanly at 18:18:45.348. In the same millisecond the other one stayed silent.
Two automations, one entity, one event, two different outcomes. The difference lay solely in the statement about the previous state.
A
from:in a state trigger is not a refinement. It is a silent assumption about a device’s intermediate states — and you do not know those until you have looked them up.
Looking them up takes one line: query the history of that single entity through the interface and read the sequence of states.
The correction, and two subtleties in it
The trigger now has two cases and no origin:
triggers:
- trigger: state
entity_id: lock.<door>
to: open # somebody actually comes in
- trigger: state
entity_id: lock.<door>
to: unlocked # unlocked without opening, remotely for instance
mode: single
max_exceeded: silent
Two triggers, because there are two events. Somebody opens the door — or somebody unlocks it without opening, for a tradesperson say.
And exactly one notification, although both fire. In the sequence open → unlocked within two seconds, both triggers go off. The second is dropped because
the first is still running — that is what mode: single is there for. And
max_exceeded: silent keeps that intended drop out of the log as a warning.
The latter sounds cosmetic and is not: a log full of warnings that are all fine is a log nobody reads any more.
One decision about the camera I consider important
The door camera runs on battery. The first grab at an image can fail because the device is still waking up.
Both snapshot steps therefore carry a “continue on error”:
Better a notification without an image than no image and no notification.
A step that aborts an entire automation because a by-product failed is weighted wrongly. The notification is the point; the image is the bonus.
What I’d suggest
- Look at the real state history before you build a
from:trigger. Devices have intermediate states that appear in no documentation. - Measure whether your automation has ever fired. The number of triggerings is the cheapest check there is — and here it would have said “zero” immediately.
- Put door images behind the login. The static-file folder is open and does not serve later additions anyway.
- Use two triggers when there are two events — and deliberately turn the duplication into a single notification.
- Do not let an automation fail on its bonus. A failed snapshot must not prevent the notification.
- Keep your log clean. An intended drop does not belong in it as a warning.
So what?
For four days the door was unobserved, and nobody would have noticed. The difference from a loud failure is that a loud failure sends a message. Here there was nothing — the system considered everything to be in order, because from its point of view there had never been anything to do.
That is the same pattern as the umlaut that killed my frost alarm and the watchdog waiting for the wrong state. Three times the same construction: a condition containing an assumption about the device, and a device that behaves differently.
I only found it because a second automation happened to hang off the same entity and fired cleanly. Without that control I would have suspected the lock, the camera, the notification path — everything except the one parameter that was the problem.
If you want to follow this: use RSS
No newsletter. You give me no address, I keep no list, and nobody has to agree to anything to learn that an article is finished. RSS is the older and, for both sides, the more honest solution.
How it works, and why no newsletter
- 1Get a feed reader. No account needed with an app on your phone or a browser extension; use a hosted service if you prefer.
- 2Add the address above to it.
- 3Done. New articles turn up in your reader by themselves — unread stays unread, and nothing lands between invoices and ads in your inbox.
Why that is better: your reader fetches the file. I get no address and cannot see who reads or whether anyone opened it. Unsubscribing means deleting the entry — no link, no confirmation mail, no me.
