1 """Support for a ScreenLogic Sensor."""
3 from collections.abc
import Callable
8 from screenlogicpy.const.data
import ATTR, DEVICE, GROUP, VALUE
9 from screenlogicpy.const.msg
import CODE
10 from screenlogicpy.device_const.chemistry
import DOSE_STATE
11 from screenlogicpy.device_const.pump
import PUMP_TYPE
12 from screenlogicpy.device_const.system
import EQUIPMENT_FLAG
15 DOMAIN
as SENSOR_DOMAIN,
18 SensorEntityDescription,
25 from .coordinator
import ScreenlogicDataUpdateCoordinator
28 ScreenLogicEntityDescription,
29 ScreenLogicPushEntity,
30 ScreenLogicPushEntityDescription,
32 from .types
import ScreenLogicConfigEntry
33 from .util
import cleanup_excluded_entity, get_ha_unit
35 _LOGGER = logging.getLogger(__name__)
38 @dataclasses.dataclass(frozen=True, kw_only=True)
40 SensorEntityDescription, ScreenLogicEntityDescription
42 """Describes a ScreenLogic sensor."""
44 value_mod: Callable[[int | str], int | str] |
None =
None
47 @dataclasses.dataclass(frozen=True, kw_only=True)
49 ScreenLogicSensorDescription, ScreenLogicPushEntityDescription
51 """Describes a ScreenLogic push sensor."""
54 SUPPORTED_CORE_SENSORS = [
56 subscription_code=CODE.STATUS_CHANGED,
57 data_root=(DEVICE.CONTROLLER, GROUP.SENSOR),
58 key=VALUE.AIR_TEMPERATURE,
59 device_class=SensorDeviceClass.TEMPERATURE,
60 state_class=SensorStateClass.MEASUREMENT,
64 SUPPORTED_PUMP_SENSORS = [
66 data_root=(DEVICE.PUMP,),
68 device_class=SensorDeviceClass.POWER,
71 data_root=(DEVICE.PUMP,),
73 enabled_lambda=
lambda type: type != PUMP_TYPE.INTELLIFLO_VS,
76 data_root=(DEVICE.PUMP,),
78 enabled_lambda=
lambda type: type != PUMP_TYPE.INTELLIFLO_VF,
82 SUPPORTED_INTELLICHEM_SENSORS = [
84 subscription_code=CODE.STATUS_CHANGED,
85 data_root=(DEVICE.CONTROLLER, GROUP.SENSOR),
87 state_class=SensorStateClass.MEASUREMENT,
90 subscription_code=CODE.STATUS_CHANGED,
91 data_root=(DEVICE.CONTROLLER, GROUP.SENSOR),
93 state_class=SensorStateClass.MEASUREMENT,
96 subscription_code=CODE.CHEMISTRY_CHANGED,
97 data_root=(DEVICE.INTELLICHEM, GROUP.SENSOR),
99 state_class=SensorStateClass.MEASUREMENT,
102 subscription_code=CODE.CHEMISTRY_CHANGED,
103 data_root=(DEVICE.INTELLICHEM, GROUP.SENSOR),
105 state_class=SensorStateClass.MEASUREMENT,
108 subscription_code=CODE.CHEMISTRY_CHANGED,
109 data_root=(DEVICE.INTELLICHEM, GROUP.SENSOR),
110 key=VALUE.ORP_SUPPLY_LEVEL,
111 state_class=SensorStateClass.MEASUREMENT,
112 value_mod=
lambda val:
int(val) - 1,
115 subscription_code=CODE.CHEMISTRY_CHANGED,
116 data_root=(DEVICE.INTELLICHEM, GROUP.SENSOR),
117 key=VALUE.PH_SUPPLY_LEVEL,
118 state_class=SensorStateClass.MEASUREMENT,
119 value_mod=
lambda val:
int(val) - 1,
122 subscription_code=CODE.CHEMISTRY_CHANGED,
123 data_root=(DEVICE.INTELLICHEM, GROUP.SENSOR),
124 key=VALUE.PH_PROBE_WATER_TEMP,
125 device_class=SensorDeviceClass.TEMPERATURE,
126 state_class=SensorStateClass.MEASUREMENT,
129 subscription_code=CODE.CHEMISTRY_CHANGED,
130 data_root=(DEVICE.INTELLICHEM, GROUP.SENSOR),
131 key=VALUE.SATURATION,
132 state_class=SensorStateClass.MEASUREMENT,
135 subscription_code=CODE.CHEMISTRY_CHANGED,
136 data_root=(DEVICE.INTELLICHEM, GROUP.CONFIGURATION),
137 key=VALUE.CALCIUM_HARDNESS,
138 entity_registry_enabled_default=
False,
141 subscription_code=CODE.CHEMISTRY_CHANGED,
142 data_root=(DEVICE.INTELLICHEM, GROUP.CONFIGURATION),
144 entity_registry_enabled_default=
False,
147 subscription_code=CODE.CHEMISTRY_CHANGED,
148 data_root=(DEVICE.INTELLICHEM, GROUP.CONFIGURATION),
149 key=VALUE.ORP_SETPOINT,
152 subscription_code=CODE.CHEMISTRY_CHANGED,
153 data_root=(DEVICE.INTELLICHEM, GROUP.CONFIGURATION),
154 key=VALUE.PH_SETPOINT,
157 subscription_code=CODE.CHEMISTRY_CHANGED,
158 data_root=(DEVICE.INTELLICHEM, GROUP.CONFIGURATION),
159 key=VALUE.TOTAL_ALKALINITY,
160 entity_registry_enabled_default=
False,
163 subscription_code=CODE.CHEMISTRY_CHANGED,
164 data_root=(DEVICE.INTELLICHEM, GROUP.CONFIGURATION),
165 key=VALUE.SALT_TDS_PPM,
166 entity_registry_enabled_default=
False,
169 subscription_code=CODE.CHEMISTRY_CHANGED,
170 data_root=(DEVICE.INTELLICHEM, GROUP.DOSE_STATUS),
171 key=VALUE.ORP_DOSING_STATE,
172 device_class=SensorDeviceClass.ENUM,
173 options=[
"Dosing",
"Mixing",
"Monitoring"],
174 value_mod=
lambda val: DOSE_STATE(val).title,
177 subscription_code=CODE.CHEMISTRY_CHANGED,
178 data_root=(DEVICE.INTELLICHEM, GROUP.DOSE_STATUS),
179 key=VALUE.ORP_LAST_DOSE_TIME,
180 device_class=SensorDeviceClass.DURATION,
181 state_class=SensorStateClass.TOTAL_INCREASING,
184 subscription_code=CODE.CHEMISTRY_CHANGED,
185 data_root=(DEVICE.INTELLICHEM, GROUP.DOSE_STATUS),
186 key=VALUE.ORP_LAST_DOSE_VOLUME,
187 device_class=SensorDeviceClass.VOLUME,
188 state_class=SensorStateClass.TOTAL_INCREASING,
191 subscription_code=CODE.CHEMISTRY_CHANGED,
192 data_root=(DEVICE.INTELLICHEM, GROUP.DOSE_STATUS),
193 key=VALUE.PH_DOSING_STATE,
194 device_class=SensorDeviceClass.ENUM,
195 options=[
"Dosing",
"Mixing",
"Monitoring"],
196 value_mod=
lambda val: DOSE_STATE(val).title,
199 subscription_code=CODE.CHEMISTRY_CHANGED,
200 data_root=(DEVICE.INTELLICHEM, GROUP.DOSE_STATUS),
201 key=VALUE.PH_LAST_DOSE_TIME,
202 device_class=SensorDeviceClass.DURATION,
203 state_class=SensorStateClass.TOTAL_INCREASING,
206 subscription_code=CODE.CHEMISTRY_CHANGED,
207 data_root=(DEVICE.INTELLICHEM, GROUP.DOSE_STATUS),
208 key=VALUE.PH_LAST_DOSE_VOLUME,
209 device_class=SensorDeviceClass.VOLUME,
210 state_class=SensorStateClass.TOTAL_INCREASING,
214 SUPPORTED_SCG_SENSORS = [
216 data_root=(DEVICE.SCG, GROUP.SENSOR),
218 state_class=SensorStateClass.MEASUREMENT,
221 data_root=(DEVICE.SCG, GROUP.CONFIGURATION),
222 key=VALUE.SUPER_CHLOR_TIMER,
229 config_entry: ScreenLogicConfigEntry,
230 async_add_entities: AddEntitiesCallback,
233 coordinator = config_entry.runtime_data
234 gateway = coordinator.gateway
236 entities: list[ScreenLogicSensor] = [
238 for core_sensor_description
in SUPPORTED_CORE_SENSORS
241 *core_sensor_description.data_root, core_sensor_description.key
247 for pump_index, pump_data
in gateway.get_data(DEVICE.PUMP).items():
248 if not pump_data
or not pump_data.get(VALUE.DATA):
250 pump_type = pump_data[VALUE.TYPE]
251 for proto_pump_sensor_description
in SUPPORTED_PUMP_SENSORS:
252 if not pump_data.get(proto_pump_sensor_description.key):
257 copy(proto_pump_sensor_description),
263 chem_sensor_description: ScreenLogicPushSensorDescription
264 for chem_sensor_description
in SUPPORTED_INTELLICHEM_SENSORS:
265 chem_sensor_data_path = (
266 *chem_sensor_description.data_root,
267 chem_sensor_description.key,
269 if EQUIPMENT_FLAG.INTELLICHEM
not in gateway.equipment_flags:
272 if gateway.get_data(*chem_sensor_data_path):
273 chem_sensor_description = dataclasses.replace(
274 chem_sensor_description, entity_category=EntityCategory.DIAGNOSTIC
278 scg_sensor_description: ScreenLogicSensorDescription
279 for scg_sensor_description
in SUPPORTED_SCG_SENSORS:
280 scg_sensor_data_path = (
281 *scg_sensor_description.data_root,
282 scg_sensor_description.key,
284 if EQUIPMENT_FLAG.CHLORINATOR
not in gateway.equipment_flags:
287 if gateway.get_data(*scg_sensor_data_path):
288 scg_sensor_description = dataclasses.replace(
289 scg_sensor_description, entity_category=EntityCategory.DIAGNOSTIC
297 """Representation of a ScreenLogic sensor entity."""
299 entity_description: ScreenLogicSensorDescription
300 _attr_has_entity_name =
True
304 coordinator: ScreenlogicDataUpdateCoordinator,
305 entity_description: ScreenLogicSensorDescription,
307 """Initialize of the entity."""
308 super().
__init__(coordinator, entity_description)
315 """State of the sensor."""
318 return value_mod(val)
if value_mod
else val
322 """Representation of a ScreenLogic push sensor entity."""
324 entity_description: ScreenLogicPushSensorDescription
328 """Representation of a ScreenLogic pump sensor."""
330 _attr_entity_category = EntityCategory.DIAGNOSTIC
331 _attr_state_class = SensorStateClass.MEASUREMENT
335 coordinator: ScreenlogicDataUpdateCoordinator,
336 entity_description: ScreenLogicSensorDescription,
340 """Initialize of the entity."""
341 entity_description = dataclasses.replace(
342 entity_description, data_root=(DEVICE.PUMP, pump_index)
344 super().
__init__(coordinator, entity_description)
345 if entity_description.enabled_lambda:
347 entity_description.enabled_lambda(pump_type)
_attr_entity_registry_enabled_default
None __init__(self, ScreenlogicDataUpdateCoordinator coordinator, ScreenLogicSensorDescription entity_description, int pump_index, int pump_type)
_attr_native_unit_of_measurement
None __init__(self, ScreenlogicDataUpdateCoordinator coordinator, ScreenLogicSensorDescription entity_description)
str|int|float native_value(self)
web.Response get(self, web.Request request, str config_key)
None async_setup_entry(HomeAssistant hass, ScreenLogicConfigEntry config_entry, AddEntitiesCallback async_add_entities)
None cleanup_excluded_entity(ScreenlogicDataUpdateCoordinator coordinator, str platform_domain, ScreenLogicDataPath data_path)