-
-
Notifications
You must be signed in to change notification settings - Fork 110
/
Copy pathsensor.py
191 lines (152 loc) · 6.3 KB
/
sensor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
from datetime import date
from datetime import datetime
from typing import Optional
from typing import Union
from typing import cast
from homeassistant.components.sensor import SensorDeviceClass
from homeassistant.components.sensor import SensorEntity
from homeassistant.components.sensor import SensorStateClass
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory
from homeassistant.const import PERCENTAGE
from homeassistant.const import UnitOfTemperature
from homeassistant.const import UnitOfTime
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from plugp100.new.components.battery_component import BatteryComponent
from plugp100.new.components.humidity_component import HumidityComponent
from plugp100.new.components.report_mode_component import ReportModeComponent
from plugp100.new.components.temperature_component import TemperatureComponent
from plugp100.new.tapodevice import TapoDevice
from plugp100.responses.temperature_unit import TemperatureUnit
from custom_components.tapo.const import DOMAIN
from custom_components.tapo.coordinators import HassTapoDeviceData
from custom_components.tapo.coordinators import TapoDataCoordinator
from custom_components.tapo.entity import CoordinatedTapoEntity
COMPONENT_MAPPING = {
HumidityComponent: 'HumiditySensor',
TemperatureComponent: 'TemperatureSensor',
ReportModeComponent: 'ReportIntervalDiagnostic',
BatteryComponent: 'BatteryLevelSensor'
}
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
):
data = cast(HassTapoDeviceData, hass.data[DOMAIN][entry.entry_id])
for child_coordinator in data.child_coordinators:
sensors = [
eval(cls)(child_coordinator, child_coordinator.device)
for (component, cls) in COMPONENT_MAPPING.items()
if child_coordinator.device.has_component(component)
]
# temporary workaround to avoid getting battery percentage on not supported devices
if battery := child_coordinator.device.get_component(BatteryComponent):
if battery.battery_percentage == -1:
sensors = list(filter(lambda x: not isinstance(x, BatteryLevelSensor), sensors))
async_add_entities(sensors, True)
class HumiditySensor(CoordinatedTapoEntity, SensorEntity):
_attr_has_entity_name = True
def __init__(
self,
coordinator: TapoDataCoordinator,
device: TapoDevice
):
super().__init__(coordinator, device)
self._attr_name = "Humidity"
@property
def unique_id(self):
return super().unique_id + "_" + self._attr_name.replace(" ", "_")
@property
def device_class(self) -> Optional[str]:
return SensorDeviceClass.HUMIDITY
@property
def state_class(self) -> Optional[str]:
return SensorStateClass.MEASUREMENT
@property
def native_unit_of_measurement(self) -> Optional[str]:
return PERCENTAGE
@property
def native_value(self) -> Union[StateType, date, datetime]:
if humidity := self.device.get_component(HumidityComponent):
return humidity.current_humidity
return None
class TemperatureSensor(CoordinatedTapoEntity, SensorEntity):
_attr_has_entity_name = True
_temperature_component: TemperatureComponent
def __init__(
self,
coordinator: TapoDataCoordinator,
device: TapoDevice
):
super().__init__(coordinator, device)
self._attr_name = "Temperature"
self._temperature_component = device.get_component(TemperatureComponent)
@property
def unique_id(self):
return super().unique_id + "_" + self._attr_name.replace(" ", "_")
@property
def device_class(self) -> Optional[str]:
return SensorDeviceClass.TEMPERATURE
@property
def state_class(self) -> Optional[str]:
return SensorStateClass.MEASUREMENT
@property
def native_unit_of_measurement(self) -> Optional[str]:
if self._temperature_component.temperature_unit == TemperatureUnit.CELSIUS:
return UnitOfTemperature.CELSIUS
elif self._temperature_component.temperature_unit == TemperatureUnit.FAHRENHEIT:
return UnitOfTemperature.FAHRENHEIT
else:
return None
@property
def native_value(self) -> Union[StateType, date, datetime]:
return self._temperature_component.current_temperature
class BatteryLevelSensor(CoordinatedTapoEntity, SensorEntity):
_attr_has_entity_name = True
def __init__(
self,
coordinator: TapoDataCoordinator,
device: TapoDevice
):
super().__init__(coordinator, device)
self._attr_name = "Battery Percentage"
@property
def unique_id(self):
return super().unique_id + "_" + self._attr_name.replace(" ", "_")
@property
def device_class(self) -> Optional[str]:
return SensorDeviceClass.BATTERY
@property
def state_class(self) -> Optional[str]:
return SensorStateClass.MEASUREMENT
@property
def native_unit_of_measurement(self) -> Optional[str]:
return PERCENTAGE
@property
def native_value(self) -> Union[StateType, date, datetime]:
return self.device.get_component(BatteryComponent).battery_percentage
class ReportIntervalDiagnostic(CoordinatedTapoEntity, SensorEntity):
def __init__(
self,
coordinator: TapoDataCoordinator,
device: TapoDevice
):
super().__init__(coordinator, device)
self._attr_name = "Report Interval"
self._attr_entity_category = EntityCategory.DIAGNOSTIC
@property
def unique_id(self):
return super().unique_id + "_" + self._attr_name.replace(" ", "_")
@property
def device_class(self) -> Optional[str]:
return SensorDeviceClass.DURATION
@property
def state_class(self) -> Optional[str]:
return SensorStateClass.TOTAL
@property
def native_unit_of_measurement(self) -> Optional[str]:
return UnitOfTime.SECONDS
@property
def native_value(self) -> Union[StateType, date, datetime]:
return self.device.get_component(ReportModeComponent).report_interval_seconds