Repository navigation
feat(gateway): support Hub display alongside another inverter provider - #5496
Conversation
Code reviewFound 1 issue:
batpred/apps/predbat/gateway.py Lines 684 to 693 in 68e7ee5 Confirmed through Reviewed with Codex using the code-review workflow. |
|
The health-check blocker is addressed in stacked draft #5500, commit a6f4528. It reports optional display connectivity separately and preserves the active control transport checks. Regression tests exercise the real Components, final run-status and web ping paths for broker disconnection, offline Hub and stale telemetry, plus stopped-thread detection. All 14 display tests, native Gateway/components groups and the local TLS MQTT cross-repository integration pass. Independent review found no new blocker. Nothing deployed or enabled in production. |
There was a problem hiding this comment.
🟡 Changes recommended
Component argument coercion prevents invalid display-mode strings from reaching the strict validator.
1 open finding
What changed in this PR
Adds a display-only Gateway mode so another integration can supply inverter data and control.
Changes:
- Isolates display telemetry and MQTT publishing from inverter control.
- Excludes display-only gateways from inverter-source health.
- Adds documentation and regression tests.
| File | Description |
|---|---|
docs/apps-yaml.md |
Documents display-only operation. |
apps/predbat/gateway.py |
Implements display-only lifecycle and publish restrictions. |
apps/predbat/components.py |
Registers configuration and excludes display mode from inverter health. |
apps/predbat/tests/test_gateway.py |
Registers the new tests. |
apps/predbat/tests/test_gateway_display.py |
Tests display isolation and lifecycle behavior. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| "mqtt_port": {"required": False, "config": "gateway_mqtt_port", "default": 8883}, | ||
| "mqtt_token": {"required": True, "secret": True, "config": "gateway_mqtt_token"}, | ||
| "gateway_inverter_serial": {"required": False, "config": "gateway_inverter_serial", "default": None}, | ||
| "gateway_display_only": {"required": False, "config": "gateway_display_only", "default": False}, |
Resolve the run_gateway_tests conflict with #5496 by registering both TestGatewayDischargeWindow and TestGatewayDisplayOnly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

A paired Hub can display PredBat's plan and live information while Cloud or another inverter provider supplies data and control.
gateway_display_only: truestarts the Gateway component without requiring an inverter, keeps it out of inverter-source health, and prevents discovery from replacing the selected provider's entities/configuration.The final MQTT publish boundary permits only the display-data topic in this mode. Commands, schedules, EV messages and unknown topics are blocked; plan execution and standby-release housekeeping are disabled. OAuth refresh remains available. The default is false, including an explicit string
"false"; invalid values fail initialization.Companion SaaS configuration: https://github.com/Predictive-Cloud-Ltd/predbat-saas/pull/2106 (disabled by default). Rebased onto current main d6985b6, retaining the configured-inverter/rating fixes in #5475. The only merge conflict was class defaults; both the serial-list default and display flag are retained.
Validation:
unit_test.py --test gateway --test componentspasses both groups after rebase, including existing control tests and 10 component tests.git diff --checkpasses.No production deployment or canary enabled. Remaining review gates: combined SaaS/engine session with enforced standby and token refresh, role transition tests, and customer-facing onboarding/control toggle. Automatic backup is a separate follow-up.