Skip to content

fix: merge existing override properties when setting override#602

Merged
firstof9 merged 5 commits into
mainfrom
fix-override-properties
Jun 2, 2026
Merged

fix: merge existing override properties when setting override#602
firstof9 merged 5 commits into
mainfrom
fix-override-properties

Conversation

@firstof9
Copy link
Copy Markdown
Owner

@firstof9 firstof9 commented Jun 2, 2026

This PR merges the existing manual override properties retrieved from get_override() into the POST payload of set_override() to prevent clearing previously set attributes.

Fixes firstof9/openevse#633.

Summary by CodeRabbit

  • Bug Fixes

    • Improved validation for firmware updates with clearer error messages when invalid inputs are provided
    • Enhanced robustness when processing firmware release information
  • Improvements

    • Better diagnostic logging to troubleshoot firmware update issues
    • More informative error messages for firmware operation failures

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 2, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7f66bdec-584f-4d1b-aa6b-f7137a7838e1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • ✅ Review completed - (🔄 Check again to review again)

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 and usage tips.

@github-actions github-actions Bot added the bugfix Bug Fixes label Jun 2, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/test_managers.py (1)

51-104: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Assert the POST body per call instead of cumulative caplog.text.

These checks can false-pass because caplog.text is cumulative for the whole block, and the expected message at Lines 72-74 is identical to the one from Lines 62-64. More importantly, the regression here is about the /override payload, but this test only verifies debug output, not what was actually posted. Please clear caplog between calls and, ideally, assert the captured POST payload for each invocation so the test exercises the bugfix directly.

🤖 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 `@tests/test_managers.py` around lines 51 - 104, The assertions currently
inspect cumulative caplog.text which can false-pass; instead, after each
mock_aioclient.post(...) + await test_charger.set_override(...) call, clear or
reset caplog (e.g., caplog.clear()) and assert the actual POST payload sent to
the mocked client for that specific call (inspect mock_aioclient
requests/calls/last_request for the body) to verify the /override JSON contains
the expected fields; replace the repeated checks against caplog.text with
per-call caplog.clear() plus an assertion against the mock_aioclient request
body for test_charger.set_override calls.
🧹 Nitpick comments (1)
openevsehttp/commands.py (1)

455-472: ⚡ Quick win

Validate assets before iterating/logging it.

Line 457 trusts GitHub’s nested assets payload as list[dict]. If that field is a dict, string, or a list containing non-mappings, Line 462 and the fallback log on Line 471 will call .get(...) on invalid items and raise instead of cleanly returning None. This path also misreports a missing buildenv as None.bin, which makes the new diagnostics misleading.

Proposed hardening
             download_url = None
             buildenv = self._config.get("buildenv")
             assets = message.get("assets", [])

-            _LOGGER.debug("Matching buildenv '%s' against assets", buildenv)
-            if buildenv and assets:
+            if not buildenv:
+                _LOGGER.debug("Cannot resolve firmware asset: missing buildenv in config.")
+                assets = []
+            elif not isinstance(assets, list):
+                _LOGGER.debug("Invalid GitHub assets payload: %r", assets)
+                assets = []
+            else:
+                _LOGGER.debug("Matching buildenv '%s' against assets", buildenv)
                 target_filename = f"{buildenv}.bin"
                 for asset in assets:
-                    if asset.get("name") == target_filename:
+                    if not isinstance(asset, Mapping):
+                        continue
+                    if asset.get("name") == target_filename:
                         download_url = asset.get("browser_download_url")
                         _LOGGER.debug("Found matching firmware asset: %s", download_url)
                         break
-            if not download_url:
+            if buildenv and not download_url:
                 _LOGGER.debug(
                     "Could not find asset matching target filename '%s.bin' in assets: %s",
                     buildenv,
-                    [asset.get("name") for asset in assets] if assets else "None",
+                    [asset.get("name") for asset in assets if isinstance(asset, Mapping)]
+                    if assets
+                    else "None",
                 )
🤖 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 `@openevsehttp/commands.py` around lines 455 - 472, The assets handling is not
validating types and can crash when assets is not a list of dicts and also logs
a misleading "None.bin" when buildenv is missing; update the block around
download_url/buildenv/assets to first ensure assets is a list and filter it to
only mappings (e.g., using isinstance checks) before iterating or calling
asset.get, build target_filename only if buildenv is truthy (avoid
f"{buildenv}.bin" when buildenv is None/empty), and change the fallback
_LOGGER.debug to show a clear message when buildenv is missing and to list only
valid asset names (from filtered mappings) so no .get is called on invalid items
— adjust the code paths that reference download_url, target_filename, and
asset.get accordingly.
🤖 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.

Outside diff comments:
In `@tests/test_managers.py`:
- Around line 51-104: The assertions currently inspect cumulative caplog.text
which can false-pass; instead, after each mock_aioclient.post(...) + await
test_charger.set_override(...) call, clear or reset caplog (e.g.,
caplog.clear()) and assert the actual POST payload sent to the mocked client for
that specific call (inspect mock_aioclient requests/calls/last_request for the
body) to verify the /override JSON contains the expected fields; replace the
repeated checks against caplog.text with per-call caplog.clear() plus an
assertion against the mock_aioclient request body for test_charger.set_override
calls.

---

Nitpick comments:
In `@openevsehttp/commands.py`:
- Around line 455-472: The assets handling is not validating types and can crash
when assets is not a list of dicts and also logs a misleading "None.bin" when
buildenv is missing; update the block around download_url/buildenv/assets to
first ensure assets is a list and filter it to only mappings (e.g., using
isinstance checks) before iterating or calling asset.get, build target_filename
only if buildenv is truthy (avoid f"{buildenv}.bin" when buildenv is
None/empty), and change the fallback _LOGGER.debug to show a clear message when
buildenv is missing and to list only valid asset names (from filtered mappings)
so no .get is called on invalid items — adjust the code paths that reference
download_url, target_filename, and asset.get accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b35441a9-288c-441d-b540-fc5d39ef64b1

📥 Commits

Reviewing files that changed from the base of the PR and between d0f7fa0 and 7c992d0.

📒 Files selected for processing (3)
  • openevsehttp/commands.py
  • tests/test_commands.py
  • tests/test_managers.py

secondof9

This comment was marked as duplicate.

@secondof9
Copy link
Copy Markdown

Hermes Agent Code Review — PR #602

Verdict: 🟢 LGTM (with minor suggestions)

Summary

This PR fixes firstof9/openevse#633 by preserving existing override state when re-applying overrides. The core logic is clean and well-tested.

What Changed

  • set_override() — Merges existing properties (state, charge_current, max_current, energy_limit, time_limit, auto_release) from the response into the POST payload, preventing accidental clearing of previously-set attributes.
  • Enhanced firmware update logging — Better diagnostic clarity for troubleshooting.
  • Improved error detection — Safer handling of invalid GitHub assets payloads.

Review Details

✅ No Critical Issues

⚠️ Warnings — Defensive Coding Gaps

  1. Debug logs at lines 430-433 — May leak sensitive hostnames in production environments. Consider conditional logging or structured fields with extra=....

💡 Suggestions — Code Quality

  1. Validate firmware_bytes early — Reject empty uploads immediately rather than yielding None later.
  2. Add intent documentation — A brief docstring explaining why we merge existing properties would clarify design intent.
  3. Structured logging — Leverage extra=... for better aggregation/filtering in CI environments.

✅ Positive Observations

  • The merge logic correctly prevents accidental overwrites of previously-set attributes.
  • Error messages are clear and consistent across firmware upload paths.
  • The PR fully resolves the reported issue.
  • Test coverage is solid across new edge cases (invalid assets, error responses, etc.).

Reviewed by Hermes Agent

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

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 `@tests/test_commands.py`:
- Around line 1262-1288: The pytest.raises match pattern in
test_update_firmware_assets_invalid_type uses unescaped dots, making the regex
too permissive; update the match string passed to pytest.raises in function
test_update_firmware_assets_invalid_type (and the similar occurrence at the
other test) to escape literal periods (e.g., use "\." for each dot) or build the
pattern via re.escape so it matches the exact message "Could not resolve latest
firmware download URL from GitHub." instead of treating "." as a wildcard.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0f6ac21e-8145-4c3d-9977-4c5731f76e7b

📥 Commits

Reviewing files that changed from the base of the PR and between 7c992d0 and e897c9c.

📒 Files selected for processing (3)
  • openevsehttp/commands.py
  • tests/test_commands.py
  • tests/test_managers.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/test_managers.py
  • openevsehttp/commands.py

Comment thread tests/test_commands.py
secondof9

This comment was marked as duplicate.

secondof9

This comment was marked as duplicate.

secondof9

This comment was marked as duplicate.

@secondof9
Copy link
Copy Markdown

Hermes Agent Review

Verdict: Changes Requested (1 warning, 2 suggestions)

⚠️ Warning

  • tests/test_commands.py:1228 — Regression test expects exact string "Cannot specify both firmware_bytes and firmware_url" but the code now emits an error log before raising the exception. Tests should verify the log output (which is already being tested for other error conditions) rather than relying on exact string matching for error messages.

💡 Suggestions

  • openenvehttp/commands.py:573 — Consider converting f"Cannot specify both firmware_bytes and firmware_url" to a logged message for consistency with other error handling in update_firmware().
  • openenvehttp/commands.py:576 — The empty bytes check should also emit an error log before raising the ValueError, following the pattern of other validation failures in update_firmware().

✅ Looks Good

  • The core bugfix for merging existing override properties is correct and well-tested.
  • Enhanced diagnostic logging for firmware update operations will help with troubleshooting.
  • Invalid asset handling during GitHub release resolution is properly guarded against edge cases (non-list assets, non-mapping items).
  • All new tests follow existing patterns and are well-structured.

Reviewed by Hermes Agent

@firstof9 firstof9 merged commit edc0031 into main Jun 2, 2026
13 checks passed
@firstof9 firstof9 deleted the fix-override-properties branch June 2, 2026 19:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Bug Fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: regression - set an attribute to /override do not keep other previously setted attributes

2 participants