diff --git a/homeassistant/components/climacell/const.py b/homeassistant/components/climacell/const.py index bcbd139028a..9e80c769abf 100644 --- a/homeassistant/components/climacell/const.py +++ b/homeassistant/components/climacell/const.py @@ -170,9 +170,6 @@ class ClimaCellSensorEntityDescription(SensorEntityDescription): "`unit_imperial` and `unit_metric` both need to be None or both need " "to be defined." ) - if self.name is None: # pragma: no cover - raise TypeError - self.name_ = self.name CC_SENSOR_TYPES = ( diff --git a/homeassistant/components/climacell/sensor.py b/homeassistant/components/climacell/sensor.py index d67cde18e0b..3f96dd9e02c 100644 --- a/homeassistant/components/climacell/sensor.py +++ b/homeassistant/components/climacell/sensor.py @@ -65,7 +65,7 @@ class BaseClimaCellSensorEntity(ClimaCellEntity, SensorEntity): self._attr_entity_registry_enabled_default = False self._attr_name = f"{self._config_entry.data[CONF_NAME]} - {description.name}" self._attr_unique_id = ( - f"{self._config_entry.unique_id}_{slugify(description.name_)}" + f"{self._config_entry.unique_id}_{slugify(description.name)}" ) self._attr_extra_state_attributes = {ATTR_ATTRIBUTION: self.attribution} self._attr_unit_of_measurement = ( diff --git a/homeassistant/components/melcloud/sensor.py b/homeassistant/components/melcloud/sensor.py index 104f463306f..6c303e8e3c3 100644 --- a/homeassistant/components/melcloud/sensor.py +++ b/homeassistant/components/melcloud/sensor.py @@ -22,21 +22,19 @@ from .const import DOMAIN @dataclass -class MelcloudSensorEntityDescription(SensorEntityDescription): +class MelcloudRequiredKeysMixin: + """Mixin for required keys.""" + + value_fn: Callable[[Any], float] + enabled: Callable[[Any], bool] + + +@dataclass +class MelcloudSensorEntityDescription( + SensorEntityDescription, MelcloudRequiredKeysMixin +): """Describes Melcloud sensor entity.""" - _value_fn: Callable[[Any], float] | None = None - _enabled: Callable[[Any], bool] | None = None - - def __post_init__(self) -> None: - """Ensure all required fields are set.""" - if self._value_fn is None: # pragma: no cover - raise TypeError - if self._enabled is None: # pragma: no cover - raise TypeError - self.value_fn = self._value_fn - self.enabled = self._enabled - ATA_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = ( MelcloudSensorEntityDescription( @@ -45,8 +43,8 @@ ATA_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = ( icon="mdi:thermometer", unit_of_measurement=TEMP_CELSIUS, device_class=DEVICE_CLASS_TEMPERATURE, - _value_fn=lambda x: x.device.room_temperature, - _enabled=lambda x: True, + value_fn=lambda x: x.device.room_temperature, + enabled=lambda x: True, ), MelcloudSensorEntityDescription( key="energy", @@ -54,8 +52,8 @@ ATA_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = ( icon="mdi:factory", unit_of_measurement=ENERGY_KILO_WATT_HOUR, device_class=DEVICE_CLASS_ENERGY, - _value_fn=lambda x: x.device.total_energy_consumed, - _enabled=lambda x: x.device.has_energy_consumed_meter, + value_fn=lambda x: x.device.total_energy_consumed, + enabled=lambda x: x.device.has_energy_consumed_meter, ), ) ATW_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = ( @@ -65,8 +63,8 @@ ATW_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = ( icon="mdi:thermometer", unit_of_measurement=TEMP_CELSIUS, device_class=DEVICE_CLASS_TEMPERATURE, - _value_fn=lambda x: x.device.outside_temperature, - _enabled=lambda x: True, + value_fn=lambda x: x.device.outside_temperature, + enabled=lambda x: True, ), MelcloudSensorEntityDescription( key="tank_temperature", @@ -74,8 +72,8 @@ ATW_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = ( icon="mdi:thermometer", unit_of_measurement=TEMP_CELSIUS, device_class=DEVICE_CLASS_TEMPERATURE, - _value_fn=lambda x: x.device.tank_temperature, - _enabled=lambda x: True, + value_fn=lambda x: x.device.tank_temperature, + enabled=lambda x: True, ), ) ATW_ZONE_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = ( @@ -85,8 +83,8 @@ ATW_ZONE_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = ( icon="mdi:thermometer", unit_of_measurement=TEMP_CELSIUS, device_class=DEVICE_CLASS_TEMPERATURE, - _value_fn=lambda zone: zone.room_temperature, - _enabled=lambda x: True, + value_fn=lambda zone: zone.room_temperature, + enabled=lambda x: True, ), MelcloudSensorEntityDescription( key="flow_temperature", @@ -94,8 +92,8 @@ ATW_ZONE_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = ( icon="mdi:thermometer", unit_of_measurement=TEMP_CELSIUS, device_class=DEVICE_CLASS_TEMPERATURE, - _value_fn=lambda zone: zone.flow_temperature, - _enabled=lambda x: True, + value_fn=lambda zone: zone.flow_temperature, + enabled=lambda x: True, ), MelcloudSensorEntityDescription( key="return_temperature", @@ -103,8 +101,8 @@ ATW_ZONE_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = ( icon="mdi:thermometer", unit_of_measurement=TEMP_CELSIUS, device_class=DEVICE_CLASS_TEMPERATURE, - _value_fn=lambda zone: zone.return_temperature, - _enabled=lambda x: True, + value_fn=lambda zone: zone.return_temperature, + enabled=lambda x: True, ), ) diff --git a/homeassistant/components/netatmo/sensor.py b/homeassistant/components/netatmo/sensor.py index 58d4532e40d..14128aefa6a 100644 --- a/homeassistant/components/netatmo/sensor.py +++ b/homeassistant/components/netatmo/sensor.py @@ -62,23 +62,22 @@ SUPPORTED_PUBLIC_SENSOR_TYPES: tuple[str, ...] = ( @dataclass -class NetatmoSensorEntityDescription(SensorEntityDescription): +class NetatmoRequiredKeysMixin: + """Mixin for required keys.""" + + netatmo_name: str + + +@dataclass +class NetatmoSensorEntityDescription(SensorEntityDescription, NetatmoRequiredKeysMixin): """Describes Netatmo sensor entity.""" - _netatmo_name: str | None = None - - def __post_init__(self) -> None: - """Ensure all required attributes are set.""" - if self._netatmo_name is None: # pragma: no cover - raise TypeError - self.netatmo_name = self._netatmo_name - SENSOR_TYPES: tuple[NetatmoSensorEntityDescription, ...] = ( NetatmoSensorEntityDescription( key="temperature", name="Temperature", - _netatmo_name="Temperature", + netatmo_name="Temperature", entity_registry_enabled_default=True, unit_of_measurement=TEMP_CELSIUS, device_class=DEVICE_CLASS_TEMPERATURE, @@ -86,14 +85,14 @@ SENSOR_TYPES: tuple[NetatmoSensorEntityDescription, ...] = ( NetatmoSensorEntityDescription( key="temp_trend", name="Temperature trend", - _netatmo_name="temp_trend", + netatmo_name="temp_trend", entity_registry_enabled_default=False, icon="mdi:trending-up", ), NetatmoSensorEntityDescription( key="co2", name="CO2", - _netatmo_name="CO2", + netatmo_name="CO2", unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION, entity_registry_enabled_default=True, device_class=DEVICE_CLASS_CO2, @@ -101,7 +100,7 @@ SENSOR_TYPES: tuple[NetatmoSensorEntityDescription, ...] = ( NetatmoSensorEntityDescription( key="pressure", name="Pressure", - _netatmo_name="Pressure", + netatmo_name="Pressure", entity_registry_enabled_default=True, unit_of_measurement=PRESSURE_MBAR, device_class=DEVICE_CLASS_PRESSURE, @@ -109,14 +108,14 @@ SENSOR_TYPES: tuple[NetatmoSensorEntityDescription, ...] = ( NetatmoSensorEntityDescription( key="pressure_trend", name="Pressure trend", - _netatmo_name="pressure_trend", + netatmo_name="pressure_trend", entity_registry_enabled_default=False, icon="mdi:trending-up", ), NetatmoSensorEntityDescription( key="noise", name="Noise", - _netatmo_name="Noise", + netatmo_name="Noise", entity_registry_enabled_default=True, unit_of_measurement=SOUND_PRESSURE_DB, icon="mdi:volume-high", @@ -124,7 +123,7 @@ SENSOR_TYPES: tuple[NetatmoSensorEntityDescription, ...] = ( NetatmoSensorEntityDescription( key="humidity", name="Humidity", - _netatmo_name="Humidity", + netatmo_name="Humidity", entity_registry_enabled_default=True, unit_of_measurement=PERCENTAGE, device_class=DEVICE_CLASS_HUMIDITY, @@ -132,7 +131,7 @@ SENSOR_TYPES: tuple[NetatmoSensorEntityDescription, ...] = ( NetatmoSensorEntityDescription( key="rain", name="Rain", - _netatmo_name="Rain", + netatmo_name="Rain", entity_registry_enabled_default=True, unit_of_measurement=LENGTH_MILLIMETERS, icon="mdi:weather-rainy", @@ -140,7 +139,7 @@ SENSOR_TYPES: tuple[NetatmoSensorEntityDescription, ...] = ( NetatmoSensorEntityDescription( key="sum_rain_1", name="Rain last hour", - _netatmo_name="sum_rain_1", + netatmo_name="sum_rain_1", entity_registry_enabled_default=False, unit_of_measurement=LENGTH_MILLIMETERS, icon="mdi:weather-rainy", @@ -148,7 +147,7 @@ SENSOR_TYPES: tuple[NetatmoSensorEntityDescription, ...] = ( NetatmoSensorEntityDescription( key="sum_rain_24", name="Rain today", - _netatmo_name="sum_rain_24", + netatmo_name="sum_rain_24", entity_registry_enabled_default=True, unit_of_measurement=LENGTH_MILLIMETERS, icon="mdi:weather-rainy", @@ -156,7 +155,7 @@ SENSOR_TYPES: tuple[NetatmoSensorEntityDescription, ...] = ( NetatmoSensorEntityDescription( key="battery_percent", name="Battery Percent", - _netatmo_name="battery_percent", + netatmo_name="battery_percent", entity_registry_enabled_default=True, unit_of_measurement=PERCENTAGE, device_class=DEVICE_CLASS_BATTERY, @@ -164,14 +163,14 @@ SENSOR_TYPES: tuple[NetatmoSensorEntityDescription, ...] = ( NetatmoSensorEntityDescription( key="windangle", name="Direction", - _netatmo_name="WindAngle", + netatmo_name="WindAngle", entity_registry_enabled_default=True, icon="mdi:compass-outline", ), NetatmoSensorEntityDescription( key="windangle_value", name="Angle", - _netatmo_name="WindAngle", + netatmo_name="WindAngle", entity_registry_enabled_default=False, unit_of_measurement=DEGREE, icon="mdi:compass-outline", @@ -179,7 +178,7 @@ SENSOR_TYPES: tuple[NetatmoSensorEntityDescription, ...] = ( NetatmoSensorEntityDescription( key="windstrength", name="Wind Strength", - _netatmo_name="WindStrength", + netatmo_name="WindStrength", entity_registry_enabled_default=True, unit_of_measurement=SPEED_KILOMETERS_PER_HOUR, icon="mdi:weather-windy", @@ -187,14 +186,14 @@ SENSOR_TYPES: tuple[NetatmoSensorEntityDescription, ...] = ( NetatmoSensorEntityDescription( key="gustangle", name="Gust Direction", - _netatmo_name="GustAngle", + netatmo_name="GustAngle", entity_registry_enabled_default=False, icon="mdi:compass-outline", ), NetatmoSensorEntityDescription( key="gustangle_value", name="Gust Angle", - _netatmo_name="GustAngle", + netatmo_name="GustAngle", entity_registry_enabled_default=False, unit_of_measurement=DEGREE, icon="mdi:compass-outline", @@ -202,7 +201,7 @@ SENSOR_TYPES: tuple[NetatmoSensorEntityDescription, ...] = ( NetatmoSensorEntityDescription( key="guststrength", name="Gust Strength", - _netatmo_name="GustStrength", + netatmo_name="GustStrength", entity_registry_enabled_default=False, unit_of_measurement=SPEED_KILOMETERS_PER_HOUR, icon="mdi:weather-windy", @@ -210,21 +209,21 @@ SENSOR_TYPES: tuple[NetatmoSensorEntityDescription, ...] = ( NetatmoSensorEntityDescription( key="reachable", name="Reachability", - _netatmo_name="reachable", + netatmo_name="reachable", entity_registry_enabled_default=False, icon="mdi:signal", ), NetatmoSensorEntityDescription( key="rf_status", name="Radio", - _netatmo_name="rf_status", + netatmo_name="rf_status", entity_registry_enabled_default=False, icon="mdi:signal", ), NetatmoSensorEntityDescription( key="rf_status_lvl", name="Radio Level", - _netatmo_name="rf_status", + netatmo_name="rf_status", entity_registry_enabled_default=False, unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT, device_class=DEVICE_CLASS_SIGNAL_STRENGTH, @@ -232,14 +231,14 @@ SENSOR_TYPES: tuple[NetatmoSensorEntityDescription, ...] = ( NetatmoSensorEntityDescription( key="wifi_status", name="Wifi", - _netatmo_name="wifi_status", + netatmo_name="wifi_status", entity_registry_enabled_default=False, icon="mdi:wifi", ), NetatmoSensorEntityDescription( key="wifi_status_lvl", name="Wifi Level", - _netatmo_name="wifi_status", + netatmo_name="wifi_status", entity_registry_enabled_default=False, unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT, device_class=DEVICE_CLASS_SIGNAL_STRENGTH, @@ -247,7 +246,7 @@ SENSOR_TYPES: tuple[NetatmoSensorEntityDescription, ...] = ( NetatmoSensorEntityDescription( key="health_idx", name="Health", - _netatmo_name="health_idx", + netatmo_name="health_idx", entity_registry_enabled_default=True, icon="mdi:cloud", ), diff --git a/homeassistant/util/__init__.py b/homeassistant/util/__init__.py index bf11103b3fa..60f3e409f06 100644 --- a/homeassistant/util/__init__.py +++ b/homeassistant/util/__init__.py @@ -79,9 +79,9 @@ def sanitize_path(path: str) -> str: return path -def slugify(text: str, *, separator: str = "_") -> str: +def slugify(text: str | None, *, separator: str = "_") -> str: """Slugify a given text.""" - if text == "": + if text == "" or text is None: return "" slug = unicode_slug.slugify(text, separator=separator) return "unknown" if slug == "" else slug diff --git a/tests/util/test_init.py b/tests/util/test_init.py index 34e95013b26..7a4f13cb767 100644 --- a/tests/util/test_init.py +++ b/tests/util/test_init.py @@ -74,6 +74,7 @@ def test_slugify(): assert util.slugify("$$$") == "unknown" assert util.slugify("$something") == "something" assert util.slugify("") == "" + assert util.slugify(None) == "" def test_repr_helper():