Skip to content

Validate freeze protection temperature against device limits - #116

Merged
eman merged 2 commits into
mainfrom
fix/112-freeze-protection-validation
Jul 23, 2026
Merged

Validate freeze protection temperature against device limits#116
eman merged 2 commits into
mainfrom
fix/112-freeze-protection-validation

Conversation

@eman

@eman eman commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Summary

  • set_freeze_protection_temperature (src/nwp500/mqtt/control.py) documented a 35–45°F valid range but sent the value straight through with no validation, unlike set_dhw_temperature, which validates against device feature limits before sending.
  • Now fetches device features and validates temperature against features.freeze_protection_temp_min / features.freeze_protection_temp_max (mirrors the set_dhw_temperature pattern), raising RangeValidationError for out-of-range values and DeviceCapabilityError if features aren't cached/available yet.

Fixes #112

Test plan

  • Added TestFreezeProtectionTemperatureValidation in tests/test_protocol_correctness.py:
    • rejects an out-of-range temperature and does not publish
    • accepts an in-range temperature and publishes
    • raises DeviceCapabilityError when device features are unavailable
  • Full suite: 607 passed, 4 skipped.

set_freeze_protection_temperature documented a 35-45°F valid range but
never enforced it, unlike set_dhw_temperature which validates against
device feature limits. Now validates temperature against
features.freeze_protection_temp_min/_max before sending, raising
RangeValidationError out of range and DeviceCapabilityError if device
features aren't available yet.

Fixes #112

Copilot AI 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.

Pull request overview

This PR brings set_freeze_protection_temperature in src/nwp500/mqtt/control.py in line with other temperature-setting commands by validating the requested freeze-protection threshold against device-reported feature limits before publishing the MQTT command, addressing issue #112.

Changes:

  • Added device-feature-based range validation for set_freeze_protection_temperature, raising RangeValidationError when out of range.
  • Added an explicit DeviceCapabilityError path when device features are unavailable for validation.
  • Added protocol correctness tests covering in-range publish, out-of-range rejection (no publish), and missing-features behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/nwp500/mqtt/control.py Fetches device features and validates freeze-protection temperature against freeze_protection_temp_min/max before sending command.
tests/test_protocol_correctness.py Adds async regression tests to ensure validation behavior and “no publish on failure” semantics.

Comment thread src/nwp500/mqtt/control.py Outdated
Comment on lines +830 to +834
@@ -831,7 +831,30 @@ async def set_freeze_protection_temperature(

Returns:
Publish packet ID

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in 3caebbf — reworded to describe validation against the device's own reported freeze_protection_temp_min/_max limits instead of a hard-coded range.

Comment on lines +841 to +850
features = await self._get_device_features(device)
if features is None:
raise DeviceCapabilityError(
"freeze_protection_use",
(
"Device features not available. "
"Unable to validate temperature range."
),
)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Good catch — fixed in 3caebbf. Added freeze_protection_use to _CAPABILITY_MAP and decorated the method with @requires_capability("freeze_protection_use"), matching the pattern used everywhere else. Added a regression test (test_blocked_when_device_lacks_freeze_protection).

Review feedback on #116 (Copilot):
- Range validation alone let the command through to devices that report
  freeze_protection_use=False; add the capability to _CAPABILITY_MAP and
  decorate set_freeze_protection_temperature with
  @requires_capability("freeze_protection_use"), consistent with every
  other controllable feature.
- The docstring hard-coded a fixed 35-45°F range even though validation
  is against the device's own reported limits; reworded to describe
  device-specific validation instead.
@eman
eman merged commit 5c6053b into main Jul 23, 2026
7 checks passed
eman added a commit that referenced this pull request Jul 23, 2026
Resolves conflicts with #115 (docstring fix) and #116 (freeze
protection validation), both merged to main after this branch was cut.
Conflicts were purely additive: dr_setting_use and
freeze_protection_use both added to _CAPABILITY_MAP, and their
respective test classes both added to test_protocol_correctness.py /
test_device_capabilities.py. Combined capability count is now 10.
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.

BUG: set_freeze_protection_temperature ignores its documented 35-45F range (no validation)

2 participants