Skip to content

Handle missing thermostat data#860

Closed
bouwew wants to merge 13 commits intomainfrom
jessevonk
Closed

Handle missing thermostat data#860
bouwew wants to merge 13 commits intomainfrom
jessevonk

Conversation

@bouwew
Copy link
Contributor

@bouwew bouwew commented Mar 6, 2026

Partly a solution for plugwise/plugwise-beta#1030

Summary by CodeRabbit

  • Bug Fixes

    • Improved robustness when thermostat data is missing to avoid failures and improve stability
  • Tests

    • Added a new integration test for device connectivity
    • Added a large device fixture and reformatted many existing test fixtures for readability and consistency
  • Documentation

    • Updated ongoing changelog with the new robustness note and existing optimization entry

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 6, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fceb619c-e753-45e8-8f86-fc5b2d7d0afa

📥 Commits

Reviewing files that changed from the base of the PR and between 1dec4d3 and 718b3e0.

📒 Files selected for processing (1)
  • plugwise/helper.py

📝 Walkthrough

Walkthrough

Adds and reformats many JSON fixtures (new large Adam/Jvonk datasets and widespread array reflows), introduces defensive guards in plugwise/helper.py for missing thermostat data, adds an async Adam connection test, and updates CHANGELOG.md.

Changes

Cohort / File(s) Summary
New large fixtures & test data
fixtures/adam_bad_thermostat/data.json, fixtures/adam_jvonk/data.json, fixtures/adam_jvonk/data.json, tests/data/adam/adam_bad_thermostat.json
Add comprehensive Adam/Jvonk JSON fixtures and a large testdata JSON file describing gateways, thermostats, zones, sensors, and relationships.
Fixture formatting updates
fixtures/.../data.json (multiple files, e.g. fixtures/adam_heatpump_cooling/data.json, fixtures/adam_jip/data.json, fixtures/adam_multiple_devices_per_zone/data.json, fixtures/adam_onoff_cooling_fake_firmware/data.json, fixtures/adam_plus_anna*/data.json, fixtures/anna_*/data.json, fixtures/m_adam_*/data.json, fixtures/m_anna_*/data.json, fixtures/stretch_v23/data.json)
Reflowed many JSON array literals from single-line to multi-line formatting (preset_modes, available_schedules, gateway_modes, zone_profiles, thermostat primary/secondary arrays, etc.) without changing values.
Thermostat safety guards & refactor
plugwise/helper.py
Add missing-thermostat guards in _control_state and _regulation_control, use a local thermostat variable, log and return early when absent, and adjust data mutation (pop/increment) logic.
Test addition
tests/test_adam.py
Add async test test_connect_adam_jvonk to exercise Adam connection using the new fixture.
Changelog
CHANGELOG.md
Update Ongoing changelog: add entry about handling missing thermostat data and retain an optimization entry.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • CoMPaTech
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Handle missing thermostat data' directly reflects the main functional change in the PR (guards for missing thermostat data in helper.py), making it clear and specific.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jessevonk

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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.

@coderabbitai coderabbitai bot requested a review from CoMPaTech March 6, 2026 17:50
@codecov
Copy link

codecov bot commented Mar 6, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (65251da) to head (1dec4d3).

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #860   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           21        21           
  Lines         3443      3456   +13     
=========================================
+ Hits          3443      3456   +13     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coderabbitai coderabbitai bot added the bug Something isn't working label Mar 6, 2026
@bouwew bouwew marked this pull request as ready for review March 6, 2026 17:53
@bouwew bouwew requested a review from a team as a code owner March 6, 2026 17:53
Copy link
Contributor

@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 (2)
plugwise/helper.py (1)

867-872: Avoid warning on every refresh for the same broken zone.

_get_location_data() calls _regulation_control() on each update, so a permanently missing thermostat will emit this warning every poll cycle. Consider logging once per zone or downgrading this to debug to avoid log spam.

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

In `@plugwise/helper.py` around lines 867 - 872, The current LOGGER.warning in
_get_location_data() / _regulation_control() will spam logs every poll for zones
missing a thermostat; change this to warn only once per zone by tracking seen
broken zones (e.g., add a set attribute like self._warned_missing_thermostat and
use data["name"] as the key), log the warning only if the zone is not in that
set, add the zone to the set after warning, and remove the zone from the set
when a thermostat is present again; alternatively, if you prefer no persistent
state, change LOGGER.warning to LOGGER.debug in the thermostat None branch to
stop repeated warnings.
tests/data/adam/adam_bad_thermostat.json (1)

1-532: Avoid maintaining a third copy of this payload.

This file appears identical to fixtures/adam_bad_thermostat/data.json and fixtures/adam_jvonk/data.json in the same PR. Keeping three large copies synchronized is easy to miss, and the regression can drift away from the source fixture that reproduces the bug. Consider loading a single canonical JSON fixture in the test helper, or generating this test payload from that source instead.

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

In `@tests/data/adam/adam_bad_thermostat.json` around lines 1 - 532, This JSON
payload is a duplicate of the fixture used in
fixtures/adam_bad_thermostat/data.json and fixtures/adam_jvonk/data.json; remove
this redundant file and update tests to load the single canonical fixture
instead (or generate it from that source) via the test helper so all tests
reference one source of truth (search for uses of this file name in tests and
replace them to load the canonical fixture, or add a loader function in the test
helper to return the shared fixture).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/test_adam.py`:
- Around line 19-25: The test test_connect_adam_jvonk is misconfigured: it sets
self.smile_setup = "adam_bad_thermostat" so load_testdata() loads the
bad-thermostat fixture instead of the intended JVonk dataset; fix by either
renaming the test to reflect the bad-thermostat fixture or change
self.smile_setup to the correct JVonk fixture name (the JVonk JSON identifier
used by load_testdata), ensuring test_connect_adam_jvonk actually loads the
JVonk data before calling connect_wrapper.

---

Nitpick comments:
In `@plugwise/helper.py`:
- Around line 867-872: The current LOGGER.warning in _get_location_data() /
_regulation_control() will spam logs every poll for zones missing a thermostat;
change this to warn only once per zone by tracking seen broken zones (e.g., add
a set attribute like self._warned_missing_thermostat and use data["name"] as the
key), log the warning only if the zone is not in that set, add the zone to the
set after warning, and remove the zone from the set when a thermostat is present
again; alternatively, if you prefer no persistent state, change LOGGER.warning
to LOGGER.debug in the thermostat None branch to stop repeated warnings.

In `@tests/data/adam/adam_bad_thermostat.json`:
- Around line 1-532: This JSON payload is a duplicate of the fixture used in
fixtures/adam_bad_thermostat/data.json and fixtures/adam_jvonk/data.json; remove
this redundant file and update tests to load the single canonical fixture
instead (or generate it from that source) via the test helper so all tests
reference one source of truth (search for uses of this file name in tests and
replace them to load the canonical fixture, or add a loader function in the test
helper to return the shared fixture).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f0039a41-b4d5-48f0-96ef-ab945a9cbe70

📥 Commits

Reviewing files that changed from the base of the PR and between 65251da and d0caf24.

📒 Files selected for processing (38)
  • fixtures/adam_bad_thermostat/data.json
  • fixtures/adam_heatpump_cooling/data.json
  • fixtures/adam_jip/data.json
  • fixtures/adam_jvonk/data.json
  • fixtures/adam_multiple_devices_per_zone/data.json
  • fixtures/adam_onoff_cooling_fake_firmware/data.json
  • fixtures/adam_plus_anna/data.json
  • fixtures/adam_plus_anna_new/data.json
  • fixtures/adam_plus_anna_new_regulation_off/data.json
  • fixtures/adam_zone_per_device/data.json
  • fixtures/anna_elga_2/data.json
  • fixtures/anna_elga_2_cooling/data.json
  • fixtures/anna_elga_2_schedule_off/data.json
  • fixtures/anna_elga_no_cooling/data.json
  • fixtures/anna_heatpump_cooling/data.json
  • fixtures/anna_heatpump_cooling_fake_firmware/data.json
  • fixtures/anna_heatpump_heating/data.json
  • fixtures/anna_loria_cooling_active/data.json
  • fixtures/anna_loria_driessens/data.json
  • fixtures/anna_loria_heating_idle/data.json
  • fixtures/anna_p1/data.json
  • fixtures/anna_v4/data.json
  • fixtures/anna_v4_dhw/data.json
  • fixtures/anna_v4_no_tag/data.json
  • fixtures/anna_without_boiler_fw441/data.json
  • fixtures/legacy_anna/data.json
  • fixtures/legacy_anna_2/data.json
  • fixtures/m_adam_cooling/data.json
  • fixtures/m_adam_heating/data.json
  • fixtures/m_adam_jip/data.json
  • fixtures/m_adam_multiple_devices_per_zone/data.json
  • fixtures/m_anna_heatpump_cooling/data.json
  • fixtures/m_anna_heatpump_idle/data.json
  • fixtures/stretch_v23/data.json
  • plugwise/helper.py
  • tests/data/adam/adam_bad_thermostat.json
  • tests/test_adam.py
  • userdata/adam_bad_thermostat/core.domain_objects.xml

Comment on lines +19 to +25
@pytest.mark.asyncio
async def test_connect_adam_jvonk(self):
"""Test Adam with missing thermostat data."""
self.smile_setup = "adam_bad_thermostat"

testdata = await self.load_testdata(SMILE_TYPE, self.smile_setup)
server, api, client = await self.connect_wrapper(raise_timeout=True)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

This test never exercises the JVonk fixture.

Line 22 sets self.smile_setup to adam_bad_thermostat, and load_testdata() resolves the JSON path from that value. So test_connect_adam_jvonk() is currently validating the bad-thermostat fixture instead of a JVonk dataset. Either rename the test to match what it covers or point self.smile_setup at the intended JVonk fixture.

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

In `@tests/test_adam.py` around lines 19 - 25, The test test_connect_adam_jvonk is
misconfigured: it sets self.smile_setup = "adam_bad_thermostat" so
load_testdata() loads the bad-thermostat fixture instead of the intended JVonk
dataset; fix by either renaming the test to reflect the bad-thermostat fixture
or change self.smile_setup to the correct JVonk fixture name (the JVonk JSON
identifier used by load_testdata), ensuring test_connect_adam_jvonk actually
loads the JVonk data before calling connect_wrapper.

Copy link
Member

@CoMPaTech CoMPaTech left a comment

Choose a reason for hiding this comment

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

Remark before merging, CRAI is about right to call the naming of the test - for others directories are tagged with @githubname file in the directories?

@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 7, 2026

@coderabbitai coderabbitai bot requested a review from CoMPaTech March 7, 2026 10:14
@bouwew bouwew closed this Mar 7, 2026
@bouwew bouwew deleted the jessevonk branch March 7, 2026 10:14
@bouwew
Copy link
Contributor Author

bouwew commented Mar 8, 2026

@CoMPaTech Yes I missed that one, implemented via fb63431

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants