Repository navigation
Replace IntegrationSensor with native Left-Riemann EnergySensor - #1107
Open
Moustachauve wants to merge 9 commits into
Open
Moustachauve wants to merge 9 commits into
Moustachauve wants to merge 9 commits into
Conversation
EnergySensor previously subclassed Home Assistant Core's private IntegrationSensor class directly to estimate cumulative energy from device power readings. Because IntegrationSensor is an internal helper entity rather than a public base class, upstream constructor changes in Home Assistant 2026.2 and 2026.11 repeatedly broke Hilo setups and required fragile version-checking branches, entity registry workarounds to resolve the source power entity_id, and state machine listeners. Have EnergySensor inherit directly from HiloEntity and RestoreSensor instead, computing the Left-Riemann sum in-process whenever the underlying HiloDevice updates (via SignalR or coordinator polling) as well as on a 5-minute fallback timer for constant-power periods. Accumulating directly from the in-memory device power attribute removes all coupling to homeassistant.components.integration, preserves existing entity unique_ids and restored states (including seamless fallback for states persisted by IntegrationSensor), and retains full Decimal precision across intervals while rounding native_value to 2 decimal places.
tests/test_sensor.py previously constructed mock Hilo and HiloDevice instances manually in each test and asserted individual entity metadata properties in Python code. Use setup_with_selected_platforms with Platform.SENSOR and Syrupy snapshots (snapshot_platform) instead, matching the testing pattern used across the switch and light platform tests while exercising the full sensor platform setup and retaining 100% coverage of EnergySensor.
Home Assistant 2026.3+ (Python 3.14) prepends the device name to original_name and friendly_name on entities whose name does not already start with the device name (such as Gateway sensors), causing full- platform snapshots to diverge from Home Assistant 2026.2 (Python 3.13). Additionally, leaving invalid power values on the shared Smart Plug device at test teardown caused PowerSensor.state to raise during the Python 3.13 teardown coordinator refresh. Scope test_energy_sensor_entities snapshots to the EnergySensor entities and restore valid device power before teardown so the test suite passes on both Python 3.13 and Python 3.14.
Moustachauve
marked this pull request as ready for review
October 29, 2026 04:09
EnergySensor previously subclassed Home Assistant Core's private IntegrationSensor class directly to estimate cumulative energy from device power readings. Because IntegrationSensor is an internal helper entity rather than a public base class, upstream constructor changes in Home Assistant 2026.2 and 2026.11 repeatedly broke Hilo setups and required fragile version-checking branches, entity registry workarounds to resolve the source power entity_id, and state machine listeners. Have EnergySensor inherit directly from HiloEntity and RestoreSensor instead, computing the Left-Riemann sum in-process whenever the underlying HiloDevice updates (via SignalR or coordinator polling) as well as on a 5-minute fallback timer for constant-power periods. Accumulating directly from the in-memory device power attribute removes all coupling to homeassistant.components.integration, preserves existing entity unique_ids and restored states (including seamless fallback for states persisted by IntegrationSensor), and retains full Decimal precision across intervals while rounding native_value to 2 decimal places.
tests/test_sensor.py previously constructed mock Hilo and HiloDevice instances manually in each test and asserted individual entity metadata properties in Python code. Use setup_with_selected_platforms with Platform.SENSOR and Syrupy snapshots (snapshot_platform) instead, matching the testing pattern used across the switch and light platform tests while exercising the full sensor platform setup and retaining 100% coverage of EnergySensor.
Home Assistant 2026.3+ (Python 3.14) prepends the device name to original_name and friendly_name on entities whose name does not already start with the device name (such as Gateway sensors), causing full- platform snapshots to diverge from Home Assistant 2026.2 (Python 3.13). Additionally, leaving invalid power values on the shared Smart Plug device at test teardown caused PowerSensor.state to raise during the Python 3.13 teardown coordinator refresh. Scope test_energy_sensor_entities snapshots to the EnergySensor entities and restore valid device power before teardown so the test suite passes on both Python 3.13 and Python 3.14.
Moustachauve
force-pushed
the
refactor/native-energy-sensor
branch
from
October 30, 2026 01:49
47a7b7b to
ebc29b3
Compare
Commit 8803d86 (PR dvd-dev#1001) added "Disconnected": false to the Thermostat 1 fixture entry in tests/fixtures/all_devices.json so the baseboard thermostat starts online during test setup. As a result, sensor.thermostat_1_hilo_energy initializes to "0.00" rather than "unavailable".
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
EnergySensor previously subclassed Home Assistant Core's private
IntegrationSensorclass directly to estimate cumulative energy from device power readings. BecauseIntegrationSensoris an internal helper entity rather than a public base class, upstream constructor changes in Home Assistant 2026.2 and 2026.11 (#1106) repeatedly broke Hilo setups and required fragile version-checking branches, entity registry workarounds to resolve the source powerentity_id, and state machine listeners.Having
EnergySensorinherit directly fromHiloEntityandRestoreSensorremoves all coupling tohomeassistant.components.integrationand avoids future breakage when Home Assistant Core modifies its internal helper classes. Instead of watching another entity in the state machine by string ID,EnergySensornow computes the Left-Riemann sum directly from the in-memoryHiloDevicepower attribute whenever the device updates (via SignalR or coordinator polling) as well as on a 5-minute fallback timer for constant-power periods. FullDecimalprecision is retained across intervals internally while roundingnative_valueto 2 decimal places so small energy increments are never lost to per-tick rounding.Existing installations migrate seamlessly without losing historical statistics or requiring reconfiguration: entity
unique_ids, device classes, andTOTAL_INCREASINGstate classes are unchanged, andasync_added_to_hassrestores previous totals from both standardRestoreSensornative data and legacyIntegrationSensorextra data (last_valid_state). Moving the accumulation state ontopyhilo'sHiloDeviceis noted for a follow-up refactor once device update lifecycles are consolidated in the library.IntegrationSensor, which broke in 2026.2 and 2026.11 (#1106) and needed version checks.power * dt / 3,600,000) ourselves instead of delegating it to HA.HiloDevicein memory instead of watching a siblingsensor.*_powerentity in the state machine.unique_ids and restores state from bothRestoreSensorand legacyIntegrationSensorstorage.pyhilolater since it only depends on device power updates.