Across locationsThree places, one routineEnergy and costGetting started and running it

Three cities, three data sources, one question: when do I leave?

Departure boards in Merano, Kapfenberg and Vienna. The same idea built three times — and three times I got it wrong in a different place.

In each of my three homes the same question comes up: when do I have to leave?

I built the answer three times — first in Merano, then in Kapfenberg, last in Vienna. Each time on the same model, each time with a different data source, and each time I got something wrong in a different place.

The mistakes are the interesting part, because they did not repeat. They moved.

The same idea three times, three different technologies

Built Source
Merano 09.08.2026 Südtirolmobil, EFA interface
Kapfenberg 30.08.2026 Verbundlinie Steiermark, the same EFA interface
Vienna 06.09.2026 the Wiener Linien open real-time data, its own format

Two locations share a protocol, the third does not. That is the normal case in Austria and Italy: there is no common format, but there are two large camps — and with luck the second location falls into the same one.

Kapfenberg was therefore done in an afternoon. Vienna needed a rebuild.

The one idea that makes the difference

All three boards have a property you will not find on any timetable at a stop: they know the walk.

Every sensor knows how long it takes to reach its stop, and departures closer than that never enter the list at all.

A train leaving in 8 minutes while you need 15 to get to the station is not information, it is a trap.

That sounds small and changes everything. An ordinary departure board shows the next departure. A useful one shows the next reachable departure.

Where the time lives is a decision

The walking time sits in the sensor, not in the display. So it applies to every card and every later automation alike, and there is exactly one place to change it.

The cards only write the value into their heading — and read it from the sensor to do so. That way the label cannot diverge from the filtering. A board with “15 min walk” in the heading that filters on 10 is worse than none.

And a consequence I had not considered

At the station, of 18 buses queried only three survived the filter. In the first quarter of an hour a lot simply leaves.

The query limits had to go up considerably — to 34 departures at one stop. Lengthen the walk and you have to raise them too, or the card empties. That is not a fault of the filter but its logical consequence.

Three traps in the templates

All three cost me time, and all three are invisible: the configuration check passes cleanly.

First: variables are not tracked. The first draft built the list in a variable block and read it only by name. Check clean, raw data full — and the sensors stayed permanently empty. Home Assistant derives the triggers for recomputation from the entities appearing in the state itself. If the access sits only in a variable, the sensor knows no source and never recalculates. The loop belongs directly in the state — even though you then write it twice.

Second: the source sorts by timetable, not by real time. One evening a bus three minutes late stood ahead of the punctual one leaving the same minute. In reality the punctual one went first. So the sensors sort themselves — by the field that already contains the delay.

Third: numbers arrive as strings. Sorting on them gives "1" < "12" < "4". Convert to a number first, then sort.

And an addition that did not fit the list of three but is the same kind: attributes have to be strings. A numeric value was silently discarded — the check passed, the attribute was simply missing from the state.

The mistake I made twice

Now the one that actually moved.

In Vienna I had concluded from one measurement that the source delivers at most about five departures per line. That went into the documentation and into the dashboard header.

Wrong. Measured again the next midday:

per line and direction reach
night, 15-minute interval 3–5 —
midday, 7-minute interval 7 up to about an hour ahead

Measured across eleven lines: always at most seven, and always about an hour out. The limit is not the count but the time window. On a 15-minute interval, only four fit into an hour.

I had measured at night — and so measured the night window.

The same mistake had already caught me in Kapfenberg, where I measured the Sunday timetable on a Sunday and took it for the normal case. And again it only showed when somebody looked at a different time of day.

The lesson is inconvenient because it demands patience: a measurement on a transport network is only a measurement once it has been taken at several times of day. Anything else is a snapshot that looks like a finding.

The rabbit

A small rabbit runs across all three dashboards. Every minute it hops one line further, across all the cards.

It has exactly one purpose: it shows the display is still alive. A frozen departure board looks like a working one — the times are right there. You only notice when nothing moves any more, and by then you have missed the bus.

Computed wrongly twice

In Kapfenberg it is spread across 24 fixed places: four cards of six lines each. That assumes every card always has six lines.

In Vienna it does not. One card came to a single line on the first night.

First attempt: two-stage — pick the card first, then the line within its length. That solves the length problem and falls flat as soon as a card is empty:

  Stop · Line (7 min walk)
  nothing reachable any more

Rabbits: 0

The rabbit was computationally on the card that had nothing to show. On the whole dashboard there was none.

The same thinking error as in Kapfenberg, one level up: selecting a card without knowing whether it has anything to display.

And how it was noticed

This is the part I have kept.

It was only noticed because the rendering was counted — a line printing how many rabbits are on the dashboard.

Looking would not have caught it. A missing rabbit looks like a rabbit that is currently somewhere else.

The solution now is one calculation across all cards together: each card reads the lengths of all lists and lays the places end to end. The rabbit therefore always lands where a line actually exists.

What I would advise

  1. Filter by the walk, not by the clock. The next departure is rarely the one you need. The time belongs in the sensor, not in the label.
  2. Measure at several times of day. Every transport interface behaves differently at night than at midday, on Sunday than on a weekday. I fell for it twice.
  3. Sort it yourself. If the source sorts by timetable, the late bus stands ahead of the punctual one. The field with the real time is the right one.
  4. Build in a sign of life. Something that visibly moves. A dashboard with frozen numbers is more dangerous than an empty one.
  5. And count what you render. A mistake that would only show on inspection does not show.

So what?

Building the same thing three times sounds wasteful. It was the opposite: the second build took an afternoon because the protocol was the same. The third needed a new source, but every decision was already made — walking filter, own sorting, sign of life.

What did not transfer were the assumptions. Every city has its own behaviour, and exactly where I inferred from one place to another, that is where the mistake was.

The idea transfers. The measurement does not.