Repository navigation
Occupancy heat gain drives solar-shading deployment — entering a room lowers the blind #418
Description
RoomMind: 1.7.6 HA: 2026.8.3 (HAOS)
What happens
Every morning, a few seconds after I enter my bathroom, RoomMind lowers the
external roller shutter. The room is small (6 m², SE-facing Velux roof
window). It happens during the morning sun window, so it looks like solar
shading — but the trigger is me walking in, not the sun.
Why (traced through the code)
RoomMind now estimates an occupancy heat gain (Q_occupancy; ≈ 1.46 °C for
this room per diagnostics). That gain is fed into the peak-temperature
prediction that the cover logic uses to decide shading:
control/mpc_controller.py:occupancy_series = [self.q_occupancy] * horizon_blocks
— held constant over the entire ~8 h lookahead.- It goes into
optimizer.optimize(...)→plan.temperatures. predicted_peak_temp = max(plan.temperatures[1:])— includes the
occupancy gain.coordinator.pypasses exactly this value:
cover_orchestrator.async_process(predicted_peak_temp=controller.predicted_peak_temp, ...).cover_manager.evaluate():excess = predicted_peak_temp - target_temp;
excess > covers_deploy_threshold(default 1.5) → deploy → blind closes.
So the moment the occupancy sensor goes on, q_occupancy becomes 1.0, the
predicted peak jumps ~1.5 °C, the threshold is crossed, and the shutter
deploys on the next 30 s cycle.
This is a category error: external shading attenuates solar gain only;
it cannot counteract metabolic/occupancy heat. The project already feeds
unshaded solar into the MPC to avoid the deploy↔retract oscillation — the
same decoupling should apply to occupancy.
Compounding factor: cover target in heat_only rooms
cover_orchestrator.async_process:
cover_target = (
targets.cool if mode == MODE_COOLING and targets.cool is not None
else targets.heat if targets.heat is not None
else 22.0
)A heat_only room never reaches MODE_COOLING, so overheat shading is
compared against the heating setpoint (~22 °C here). That makes the
threshold trivially easy to cross — the occupancy bump alone is enough.
Against a cooling/upper-comfort value (24–27 °C) it would not fire on
occupancy.
Setup
climate_mode: heat_only, single 135° (SE) Velux shutter,
covers_auto_enabled: true, covers_deploy_threshold: 1.5,
covers_min_position: 0, covers_snap_deploy: false,
covers_outdoor_min_temp: 10. Diagnostics at report time:
current_temp 23.2, outdoor 15.8, heat_target 22, cool_target 22,
model Q_occupancy ≈ 1.46, n_idle > 40000.
Proposed fix
- Primary: compute the peak used for the cover decision with
occupancy excluded (occupancy_series = [0.0] * horizon), e.g. expose
MPCController.predicted_peak_temp_unoccupiedand pass that into
cover_orchestrator.async_process. Mirrors the existing "unshaded solar
for the cover decision" approach. (The trajectory still starts from the
measuredcurrent_temp, which carries a small already-realised
occupancy offset — acceptable; the constant horizon term is the
dominant effect.) - Secondary: derive
cover_targetfrom an upper comfort bound
(comfort_cool/eco_cool/ a dedicatedcovers_comfort_max_temp),
independent ofclimate_mode, so a heat_only room isn't shaded toward
its heating setpoint.
Related (lower priority)
occupancy_seriesis constant over the full horizon; a decay (like
_build_residual_series) or a bounded dwell window would reduce
over-prediction for climate control too.
Workaround
Disable switch.roommind_<room>_cover_auto, or raise
covers_deploy_threshold to ~4–5 °C for the affected room.
In the meantime I've had to teach my bathroom light automation to switch the
lights on the instant the room goes dark, so that a shutter dropping to 0%
mid-morning doesn't leave anyone stranded in pitch black during
time-sensitive, bathroom-relevant activities. It works — but a predictive
thermostat integration probably shouldn't be a load-bearing dependency for
reliably seeing what you're doing on your own toilet. 🙂
Activity
fix: keep occupancy heat out of the shading peak so covers stop deplo…
fix: shade against the comfort cooling ceiling instead of the heating…
snazzybean commentedon Sep 16, 2026
v1.7.7 keeps body heat out of the shading prediction and now compares it against the comfort cooling temperature instead of the heating setpoint. Feedback welcome!
Luke2105-Loft59 commentedon Sep 19, 2026
Thanks for the quick fix! Confirming on v1.7.7 (HAOS, bathroom, heat_only, covers_auto_enabled: true, covers_deploy_threshold: 1.5 — default, no workaround applied): over the last ~2 days the presence sensor triggered ~45 times, including several times during the morning sun window, and the roller shutter stayed open every time. Before the update it lowered within seconds of entering the room. Looks fixed on my side, so from my perspective the issue can be closed.
I'm keeping my bathroom light automation as a safety net, since RoomMind's solar shading can still legitimately close the shutter on sunny mornings.
snazzybean commentedon Oct 10, 2026
Addressed in v1.7.7
github-actions commentedon Oct 10, 2026
@Luke2105-Loft59 This issue was closed. If you believe it should be reopened, just include
/reopenin a comment and it will be reopened automatically.