Background
1.4.0 shipped RestoreSensor on the four electrical-reading sensors (current, voltage, energy_consumed, power_derived) so they survive HA restarts (#144). That covers the boot path but not the mid-session transient HTS disconnect path, which can be 5+ minutes long on a busy install and surfaces as the sensors going unavailable even though we have a perfectly good last-known value.
Example from bvis-home on 1.4.0 (HTS dropped + reconnected ~5 min later, healthy install):
21:30:12.257 WARNING [aegis_ajax.api.hts.client] ACK failed: Connection lost
21:30:12.360 WARNING [aegis_ajax.api.hts.client] HTS connection error in listen: Connection closed by remote
21:35:12.299 INFO [aegis_ajax.coordinator] HTS connected, 1 hub(s)
During those 5 minutes, the four electrical-reading sensors render as unavailable because coordinator._handle_hts_disconnect() calls self.device_readings.clear() (coordinator.py:569). The sensor entity's available property then short-circuits to False.
Desired behaviour
Three scenarios, with the contract the integration should honour for the electrical-reading sensors:
- Active HTS connection — values update as deltas arrive (current behaviour, unchanged). HA's recorder/state_machine persists each state change automatically, so the "last value at next restart" is always the most recent live value.
- HTS disconnected mid-session — keep the last known value visible to the user. The hub remembers device state across our socket outages; our cached value is the truth until proven otherwise by a fresh delta when HTS reconnects.
- Boot / fresh entity —
RestoreSensor seeds the entity from HA's persisted last state until the first live delta lands (already works after 1.4.0).
Scope
In:
- The four sensor classes in
_AjaxDeviceReadingsBase subclasses (AjaxDeviceCurrentSensor, AjaxDeviceVoltageSensor, AjaxDeviceEnergyConsumedSensor, AjaxDeviceDerivedPowerSensor).
AjaxCobrandedCoordinator._handle_hts_disconnect().
Out:
- Hub-network sensors (
ethernet_ip, wifi_ssid, gsm_signal_level, mains power, etc.) — these intentionally go unavailable during HTS outages. Their value reflects "what we currently know about the hub's network state" and during an outage we genuinely don't know. Showing a 5-minute-old wifi_ssid would be misleading. The existing hub_network.clear() in _handle_hts_disconnect stays.
Proposed fix
One line, plus tests.
coordinator.py:567-570, current:
if self.hub_network or self.device_readings:
self.hub_network.clear()
self.device_readings.clear()
self.async_set_updated_data({"spaces": self.spaces, "devices": self.devices})
Change to:
# Hub-network state IS stale once HTS drops (we don't know the hub's
# current connection state without the stream). Per-device electrical
# readings are device-state the hub itself remembers — keep them
# visible so a transient reconnect cycle doesn't blow away the value
# the user was just looking at.
if self.hub_network:
self.hub_network.clear()
self.async_set_updated_data({"spaces": self.spaces, "devices": self.devices})
With the clear removed, after disconnect:
device_readings[device_id] retains the cached value.
- The sensor's
_live_native_value keeps returning that value.
- HA continues to persist the unchanged state on each periodic snapshot.
- When HTS reconnects, the first
STATUS_UPDATE delta for the device updates the cached value as usual.
Test plan
- New
TestHandleHtsDisconnect coordinator case: pre-seed device_readings, call _handle_hts_disconnect(), assert the dict is untouched but hub_network is cleared.
- Adjust the existing
test_hts_disconnect_clears_device_readings test to assert the opposite (rename it accordingly).
- New sensor integration test: with
_handle_hts_disconnect() called mid-session, entity.available stays True and native_value keeps returning the cached value.
- Hub-network sensors should keep their existing
unavailable behaviour (no change to that path).
Release target
1.4.1 patch — pure bug fix, no new functionality, no breaking changes. SemVer PATCH (consistent with the SemVer-strict-from-1.3.0 policy).
References
Background
1.4.0shippedRestoreSensoron the four electrical-reading sensors (current,voltage,energy_consumed,power_derived) so they survive HA restarts (#144). That covers the boot path but not the mid-session transient HTS disconnect path, which can be 5+ minutes long on a busy install and surfaces as the sensors goingunavailableeven though we have a perfectly good last-known value.Example from
bvis-homeon1.4.0(HTS dropped + reconnected ~5 min later, healthy install):During those 5 minutes, the four electrical-reading sensors render as
unavailablebecausecoordinator._handle_hts_disconnect()callsself.device_readings.clear()(coordinator.py:569). The sensor entity'savailableproperty then short-circuits toFalse.Desired behaviour
Three scenarios, with the contract the integration should honour for the electrical-reading sensors:
RestoreSensorseeds the entity from HA's persisted last state until the first live delta lands (already works after1.4.0).Scope
In:
_AjaxDeviceReadingsBasesubclasses (AjaxDeviceCurrentSensor,AjaxDeviceVoltageSensor,AjaxDeviceEnergyConsumedSensor,AjaxDeviceDerivedPowerSensor).AjaxCobrandedCoordinator._handle_hts_disconnect().Out:
ethernet_ip,wifi_ssid,gsm_signal_level,mains power, etc.) — these intentionally gounavailableduring HTS outages. Their value reflects "what we currently know about the hub's network state" and during an outage we genuinely don't know. Showing a 5-minute-oldwifi_ssidwould be misleading. The existinghub_network.clear()in_handle_hts_disconnectstays.Proposed fix
One line, plus tests.
coordinator.py:567-570, current:Change to:
With the clear removed, after disconnect:
device_readings[device_id]retains the cached value._live_native_valuekeeps returning that value.STATUS_UPDATEdelta for the device updates the cached value as usual.Test plan
TestHandleHtsDisconnectcoordinator case: pre-seeddevice_readings, call_handle_hts_disconnect(), assert the dict is untouched buthub_networkis cleared.test_hts_disconnect_clears_device_readingstest to assert the opposite (rename it accordingly)._handle_hts_disconnect()called mid-session,entity.availablestaysTrueandnative_valuekeeps returning the cached value.unavailablebehaviour (no change to that path).Release target
1.4.1patch — pure bug fix, no new functionality, no breaking changes. SemVer PATCH (consistent with the SemVer-strict-from-1.3.0 policy).References
1.4.0stable: https://github.com/bvis/aegis-hass/releases/tag/v1.4.0RestoreSensorintroduction: feat: restore electrical readings on boot + clarify update entity semantics #144device_readings.clear()was added when the readings feature shipped (around feat(hts): WallSwitch / Socket electrical readings as HA sensors #137 /1.4.0-beta.1); it mirrors thehub_network.clear()that's been there since the HTS implementation. The pattern is appropriate for stream-derived state but wrong for device-state.