Skip to content

[water_heater] Fix device_id missing from state responses#14212

Merged
jesserockz merged 1 commit intodevfrom
fix-water-heater-device-id
Feb 22, 2026
Merged

[water_heater] Fix device_id missing from state responses#14212
jesserockz merged 1 commit intodevfrom
fix-water-heater-device-id

Conversation

@bdraco
Copy link
Member

@bdraco bdraco commented Feb 22, 2026

What does this implement/fix?

try_send_water_heater_state() was the only entity type that directly called encode_message_to_buffer() instead of fill_and_encode_entity_state(). This meant device_id was never set on WaterHeaterStateResponse, causing entities with device_id configured to show as unknown in Home Assistant.

The fix replaces the direct encode_message_to_buffer() call with fill_and_encode_entity_state(), matching every other entity type (sensor, climate, switch, cover, fan, light, etc.).

Also expands the device_id integration test from 5 entity types to 17, covering all stateful entity types that support device_id.

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Developer breaking change (an API change that could break external components)
  • Code quality improvements to existing code or addition of tests
  • Other

Related issue or feature (if applicable):

Pull request in esphome-docs with documentation (if applicable):

  • N/A

Test Environment

  • ESP32
  • ESP32 IDF
  • ESP8266
  • RP2040
  • BK72xx
  • RTL87xx
  • LN882x
  • nRF52840

Example entry for config.yaml:

water_heater:
  - platform: template
    name: "Boiler"
    device_id: my_device  # This now works correctly
    optimistic: true
    supported_modes:
      - "OFF"
      - ELECTRIC
    visual:
      min_temperature: 30.0
      max_temperature: 85.0
      target_temperature_step: 0.5

Checklist:

  • The code change is tested and works locally.
  • Tests have been added to verify that the new code works (under tests/ folder).

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

Copilot AI review requested due to automatic review settings February 22, 2026 22:39
@bdraco bdraco requested a review from a team as a code owner February 22, 2026 22:39
@github-actions
Copy link
Contributor

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#14212
    components: [api]
    refresh: 1h

(Added by the PR bot)

@github-actions
Copy link
Contributor

👋 Hi there! This PR modifies 1 file(s) with codeowners.

@esphome/core - As codeowner(s) of the affected files, your review would be appreciated! 🙏

Note: Automatic review request may have failed, but you're still welcome to review.

@codecov-commenter
Copy link

codecov-commenter commented Feb 22, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 74.27%. Comparing base (1753074) to head (cdb2e32).
⚠️ Report is 2 commits behind head on dev.

Additional details and impacted files
@@           Coverage Diff           @@
##              dev   #14212   +/-   ##
=======================================
  Coverage   74.27%   74.27%           
=======================================
  Files          55       55           
  Lines       11591    11591           
  Branches     1582     1582           
=======================================
  Hits         8609     8609           
  Misses       2578     2578           
  Partials      404      404           

☔ 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.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 22, 2026

Memory Impact Analysis

Components: api
Platform: esp8266-ard

Metric Target Branch This PR Change
RAM 32,572 bytes 32,572 bytes ➡️ +0 bytes (0.00%)
Flash 447,431 bytes 447,431 bytes ➡️ +0 bytes (0.00%)

Note: This analysis measures static RAM and Flash usage only (compile-time allocation).
Dynamic memory (heap) cannot be measured automatically.
⚠️ You must test this PR on a real device to measure free heap and ensure no runtime memory issues.

This analysis runs automatically when components change. Memory usage is measured from a representative test configuration.

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

This PR fixes a bug where the water_heater component's state responses didn't include the device_id field, causing entities with device_id configured to appear as unknown in Home Assistant. The fix aligns the water_heater implementation with all other entity types by using fill_and_encode_entity_state() instead of directly calling encode_message_to_buffer().

Changes:

  • Fixed water_heater state encoding to populate device_id field by using fill_and_encode_entity_state()
  • Expanded device_id integration test coverage from 5 to 17 entity types to prevent similar bugs in other components

Reviewed changes

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

File Description
esphome/components/api/api_connection.cpp Replaced manual key setting and encode_message_to_buffer() call with fill_and_encode_entity_state() to properly populate both key and device_id fields
tests/integration/test_device_id_in_state.py Expanded test to verify device_id for 17 entity types (sensor, binary_sensor, switch, text_sensor, light, cover, fan, lock, number, select, text, valve, water_heater, alarm_control_panel, date, time, datetime) with improved error messages
tests/integration/fixtures/device_id_in_state.yaml Added test entities for 12 additional entity types (cover, fan, lock, number, select, text, valve, water_heater, alarm_control_panel, date, time, datetime, event)

Water heater was the only entity type that directly called
encode_message_to_buffer() instead of fill_and_encode_entity_state().
This meant device_id was never set on WaterHeaterStateResponse,
causing entities with device_id to show as unknown in Home Assistant.

Expand the device_id integration test to cover all entity types:
cover, fan, lock, number, select, text, valve, water_heater,
alarm_control_panel, date, time, datetime, and event.

Closes #14206
@bdraco bdraco force-pushed the fix-water-heater-device-id branch from 1ec6484 to cdb2e32 Compare February 22, 2026 22:43
@jesserockz jesserockz enabled auto-merge (squash) February 22, 2026 23:00
@bdraco
Copy link
Member Author

bdraco commented Feb 22, 2026

thanks

@jesserockz jesserockz merged commit b539a5a into dev Feb 22, 2026
27 checks passed
@jesserockz jesserockz deleted the fix-water-heater-device-id branch February 22, 2026 23:07
tomaszduda23 pushed a commit to tomaszduda23/esphome that referenced this pull request Feb 23, 2026
@github-actions github-actions bot locked and limited conversation to collaborators Feb 24, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

water_heater component stops working correctly after adding device_id

4 participants