What Smart Relays Do During a Two-Second Power Flicker: A Configuration-First Bench Procedure
The flicker is not the variable you think it is
A two-second mains interruption is a useful test, but it is not the thing that decides whether your relay comes back on. The dominant variable is the relay’s configured power-on behavior — the firmware restore mode, the GPIO wiring polarity, and the hardware pull-up state during the window before firmware runs. If you bench-test a flicker without first recording those three things, you are measuring your own configuration, not the relay.
This is the procedure I would use to characterize a relay after a brief outage, and the reason each step exists. I have not run this against a specific board for this article, so treat the expected outcomes below as hypotheses to verify, not measurements.
What actually sets the power-on state
For an ESPHome-based relay, the GPIO switch platform is the layer that drives the coil. The documentation describes it plainly: the platform lets you use any pin on the node as a switch, and you can hook a relay to a GPIO pin and use it through the platform (ESPHome GPIO Switch).
Two details in that same page matter more than the flicker duration:
- Reset-time pin state. ESPHome warns that at reset time, before any of its code runs, relay GPIO pins may have pull-ups active, so the relay may be active before ESPHome can manually deactivate it. A relay that clicks on during a flicker may be reflecting hardware behavior, not your restore mode.
- Software interlocks are not safety interlocks. ESPHome describes its interlock feature as a software interlock and recommends hardware interlocks such as SPDT-type relays where simultaneous activation matters.
That second point is the tradeoff-aware part: if two relays must never be energized together, a firmware setting is not the control. Use the hardware interlock and treat the software interlock as a convenience.
The restore-mode vocabulary, and where it comes from
ESPHome’s GPIO switch restore modes include RESTORE_DEFAULT_ON, ALWAYS_OFF, ALWAYS_ON, and the inverted variants RESTORE_INVERTED_DEFAULT_OFF and RESTORE_INVERTED_DEFAULT_ON. The inverted modes were added in a merged pull request modeled on Tasmota’s PowerOnState toggle behavior (ESPHome PR #1810).
The code path is worth reading because it shows the decision order. In the GPIO switch setup, the initial state is taken from the stored state or a default, and the inverted modes negate that value. For example, the inverted-default-off case sets the initial state to the negation of the stored value, defaulting to true when nothing is stored (PR #1810 files).
Two cautions. First, the live GPIO switch documentation page I retrieved does not list the inverted modes; the PR is the historical source for them, so confirm against the documentation for your installed ESPHome version before relying on the name. Second, RESTORE_* depends on a stored preference surviving the outage. A brief flicker may not clear flash, but a longer outage or a firmware reflash can, and then the default branch is what runs.
Active-low wiring is a separate setting from restore mode. ESPHome creates an active-low switch with the inverted pin schema (GPIO Switch). If you change the wiring polarity and leave the restore mode alone, the observed behavior after a flicker will change even though the restore mode string did not.
A repeatable bench procedure
This is a method, not a report of results. Run it on a bench with the load disconnected or replaced by a safe indicator, and follow your local rules for working near mains voltage.
- Record the configuration before touching power. Write down the switch’s
restore_mode, whether the pin is inverted, the board and firmware version, and whether anyon_bootautomation drives the relay. This is the baseline the observation will be compared against. - Record the physical state at rest. With mains present and the relay commanded off, note the contact state and any indicator LED. Do the same commanded on.
- Interrupt mains for a controlled interval. Start with a short interval, then repeat with a longer one. The point is to bracket the behavior, not to prove a two-second number.
- Observe at re-energization, in order. Watch the relay contact first, then the ESPHome entity state, then the Home Assistant entity state. Note the order and the delay between them.
- Compare against the configured default, not an assumed one. If the relay came back on and the mode is
RESTORE_DEFAULT_OFF, that is a finding. If it came back on and the mode isALWAYS_ON, that is the configuration working. - Repeat after a firmware change. Restore modes and defaults can change with versions; the table is only valid for the build you tested.
Keep the results as a per-relay table: restore mode, polarity, firmware version, observed contact state after short and long interruptions, and any discrepancy between the three state layers. That table is the maintenance artifact. Update it when you reflash.
Three state layers, and why a mismatch is diagnostic
After re-energization you have three things that can disagree:
- The physical relay contact. This is what the load sees. Nothing in Home Assistant changes it.
- The ESPHome entity state. This is the firmware’s belief about the switch, which may be set by restore mode or by an automation.
- The Home Assistant switch entity state. Home Assistant switch entities can be
on,off,unavailable, orunknown(Switch integration).unavailablemeans the entity cannot provide its state right now, for example because Home Assistant cannot reach the device (State object).
Home Assistant also exposes an assumed_state attribute that is true when the current state is an assumption (State object). If that attribute is present after a flicker, the dashboard is telling you it does not know the physical position. Treat that as a prompt to check the relay, not as a state you can automate against.
A mismatch between layers is not noise. It tells you which layer to fix: wiring and pull-ups for the contact, restore mode for the firmware belief, and integration reachability for the Home Assistant view.
Where Zigbee and Z-Wave complicate the picture
For Zigbee relays, the availability flag is a reachability signal, not a contact position. Zigbee2MQTT’s availability feature is disabled by default and must be enabled. When enabled, active devices are expected to check in every 10 minutes by default and are marked offline if they do not; passive battery devices get 25 hours (Device availability).
Zigbee2MQTT does retrieve device state when a device reconnects or announces itself, which the documentation notes is handy when a device turns itself on after being reconnected to mains power (Device availability). That retrieval is useful, but it is a read of the device’s reported state, not a guarantee that the physical contact matches.
The failure reports run in both directions. A Zigbee2MQTT discussion describes devices remaining offline or unavailable after a power outage, with lights on and plugs off when they should not be (Discussion #11580). A separate issue reports a powered-off sensor’s availability staying online until the service was restarted (Issue #27652). Neither report is a controlled test, but together they are enough to say: do not treat the availability flag as a proxy for the relay’s physical position.
For Z-Wave, the Home Assistant integration page describes the adapter, server, and integration layers and notes that the first startup interviews the entire network, which can take a while (Z-Wave integration). That startup behavior is a reason to test the whole stack after a power event, not just the relay.
Writing automations that survive an unexpected default
The practical rule: an automation should not assume that a relay’s state after re-energization matches its state before the outage. Two habits help.
- Gate on reachability, then verify. Use
unavailableandunknownas reasons to wait or alert, not as reasons to command. A command sent to an unreachable device may be queued or dropped depending on the integration. - Make the safe state the default. For loads where an unexpected on is the hazard, choose a restore mode whose default is off, and put the hardware interlock in place where simultaneous activation matters. For loads where an unexpected off is the hazard, the tradeoff reverses; state it explicitly in the table.
If you are auditing the small systems around this relay — the hub, the broker, the network path — the same configuration-first discipline applies. The audit method in How to Audit the Small Systems That Quietly Run Your Week is a reasonable companion for recording what each layer is supposed to do before you test what it does.
When a plain switch or mechanical timer is the better choice
If the load must return to a known state after any outage, and the cost of a wrong state is high, a latching mechanical switch or a mechanical timer removes the firmware variable entirely. A smart relay earns its place when you need remote control, scheduling, or state reporting — and when you have documented and tested its power-on behavior. If you cannot state the restore mode and the wiring polarity for a given relay from memory or from your table, that relay is not yet characterized.
FAQ
Does a two-second flicker reboot an ESPHome relay?
It depends on the board’s power supply holdup and the firmware’s behavior. I have not seen a documented threshold that applies across boards, so the bench procedure above brackets short and long interruptions rather than assuming a number.
Why did my relay turn on even though I set it to default off?
Check three things in order: whether the pin is inverted, whether the GPIO has a pull-up active during reset before ESPHome runs (the GPIO switch documentation warns about this), and whether an on_boot automation drives the relay. The restore mode is only one of the inputs.
Is RESTORE_INVERTED_DEFAULT_ON a current option?
It was added in ESPHome PR #1810 and appears in that code. The live GPIO switch documentation page I retrieved does not list the inverted modes, so confirm against the documentation for your installed version before using the name.
Can I trust the availability flag to tell me the relay is off?
No. Availability describes reachability. Zigbee2MQTT’s own documentation describes state retrieval on reconnect, and user reports describe availability staying stale in both directions after power events. Check the physical contact or a separate sensor if the state matters.