1 """Support for the Philips Hue sensors as a platform."""
3 from __future__
import annotations
6 from datetime
import timedelta
10 from aiohue
import AiohueException, Unauthorized
11 from aiohue.v1.sensors
import TYPE_ZLL_PRESENCE
18 from ..const
import REQUEST_REFRESH_DELAY
19 from .helpers
import remove_devices
20 from .hue_event
import EVENT_CONFIG_MAP
21 from .sensor_device
import GenericHueDevice
23 SENSOR_CONFIG_MAP: dict[str, Any] = {}
24 LOGGER = logging.getLogger(__name__)
29 device_id = aiohue_sensor.uniqueid
30 if device_id
and len(device_id) > 23:
31 device_id = device_id[:23]
36 """Class that handles registering and updating Hue sensor entities.
38 Intended to be a singleton.
44 """Initialize the sensor manager."""
57 request_refresh_debouncer=debounce.Debouncer(
58 bridge.hass, LOGGER, cooldown=REQUEST_REFRESH_DELAY, immediate=
True
63 """Update sensor data."""
65 async
with asyncio.timeout(4):
66 return await self.
bridgebridge.async_request_call(
67 self.
bridgebridge.api.sensors.update
69 except Unauthorized
as err:
70 await self.
bridgebridge.handle_unauthorized_error()
72 except AiohueException
as err:
76 """Register async_add_entities methods for components."""
80 LOGGER.debug(
"Aborting start with %s, waiting for the rest", platform)
84 self.
bridgebridge.reset_jobs.append(
91 """Update sensors from the bridge."""
92 api = self.
bridgebridge.api.sensors
98 primary_sensor_devices = {}
115 if api[item_id].type != TYPE_ZLL_PRESENCE:
118 primary_sensor_devices[
_device_id(api[item_id])] = api[item_id]
123 uniqueid = api[item_id].uniqueid
124 if current.get(uniqueid, self.
current_eventscurrent_events.
get(uniqueid))
is not None:
127 sensor_type = api[item_id].type
130 event_config = EVENT_CONFIG_MAP.get(sensor_type)
131 if event_config
is not None:
132 base_name = api[item_id].name
133 name = event_config[
"name_format"].format(base_name)
134 new_event = event_config[
"class"](api[item_id], name, self.
bridgebridge)
135 self.
bridgebridge.hass.async_create_task(
136 new_event.async_update_device_registry()
140 sensor_config = SENSOR_CONFIG_MAP.get(sensor_type)
141 if sensor_config
is None:
144 base_name = api[item_id].name
145 primary_sensor = primary_sensor_devices.get(
_device_id(api[item_id]))
146 if primary_sensor
is not None:
147 base_name = primary_sensor.name
148 name = sensor_config[
"name_format"].format(base_name)
150 current[uniqueid] = sensor_config[
"class"](
151 api[item_id], name, self.
bridgebridge, primary_sensor=primary_sensor
154 to_add.setdefault(sensor_config[
"platform"], []).append(current[uniqueid])
156 self.
bridgebridge.hass.async_create_task(
159 [value.uniqueid
for value
in api.values()],
164 for platform, value
in to_add.items():
169 """Representation of a Hue sensor."""
175 """Return if sensor is available."""
176 return self.
bridgebridge.sensor_manager.coordinator.last_update_success
and (
179 or self.
sensorsensor.config.get(
"reachable",
True)
184 """Return the state class of this entity, from STATE_CLASSES, if any."""
185 return SensorStateClass.MEASUREMENT
188 """When entity is added to hass."""
190 self.async_on_remove(
191 self.
bridgebridge.sensor_manager.coordinator.async_add_listener(
192 self.async_write_ha_state
197 """Update the entity.
199 Only used by the generic entity update service.
201 await self.
bridgebridge.sensor_manager.coordinator.async_request_refresh()
205 """Representation of a Hue-brand, physical sensor."""
209 """Return the device state attributes."""
210 return {
"battery_level": self.
sensorsensor.battery}
def async_added_to_hass(self)
def extra_state_attributes(self)
def async_register_component(self, platform, async_add_entities)
def __init__(self, bridge)
def async_update_items(self)
def async_update_data(self)
web.Response get(self, web.Request request, str config_key)
def remove_devices(bridge, api_ids, current)
def _device_id(aiohue_sensor)
None async_add_listener(HomeAssistant hass, Callable[[], None] listener)