Spots

Splitting a 2,000-Line automations.yaml into 8 Files

My automations.yaml had quietly grown into a 60 KB monster. 2,144 lines. 63 automations stacked end to end in a single file, averaging about 34 lines each. Scrolling it was a chore, editing it made me nervous, and finding one particular heating automation meant a full-text search. The file worked, so there was never any pressure to touch it, and there was a good reason not to: when you refactor a live config you can silently drop the automation that keeps the heating from freezing or the alarm from missing a sensor.

So this is a small story about a

So this is a small story about a refactor I almost didn't do, and the one thing that made me trust it: I wrote a 40-line script to split the file, and then I wrote a second, longer script whose only job was to prove the first one hadn't lost anything. Why one file stops scaling

Home Assistant wires automations in through one line

Home Assistant wires automations in through one line in configuration.yaml: automation: !include automations.yaml. That single include is convenient while the file is small. With 63 automations in there, a few groups had formed without my planning them. Heating was by far the biggest concern — 21 automations, a third of the whole file, driving 11 thermostats with day and night modes and room-by-room overrides. Alarm was the next slab at 13. Then a cluster around the AC·THOR power diverter, a handful of camera and detection rules, time-based switching, system housekeeping, and a long tail of one-offs.

None of that structure was visible. It was

None of that structure was visible. It was just 2,144 lines in the order I'd happened to add each one. I wanted the heating rules in a heating file and the ability to open exactly the slice I was working on. A 40-line splitter that classifies by name

The splitter is deliberately boring. It's about 40

The splitter is deliberately boring. It's about 40 lines of pure standard-library Python — just yaml, os, and a defaultdict. It loads the YAML list, walks each automation, decides which bucket it belongs to, and dumps one file per bucket into an automations/ directory.

Here's the honest quirk: the classification isn't driven

Here's the honest quirk: the classification isn't driven by any tag or metadata field, because there isn't one. It's substring matching on the automation's German alias. If the alias contains "Heizung" it's heating; "Alarm" goes to alarm; "AC Thor" (in any of its hyphenated spellings) to ac_thor; camera and detection words to cameras; push and notification words to notifications; the time-control vocabulary to time_control; sync and reachability words to system; and everything the rules don't catch falls through to a misc bucket. So the classification depends entirely on how consistently I named things.

Two of the dump arguments are worth explaining

Two of the dump arguments are worth explaining. allow_unicode=True keeps the German umlauts intact instead of mangling them into escape sequences, so a name like "Büro" survives the round trip. And sort_keys=False preserves the original key order inside each automation — the trigger, condition and action stay in the order I wrote them, instead of getting alphabetised into nonsense. Eight buckets the data chose for itself

I didn't pick eight up front; I had

I didn't pick eight up front; I had half expected to hand-carve a dozen or so files. The committed splitter emits eight category files: heating, alarm, ac_thor, cameras, notifications, time_control, system, and misc. The distribution is lopsided: heating is 21 automations (33%), alarm is 13 (21%), AC·THOR is 5 (8%), and then it thins fast into pairs and singletons. By estimated size the heating file lands around 700 lines on its own, alarm around 440, cameras around 270, ac_thor around 170.

A 700-line heating file controlling 11 thermostats with

A 700-line heating file controlling 11 thermostats with near-identical day/night/presence logic is an obvious candidate for templating into a handful of parameterised scripts, and with it isolated I can see what that would look like. The AC·THOR file, by contrast, came out clean and self-contained: temperature monitoring, power management, and a bit of system detection, all in one place.

Before I changed a single line of configuration.yaml

Before I changed a single line of configuration.yaml, I wrote a second script — about 160 lines — whose entire purpose is to re-read the original file and every split file and assert the round trip is lossless. It runs five checks. One: the total automation count matches. Two: the set of unique aliases matches, with no automation missing and none invented. Three: any duplicate aliases are identical between original and split. Four: every automation id value matches as a set. Five: a per-alias deep dictionary comparison to catch silent content drift.

News

Splitting a 2,000-Line automations.yaml into 8 Files

My automations.yaml had quietly grown into a 60 KB monster.

@spots #dev
Source: Dev.to
See more like this