1 """Support for OpenUV sensors."""
3 from __future__
import annotations
5 from collections.abc
import Callable, Mapping
6 from dataclasses
import dataclass
12 SensorEntityDescription,
24 TYPE_CURRENT_OZONE_LEVEL,
25 TYPE_CURRENT_UV_INDEX,
26 TYPE_CURRENT_UV_LEVEL,
28 TYPE_SAFE_EXPOSURE_TIME_1,
29 TYPE_SAFE_EXPOSURE_TIME_2,
30 TYPE_SAFE_EXPOSURE_TIME_3,
31 TYPE_SAFE_EXPOSURE_TIME_4,
32 TYPE_SAFE_EXPOSURE_TIME_5,
33 TYPE_SAFE_EXPOSURE_TIME_6,
35 from .coordinator
import OpenUvCoordinator
36 from .entity
import OpenUvEntity
38 ATTR_MAX_UV_TIME =
"time"
41 TYPE_SAFE_EXPOSURE_TIME_1:
"st1",
42 TYPE_SAFE_EXPOSURE_TIME_2:
"st2",
43 TYPE_SAFE_EXPOSURE_TIME_3:
"st3",
44 TYPE_SAFE_EXPOSURE_TIME_4:
"st4",
45 TYPE_SAFE_EXPOSURE_TIME_5:
"st5",
46 TYPE_SAFE_EXPOSURE_TIME_6:
"st6",
52 """Define a friendly UV level label and its minimum UV index."""
58 UV_LABEL_DEFINITIONS = (
59 UvLabel(value=
"extreme", minimum_index=11),
60 UvLabel(value=
"very_high", minimum_index=8),
61 UvLabel(value=
"high", minimum_index=6),
62 UvLabel(value=
"moderate", minimum_index=3),
63 UvLabel(value=
"low", minimum_index=0),
68 """Return the UV label for the UV index."""
70 label
for label
in UV_LABEL_DEFINITIONS
if uv_index >= label.minimum_index
75 @dataclass(frozen=True, kw_only=True)
77 """Define a class that describes OpenUV sensor entities."""
79 value_fn: Callable[[dict[str, Any]], int | str]
82 SENSOR_DESCRIPTIONS = (
84 key=TYPE_CURRENT_OZONE_LEVEL,
85 translation_key=
"current_ozone_level",
86 native_unit_of_measurement=
"du",
87 state_class=SensorStateClass.MEASUREMENT,
88 value_fn=
lambda data: data[
"ozone"],
91 key=TYPE_CURRENT_UV_INDEX,
92 translation_key=
"current_uv_index",
93 native_unit_of_measurement=UV_INDEX,
94 state_class=SensorStateClass.MEASUREMENT,
95 value_fn=
lambda data: data[
"uv"],
98 key=TYPE_CURRENT_UV_LEVEL,
99 translation_key=
"current_uv_level",
100 device_class=SensorDeviceClass.ENUM,
101 options=[label.value
for label
in UV_LABEL_DEFINITIONS],
105 key=TYPE_MAX_UV_INDEX,
106 translation_key=
"max_uv_index",
107 native_unit_of_measurement=UV_INDEX,
108 state_class=SensorStateClass.MEASUREMENT,
109 value_fn=
lambda data: data[
"uv_max"],
112 key=TYPE_SAFE_EXPOSURE_TIME_1,
113 translation_key=
"skin_type_1_safe_exposure_time",
114 native_unit_of_measurement=UnitOfTime.MINUTES,
115 state_class=SensorStateClass.MEASUREMENT,
116 value_fn=
lambda data: data[
"safe_exposure_time"][
117 EXPOSURE_TYPE_MAP[TYPE_SAFE_EXPOSURE_TIME_1]
121 key=TYPE_SAFE_EXPOSURE_TIME_2,
122 translation_key=
"skin_type_2_safe_exposure_time",
123 native_unit_of_measurement=UnitOfTime.MINUTES,
124 state_class=SensorStateClass.MEASUREMENT,
125 value_fn=
lambda data: data[
"safe_exposure_time"][
126 EXPOSURE_TYPE_MAP[TYPE_SAFE_EXPOSURE_TIME_2]
130 key=TYPE_SAFE_EXPOSURE_TIME_3,
131 translation_key=
"skin_type_3_safe_exposure_time",
132 native_unit_of_measurement=UnitOfTime.MINUTES,
133 state_class=SensorStateClass.MEASUREMENT,
134 value_fn=
lambda data: data[
"safe_exposure_time"][
135 EXPOSURE_TYPE_MAP[TYPE_SAFE_EXPOSURE_TIME_3]
139 key=TYPE_SAFE_EXPOSURE_TIME_4,
140 translation_key=
"skin_type_4_safe_exposure_time",
141 native_unit_of_measurement=UnitOfTime.MINUTES,
142 state_class=SensorStateClass.MEASUREMENT,
143 value_fn=
lambda data: data[
"safe_exposure_time"][
144 EXPOSURE_TYPE_MAP[TYPE_SAFE_EXPOSURE_TIME_4]
148 key=TYPE_SAFE_EXPOSURE_TIME_5,
149 translation_key=
"skin_type_5_safe_exposure_time",
150 native_unit_of_measurement=UnitOfTime.MINUTES,
151 state_class=SensorStateClass.MEASUREMENT,
152 value_fn=
lambda data: data[
"safe_exposure_time"][
153 EXPOSURE_TYPE_MAP[TYPE_SAFE_EXPOSURE_TIME_5]
157 key=TYPE_SAFE_EXPOSURE_TIME_6,
158 translation_key=
"skin_type_6_safe_exposure_time",
159 native_unit_of_measurement=UnitOfTime.MINUTES,
160 state_class=SensorStateClass.MEASUREMENT,
161 value_fn=
lambda data: data[
"safe_exposure_time"][
162 EXPOSURE_TYPE_MAP[TYPE_SAFE_EXPOSURE_TIME_6]
169 hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
171 """Set up a OpenUV sensor based on a config entry."""
172 coordinators: dict[str, OpenUvCoordinator] = hass.data[DOMAIN][entry.entry_id]
177 for description
in SENSOR_DESCRIPTIONS
183 """Define a binary sensor for OpenUV."""
185 entity_description: OpenUvSensorEntityDescription
189 """Return entity specific state attributes."""
192 if uv_max_time :=
parse_datetime(self.coordinator.data[
"uv_max_time"]):
193 attrs[ATTR_MAX_UV_TIME] =
as_local(uv_max_time)
198 """Return the sensor value."""
int|str native_value(self)
Mapping[str, Any] extra_state_attributes(self)
datetime|None parse_datetime(str|None value)
None async_setup_entry(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities)
str get_uv_label(int uv_index)
dt.datetime as_local(dt.datetime dattim)