[web_server] Add climate preset, fan mode, and humidity support#14061
[web_server] Add climate preset, fan mode, and humidity support#14061bdraco merged 1 commit intoesphome:devfrom
Conversation
|
To use the changes from this PR as an external component, add the following to your ESPHome configuration YAML file: external_components:
- source: github://pr#14061
components: [web_server]
refresh: 1h(Added by the PR bot) |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## dev #14061 +/- ##
=======================================
Coverage 74.11% 74.11%
=======================================
Files 55 55
Lines 11590 11590
Branches 1578 1578
=======================================
Hits 8590 8590
Misses 2598 2598
Partials 402 402 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
That sounds like a bug in the frontend |
It's arguably more of a protocol design issue than a frontend bug. SSE state events are designed as partial updates merged via Object.assign(). The issue is that when an optional field like preset transitions from set → unset, omitting it from the payload gives the frontend no signal to clear the previous value. The frontend would need to track which fields are expected per entity type and explicitly null missing ones, which adds complexity and couples the frontend tightly to backend schema knowledge. Always including supported fields (with empty string as the "unset" sentinel) keeps the contract simple: if a trait is supported, the field is always present in the payload, and the frontend can rely on the value it receives. Also see the discord thread |
|
That seems like a design mismatch. If we are expecting partial updates and we aren't comparing against the previous state, we end up sending everything anyways |
|
It looks like this puts us out of sync with the REST API |
You're right — other components (fan, cover, valve) omit optional fields when not supported/set. Climate is unique in having mutually exclusive optional pairs (fan_mode/custom_fan_mode, preset/custom_preset) which other entity types don't have. Happy to align the approach if there's a preferred pattern — should the frontend handle clearing stale values for missing keys instead? |
|
We probably need to do something with the frontend for climate to minimize the payload coming from the backend since we keep allocating larger and larger json payloads on the device to the point we will start to have a problem |
|
Also we are trying to fix the heap churn issue with the web_server with long connected SSE in #13625 so if we can keep the climate payload under 512 bytes it will never allocate once that PR is merged |
66518d5 to
5f6754a
Compare
|
We are sending min_temp/max_temp/step every time as well and we don't need to. And for water heater its wrong... |
Move min/max temperature and step traits into DETAIL_ALL block so they are only sent once on initial connection instead of on every state update. Rename keys from min_temperature/max_temperature to min_temp/max_temp to match what the frontend expects. Discovered while reviewing #14061.
5f6754a to
8d3f4c5
Compare
|
note that clang-format is still failing https://github.com/esphome/esphome/actions/runs/22166826625/job/64095845122?pr=14061 |
|
Reworked based on feedback. The PR now only touches the backend minimally. I updated description with the changes and reasoning. |
- Add preset/custom_preset to climate REST API (parse_string_param_ for preset in handle_climate_request) - Fix fan_modes trait gate: use get_supports_fan_modes() instead of get_supported_custom_fan_modes().empty() - Always list presets/custom_presets options in DETAIL_ALL regardless of current state - Add current_humidity to climate state JSON when supported
8d3f4c5 to
ccf1f41
Compare
Memory Impact AnalysisComponents:
This analysis runs automatically when components change. Memory usage is measured from a representative test configuration. |
|
For reference the frontend PR: esphome/esphome-webserver#191 |
|
Current version LGTM |
There was a problem hiding this comment.
Pull request overview
This PR enhances the web_server REST/JSON interface for climate entities so the web UI (and other REST clients) can view and control additional climate capabilities, and receive current humidity when supported.
Changes:
- Add REST
setsupport for climatepreset(string-based, covering standard + custom presets). - Fix
fan_modestrait JSON gating to correctly depend on overall fan-mode support. - Always include presets/custom_presets option lists in
DETAIL_ALL, and includecurrent_humidityin state JSON when supported.
What does this implement/fix?
The web server climate card had no way to view or change presets or fan modes, and current humidity was not displayed.
get_supported_custom_fan_modes()instead ofget_supports_fan_modes()Types of changes
Test Environment
Checklist:
tests/folder).Tests in tests/components/web_server/ are compilation validation only