home-assistant/core · warning · ServiceValidationError
not_a_water_heater_device
not_a_water_heater_device
Error message
The selected device ({device_name}) is not a water heater. Please select the water heater sub-device. What it means
ServiceValidationError raised by `_ensure_water_heater_device` when the bsblan device passed to `set_hot_water_schedule` is not the water-heater sub-device. The check requires an identifier of the form `{something}-water-heater` in the domain-bsblan identifiers; the main controller device or a circuit device fails it. Translation key `not_a_water_heater_device` names the device.
Source
Thrown at homeassistant/components/bsblan/services.py:178
translation_domain=DOMAIN,
translation_key="config_entry_not_loaded",
translation_placeholders={"device_name": device_entry.name or device_id},
)
return entry, device_entry
def _device_name(device_entry: dr.DeviceEntry) -> str:
"""Return the best available display name for a device."""
return device_entry.name_by_user or device_entry.name or device_entry.id
def _ensure_water_heater_device(device_entry: dr.DeviceEntry) -> None:
"""Validate the service targets the water heater sub-device."""
for domain, identifier in device_entry.identifiers:
if domain == DOMAIN and identifier.endswith("-water-heater"):
return
raise ServiceValidationError(
translation_domain=DOMAIN,
translation_key="not_a_water_heater_device",
translation_placeholders={"device_name": _device_name(device_entry)},
)
async def set_hot_water_schedule(service_call: ServiceCall) -> None:
"""Set hot water heating schedule."""
entry, device_entry = _resolve_config_entry(service_call)
_ensure_water_heater_device(device_entry)
client = entry.runtime_data.client
days = _build_weekly_schedule_days(service_call)
dhw_schedule = DHWSchedule(**days)
LOGGER.debug("Setting hot water schedule: %s", dhw_schedule)
try:View on GitHub (pinned to 58a3fdb3ea)
Solutions
- Select the sub-device literally named/labeled as the water heater (identifier ending in `-water-heater`).
- In YAML, confirm the device's identifiers via Developer Tools > Template before hardcoding.
- If no water-heater sub-device exists, the boiler has no DHW circuit exposed — this action cannot be used.
Defensive patterns
Strategy: type-guard
Validate before calling
# template: confirm the chosen device is the water heater sub-device
{{ device_attr(device_id, 'identifiers') | select('match', 'bsblan:.*-water-heater$') | list | length > 0 }} Type guard
def is_water_heater_device(device_entry: dr.DeviceEntry) -> bool:
return any(
domain == "bsblan" and identifier.endswith("-water-heater")
for domain, identifier in device_entry.identifiers
) Prevention
- Select the sub-device named 'water heater' in the picker, not the controller device.
- Check identifiers in Developer Tools before hardcoding a device_id.
- If no water-heater sub-device exists, the boiler exposes no DHW — don't use this action.
When it happens
Trigger: Calling `bsblan.set_hot_water_schedule` with the top-level BSB-LAN controller device (or a heating-circuit device) instead of the dedicated water heater sub-device created for DHW.
Common situations: Users selecting the 'BSB-LAN Controller' device in the picker or in YAML because it is the most prominent one; homes without a DHW circuit where no water-heater sub-device exists at all.
Related errors
- invalid_device_id
- no_config_entry_for_device
- Operation mode not supported
- end_time_before_start_time
- config_entry_not_loaded
AI-assisted analysis of home-assistant/core@58a3fdb3ea (2026-08-14).
Data as JSON: /api/errors/bc7ff715ef073e42.
Report an issue: GitHub.