Skip to content

Add Matter Thermostat presets feature#160885

Open
lboue wants to merge 85 commits intohome-assistant:devfrom
lboue:MA-TH-Presets
Open

Add Matter Thermostat presets feature#160885
lboue wants to merge 85 commits intohome-assistant:devfrom
lboue:MA-TH-Presets

Conversation

@lboue
Copy link
Contributor

@lboue lboue commented Jan 13, 2026

Proposed change

This pull request introduces support for thermostat preset modes in the Home Assistant Matter integration. Users can now easily switch between predefined climate presets (e.g., Home, Away, Sleep, Eco) on Matter-compatible thermostats through the Home Assistant UI and service calls.

  • Adds Matter thermostat preset support: parses Presets/PresetTypes attributes, maps known names to HA presets, exposes preset modes/state, and sends SetActivePresetRequest commands with optimistic updates and validation (handles Matter errors).
  • Splits device update logic into clearer helpers (presets, HVAC mode/action, target temps, limits) and enables preset feature flag when supported.
  • Extends Matter constants and fixtures to include preset data and active preset handle.
  • Updates climate entity snapshots/expectations to include preset modes and feature bits; raises validation error for invalid preset selection.
  • Adds integration tests for Eve Thermo v5 covering preset parsing, service calls, state updates, and invalid preset handling.
Details

The presets available on this thermostat are:

No. Preset Temperature
1 🏠 Home 22.0°C
2 🏙️ Away 18.0°C
3 😴 Sleep 20.0°C
4 🌅 Wake 23.0°C
5 🏖️ Vacation 16.0°C
6 🌙 GoingToSleep 21.0°C
254 🌱 Eco 16.0°C

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New integration (thank you!)
  • New feature (which adds functionality to an existing integration)
  • Deprecation (breaking change to happen in the future)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Additional information

Checklist

  • I understand the code I am submitting and can explain how it works.
  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • I have followed the perfect PR recommendations
  • The code has been formatted using Ruff (ruff format homeassistant tests)
  • Tests have been added to verify that the new code works.
  • Any generated code has been carefully reviewed for correctness and compliance with project standards.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • The manifest file has all fields filled out correctly.
    Updated and included derived files by running: python3 -m script.hassfest.
  • New or updated dependencies have been added to requirements_all.txt.
    Updated by running python3 -m script.gen_requirements_all.
  • For the updated dependencies - a link to the changelog, or at minimum a diff between library versions is added to the PR description.

To help with the load of incoming pull requests:

@home-assistant
Copy link

Hey there @home-assistant/matter, mind taking a look at this pull request as it has been labeled with an integration (matter) you are listed as a code owner for? Thanks!

Code owner commands

Code owners of matter can trigger bot actions by commenting:

  • @home-assistant close Closes the pull request.
  • @home-assistant rename Awesome new title Renames the pull request.
  • @home-assistant reopen Reopen the pull request.
  • @home-assistant unassign matter Removes the current integration label and assignees on the pull request, add the integration domain after the command.
  • @home-assistant add-label needs-more-information Add a label (needs-more-information, problem in dependency, problem in custom component) to the pull request.
  • @home-assistant remove-label needs-more-information Remove a label (needs-more-information, problem in dependency, problem in custom component) on the pull request.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

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

Comment on lines +297 to +305
# Optimistically update the endpoint's ActivePresetHandle attribute
# to prevent _update_from_device() from reverting to stale device state
active_preset_path = create_attribute_path_from_attribute(
endpoint_id=self._endpoint.endpoint_id,
attribute=clusters.Thermostat.Attributes.ActivePresetHandle,
)
self._endpoint.set_attribute_value(active_preset_path, active_preset_handle)
self._update_from_device()
self.async_write_ha_state()
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

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

The async_set_preset_mode method calls async_write_ha_state() after optimistic updates, but async_set_hvac_mode (lines 307-325) does not. This inconsistency suggests that either async_set_preset_mode has an unnecessary explicit state write (since device attribute updates will trigger _on_matter_event which already calls async_write_ha_state()), or async_set_hvac_mode is missing one. Review the existing pattern: if write_attribute and send_device_command automatically trigger state updates through subscriptions, the explicit async_write_ha_state() call may be redundant. If it's needed for immediate UI feedback before device confirmation, consider documenting why and applying it consistently to both methods.

Copilot uses AI. Check for mistakes.
Copy link
Member

Choose a reason for hiding this comment

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

Please address this comment. Why do we need to write state optimistically?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

When SetActivePresetRequest is sent to the device, the ActivePresetHandle attribute is updated on the device side immediately. However, Home Assistant only learns about attribute changes via Matter subscriptions, which are subject to a negotiated minIntervalFloor set by the device. This means the subscription report carrying the updated ActivePresetHandle value may arrive several seconds later, even though the device has already applied the change.

Without the optimistic update, HA would keep displaying the previous preset mode in the UI until the subscription report arrives, creating a confusing inconsistency right after the user triggers the action.

To avoid this, async_set_preset_mode() immediately:

  1. Updates _attr_preset_mode to the new value and calls async_write_ha_state() so the UI reflects the change instantly.
  2. Calls set_attribute_value() on the local endpoint cache for ActivePresetHandle, so that any intermediate call to _update_from_device() (e.g. triggered by another subscription report on a different attribute) does not revert the preset back to the old value before the device's own subscription report arrives.

This is consistent with how async_set_hvac_mode() handles the SystemMode attribute in the same file.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

@home-assistant home-assistant bot marked this pull request as draft March 6, 2026 12:09
@home-assistant
Copy link

home-assistant bot commented Mar 6, 2026

Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍

Learn more about our pull request process.

@lboue
Copy link
Contributor Author

lboue commented Mar 13, 2026

I noticed that there's a bug in the SDK related to Thermostats:
project-chip/connectedhomeip#43583.

This will be included in future versions, but it will take some time for this patch to be incorporated into future firmware updates.

…mate to address SDK bug and reporting delays
@lboue lboue requested a review from MartinHjelmare March 13, 2026 22:30
@lboue lboue marked this pull request as ready for review March 13, 2026 22:32
Copilot AI review requested due to automatic review settings March 13, 2026 22:32
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

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

)

async def async_set_preset_mode(self, preset_mode: str) -> None:
"""Set new preset mode."""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants