Of everything here, the piece I use most is also the dumbest. When my phone drops the car's bluetooth, which happens when I get out and walk away, a small service waits sixty seconds, asks the car whether it is locked, and locks it if it is not. That is the entire feature. It exists because I was walking back out to the car in the dark two or three times a week to check.
It is also the only thing on the original list that I have actually built. When I started this I wrote down three things that annoyed me about living here, and I have since built a lighting system of some complexity, a translation layer in Swift, a calibration rig, and a monitoring daemon that watches the other daemons. Two of the three original annoyances are fixed almost by accident, as side effects of infrastructure I built for its own sake. The car one is the only place I sat down and solved the actual problem I had. I am not sure what to do with that observation, so I am just going to leave it here.
It is deliberately built so the only command it can ever send is lock. It cannot unlock, it cannot start anything, it cannot open anything. If it goes completely haywire the worst it can do is lock an already locked car repeatedly.
On Monday morning it did not run. I noticed because I went and looked, which is the only reason any of this is written down.
Three bugs, stacked
A timer meant to be polite ate the real event. The service limits how often it will call out to the car, because that connection has a daily quota and I did not want to burn it on nothing. Twenty minutes between runs. Reasonable. What actually happened is that my phone dropped the connection once at 9:15 while I was still sitting in the car, which started the twenty minute clock, and then the genuine departure at 9:25 landed inside that window and was silently discarded. The one event that mattered was thrown away by a quota protection that had already spent its run on a false alarm.
The safety check was aborting nearly every run. Before locking, it asks whether the car is running, on the theory that if the engine is on then the driver has come back and I should leave well alone. Sensible for a petrol car. This one is electric, and that flag tracks whether the car is powered up in any sense, including sitting parked with the climate control on. It reads as running while the car is locked and empty on the driveway. So the check designed to prevent one rare annoyance was quietly cancelling the entire feature most of the time.
Two supervisors, one port. At some point I had configured the service to be kept alive both as a system daemon and as a user agent. Both were trying. They were fighting over the same network port in a permanent crash loop, one winning and the other restarting every ten seconds forever.
The part that made it hard to see
None of this was in the logs, because the surviving process was writing to a file that had been deleted out from under it. On this sort of system a program holds on to the file it opened, not the name, so when something replaced the log file the process carried on writing happily into a thing with no name and no way to read it. The log on disk had been frozen for two days and looked completely normal.
The only reason I could reconstruct any of it is that the service also appends to a separate event file for its own record, and that one was intact. Two independent trails, by accident rather than design, and the accident is the only reason I know what happened.
Fixed
The rate limit is per event type now, and it clears itself whenever a run ends without actually confirming the car is locked, so a false alarm can no longer spend the budget for a real departure. The lock state is checked before the engine flag, and the engine flag no longer cancels anything, it just gets noted. One supervisor. Logs going somewhere that exists.
The car, for the record, was locked the entire time. I had locked it myself, the normal way, with the handle, like a person. There is something quite funny about spending a morning debugging an automation whose entire job is to cover for a habit I apparently already have.