Gen3 gRPC integration (refactored from #169)#171
Open
Griswoldlabs wants to merge 13 commits intomainfrom
Open
Conversation
… loading - const.py: Add CONF_PANEL_GENERATION constant - span_panel_api.py: Add capabilities property delegating to client (falls back to GEN2_FULL) - __init__.py: Replace static PLATFORMS with capability-gated platform loading; store active_platforms per entry so unload is exact - config_flow.py: Add panel generation dropdown (auto/gen2/gen3); add async_step_gen3_setup for gRPC probe without JWT auth - sensors/factory.py: Capability-gate DSM, energy, hardware status, battery, and solar sensor groups; power sensors always created - manifest.json: Bump version to 1.3.2; require span-panel-api[grpc]~=1.1.15 - pyproject.toml: Update span-panel-api dev dep to 1.1.15 with grpc extra - .github/workflows/ci.yml: Update sed command for new dep format and version - scripts/sync-dependencies.py: Handle package extras in version regex - docs/dev/gen3-grpc-integration-plan.md: Add Phase 1 complete / Phase 2 deferred plan
Replace the four-call get_all_data() fetch with a single get_snapshot() call that returns a unified SpanPanelSnapshot. Each domain object now has a from_snapshot() factory that maps snapshot fields to its internal structure — enabling Gen3 data to flow through the same entity classes as Gen2 for the metrics they share. Changes: - span_panel.py: update() calls api.get_snapshot() and passes the snapshot to the four from_snapshot() factories atomically - span_panel_api.py: add get_snapshot() delegating to client.get_snapshot() with the same error handling pattern as other API methods - span_panel_circuit.py: add from_snapshot(SpanCircuitSnapshot) - span_panel_data.py: add from_snapshot(SpanPanelSnapshot) - span_panel_hardware_status.py: add from_snapshot(SpanPanelSnapshot) - span_panel_storage_battery.py: add from_snapshot(SpanPanelSnapshot) - tests/conftest.py: register real SpanPanelSnapshot/SpanCircuitSnapshot on the mock so test fixtures can construct real snapshot instances - tests/test_span_panel.py: rewrite TestSpanPanelUpdate to use get_snapshot() mock returning a real SpanPanelSnapshot fixture
coordinator.py: - Detect PUSH_STREAMING capability at init; pass update_interval=None to disable polling timer for Gen3 - _register_push_callback(), _on_push_data(), _async_push_update() drive entity updates from gRPC stream callbacks - _push_update_pending guard prevents stacking concurrent async tasks - async_shutdown() unregisters push callback before super() span_panel_api.py: - _create_client() Gen3 branch instantiates SpanGrpcClient - register_push_callback() exposes callback registration without callers accessing _client directly - Simulation always uses Gen2 transport: _panel_generation normalised to "gen2" when simulation_mode=True, regardless of panel_generation setting __init__.py: - async_unload_entry: fixed cleanup to use coordinator.span_panel (not the nonexistent coordinator.span_panel_api) - v1->v2 migration stamps panel_generation="gen2" on existing entries (all v1 entries pre-date Gen3 support) sensor_definitions.py: - CIRCUIT_GEN3_SENSORS: voltage, current, apparent/reactive power, frequency, power factor per circuit (gated on PUSH_STREAMING) - PANEL_GEN3_SENSORS: main feed voltage, current, frequency sensors/factory.py + sensors/circuit.py: - Gen3-only sensor creation from SpanCircuitSnapshot non-None fields span_panel.py, span_panel_circuit.py, span_panel_data.py: - snapshot-based update() and from_snapshot() factories docs/dev/gen3-grpc-integration-plan.md: - Mark Phase 2b complete; document circuit IID mapping bug fix in library
Covers editable install workflow, local HA core and Docker container options, debug logging config, and diagnostic symptom table.
…er overload Gen3 gRPC stream pushes data every ~1s. The previous callback-driven approach forwarded each notification to HA as a state write, causing CPU/disk spikes (reported by cecilkootz on MLO 48). Now both Gen2 and Gen3 use the same polling timer (default 15s). The gRPC stream still runs in the background keeping the client buffer fresh; the coordinator simply reads the latest snapshot at each scan interval. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace warning-level debug log with info-level log that shows the number of circuits, entities created, and the resolved serial number. Helps diagnose sensor registration issues during setup. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Bump python constraint to >=3.14.2,<3.15 to match HA core requirement - Pin homeassistant to 2026.2.2 (latest stable with pytest-homeassistant-custom-component support) - Add mashumaro >=3.17.0 floor to prevent poetry under-resolving below HA package_constraints.txt minimum - Drop homeassistant-stubs path-dep approach; restore homeassistant-stubs = 2026.2.2 - Update pyright pythonVersion to 3.14 - Update CI workflows (ci.yml, ci-simulation-example.yml) to python-version: "3.14" - Regenerate poetry.lock
- Update .python-version from 3.13.2 to 3.14.2 (already on main) - Tighten pytest-homeassistant-custom-component to ^0.13.315 (matches main) - Regenerate poetry.lock
- Update integration description to note Gen2 (REST/OpenAPI) and Gen3 (gRPC) support - Annotate feature list with Gen2/Gen3 availability - Update installation steps and authorization section for Gen3 (no auth required) - Replace outdated Limitations section with Panel Generation Support section covering Gen3 read-only constraints, missing features, and Gen3-exclusive metrics - Add Gen2 vs Gen3 feature comparison table
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.
Gen3 (MAIN 40 / MLO 48) gRPC Support — Refactored
Supersedes #169. This is the refactored integration that uses
span-panel-apiv1.1.15 for all gRPC transport — no transport code remains in the integration itself.What's included
scan_intervalto avoid overwhelming HA's recorderpanel_generation=gen2on existing entriesArchitecture (Phase 1 + 2a + 2b)
CONF_PANEL_GENERATIONconstant, capabilities property, capability-gated platform loading, config flow Gen3 step, capability-gated sensor factorySpanPanel.update()migrated to singleget_snapshot()call;from_snapshot()factories on all domain objectsSpanPanelApi._create_client()Gen3 branch,register_push_callback(), coordinator push-streaming extensions, Gen3-only sensor definitions, simulation normalizes to Gen2Key files changed
__init__.pypanel_generationconfig_flow.pyasync_step_gen3_setupcoordinator.pyspan_panel_api.py_create_client()Gen3/Gen2 branching;register_push_callback()span_panel.pyupdate()viaget_snapshot()for both generationssensors/factory.pysensor_definitions.pyCIRCUIT_GEN3_SENSORS,PANEL_GEN3_SENSORSmanifest.jsonspan-panel-api[grpc]~=1.1.15, version 1.3.2Dependencies
SpanGrpcClient,PanelCapability,SpanPanelSnapshotTesting
SPAN firmware 7.2.0 (rolling out Feb 2026) disables local gRPC access:
Credits
Full design docs: