Handle station-level StatusNotification in OCPP 2.0.1 - #2020
Conversation
OCPP 2.0.1 permits a StatusNotification for the charging station itself (evseId=0/connectorId=0) and some chargers send one on every boot - the FoxESS A-series does. _apply_status_notification fed those straight into the per-connector bookkeeping, where evse_id - 1 == -1 either raised IndexError, on the first such notification while _connector_status was still empty, or silently wrote the station's status into the LAST EVSE's slot once it was not. The IndexError propagates out of the status-notification flush and aborts post_connect, so the charger never finishes setting up. Record station-level notifications as the charger-level Status metric instead - the same key the OCPP 1.6 handler uses for connectorId=0 and that the availability switch reads. (0, Status.Connector) deliberately stays owned by the EVSE aggregation in _report_evse_status: a station-level 'Available' written there would mask a faulted connector through the flattened sensor's fallback chain.
|
Important Review skippedNo new commits to review since the last review. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthrough
ChangesStation-Level Status Handling
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@custom_components/ocpp/ocppv201.py`:
- Around line 180-184: Update the station-level branch in the StatusNotification
handling around the evse_id and connector_id check to match only when both
identifiers equal zero. Ensure mixed-zero or negative combinations do not enter
this branch and continue through the EVSE/connector handling path.
- Around line 168-185: Update on_status_notification so the exact station-level
tuple (evse_id, connector_id) == (0, 0) bypasses _ensure_connector_map() and
reaches the charger-level metrics branch immediately. Preserve connector-map
buffering for all other notifications, and add a regression covering empty or
unavailable inventory that verifies charger-level Status is set rather than
queued.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 14e57293-5867-4bd0-a16c-b76c5cc67fe5
📒 Files selected for processing (2)
custom_components/ocpp/ocppv201.pytests/test_charge_point_v201.py
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2020 +/- ##
=======================================
Coverage 95.04% 95.05%
=======================================
Files 12 12
Lines 3005 3011 +6
=======================================
+ Hits 2856 2862 +6
Misses 149 149 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Review findings on the guard: A station-level StatusNotification never routes through the connector map, so holding it behind _ensure_connector_map stranded it forever on a charger whose inventory yields no map - and the chargers that send station-level statuses are exactly the ones with such inventories. It is now applied immediately, so the charger-level Status works regardless of what the inventory turns out to be. The station-level predicate is tightened to exactly (0, 0). Other degenerate ids - (1, 0), (0, 1), negatives - are neither station-level nor a real connector: fed to the per-connector bookkeeping they would index with -1 (the IndexError / silent last-slot overwrite this guard exists to prevent), and recorded as station-level they would misattribute another entity's state to the charger. They are logged at debug level and dropped.
|
Both findings addressed in c5d0b97. On the predicate: took the intent but not the committable suggestion — restricting to |
|
@coderabbitai review |
✅ Action performedReview finished.
|
Part of the OCPP 2.0.1 work from #2008 (follows #2012 and #2013). One more PR — a connector-count fallback for chargers whose inventory reports no connectors — builds on this and will follow separately.
The problem
Some chargers send a station-level
StatusNotificationwithevseId=0/connectorId=0— the FoxESS A-series sends one on every boot, mirroring OCPP 1.6'sconnectorId=0convention for the charge point itself._apply_status_notificationfeeds it straight into the per-connector bookkeeping, whereevse_id - 1 == -1:_connector_statusis still empty,self._connector_status[-1]raisesIndexError, which propagates out of the status-notification flush and abortspost_connect— the charger never finishes setting up;_connector_statusis populated, Python's negative indexing makes it silently write the station's status into the LAST EVSE's slot.The fix
Station-level notifications are recorded as the charger-level
Statusmetric — the same key the OCPP 1.6 handler uses forconnectorId=0and that the availability switch reads — and never enter the per-connector path.Deliberately not written to
(0, Status.Connector): that key is owned by the EVSE aggregation in_report_evse_status, and a station-levelAvailablewritten there would mask a faulted connector through the flattened sensor's fallback chain.Testing
Unavailablearrives before the connector'sAvailable, and the test asserts no crash, the charger-levelStatusmetric receives it, and the connector's own status is not clobbered. Mutation-verified: with the guard removed, the flush aborts and connector status never lands.(0,0)notification routes to the chargerStatussensor on every 2.0.1 connection, with normal connector handling unchanged.pre-commit run --all-filespass.Summary by CodeRabbit
StatusNotificationhandling to apply correctly for the valid(0,0)case.