Skip to content

feat(gateway): support Hub display alongside another inverter provider - #5496

Merged
springfall2008 merged 1 commit into
mainfrom
feat/hub-display-only
Oct 13, 2026
Merged

springfall2008 merged 1 commit into
mainfrom
feat/hub-display-only

Conversation

@mgazza

@mgazza mgazza commented Oct 11, 2026

Copy link
Copy Markdown
Collaborator

A paired Hub can display PredBat's plan and live information while Cloud or another inverter provider supplies data and control. gateway_display_only: true starts 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:

  • All 12 focused display-isolation tests pass after rebase.
  • Project unit_test.py --test gateway --test components passes both groups after rebase, including existing control tests and 10 component tests.
  • git diff --check passes.
  • GitNexus staged analysis flags a high change scope across Gateway lifecycle/telemetry and component health; this remains a draft pending integration review.

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.

@mgazza

mgazza commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator Author

Code review

Found 1 issue:

  1. [P1] An optional display outage fails the working Cloud optimiser's health check. The display branch returns successfully, but Gateway remains part of Components.is_all_alive(). Its transport health fails immediately on an MQTT disconnect, after two minutes of stale online telemetry, or after 60 minutes without a success timestamp for an offline Hub. This makes PredBat.is_running() false, /api/ping return HTTP 500, and an otherwise successful Cloud optimisation run report component errors. The production liveness probe also uses /api/ping, so a sustained display outage eventually restarts the healthy optimiser. Report display transport health separately from the selected provider's operational health.

if self.gateway_display_only:
# The JSON display topic is separate from the executable schedule. Never
# refresh schedules, release read-only, reset inverters or control EVs here.
if self._mqtt_connected and self._last_status is not None:
await self._publish_predbat_data()
await self._check_token_refresh()
return True
# Publish any queued plan from on_plan_executed hook

Confirmed through GatewayMQTT.is_alive, Components.is_all_alive, PredBat.is_running, record_final_run_status and the ping handler. Confidence: 95/100. Reviewed alongside SaaS #2106 and #2108; no additional high-confidence findings in those display changes.

Reviewed with Codex using the code-review workflow.

@mgazza

mgazza commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator Author

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.

@springfall2008
springfall2008 marked this pull request as ready for review October 12, 2026 07:16
Copilot AI balanced review requested due to automatic review settings October 12, 2026 07:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 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},
@springfall2008
springfall2008 merged commit 0975c2b into main Oct 13, 2026
3 checks passed
@springfall2008
springfall2008 deleted the feat/hub-display-only branch October 13, 2026 19:13
springfall2008 pushed a commit that referenced this pull request Oct 14, 2026
Resolve the run_gateway_tests conflict with #5496 by registering both
TestGatewayDischargeWindow and TestGatewayDisplayOnly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
springfall2008 pushed a commit that referenced this pull request Oct 14, 2026
Resolve the run_gateway_tests conflict with #5496 and #5532 by registering
TestGatewayChargeWindow, TestGatewayDischargeWindow and TestGatewayDisplayOnly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants