Skip to content

refactor: Extract preset management into PresetManager#1950

Draft
cl445 wants to merge 2 commits intoKartoffelToby:developfrom
cl445:refactor/phase4-preset-manager
Draft

refactor: Extract preset management into PresetManager#1950
cl445 wants to merge 2 commits intoKartoffelToby:developfrom
cl445:refactor/phase4-preset-manager

Conversation

@cl445
Copy link
Contributor

@cl445 cl445 commented Feb 26, 2026

Summary

  • Extract 5 loose preset attributes from climate.py into a new PresetManager dataclass in utils/preset_manager.py
  • Simplify async_set_preset_mode from ~100 lines to ~35 lines by delegating save/restore/clamping logic to PresetManager.activate()
  • Update number.py (BetterThermostatPresetNumber) to use preset_mgr.update_temperature() / get_temperature() instead of direct dict access

Details

New file: utils/preset_manager.py (~100 lines)

  • PresetManager dataclass with mode, temperatures, enabled_presets, saved_temperature
  • activate(preset, current_temp, min_temp, max_temp) → handles save/restore/clamping, returns new target temp
  • deactivate() → returns to PRESET_NONE, returns saved temp
  • update_temperature() / get_temperature() → API for Number entities
  • available_modes property → [PRESET_NONE] + enabled_presets
  • mypy --strict clean, no Any/cast/type: ignore workarounds

Removed from climate.py:

  • self._preset_modeself.preset_mgr.mode
  • self._preset_temperatureself.preset_mgr.saved_temperature
  • self._preset_temperaturesself.preset_mgr.temperatures
  • self._enabled_presetsself.preset_mgr.enabled_presets
  • self._original_preset_temperatures (dead code, never read)
  • 7 unused PRESET_* constant imports

Test plan

  • 22 new unit tests in tests/unit/test_preset_manager.py covering activate, deactivate, clamping, saved_temperature lifecycle, instance isolation
  • Full test suite passes (896 tests, 0 failures)
  • mypy --strict clean for preset_manager.py
Replace 5 loose preset attributes (_preset_mode, _preset_temperature,
_enabled_presets, _preset_temperatures, _original_preset_temperatures)
with a single PresetManager dataclass that encapsulates mode tracking,
temperature storage, and save/restore logic.

- New PresetManager with activate/deactivate/update_temperature/get_temperature API
- Simplify async_set_preset_mode from ~100 to ~35 lines
- Update number.py to use PresetManager API instead of direct dict access
- Add 22 unit tests for PresetManager
- mypy --strict clean, no typing workarounds
@coderabbitai
Copy link

coderabbitai bot commented Feb 26, 2026

Important

Review skipped

Draft detected.

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.

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:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

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

Labels

None yet

1 participant