Skip to content

Add retry logic with exponential backoff to SetChargingProfile - #2000

Closed
Mark-Hetherington wants to merge 1 commit into
lbbrhzn:mainfrom
Mark-Hetherington:fix/set-charging-profile-retry
Closed

Add retry logic with exponential backoff to SetChargingProfile#2000
Mark-Hetherington wants to merge 1 commit into
lbbrhzn:mainfrom
Mark-Hetherington:fix/set-charging-profile-retry

Conversation

@Mark-Hetherington

@Mark-Hetherington Mark-Hetherington commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Fixes #1999

When SetChargingProfile times out due to transient network issues or charger processing delay, retry up to 3 times with exponential backoff (0.5s, 1s) before notifying the user. Immediate charger rejections still fail fast.

This prevents dynamic charge rate adjustments from silently failing on brief network hiccups.

Changes

  • Adds asyncio import for sleep() during retry backoff
  • Retries up to 3 times for exceptions (transient failures)
  • Fails immediately for active rejections (charger policy)
  • Only notifies user if all retries exhausted
  • Includes debug logging for retry attempts

Summary by CodeRabbit

  • Bug Fixes
    • Improved reliability when applying charging profiles by retrying failed requests up to three times.
    • Added short backoff delays between attempts to recover from temporary communication issues.
    • Charging requests now stop immediately on acceptance or explicit rejection, while repeated exceptions still trigger warning notification after the final attempt.

@Mark-Hetherington
Mark-Hetherington temporarily deployed to continuous-integration July 22, 2026 10:56 — with GitHub Actions Inactive
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 20da0f12-56bd-4c8f-bc57-a3e446b52fe1

📥 Commits

Reviewing files that changed from the base of the PR and between 5293bd4 and 732fffa.

📒 Files selected for processing (2)
  • custom_components/ocpp/ocppv16.py
  • custom_components/ocpp/ocppv201.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • custom_components/ocpp/ocppv16.py
  • custom_components/ocpp/ocppv201.py

📝 Walkthrough

Walkthrough

OCPP 1.6 and 2.0.1 charge-rate updates now retry SetChargingProfile exceptions up to three times with delays. Accepted responses succeed immediately, while rejected responses retain immediate failure handling.

Changes

Charge rate retry handling

Layer / File(s) Summary
SetChargingProfile retry loops
custom_components/ocpp/ocppv16.py, custom_components/ocpp/ocppv201.py
Adds retry handling for profile-based and constructed charging-profile requests, with delayed retries and final exception reporting after the retry limit.

Estimated code review effort: 3 (Moderate) | ~15–30 minutes

Possibly related PRs

Suggested reviewers: drc38

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding retry logic with backoff to SetChargingProfile.
Linked Issues check ✅ Passed The changes implement retries for transient SetChargingProfile failures while preserving immediate failure for charger rejections, matching issue #1999.
Out of Scope Changes check ✅ Passed The patch stays focused on SetChargingProfile retry behavior and does not introduce unrelated changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
custom_components/ocpp/ocppv16.py (1)

419-437: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add focused tests for the retry outcomes.

Mock self.call to cover: exception/exception/accepted with sleeps of 0.5s and 1.0s; immediate rejection with no retry; and three exceptions with exactly one notification and a False result.

🤖 Prompt for 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.

In `@custom_components/ocpp/ocppv16.py` around lines 419 - 437, Add focused tests
for the SetChargingProfile retry flow, mocking self.call to verify
exception/exception/accepted succeeds after 0.5s and 1.0s sleeps, an immediate
rejected response returns False without retrying, and three exceptions produce
exactly one notification and a False result. Anchor the tests to the method
containing the shown retry loop and assert call, sleep, and notify_ha counts.
🤖 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/ocppv16.py`:
- Around line 420-424: Adjust the retry scope around the SetChargingProfile
operation in the enclosing method so int(conn_id) and
call.SetChargingProfile(...) execute outside the retry block. Restrict retries
to the awaited self.call(req) network operation, while preserving the existing
retry and notification behavior for call failures.

---

Nitpick comments:
In `@custom_components/ocpp/ocppv16.py`:
- Around line 419-437: Add focused tests for the SetChargingProfile retry flow,
mocking self.call to verify exception/exception/accepted succeeds after 0.5s and
1.0s sleeps, an immediate rejected response returns False without retrying, and
three exceptions produce exactly one notification and a False result. Anchor the
tests to the method containing the shown retry loop and assert call, sleep, and
notify_ha counts.
🪄 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

Run ID: 6a6147ef-3cbb-4c6a-8aba-edc8d7c901bf

📥 Commits

Reviewing files that changed from the base of the PR and between c61c1f4 and 2ffa9a6.

📒 Files selected for processing (1)
  • custom_components/ocpp/ocppv16.py

Comment thread custom_components/ocpp/ocppv16.py
@Mark-Hetherington
Mark-Hetherington force-pushed the fix/set-charging-profile-retry branch from 2ffa9a6 to 5293bd4 Compare July 22, 2026 11:13
@Mark-Hetherington
Mark-Hetherington temporarily deployed to continuous-integration July 22, 2026 11:13 — with GitHub Actions Inactive

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 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 362-380: Separate response-status validation from the
retry-catching block in the SetChargingProfile flow around the identified loop,
so only exceptions from self.call are retried and non-accepted charger responses
raise HomeAssistantError once afterward. Apply the same change at
custom_components/ocpp/ocppv201.py lines 362-380 and 416-436, preserving the
existing rejection error details and successful return behavior.
🪄 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

Run ID: 6593e68d-ba45-47f5-917f-25cd46b5ca42

📥 Commits

Reviewing files that changed from the base of the PR and between 2ffa9a6 and 5293bd4.

📒 Files selected for processing (2)
  • custom_components/ocpp/ocppv16.py
  • custom_components/ocpp/ocppv201.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • custom_components/ocpp/ocppv16.py

Comment thread custom_components/ocpp/ocppv201.py
@Mark-Hetherington
Mark-Hetherington force-pushed the fix/set-charging-profile-retry branch from 5293bd4 to de30beb Compare July 22, 2026 11:19
@Mark-Hetherington
Mark-Hetherington temporarily deployed to continuous-integration July 22, 2026 11:19 — with GitHub Actions Inactive
@Mark-Hetherington
Mark-Hetherington force-pushed the fix/set-charging-profile-retry branch from de30beb to e037007 Compare July 22, 2026 11:22
@Mark-Hetherington
Mark-Hetherington temporarily deployed to continuous-integration July 22, 2026 11:22 — with GitHub Actions Inactive
@Mark-Hetherington
Mark-Hetherington force-pushed the fix/set-charging-profile-retry branch from e037007 to 8653d10 Compare July 22, 2026 11:40
@Mark-Hetherington
Mark-Hetherington temporarily deployed to continuous-integration July 22, 2026 11:40 — with GitHub Actions Inactive
Fixes lbbrhzn#1999

When SetChargingProfile times out due to transient network issues or charger
processing delay, retry up to 3 times with exponential backoff (0.5s, 1s)
before notifying the user. Immediate charger rejections still fail fast.

This prevents dynamic charge rate adjustments from silently failing on brief
network hiccups, which is common in IoT environments.

- Adds asyncio import for sleep() during retry backoff
- Retries up to 3 times for exceptions (transient failures)
- Fails immediately for active rejections (charger policy)
- Only notifies user if all retries exhausted
- Includes debug logging for retry attempts
@Mark-Hetherington
Mark-Hetherington force-pushed the fix/set-charging-profile-retry branch from 8653d10 to 732fffa Compare July 22, 2026 11:48
@Mark-Hetherington
Mark-Hetherington temporarily deployed to continuous-integration July 22, 2026 11:48 — with GitHub Actions Inactive
@Mark-Hetherington

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@drc38

drc38 commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

A more generalised approach would be preferred ie if a command timesout place it in a queue, fail the websocket connection and then on re-establishing the websocket connection process the queue in fifo order.

@Mark-Hetherington

Copy link
Copy Markdown
Contributor Author

Closing this PR. redesigning the timeout handling from ad-hoc per-call retries to a general mechanism.

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.

SetChargingProfile should retry on transient timeout failures

2 participants