diff --git a/homeassistant/components/weheat/binary_sensor.py b/homeassistant/components/weheat/binary_sensor.py index 7d6d20c12f69..a5d477c94f02 100644 --- a/homeassistant/components/weheat/binary_sensor.py +++ b/homeassistant/components/weheat/binary_sensor.py @@ -2,6 +2,7 @@ from collections.abc import Callable from dataclasses import dataclass +from functools import partial from typing import override from weheat.abstractions.heat_pump import HeatPump @@ -11,6 +12,7 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntity, BinarySensorEntityDescription, ) +from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import StateType @@ -62,6 +64,25 @@ BINARY_SENSORS = [ ] +COOLING_START_CONDITION_SENSORS = [ + WeHeatBinarySensorEntityDescription( + translation_key=f"cooling_start_condition_{condition}", + key=f"cooling_start_condition_{condition}", + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + value_fn=partial( + lambda condition, status: ( + status.cooling_start_conditions[condition] + if status.cooling_start_conditions is not None + else None + ), + condition, + ), + ) + for condition in HeatPump.COOLING_START_CONDITION_BITS +] + + async def async_setup_entry( hass: HomeAssistant, entry: WeheatConfigEntry, @@ -78,6 +99,16 @@ async def async_setup_entry( for entity_description in BINARY_SENSORS if entity_description.value_fn(weheatdata.data_coordinator.data) is not None ] + entities.extend( + WeheatHeatPumpBinarySensor( + weheatdata.heat_pump_info, + weheatdata.data_coordinator, + entity_description, + ) + for weheatdata in entry.runtime_data + if weheatdata.data_coordinator.data.cooling_start_conditions is not None + for entity_description in COOLING_START_CONDITION_SENSORS + ) async_add_entities(entities) diff --git a/homeassistant/components/weheat/icons.json b/homeassistant/components/weheat/icons.json index c5fc792dbc72..9a1a81d92f80 100644 --- a/homeassistant/components/weheat/icons.json +++ b/homeassistant/components/weheat/icons.json @@ -1,6 +1,39 @@ { "entity": { "binary_sensor": { + "cooling_start_condition_contact_not_blocked": { + "default": "mdi:snowflake-check" + }, + "cooling_start_condition_control_method": { + "default": "mdi:snowflake-check" + }, + "cooling_start_condition_demand": { + "default": "mdi:snowflake-check" + }, + "cooling_start_condition_dtc": { + "default": "mdi:snowflake-check" + }, + "cooling_start_condition_exponential_backoff": { + "default": "mdi:snowflake-check" + }, + "cooling_start_condition_heat_cool_delay": { + "default": "mdi:snowflake-check" + }, + "cooling_start_condition_indoor_unit_connected": { + "default": "mdi:snowflake-check" + }, + "cooling_start_condition_inside_temperature": { + "default": "mdi:snowflake-check" + }, + "cooling_start_condition_outside_air_temperature": { + "default": "mdi:snowflake-check" + }, + "cooling_start_condition_water_temperature": { + "default": "mdi:snowflake-check" + }, + "cooling_start_condition_water_to_air": { + "default": "mdi:snowflake-check" + }, "indoor_unit_auxiliary_pump_state": { "default": "mdi:pump" }, diff --git a/homeassistant/components/weheat/quality_scale.yaml b/homeassistant/components/weheat/quality_scale.yaml index 0f0710576533..22722cdb8983 100644 --- a/homeassistant/components/weheat/quality_scale.yaml +++ b/homeassistant/components/weheat/quality_scale.yaml @@ -76,7 +76,7 @@ rules: While unlikely to happen. Check if it is easily integrated. entity-category: done entity-device-class: done - entity-disabled-by-default: todo + entity-disabled-by-default: done entity-translations: done exception-translations: todo icon-translations: done diff --git a/homeassistant/components/weheat/strings.json b/homeassistant/components/weheat/strings.json index 74b2da3ad197..d89d0b9aa425 100644 --- a/homeassistant/components/weheat/strings.json +++ b/homeassistant/components/weheat/strings.json @@ -30,6 +30,39 @@ }, "entity": { "binary_sensor": { + "cooling_start_condition_contact_not_blocked": { + "name": "Cooling contact not blocking" + }, + "cooling_start_condition_control_method": { + "name": "Cooling allowed by control method" + }, + "cooling_start_condition_demand": { + "name": "Demand for cooling from cooling curve" + }, + "cooling_start_condition_dtc": { + "name": "No cooling-related faults" + }, + "cooling_start_condition_exponential_backoff": { + "name": "No cooling back-off waiting time" + }, + "cooling_start_condition_heat_cool_delay": { + "name": "No heating in the last 24 hours" + }, + "cooling_start_condition_indoor_unit_connected": { + "name": "Cooling indoor unit connected" + }, + "cooling_start_condition_inside_temperature": { + "name": "Cooling room warmer than desired" + }, + "cooling_start_condition_outside_air_temperature": { + "name": "Cooling outside temperature high enough" + }, + "cooling_start_condition_water_temperature": { + "name": "Water warmer than cooling curve" + }, + "cooling_start_condition_water_to_air": { + "name": "Cooling air warmer than system water" + }, "indoor_unit_auxiliary_pump_state": { "name": "Indoor unit auxiliary water pump" }, diff --git a/tests/components/weheat/snapshots/test_binary_sensor.ambr b/tests/components/weheat/snapshots/test_binary_sensor.ambr index 75cff41a5698..4b72382298ad 100644 --- a/tests/components/weheat/snapshots/test_binary_sensor.ambr +++ b/tests/components/weheat/snapshots/test_binary_sensor.ambr @@ -1,4 +1,354 @@ # serializer version: 1 +# name: test_binary_entities[binary_sensor.test_model_cooling_air_warmer_than_system_water-entry] + EntityRegistryEntrySnapshot({ + 'aliases': list([ + None, + ]), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.test_model_cooling_air_warmer_than_system_water', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'object_id_base': 'Cooling air warmer than system water', + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Cooling air warmer than system water', + 'platform': 'weheat', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'cooling_start_condition_water_to_air', + 'unique_id': '0000-1111-2222-3333_cooling_start_condition_water_to_air', + 'unit_of_measurement': None, + }) +# --- +# name: test_binary_entities[binary_sensor.test_model_cooling_air_warmer_than_system_water-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + : 'Test Model Cooling air warmer than system water', + }), + 'context': , + 'entity_id': 'binary_sensor.test_model_cooling_air_warmer_than_system_water', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_binary_entities[binary_sensor.test_model_cooling_allowed_by_control_method-entry] + EntityRegistryEntrySnapshot({ + 'aliases': list([ + None, + ]), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.test_model_cooling_allowed_by_control_method', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'object_id_base': 'Cooling allowed by control method', + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Cooling allowed by control method', + 'platform': 'weheat', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'cooling_start_condition_control_method', + 'unique_id': '0000-1111-2222-3333_cooling_start_condition_control_method', + 'unit_of_measurement': None, + }) +# --- +# name: test_binary_entities[binary_sensor.test_model_cooling_allowed_by_control_method-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + : 'Test Model Cooling allowed by control method', + }), + 'context': , + 'entity_id': 'binary_sensor.test_model_cooling_allowed_by_control_method', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_binary_entities[binary_sensor.test_model_cooling_contact_not_blocking-entry] + EntityRegistryEntrySnapshot({ + 'aliases': list([ + None, + ]), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.test_model_cooling_contact_not_blocking', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'object_id_base': 'Cooling contact not blocking', + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Cooling contact not blocking', + 'platform': 'weheat', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'cooling_start_condition_contact_not_blocked', + 'unique_id': '0000-1111-2222-3333_cooling_start_condition_contact_not_blocked', + 'unit_of_measurement': None, + }) +# --- +# name: test_binary_entities[binary_sensor.test_model_cooling_contact_not_blocking-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + : 'Test Model Cooling contact not blocking', + }), + 'context': , + 'entity_id': 'binary_sensor.test_model_cooling_contact_not_blocking', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_binary_entities[binary_sensor.test_model_cooling_indoor_unit_connected-entry] + EntityRegistryEntrySnapshot({ + 'aliases': list([ + None, + ]), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.test_model_cooling_indoor_unit_connected', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'object_id_base': 'Cooling indoor unit connected', + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Cooling indoor unit connected', + 'platform': 'weheat', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'cooling_start_condition_indoor_unit_connected', + 'unique_id': '0000-1111-2222-3333_cooling_start_condition_indoor_unit_connected', + 'unit_of_measurement': None, + }) +# --- +# name: test_binary_entities[binary_sensor.test_model_cooling_indoor_unit_connected-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + : 'Test Model Cooling indoor unit connected', + }), + 'context': , + 'entity_id': 'binary_sensor.test_model_cooling_indoor_unit_connected', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_binary_entities[binary_sensor.test_model_cooling_outside_temperature_high_enough-entry] + EntityRegistryEntrySnapshot({ + 'aliases': list([ + None, + ]), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.test_model_cooling_outside_temperature_high_enough', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'object_id_base': 'Cooling outside temperature high enough', + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Cooling outside temperature high enough', + 'platform': 'weheat', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'cooling_start_condition_outside_air_temperature', + 'unique_id': '0000-1111-2222-3333_cooling_start_condition_outside_air_temperature', + 'unit_of_measurement': None, + }) +# --- +# name: test_binary_entities[binary_sensor.test_model_cooling_outside_temperature_high_enough-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + : 'Test Model Cooling outside temperature high enough', + }), + 'context': , + 'entity_id': 'binary_sensor.test_model_cooling_outside_temperature_high_enough', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_binary_entities[binary_sensor.test_model_cooling_room_warmer_than_desired-entry] + EntityRegistryEntrySnapshot({ + 'aliases': list([ + None, + ]), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.test_model_cooling_room_warmer_than_desired', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'object_id_base': 'Cooling room warmer than desired', + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Cooling room warmer than desired', + 'platform': 'weheat', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'cooling_start_condition_inside_temperature', + 'unique_id': '0000-1111-2222-3333_cooling_start_condition_inside_temperature', + 'unit_of_measurement': None, + }) +# --- +# name: test_binary_entities[binary_sensor.test_model_cooling_room_warmer_than_desired-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + : 'Test Model Cooling room warmer than desired', + }), + 'context': , + 'entity_id': 'binary_sensor.test_model_cooling_room_warmer_than_desired', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_binary_entities[binary_sensor.test_model_demand_for_cooling_from_cooling_curve-entry] + EntityRegistryEntrySnapshot({ + 'aliases': list([ + None, + ]), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.test_model_demand_for_cooling_from_cooling_curve', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'object_id_base': 'Demand for cooling from cooling curve', + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Demand for cooling from cooling curve', + 'platform': 'weheat', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'cooling_start_condition_demand', + 'unique_id': '0000-1111-2222-3333_cooling_start_condition_demand', + 'unit_of_measurement': None, + }) +# --- +# name: test_binary_entities[binary_sensor.test_model_demand_for_cooling_from_cooling_curve-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + : 'Test Model Demand for cooling from cooling curve', + }), + 'context': , + 'entity_id': 'binary_sensor.test_model_demand_for_cooling_from_cooling_curve', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'off', + }) +# --- # name: test_binary_entities[binary_sensor.test_model_indoor_unit_auxiliary_water_pump-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ @@ -202,3 +552,203 @@ 'state': 'off', }) # --- +# name: test_binary_entities[binary_sensor.test_model_no_cooling_back_off_waiting_time-entry] + EntityRegistryEntrySnapshot({ + 'aliases': list([ + None, + ]), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.test_model_no_cooling_back_off_waiting_time', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'object_id_base': 'No cooling back-off waiting time', + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'No cooling back-off waiting time', + 'platform': 'weheat', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'cooling_start_condition_exponential_backoff', + 'unique_id': '0000-1111-2222-3333_cooling_start_condition_exponential_backoff', + 'unit_of_measurement': None, + }) +# --- +# name: test_binary_entities[binary_sensor.test_model_no_cooling_back_off_waiting_time-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + : 'Test Model No cooling back-off waiting time', + }), + 'context': , + 'entity_id': 'binary_sensor.test_model_no_cooling_back_off_waiting_time', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_binary_entities[binary_sensor.test_model_no_cooling_related_faults-entry] + EntityRegistryEntrySnapshot({ + 'aliases': list([ + None, + ]), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.test_model_no_cooling_related_faults', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'object_id_base': 'No cooling-related faults', + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'No cooling-related faults', + 'platform': 'weheat', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'cooling_start_condition_dtc', + 'unique_id': '0000-1111-2222-3333_cooling_start_condition_dtc', + 'unit_of_measurement': None, + }) +# --- +# name: test_binary_entities[binary_sensor.test_model_no_cooling_related_faults-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + : 'Test Model No cooling-related faults', + }), + 'context': , + 'entity_id': 'binary_sensor.test_model_no_cooling_related_faults', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_binary_entities[binary_sensor.test_model_no_heating_in_the_last_24_hours-entry] + EntityRegistryEntrySnapshot({ + 'aliases': list([ + None, + ]), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.test_model_no_heating_in_the_last_24_hours', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'object_id_base': 'No heating in the last 24 hours', + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'No heating in the last 24 hours', + 'platform': 'weheat', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'cooling_start_condition_heat_cool_delay', + 'unique_id': '0000-1111-2222-3333_cooling_start_condition_heat_cool_delay', + 'unit_of_measurement': None, + }) +# --- +# name: test_binary_entities[binary_sensor.test_model_no_heating_in_the_last_24_hours-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + : 'Test Model No heating in the last 24 hours', + }), + 'context': , + 'entity_id': 'binary_sensor.test_model_no_heating_in_the_last_24_hours', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_binary_entities[binary_sensor.test_model_water_warmer_than_cooling_curve-entry] + EntityRegistryEntrySnapshot({ + 'aliases': list([ + None, + ]), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.test_model_water_warmer_than_cooling_curve', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'object_id_base': 'Water warmer than cooling curve', + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Water warmer than cooling curve', + 'platform': 'weheat', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'cooling_start_condition_water_temperature', + 'unique_id': '0000-1111-2222-3333_cooling_start_condition_water_temperature', + 'unit_of_measurement': None, + }) +# --- +# name: test_binary_entities[binary_sensor.test_model_water_warmer_than_cooling_curve-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + : 'Test Model Water warmer than cooling curve', + }), + 'context': , + 'entity_id': 'binary_sensor.test_model_water_warmer_than_cooling_curve', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# ---