mirror of
https://github.com/home-assistant/core.git
synced 2026-02-15 07:36:16 +00:00
Prefer explicit DeviceClass over hint in entity_id in homekit (#152507)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
This commit is contained in:
@@ -220,31 +220,33 @@ def get_accessory( # noqa: C901
|
||||
a_type = "TemperatureSensor"
|
||||
elif device_class == SensorDeviceClass.HUMIDITY and unit == PERCENTAGE:
|
||||
a_type = "HumiditySensor"
|
||||
elif (
|
||||
device_class == SensorDeviceClass.PM10
|
||||
or SensorDeviceClass.PM10 in state.entity_id
|
||||
):
|
||||
elif device_class == SensorDeviceClass.PM10:
|
||||
a_type = "PM10Sensor"
|
||||
elif (
|
||||
device_class == SensorDeviceClass.PM25
|
||||
or SensorDeviceClass.PM25 in state.entity_id
|
||||
):
|
||||
elif device_class == SensorDeviceClass.PM25:
|
||||
a_type = "PM25Sensor"
|
||||
elif device_class == SensorDeviceClass.NITROGEN_DIOXIDE:
|
||||
a_type = "NitrogenDioxideSensor"
|
||||
elif device_class == SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS:
|
||||
a_type = "VolatileOrganicCompoundsSensor"
|
||||
elif (
|
||||
device_class == SensorDeviceClass.GAS
|
||||
or SensorDeviceClass.GAS in state.entity_id
|
||||
):
|
||||
elif device_class == SensorDeviceClass.GAS:
|
||||
a_type = "AirQualitySensor"
|
||||
elif device_class == SensorDeviceClass.CO:
|
||||
a_type = "CarbonMonoxideSensor"
|
||||
elif device_class == SensorDeviceClass.CO2 or "co2" in state.entity_id:
|
||||
elif device_class == SensorDeviceClass.CO2:
|
||||
a_type = "CarbonDioxideSensor"
|
||||
elif device_class == SensorDeviceClass.ILLUMINANCE or unit == LIGHT_LUX:
|
||||
a_type = "LightSensor"
|
||||
|
||||
# Fallbacks based on entity_id
|
||||
elif SensorDeviceClass.PM10 in state.entity_id:
|
||||
a_type = "PM10Sensor"
|
||||
elif SensorDeviceClass.PM25 in state.entity_id:
|
||||
a_type = "PM25Sensor"
|
||||
elif SensorDeviceClass.GAS in state.entity_id:
|
||||
a_type = "AirQualitySensor"
|
||||
elif "co2" in state.entity_id:
|
||||
a_type = "CarbonDioxideSensor"
|
||||
|
||||
else:
|
||||
_LOGGER.debug(
|
||||
"%s: Unsupported sensor type (device_class=%s) (unit=%s)",
|
||||
|
||||
@@ -20,6 +20,13 @@ from homeassistant.components.homekit.const import (
|
||||
TYPE_SWITCH,
|
||||
TYPE_VALVE,
|
||||
)
|
||||
from homeassistant.components.homekit.type_sensors import (
|
||||
AirQualitySensor,
|
||||
CarbonDioxideSensor,
|
||||
PM10Sensor,
|
||||
PM25Sensor,
|
||||
TemperatureSensor,
|
||||
)
|
||||
from homeassistant.components.media_player import (
|
||||
MediaPlayerDeviceClass,
|
||||
MediaPlayerEntityFeature,
|
||||
@@ -42,6 +49,20 @@ from homeassistant.const import (
|
||||
from homeassistant.core import State
|
||||
|
||||
|
||||
def get_identified_type(entity_id, attrs, config=None):
|
||||
"""Helper to return the accessory type name selected by get_accessory."""
|
||||
|
||||
def passthrough(type: type):
|
||||
return lambda *args, **kwargs: type
|
||||
|
||||
# Patch TYPES so that get_accessory returns a type instead of an instance.
|
||||
with patch.dict(
|
||||
TYPES, {type_name: passthrough(v) for type_name, v in TYPES.items()}
|
||||
):
|
||||
entity_state = State(entity_id, "irrelevant", attrs)
|
||||
return get_accessory(None, None, entity_state, 2, config or {})
|
||||
|
||||
|
||||
def test_not_supported(caplog: pytest.LogCaptureFixture) -> None:
|
||||
"""Test if none is returned if entity isn't supported."""
|
||||
# not supported entity
|
||||
@@ -425,3 +446,58 @@ def test_type_camera(type_name, entity_id, state, attrs) -> None:
|
||||
entity_state = State(entity_id, state, attrs)
|
||||
get_accessory(None, None, entity_state, 2, {})
|
||||
assert mock_type.called
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("expected_type", "entity_id", "attrs"),
|
||||
[
|
||||
(
|
||||
PM10Sensor,
|
||||
"sensor.air_quality_pm25",
|
||||
{ATTR_DEVICE_CLASS: SensorDeviceClass.PM10},
|
||||
),
|
||||
(
|
||||
PM25Sensor,
|
||||
"sensor.air_quality_pm10",
|
||||
{ATTR_DEVICE_CLASS: SensorDeviceClass.PM25},
|
||||
),
|
||||
(
|
||||
AirQualitySensor,
|
||||
"sensor.co2_sensor",
|
||||
{ATTR_DEVICE_CLASS: SensorDeviceClass.GAS},
|
||||
),
|
||||
(
|
||||
CarbonDioxideSensor,
|
||||
"sensor.air_quality_gas",
|
||||
{ATTR_DEVICE_CLASS: SensorDeviceClass.CO2},
|
||||
),
|
||||
(
|
||||
TemperatureSensor,
|
||||
"sensor.random_sensor",
|
||||
{ATTR_DEVICE_CLASS: SensorDeviceClass.TEMPERATURE},
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_explicit_device_class_takes_precedence(
|
||||
expected_type, entity_id, attrs
|
||||
) -> None:
|
||||
"""Test that explicit device_class takes precedence over entity_id hints."""
|
||||
identified_type = get_identified_type(entity_id, attrs=attrs)
|
||||
assert identified_type == expected_type
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("expected_type", "entity_id", "attrs"),
|
||||
[
|
||||
(PM10Sensor, "sensor.air_quality_pm10", {}),
|
||||
(PM25Sensor, "sensor.air_quality_pm25", {}),
|
||||
(AirQualitySensor, "sensor.air_quality_gas", {}),
|
||||
(CarbonDioxideSensor, "sensor.airmeter_co2", {}),
|
||||
],
|
||||
)
|
||||
def test_entity_id_fallback_when_no_device_class(
|
||||
expected_type, entity_id, attrs
|
||||
) -> None:
|
||||
"""Test that entity_id is used as fallback when device_class is not set."""
|
||||
identified_type = get_identified_type(entity_id, attrs=attrs)
|
||||
assert identified_type == expected_type
|
||||
|
||||
Reference in New Issue
Block a user