88from asyncsleepiq import SleepIQBed , SleepIQSleeper
99
1010from homeassistant .components .sensor import (
11+ SensorDeviceClass ,
1112 SensorEntity ,
1213 SensorEntityDescription ,
1314 SensorStateClass ,
1415)
1516from homeassistant .config_entries import ConfigEntry
17+ from homeassistant .const import UnitOfTime
1618from homeassistant .core import HomeAssistant , callback
1719from homeassistant .helpers .entity_platform import AddConfigEntryEntitiesCallback
1820
19- from .const import DOMAIN , PRESSURE , SLEEP_NUMBER
20- from .coordinator import SleepIQData , SleepIQDataUpdateCoordinator
21+ from .const import (
22+ DOMAIN ,
23+ HEART_RATE ,
24+ HRV ,
25+ PRESSURE ,
26+ RESPIRATORY_RATE ,
27+ SLEEP_DURATION ,
28+ SLEEP_NUMBER ,
29+ SLEEP_SCORE ,
30+ )
31+ from .coordinator import (
32+ SleepIQData ,
33+ SleepIQDataUpdateCoordinator ,
34+ SleepIQSleepDataCoordinator ,
35+ )
2136from .entity import SleepIQSleeperEntity
2237
2338
@@ -28,7 +43,7 @@ class SleepIQSensorEntityDescription(SensorEntityDescription):
2843 value_fn : Callable [[SleepIQSleeper ], float | int | None ]
2944
3045
31- SENSORS : tuple [SleepIQSensorEntityDescription , ...] = (
46+ BED_SENSORS : tuple [SleepIQSensorEntityDescription , ...] = (
3247 SleepIQSensorEntityDescription (
3348 key = PRESSURE ,
3449 translation_key = "pressure" ,
@@ -43,6 +58,57 @@ class SleepIQSensorEntityDescription(SensorEntityDescription):
4358 ),
4459)
4560
61+ SLEEP_HEALTH_SENSORS : tuple [SleepIQSensorEntityDescription , ...] = (
62+ SleepIQSensorEntityDescription (
63+ key = SLEEP_SCORE ,
64+ translation_key = "sleep_score" ,
65+ state_class = SensorStateClass .MEASUREMENT ,
66+ native_unit_of_measurement = "score" ,
67+ value_fn = lambda sleeper : (
68+ sleeper .sleep_data .sleep_score if sleeper .sleep_data else None
69+ ),
70+ ),
71+ SleepIQSensorEntityDescription (
72+ key = SLEEP_DURATION ,
73+ translation_key = "sleep_duration" ,
74+ device_class = SensorDeviceClass .DURATION ,
75+ state_class = SensorStateClass .MEASUREMENT ,
76+ native_unit_of_measurement = UnitOfTime .HOURS ,
77+ suggested_display_precision = 1 ,
78+ value_fn = lambda sleeper : (
79+ round (sleeper .sleep_data .duration / 3600 , 1 )
80+ if sleeper .sleep_data and sleeper .sleep_data .duration
81+ else None
82+ ),
83+ ),
84+ SleepIQSensorEntityDescription (
85+ key = HEART_RATE ,
86+ translation_key = "heart_rate_avg" ,
87+ state_class = SensorStateClass .MEASUREMENT ,
88+ native_unit_of_measurement = "bpm" ,
89+ value_fn = lambda sleeper : (
90+ sleeper .sleep_data .heart_rate if sleeper .sleep_data else None
91+ ),
92+ ),
93+ SleepIQSensorEntityDescription (
94+ key = RESPIRATORY_RATE ,
95+ translation_key = "respiratory_rate_avg" ,
96+ state_class = SensorStateClass .MEASUREMENT ,
97+ native_unit_of_measurement = "brpm" ,
98+ value_fn = lambda sleeper : (
99+ sleeper .sleep_data .respiratory_rate if sleeper .sleep_data else None
100+ ),
101+ ),
102+ SleepIQSensorEntityDescription (
103+ key = HRV ,
104+ translation_key = "hrv" ,
105+ device_class = SensorDeviceClass .DURATION ,
106+ state_class = SensorStateClass .MEASUREMENT ,
107+ native_unit_of_measurement = UnitOfTime .MILLISECONDS ,
108+ value_fn = lambda sleeper : sleeper .sleep_data .hrv if sleeper .sleep_data else None ,
109+ ),
110+ )
111+
46112
47113async def async_setup_entry (
48114 hass : HomeAssistant ,
@@ -51,24 +117,37 @@ async def async_setup_entry(
51117) -> None :
52118 """Set up the SleepIQ bed sensors."""
53119 data : SleepIQData = hass .data [DOMAIN ][entry .entry_id ]
54- async_add_entities (
120+
121+ entities : list [SensorEntity ] = []
122+
123+ entities .extend (
55124 SleepIQSensorEntity (data .data_coordinator , bed , sleeper , description )
56125 for bed in data .client .beds .values ()
57126 for sleeper in bed .sleepers
58- for description in SENSORS
127+ for description in BED_SENSORS
59128 )
60129
130+ entities .extend (
131+ SleepIQSensorEntity (data .sleep_data_coordinator , bed , sleeper , description )
132+ for bed in data .client .beds .values ()
133+ for sleeper in bed .sleepers
134+ for description in SLEEP_HEALTH_SENSORS
135+ )
136+
137+ async_add_entities (entities )
138+
61139
62140class SleepIQSensorEntity (
63- SleepIQSleeperEntity [SleepIQDataUpdateCoordinator ], SensorEntity
141+ SleepIQSleeperEntity [SleepIQDataUpdateCoordinator | SleepIQSleepDataCoordinator ],
142+ SensorEntity ,
64143):
65144 """Representation of a SleepIQ sensor."""
66145
67146 entity_description : SleepIQSensorEntityDescription
68147
69148 def __init__ (
70149 self ,
71- coordinator : SleepIQDataUpdateCoordinator ,
150+ coordinator : SleepIQDataUpdateCoordinator | SleepIQSleepDataCoordinator ,
72151 bed : SleepIQBed ,
73152 sleeper : SleepIQSleeper ,
74153 description : SleepIQSensorEntityDescription ,
0 commit comments