mirror of
https://github.com/home-assistant/core.git
synced 2026-04-02 00:20:30 +01:00
Fix KeyError for device temperature sensor in Unifi integration (#166410)
This commit is contained in:
@@ -300,13 +300,22 @@ def make_wan_latency_sensors() -> tuple[UnifiSensorEntityDescription, ...]:
|
||||
@callback
|
||||
def async_device_temperatures_value_fn(
|
||||
temperature_name: str, hub: UnifiHub, device: Device
|
||||
) -> float:
|
||||
) -> float | None:
|
||||
"""Retrieve the temperature of the device."""
|
||||
return_value: float = 0
|
||||
if device.temperatures:
|
||||
temperature = _device_temperature(temperature_name, device.temperatures)
|
||||
return_value = temperature if temperature is not None else 0
|
||||
return return_value
|
||||
return _device_temperature(temperature_name, device.temperatures)
|
||||
return None
|
||||
|
||||
|
||||
@callback
|
||||
def async_device_temperatures_available_fn(
|
||||
temperature_name: str, hub: UnifiHub, obj_id: str
|
||||
) -> bool:
|
||||
"""Determine if a device temperature has a value."""
|
||||
device = hub.api.devices[obj_id]
|
||||
if not async_device_available_fn(hub, obj_id):
|
||||
return False
|
||||
return _device_temperature(temperature_name, device.temperatures or []) is not None
|
||||
|
||||
|
||||
@callback
|
||||
@@ -315,7 +324,11 @@ def async_device_temperatures_supported_fn(
|
||||
) -> bool:
|
||||
"""Determine if an device have a temperatures."""
|
||||
if (device := hub.api.devices[obj_id]) and device.temperatures:
|
||||
return _device_temperature(temperature_name, device.temperatures) is not None
|
||||
return any(
|
||||
temperature_name in temperature["name"]
|
||||
for temperature in device.temperatures
|
||||
)
|
||||
|
||||
return False
|
||||
|
||||
|
||||
@@ -326,7 +339,8 @@ def _device_temperature(
|
||||
"""Return the temperature of the device."""
|
||||
for temperature in temperatures:
|
||||
if temperature_name in temperature["name"]:
|
||||
return temperature["value"]
|
||||
if (value := temperature.get("value")) is not None:
|
||||
return value
|
||||
return None
|
||||
|
||||
|
||||
@@ -344,7 +358,7 @@ def make_device_temperatur_sensors() -> tuple[UnifiSensorEntityDescription, ...]
|
||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||
entity_registry_enabled_default=False,
|
||||
api_handler_fn=lambda api: api.devices,
|
||||
available_fn=async_device_available_fn,
|
||||
available_fn=partial(async_device_temperatures_available_fn, name),
|
||||
device_info_fn=async_device_device_info_fn,
|
||||
name_fn=lambda device: f"{device.name} {name} Temperature",
|
||||
object_fn=lambda api, obj_id: api.devices[obj_id],
|
||||
|
||||
@@ -1774,6 +1774,75 @@ async def test_device_temperatures(
|
||||
assert hass.states.get(entity_id).state == updated_state
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"device_payload",
|
||||
[
|
||||
[
|
||||
{
|
||||
"board_rev": 3,
|
||||
"device_id": "mock-id",
|
||||
"has_fan": True,
|
||||
"fan_level": 0,
|
||||
"ip": "10.0.1.1",
|
||||
"last_seen": 1562600145,
|
||||
"mac": "00:00:00:00:01:01",
|
||||
"model": "US16P150",
|
||||
"name": "Device",
|
||||
"next_interval": 20,
|
||||
"overheating": True,
|
||||
"state": 1,
|
||||
"type": "usw",
|
||||
"upgradable": True,
|
||||
"uptime": 60,
|
||||
"version": "4.0.42.10433",
|
||||
"temperatures": [
|
||||
{"name": "CPU", "type": "cpu", "value": 66.0},
|
||||
],
|
||||
}
|
||||
]
|
||||
],
|
||||
)
|
||||
@pytest.mark.usefixtures("config_entry_setup")
|
||||
async def test_device_temperature_with_missing_value(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
mock_websocket_message,
|
||||
device_payload: list[dict[str, Any]],
|
||||
) -> None:
|
||||
"""Verify that device temperatures sensors are working as expected."""
|
||||
entity_id = "sensor.device_device_cpu_temperature"
|
||||
|
||||
temperature_entity = entity_registry.async_get(entity_id)
|
||||
assert temperature_entity.disabled_by == RegistryEntryDisabler.INTEGRATION
|
||||
|
||||
# Enable entity
|
||||
entity_registry.async_update_entity(entity_id=entity_id, disabled_by=None)
|
||||
|
||||
await hass.async_block_till_done()
|
||||
|
||||
async_fire_time_changed(
|
||||
hass,
|
||||
dt_util.utcnow() + timedelta(seconds=RELOAD_AFTER_UPDATE_DELAY + 1),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Verify sensor state
|
||||
assert hass.states.get(entity_id).state == "66.0"
|
||||
|
||||
# Remove temperature value from payload
|
||||
device = deepcopy(device_payload[0])
|
||||
device["temperatures"][0].pop("value")
|
||||
|
||||
mock_websocket_message(message=MessageKey.DEVICE, data=device)
|
||||
|
||||
assert hass.states.get(entity_id).state == STATE_UNAVAILABLE
|
||||
|
||||
# Send original payload again to verify sensor recovers
|
||||
mock_websocket_message(message=MessageKey.DEVICE, data=device_payload[0])
|
||||
|
||||
assert hass.states.get(entity_id).state == "66.0"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"device_payload",
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user