Skip to content

Add eGauge integration#155279

Merged
joostlek merged 83 commits into
home-assistant:devfrom
neggert:egauge-integration
Dec 8, 2025
Merged

Add eGauge integration#155279
joostlek merged 83 commits into
home-assistant:devfrom
neggert:egauge-integration

Conversation

@neggert
Copy link
Copy Markdown
Contributor

@neggert neggert commented Oct 27, 2025

Proposed change

This PR adds an integration for eGauge energy meters. These meters are commonly installed alongside residential solar installations. They provide real-time and historical data around energy usage, but also support other types of sensors such as temperature.

This PR implements power and energy sensors only, with other sensor types left for future work.

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New integration (thank you!)
  • New feature (which adds functionality to an existing integration)
  • Deprecation (breaking change to happen in the future)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Additional information

This integration is intended to eventually replace the egauge custom component, which I have maintained for several years. This is a complete re-write using eGauge's newer JSON-based API which will eventually replace the XML-based API that the custom component is based on.

The integration uses the egauge-async library that I've created, since the official egauge-python library does not support async.

Checklist

  • I understand the code I am submitting and can explain how it works.
  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • I have followed the perfect PR recommendations
  • The code has been formatted using Ruff (ruff format homeassistant tests)
  • Tests have been added to verify that the new code works.
  • Any generated code has been carefully reviewed for correctness and compliance with project standards.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • The manifest file has all fields filled out correctly.
    Updated and included derived files by running: python3 -m script.hassfest.
  • New or updated dependencies have been added to requirements_all.txt.
    Updated by running python3 -m script.gen_requirements_all.
  • For the updated dependencies - a link to the changelog, or at minimum a diff between library versions is added to the PR description.

To help with the load of incoming pull requests:

neggert and others added 24 commits October 27, 2025 10:54
Create basic skeleton for eGauge energy monitor integration:
- manifest.json with Bronze quality scale and local polling
- Empty __init__.py placeholder
- Constants file with domain and logger
- Strings structure for config flow

Part of implementation for eGauge integration supporting power and
energy sensors for Home Assistant Energy Dashboard.
Implement user configuration flow for eGauge devices:
- User step with host, username, password inputs
- Connection validation using get_device_serial_number()
- Unique ID from device serial number
- Error handling for authentication and connection failures
- Reauthentication flow for credential updates
- Update strings.json with reauth step

Uses async_get_clientsession for httpx client following Platinum
quality scale best practices.
Create data structures for eGauge integration:
- EgaugeData dataclass containing measurements, counters, and register info
- Type alias EgaugeConfigEntry for type-safe config entry access

These models support the coordinator pattern where static and dynamic
data are handled separately, and allow for extensible sensor types.
Implement coordinator that manages all data fetching:
- Fetches static device info (serial, hostname, registers) on first refresh
- Fetches dynamic data (measurements, counters) every 30 seconds
- Type-agnostic design - fetches ALL register types for extensibility
- Proper exception handling for auth failures and connection errors

Coordinator owns all data fetching responsibility, keeping __init__.py
clean and following separation of concerns best practices.
Create shared base entity for all eGauge sensors:
- Inherits from CoordinatorEntity for data management
- Uses has_entity_name pattern for entity naming
- Creates DeviceInfo with serial-based identifiers
- Uses hostname for user-friendly device name
- Generic constructor accepts register name and info for reusability

This base class will be extended by all sensor types.

Also fixes type hints in coordinator for serial_number and hostname
to be non-optional (they're populated on first refresh before entities
are created).
Implement sensor platform with extensible architecture:
- Mapping-based SENSOR_TYPES for easy addition of new types
- EgaugePowerSensor for instantaneous power (W)
- EgaugeEnergySensor for cumulative energy (kWh)
- Energy sensors support Energy Dashboard with TOTAL_INCREASING
- Converts watt-seconds to kWh (divide by 3,600,000)
- Gracefully ignores unsupported register types

Power registers get both instantaneous and cumulative sensors.
Future sensor types can be added by creating a class and adding
to SENSOR_TYPES mapping - no coordinator changes needed.
Add integration entry point with clean architecture:
- async_setup_entry creates EgaugeJsonClient with async_get_clientsession
- Coordinator handles all data fetching (static and dynamic)
- Runtime data stores coordinator for platform access
- async_unload_entry cleanly unloads sensor platform
- No exception handling needed - coordinator handles all errors

Follows separation of concerns: __init__.py is simple orchestration,
coordinator owns data fetching logic.
Create quality_scale.yaml documenting Bronze tier compliance:
- config-flow: UI configuration implemented
- entity-unique-id: All sensors have serial-based unique IDs
- test-before-configure: Config flow validates connection
- test-before-setup: Coordinator tests connection on first refresh
- action-setup: Exempt (no custom actions)

Integration meets all Bronze quality scale requirements.
Create test fixtures and mocks:
- MockConfigEntry with realistic eGauge configuration
- mock_egauge_client fixture with complete API mocking
- Includes power registers (Grid, Solar) and unsupported type (Temp)
- Realistic test data: measurements in W, counters in Ws
- init_integration fixture for easy test setup

Test data designed to verify both sensor creation and graceful
handling of unsupported register types.
Comprehensive config flow test coverage:
- test_user_flow: Successful device setup
- test_user_flow_errors: Parametrized error handling
  (authentication, connection, unknown errors)
- test_user_flow_already_configured: Duplicate prevention
- test_reauth_flow: Credential update flow
- test_reauth_flow_errors: Reauth error handling

Achieves 100% config flow coverage with error recovery testing.
Add sensor platform tests with snapshot testing:
- Verifies all sensor entities via snapshot_platform
- Validates device creation with correct attributes
- Confirms all entities assigned to device
- Checks only power sensors created (temperature ignored)
- Tests that 4 sensors total (2 power + 2 energy)

Snapshots will be generated on first test run.
Test integration lifecycle and error handling:
- test_setup_success: Verifies successful integration setup
- test_setup_connection_error: Tests retry on connection failure
- test_setup_auth_error: Tests auth error handling
- test_unload_entry: Validates clean unload

Covers coordinator initialization, error states, and proper
config entry state transitions.
Update imports to use correct module paths:
- EgaugeJsonClient from egauge_async.json.client
- RegisterInfo, RegisterType from egauge_async.json.models
- EgaugeAuthenticationError, EgaugeParsingException from egauge_async.json.client
- Replace EgaugeConnectionError with httpx.ConnectError (library uses httpx exceptions)

Fixes compatibility with egauge-async library structure.
Still need to add docs.
Add comprehensive functional tests beyond structural snapshots:

Sensor value tests (test_sensor.py):
- test_power_sensor_values: Verify power sensors show correct W values
- test_energy_sensor_values: Verify energy sensors and Ws→kWh conversion

Coordinator tests (test_coordinator.py):
- test_coordinator_initial_refresh: Verify static/dynamic data fetch
- test_coordinator_periodic_update: Test 30s interval updates
- test_coordinator_auth_error: Test auth failure and reauth flow
- test_coordinator_connection_error: Test connection errors and recovery

Tests now verify actual sensor values, unit conversions, error handling,
and data refresh behavior. Coverage improved to 99% (25 tests passing).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@neggert neggert marked this pull request as ready for review November 29, 2025 17:48
@home-assistant home-assistant Bot requested review from joostlek and zweckj November 29, 2025 17:48
Comment thread homeassistant/components/egauge/config_flow.py Outdated
Comment thread homeassistant/components/egauge/sensor.py Outdated
Comment thread homeassistant/components/egauge/sensor.py Outdated
Comment thread homeassistant/components/egauge/sensor.py Outdated
Comment thread homeassistant/components/egauge/sensor.py Outdated
@home-assistant home-assistant Bot marked this pull request as draft December 1, 2025 12:31
@neggert neggert marked this pull request as ready for review December 2, 2025 02:00
@home-assistant home-assistant Bot requested a review from zweckj December 2, 2025 02:00
Comment thread homeassistant/components/egauge/sensor.py Outdated
Comment thread homeassistant/components/egauge/sensor.py Outdated
Copy link
Copy Markdown
Member

@zweckj zweckj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

two nits from my end, otherwise I'm happy

Comment thread homeassistant/components/egauge/sensor.py Outdated
Comment thread tests/components/egauge/test_config_flow.py
@neggert
Copy link
Copy Markdown
Contributor Author

neggert commented Dec 7, 2025

The test failure seems to be coming from an entirely different integration. Maybe just a flaky test.

Copy link
Copy Markdown
Member

@zweckj zweckj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy, let's see if Joost has last remarks

identifiers={(DOMAIN, coordinator.serial_number)},
name=coordinator.hostname,
manufacturer=MANUFACTURER,
model=MODEL,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to figure out which model it is?

@joostlek joostlek merged commit 2617c4a into home-assistant:dev Dec 8, 2025
62 of 63 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Dec 9, 2025
@joostlek
Copy link
Copy Markdown
Member

@neggert mind sending me a message on Discord?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants