Home Assistant is excellent at coordinating a smart home, but a hot-water system should not become unusable because one server, integration, or network service is temporarily offline. A small local controller can keep the essential schedule running while Home Assistant is being repaired.
This article describes a Shelly Pro 1PM installation that originally used Home Assistant to control a resistive hot-water element. The investigation uncovered two separate lessons: first, diagnose the relay at the device rather than trusting a stale dashboard; second, keep critical time-based control close to the load.
The symptom: not enough hot water
The first instinct is often to blame the heater, thermostat, or relay. Those are sensible possibilities, but a smart relay adds another failure mode: the relay may be healthy while software keeps turning it off.
The useful checks are simple:
- Is the relay output actually on?
- Is the relay measuring real voltage and current?
- Is the power reading zero because the element is off, or because the heater thermostat has temporarily opened the circuit?
- Which automation issued the last command?
- Is the energy or solar sensor available, or is Home Assistant treating an unavailable sensor as zero?
A direct device status request is especially valuable. It bypasses Home Assistant’s recorder and integration state, showing the relay output, voltage, current, power, and device temperature at that moment.
The real problem: two automations fighting
In this case, a daytime heating automation turned the relay on. A separate solar-surplus automation then evaluated an unavailable or zero-valued grid sensor and turned the relay off. The sequence repeated at regular intervals:
Daytime automation: ON
Solar automation: OFF
Daytime automation: ON
Solar automation: OFF
From the dashboard this looked like unreliable heating. The relay itself was not necessarily faulty; the command history was the important evidence. Disabling the competing solar automation allowed the daytime schedule to energise the heater normally.
Why the Shelly Pro 1PM is a good local fallback
The Shelly Pro 1PM is a Gen2 device with a built-in power meter and local automation features. Its stock firmware supports schedules and JavaScript-based Shelly Scripts. A script runs on the device, so it does not require Home Assistant, a cloud account, MQTT, or a working solar integration.
The fallback should be deliberately boring. For a basic resistive heater, a fixed daytime window is easier to reason about than a complicated chain of cloud-dependent conditions:
| Rule | Action |
|---|---|
| Inside the scheduled window | Allow the relay to run |
| Outside the scheduled window | Turn the relay off |
| Relay temperature reaches the safety cutoff | Turn the relay off |
| Relay cools below the restart threshold | Allow heating again within the window |
The heater’s own mechanical thermostat remains the primary control for water temperature. The Shelly temperature is the relay temperature, not a measurement of tank water. That distinction matters: a software cutoff can provide an additional protective layer, but it must not be presented as a substitute for correctly installed heater safety controls.
A small Shelly Script
The local program does three jobs every 30 seconds: it checks the clock to decide whether the 08:45–14:00 heating window is active, it turns the relay on inside that window and off outside it, and it applies a temperature safety cutoff. It fails safe if the device cannot provide a valid time or status. Temperature hysteresis prevents the relay from chattering around one threshold:
var insideHeatingWindow = minutes >= 525 && minutes < 840;
if (relayTemperature >= 80) {
switchOff("relay safety cutoff");
} else if (!insideHeatingWindow) {
switchOff("outside 08:45-14:00 schedule");
} else if (relayTemperature < 70 || relayAlreadyOn) {
switchOn("scheduled heating");
}
In other words, this is not just a temperature monitor. At 08:45 it requests ON; at 14:00 it requests OFF; and during the window it keeps the relay available for heating unless the relay-temperature safety cutoff has been reached. The water heater’s own thermostat then controls whether the element actually draws power.
There is an important restart detail. The script evaluates the schedule immediately at startup instead of waiting for the next clock boundary. If the Shelly reboots during the heating window, it can resume the intended state without Home Assistant.
Uploading and enabling the program
Shelly exposes script management through its local RPC API. The usual sequence is to create a script slot, upload the code while stopped, enable run-on-boot, and start it:
Script.Create
Script.PutCode
Script.SetConfig { enable: true }
Script.Start
After uploading, verify three things: the script appears in Script.List with enable: true, Script.GetStatus reports running: true, and the relay’s direct status still shows the expected output and power. Keep a copy of the code and record the script ID so an update or rollback is straightforward.
Avoiding the next conflict
Once the Shelly script owns the fixed fallback schedule, Home Assistant should not run a second schedule for the same relay. Leave monitoring and dashboard entities in Home Assistant, but disable any automation that can issue competing ON or OFF commands. If a solar optimiser is reintroduced later, give it a clearly defined ownership model and test what happens when its sensor becomes unavailable.
- One controller should own the relay schedule.
- Unavailable sensor data should not silently become a heating decision.
- Direct device state is the ground truth for output, voltage, current, and power.
- Home Assistant can remain the monitoring and user-interface layer.
- Keep an explicit rollback procedure for every device-side program.
Electrical and safety notes
A hot-water element is a high-power mains load. A Shelly Pro 1PM must be installed, protected, and configured within its electrical ratings by a suitably qualified person. Check the measured current against the device rating and the installation design. Do not use a software script as a replacement for the heater’s thermostat, thermal cut-out, circuit protection, or professional inspection.
The Shelly documentation covers the local Script API, timers, and Pro 1PM capabilities:
The pattern to keep
For critical household loads, use Home Assistant for visibility and convenience, but give the device a small local fallback when the load can be controlled safely with simple rules. First prove which commands are being sent. Then remove automation overlap. Finally, put the minimum reliable schedule at the device and keep the rollback path close at hand.