Skip to content

Add wait_for_next_message so CT002 serves fresh powermeter data#322

Merged
tomquist merged 5 commits intodevelopfrom
wait-for-next-message
Apr 12, 2026
Merged

Add wait_for_next_message so CT002 serves fresh powermeter data#322
tomquist merged 5 commits intodevelopfrom
wait-for-next-message

Conversation

@tomquist
Copy link
Copy Markdown
Owner

@tomquist tomquist commented Apr 12, 2026

The CT002's before_send callback now awaits wait_for_next_message() before reading the powermeter, ensuring push-based meters (MQTT, SMA, HomeWizard, Home Assistant) deliver a fresh measurement for every battery request instead of re-serving stale cached values.

Summary by CodeRabbit

  • New Features

    • Added measurement synchronization to ensure power readings reflect the latest available data from connected meters.
  • Bug Fixes

    • Improved phase charging detection to activate when either a phase is marked active or carries measurable power.
    • Fixed inspection mode to properly update consumer reports instead of skipping them.
  • Tests

    • Added comprehensive test coverage for measurement synchronization behavior across all meter types.

The CT002's before_send callback now awaits wait_for_next_message()
before reading the powermeter, ensuring push-based meters (MQTT, SMA,
HomeWizard, Home Assistant) deliver a fresh measurement for every
battery request instead of re-serving stale cached values.
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 12, 2026

Warning

Rate limit exceeded

@tomquist has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 22 minutes and 10 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 22 minutes and 10 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: db98de10-ee15-4fad-abfe-218af218400c

📥 Commits

Reviewing files that changed from the base of the PR and between 93ab7d7 and 06d8ad4.

📒 Files selected for processing (1)
  • src/astrameter/powermeter/mqtt_test.py

Walkthrough

A new wait_for_next_message() async method is being added to the powermeter abstraction layer and all implementations to enable synchronization to subsequent measurement updates. The method is integrated into the main application flow, and the ct002 meter's phase charging flag logic and inspection mode handling have been modified.

Changes

Cohort / File(s) Summary
Powermeter Base & Interface
src/astrameter/powermeter/base.py
Added wait_for_next_message(timeout=5) stub method to base class with documentation clarifying it blocks until a subsequent measurement update arrives.
Concrete Implementations
src/astrameter/powermeter/homeassistant.py, src/astrameter/powermeter/homewizard.py, src/astrameter/powermeter/mqtt.py, src/astrameter/powermeter/sma_energy_meter.py
Each added wait_for_next_message(timeout) with implementation-specific event-clearing and retry logic; HomeAssistant and HomeWizard use single wait-and-clear pattern, MQTT and SMA use loop-based patterns to ensure all values are non-null before returning.
Wrapper Implementations
src/astrameter/powermeter/pid.py, src/astrameter/powermeter/throttling.py, src/astrameter/powermeter/transform.py
Each added wait_for_next_message(timeout) delegating to the wrapped powermeter's implementation.
Powermeter Tests
src/astrameter/powermeter/homeassistant_test.py, src/astrameter/powermeter/homewizard_test.py, src/astrameter/powermeter/mqtt_test.py, src/astrameter/powermeter/pid_test.py, src/astrameter/powermeter/sma_energy_meter_test.py, src/astrameter/powermeter/throttling_test.py, src/astrameter/powermeter/transform_test.py
Added comprehensive test coverage for wait_for_next_message() across all implementations, including blocking-until-new-message verification, timeout handling, cold-start scenarios, and delegation passthrough validation.
Core Application Changes
src/astrameter/main.py
update_readings now awaits powermeter.wait_for_next_message() immediately after selecting the matching powermeter and before fetching watt values.
CT002 Meter Logic
src/astrameter/ct002/ct002.py
Phase charging flags ("A/B/C_chrg_nb") now set to "1" when either the phase is marked active or the corresponding meter power value is non-zero (previously active status only); in inspection mode, consumer reported phase is forced to "A" and consumer report update is no longer skipped.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.07% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and specifically describes the main change: adding wait_for_next_message functionality to ensure CT002 serves fresh powermeter data.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch wait-for-next-message

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.

@tomquist tomquist marked this pull request as ready for review April 12, 2026 20:34
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

🧹 Nitpick comments (1)
src/astrameter/powermeter/mqtt_test.py (1)

103-125: Good baseline tests; add a multi-topic cold-start case.

Current coverage is single-topic only. Please add a regression test where subscriptions are multi-topic and only one topic updates first, to lock down expected wait_for_next_message behavior before get_powermeter_watts().

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/astrameter/powermeter/mqtt_test.py` around lines 103 - 125, Add a new
async test that creates a multi-topic power meter via _make_pm (simulate
multi-topic subscription), starts with a cold start (no pm._message_event set
and no initial values), then schedule an update on only one of the subscribed
topics (set its value and pm._message_event.set()) after a short sleep; call
pm.wait_for_next_message(timeout=...) and assert it unblocks and that
pm.get_powermeter_watts() returns the expected value for the topic that updated
first. Ensure the test exercises wait_for_next_message and get_powermeter_watts
with multi-topic state to lock down the cold-start behavior when only one topic
produces the first message.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/astrameter/powermeter/mqtt.py`:
- Around line 176-181: The wait_for_next_message method can return after a
single topic update in multi-topic mode, leaving other phase values None and
causing get_powermeter_watts() to fail; modify wait_for_next_message to not
return until the internal multi-topic state is complete by checking the object's
phase/topic state (e.g. self._phases, self._state or expected topic list) after
the _message_event is set — use a loop that awaits _message_event.wait() with
the remaining timeout, clears the event, then verifies all expected
topics/phases are non-None before returning, and raise TimeoutError if the
overall timeout expires; keep the method name wait_for_next_message and the same
timeout semantics.

---

Nitpick comments:
In `@src/astrameter/powermeter/mqtt_test.py`:
- Around line 103-125: Add a new async test that creates a multi-topic power
meter via _make_pm (simulate multi-topic subscription), starts with a cold start
(no pm._message_event set and no initial values), then schedule an update on
only one of the subscribed topics (set its value and pm._message_event.set())
after a short sleep; call pm.wait_for_next_message(timeout=...) and assert it
unblocks and that pm.get_powermeter_watts() returns the expected value for the
topic that updated first. Ensure the test exercises wait_for_next_message and
get_powermeter_watts with multi-topic state to lock down the cold-start behavior
when only one topic produces the first message.
🪄 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: f5cca408-45d0-4a41-a0d9-3ae795641222

📥 Commits

Reviewing files that changed from the base of the PR and between fdc8056 and 7d7c8ad.

📒 Files selected for processing (17)
  • src/astrameter/ct002/ct002.py
  • src/astrameter/main.py
  • src/astrameter/powermeter/base.py
  • src/astrameter/powermeter/homeassistant.py
  • src/astrameter/powermeter/homeassistant_test.py
  • src/astrameter/powermeter/homewizard.py
  • src/astrameter/powermeter/homewizard_test.py
  • src/astrameter/powermeter/mqtt.py
  • src/astrameter/powermeter/mqtt_test.py
  • src/astrameter/powermeter/pid.py
  • src/astrameter/powermeter/pid_test.py
  • src/astrameter/powermeter/sma_energy_meter.py
  • src/astrameter/powermeter/sma_energy_meter_test.py
  • src/astrameter/powermeter/throttling.py
  • src/astrameter/powermeter/throttling_test.py
  • src/astrameter/powermeter/transform.py
  • src/astrameter/powermeter/transform_test.py

claude added 2 commits April 12, 2026 20:56
In multi-topic configurations, wait_for_next_message could return after
receiving a message on just one topic, leaving other phase values as None
and causing get_powermeter_watts() to fail. Now loops with a deadline
until all subscribed values are populated, matching wait_for_message
semantics but always waiting for a new message first.

https://claude.ai/code/session_013EAvo4q396i36rhT45LNkp
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 the current code and only fix it if needed.

Inline comments:
In `@src/astrameter/powermeter/mqtt_test.py`:
- Around line 103-117: The test test_wait_for_next_message_blocks_until_new
currently can pass for implementations that return early because it awaits the
setter task before asserting; change the test to assert that the setter task has
already completed immediately after await pm.wait_for_next_message(timeout=2)
(e.g., check task.done() or equivalent) and then assert pm.value == 42.0 to
ensure wait_for_next_message actually blocked until the new message was set;
locate the test and the call to pm.wait_for_next_message and add the post-wait
assertion referencing the existing task variable.
🪄 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: 280d492f-5011-4f99-85a6-5878a0f8b233

📥 Commits

Reviewing files that changed from the base of the PR and between 7d7c8ad and d534996.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • src/astrameter/powermeter/mqtt.py
  • src/astrameter/powermeter/mqtt_test.py
✅ Files skipped from review due to trivial changes (1)
  • CHANGELOG.md

claude added 2 commits April 12, 2026 21:10
Replace `await task` with `assert task.done()` after
wait_for_next_message returns, so the test fails if the method
returns before the setter task completes.

https://claude.ai/code/session_013EAvo4q396i36rhT45LNkp
@tomquist tomquist merged commit 30cc695 into develop Apr 12, 2026
13 checks passed
@tomquist tomquist deleted the wait-for-next-message branch April 12, 2026 21:16
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.

2 participants