← Writing

October 21, 2026 · 4 min read

Teaching the floor to start early

An experiment in progress. The floor misses its 6 AM target on cold mornings, so it now measures its own slab every night to work out when to start.

An experiment in progress. Part two of A water heater, two pumps and a concrete slab.

The rule for my radiant floor is simple: 71.5°F on the ground floor by 6 AM. On cold mornings it keeps missing.

The overnight schedule sets the floor back to Eco at 10 PM and restores Comfort at 4 AM. If the forecast is cold and the room is below 71.5°F, it runs Boost for up to 90 minutes first. That sounds like plenty of lead time. It isn't.

Three cold mornings: pumps start at 4 or 4:30 AM, the room is 69.7 to 70.5°F at 6 AM, and it gets back to 71.5°F between 9:55 and 11:10

On each of the three cold mornings so far, the pumps ran almost all the time from the restore until well after 6 AM, and the room was still a degree or two short. On two of them the room was colder at the end of the 90-minute boost than at the start. It got back to 71.5°F between about 10 and 11 AM.

The water was hot and the pumps were running. The heat was going into the concrete, not the room. On October 20 the water coming back out of the slab rose from 71°F to 91°F during the morning run, and was still climbing at 6 AM. The slab was charging, and until it charged the room got almost nothing.

A guess at the start time

Before changing the live schedule, I added a dry run that changes nothing. It only writes a line to the logbook. Between 3 and 5 AM it estimates how many minutes the floor needs to reach 71.5°F by 6:

minutes = 30 + 90 × (71.5 − room) + 4 × (50 − outside)

Each term is only counted when it is positive. The first time "now plus minutes" reaches 6 AM, it logs the start time it would have used. The three numbers are first guesses, meant to be fitted from the logs.

Morning Room Outside Dry run Actual At 6 AM
Oct 18 70.6° 44° 3:45 4:30 69.8°
Oct 20 70.4° 46° 3:38 4:00 69.7°
Oct 21 71.1° 44° 4:25 4:00 70.5°

Room and outside are at the moment of the dry run's check; times are AM.

October 21 is the telling one. Its check ran at 4:30, after the real start, and it wanted to start at 4:25. The floor actually started at 4:00, and it still missed by a degree. The formula is too optimistic, and the reason is in its inputs: it knows the room and the outside temperature, but not how much heat is already stored in the slab. A slab that coasted through a warm day with no heating needs far more time than one that ran the evening before. The room can read the same in both cases.

Measuring the slab without a sensor in it

There is no sensor in the concrete. The floor loop has a probe on its return pipe, though, and when water has been circulating through the slab for a few minutes with no heat added, it comes back at close to the slab's own temperature.

So a few times each night (hourly from 11 PM to 3 AM, then at 3:50, 5 and 6 AM), Home Assistant runs the floor pump alone for three minutes and logs the return temperature as the slab reading, next to the room and outside temperatures. If the thermostat starts a real heating run during a probe, the probe stops and gets out of the way.

One night of slab probes: the slab falls from 75.7°F to 74.2°F between 11 PM and 3:50 AM while the room falls from 73.1°F to 71.1°F and the outside falls from 48°F to 43°F

The first full night says a lot already. The slab lost about 0.3°F an hour and the room about 0.4°F, ending three degrees below the slab. That gap is what the floor gives the room, and it is not much. To lift the room a degree in the morning, the slab has to come up several degrees first, and that takes hours of runtime.

What happens next

Two steps, in order:

  1. Move the start earlier. The restore stays at 4 AM until there have been three cold mornings under it. October 20 and 21 are the first two. Each one missed by more than an hour, so after the third, the restore moves to 3 AM, the earliest the rule allows.
  2. Put the slab in the formula. With a few weeks of probe nights, the start time can depend on the slab's temperature at 3 AM and its measured recovery rate, not just the room. A warm slab could start late, or skip the boost. A cold one starts early.

The dry run keeps logging alongside the live schedule until its predictions line up with what actually happens. Only then is it a candidate to set the start time, and that change goes through me.

Most of this bookkeeping is done by what I call the climate engineer: a scheduled Claude routine that reads the night's logs every morning, keeps running notes, and proposes changes as tickets for me to approve. It can tune a few settings itself, such as the restore time, within limits I set.

I'll write up the results once the formula has a few weeks of slab data behind it.