1 """Platform to control a Zehnder ComfoAir Q350/450/600 ventilation unit."""
3 from __future__
import annotations
5 from dataclasses
import dataclass
8 from pycomfoconnect
import (
11 SENSOR_DAYS_TO_REPLACE_FILTER,
12 SENSOR_FAN_EXHAUST_DUTY,
13 SENSOR_FAN_EXHAUST_FLOW,
14 SENSOR_FAN_EXHAUST_SPEED,
15 SENSOR_FAN_SUPPLY_DUTY,
16 SENSOR_FAN_SUPPLY_FLOW,
17 SENSOR_FAN_SUPPLY_SPEED,
18 SENSOR_HUMIDITY_EXHAUST,
19 SENSOR_HUMIDITY_EXTRACT,
20 SENSOR_HUMIDITY_OUTDOOR,
21 SENSOR_HUMIDITY_SUPPLY,
24 SENSOR_PREHEATER_POWER_CURRENT,
25 SENSOR_PREHEATER_POWER_TOTAL,
26 SENSOR_TEMPERATURE_EXHAUST,
27 SENSOR_TEMPERATURE_EXTRACT,
28 SENSOR_TEMPERATURE_OUTDOOR,
29 SENSOR_TEMPERATURE_SUPPLY,
31 import voluptuous
as vol
34 PLATFORM_SCHEMA
as SENSOR_PLATFORM_SCHEMA,
37 SensorEntityDescription,
43 REVOLUTIONS_PER_MINUTE,
56 from .
import DOMAIN, SIGNAL_COMFOCONNECT_UPDATE_RECEIVED, ComfoConnectBridge
58 ATTR_AIR_FLOW_EXHAUST =
"air_flow_exhaust"
59 ATTR_AIR_FLOW_SUPPLY =
"air_flow_supply"
60 ATTR_BYPASS_STATE =
"bypass_state"
61 ATTR_CURRENT_HUMIDITY =
"current_humidity"
62 ATTR_CURRENT_RMOT =
"current_rmot"
63 ATTR_CURRENT_TEMPERATURE =
"current_temperature"
64 ATTR_DAYS_TO_REPLACE_FILTER =
"days_to_replace_filter"
65 ATTR_EXHAUST_FAN_DUTY =
"exhaust_fan_duty"
66 ATTR_EXHAUST_FAN_SPEED =
"exhaust_fan_speed"
67 ATTR_EXHAUST_HUMIDITY =
"exhaust_humidity"
68 ATTR_EXHAUST_TEMPERATURE =
"exhaust_temperature"
69 ATTR_OUTSIDE_HUMIDITY =
"outside_humidity"
70 ATTR_OUTSIDE_TEMPERATURE =
"outside_temperature"
71 ATTR_POWER_CURRENT =
"power_usage"
72 ATTR_POWER_TOTAL =
"power_total"
73 ATTR_PREHEATER_POWER_CURRENT =
"preheater_power_usage"
74 ATTR_PREHEATER_POWER_TOTAL =
"preheater_power_total"
75 ATTR_SUPPLY_FAN_DUTY =
"supply_fan_duty"
76 ATTR_SUPPLY_FAN_SPEED =
"supply_fan_speed"
77 ATTR_SUPPLY_HUMIDITY =
"supply_humidity"
78 ATTR_SUPPLY_TEMPERATURE =
"supply_temperature"
80 _LOGGER = logging.getLogger(__name__)
83 @dataclass(frozen=True, kw_only=True)
85 """Describes Comfoconnect sensor entity."""
93 key=ATTR_CURRENT_TEMPERATURE,
94 device_class=SensorDeviceClass.TEMPERATURE,
95 state_class=SensorStateClass.MEASUREMENT,
96 name=
"Inside temperature",
97 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
98 sensor_id=SENSOR_TEMPERATURE_EXTRACT,
102 key=ATTR_CURRENT_HUMIDITY,
103 device_class=SensorDeviceClass.HUMIDITY,
104 state_class=SensorStateClass.MEASUREMENT,
105 name=
"Inside humidity",
106 native_unit_of_measurement=PERCENTAGE,
107 sensor_id=SENSOR_HUMIDITY_EXTRACT,
110 key=ATTR_CURRENT_RMOT,
111 device_class=SensorDeviceClass.TEMPERATURE,
112 state_class=SensorStateClass.MEASUREMENT,
114 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
115 sensor_id=SENSOR_CURRENT_RMOT,
119 key=ATTR_OUTSIDE_TEMPERATURE,
120 device_class=SensorDeviceClass.TEMPERATURE,
121 state_class=SensorStateClass.MEASUREMENT,
122 name=
"Outside temperature",
123 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
124 sensor_id=SENSOR_TEMPERATURE_OUTDOOR,
128 key=ATTR_OUTSIDE_HUMIDITY,
129 device_class=SensorDeviceClass.HUMIDITY,
130 state_class=SensorStateClass.MEASUREMENT,
131 name=
"Outside humidity",
132 native_unit_of_measurement=PERCENTAGE,
133 sensor_id=SENSOR_HUMIDITY_OUTDOOR,
136 key=ATTR_SUPPLY_TEMPERATURE,
137 device_class=SensorDeviceClass.TEMPERATURE,
138 state_class=SensorStateClass.MEASUREMENT,
139 name=
"Supply temperature",
140 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
141 sensor_id=SENSOR_TEMPERATURE_SUPPLY,
145 key=ATTR_SUPPLY_HUMIDITY,
146 device_class=SensorDeviceClass.HUMIDITY,
147 state_class=SensorStateClass.MEASUREMENT,
148 name=
"Supply humidity",
149 native_unit_of_measurement=PERCENTAGE,
150 sensor_id=SENSOR_HUMIDITY_SUPPLY,
153 key=ATTR_SUPPLY_FAN_SPEED,
154 state_class=SensorStateClass.MEASUREMENT,
155 name=
"Supply fan speed",
156 native_unit_of_measurement=REVOLUTIONS_PER_MINUTE,
158 sensor_id=SENSOR_FAN_SUPPLY_SPEED,
161 key=ATTR_SUPPLY_FAN_DUTY,
162 state_class=SensorStateClass.MEASUREMENT,
163 name=
"Supply fan duty",
164 native_unit_of_measurement=PERCENTAGE,
166 sensor_id=SENSOR_FAN_SUPPLY_DUTY,
169 key=ATTR_EXHAUST_FAN_SPEED,
170 state_class=SensorStateClass.MEASUREMENT,
171 name=
"Exhaust fan speed",
172 native_unit_of_measurement=REVOLUTIONS_PER_MINUTE,
173 icon=
"mdi:fan-minus",
174 sensor_id=SENSOR_FAN_EXHAUST_SPEED,
177 key=ATTR_EXHAUST_FAN_DUTY,
178 state_class=SensorStateClass.MEASUREMENT,
179 name=
"Exhaust fan duty",
180 native_unit_of_measurement=PERCENTAGE,
181 icon=
"mdi:fan-minus",
182 sensor_id=SENSOR_FAN_EXHAUST_DUTY,
185 key=ATTR_EXHAUST_TEMPERATURE,
186 device_class=SensorDeviceClass.TEMPERATURE,
187 state_class=SensorStateClass.MEASUREMENT,
188 name=
"Exhaust temperature",
189 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
190 sensor_id=SENSOR_TEMPERATURE_EXHAUST,
194 key=ATTR_EXHAUST_HUMIDITY,
195 device_class=SensorDeviceClass.HUMIDITY,
196 state_class=SensorStateClass.MEASUREMENT,
197 name=
"Exhaust humidity",
198 native_unit_of_measurement=PERCENTAGE,
199 sensor_id=SENSOR_HUMIDITY_EXHAUST,
202 key=ATTR_AIR_FLOW_SUPPLY,
203 state_class=SensorStateClass.MEASUREMENT,
204 name=
"Supply airflow",
205 native_unit_of_measurement=UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
207 sensor_id=SENSOR_FAN_SUPPLY_FLOW,
210 key=ATTR_AIR_FLOW_EXHAUST,
211 state_class=SensorStateClass.MEASUREMENT,
212 name=
"Exhaust airflow",
213 native_unit_of_measurement=UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
214 icon=
"mdi:fan-minus",
215 sensor_id=SENSOR_FAN_EXHAUST_FLOW,
218 key=ATTR_BYPASS_STATE,
219 state_class=SensorStateClass.MEASUREMENT,
221 native_unit_of_measurement=PERCENTAGE,
222 icon=
"mdi:camera-iris",
223 sensor_id=SENSOR_BYPASS_STATE,
226 key=ATTR_DAYS_TO_REPLACE_FILTER,
227 name=
"Days to replace filter",
228 native_unit_of_measurement=UnitOfTime.DAYS,
230 sensor_id=SENSOR_DAYS_TO_REPLACE_FILTER,
233 key=ATTR_POWER_CURRENT,
234 device_class=SensorDeviceClass.POWER,
235 state_class=SensorStateClass.MEASUREMENT,
237 native_unit_of_measurement=UnitOfPower.WATT,
238 sensor_id=SENSOR_POWER_CURRENT,
241 key=ATTR_POWER_TOTAL,
242 device_class=SensorDeviceClass.ENERGY,
243 state_class=SensorStateClass.TOTAL_INCREASING,
245 native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
246 sensor_id=SENSOR_POWER_TOTAL,
249 key=ATTR_PREHEATER_POWER_CURRENT,
250 device_class=SensorDeviceClass.POWER,
251 state_class=SensorStateClass.MEASUREMENT,
252 name=
"Preheater power usage",
253 native_unit_of_measurement=UnitOfPower.WATT,
254 sensor_id=SENSOR_PREHEATER_POWER_CURRENT,
257 key=ATTR_PREHEATER_POWER_TOTAL,
258 device_class=SensorDeviceClass.ENERGY,
259 state_class=SensorStateClass.TOTAL_INCREASING,
260 name=
"Preheater energy total",
261 native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
262 sensor_id=SENSOR_PREHEATER_POWER_TOTAL,
266 PLATFORM_SCHEMA = SENSOR_PLATFORM_SCHEMA.extend(
268 vol.Optional(CONF_RESOURCES, default=[]): vol.All(
269 cv.ensure_list, [vol.In([desc.key
for desc
in SENSOR_TYPES])]
278 add_entities: AddEntitiesCallback,
279 discovery_info: DiscoveryInfoType |
None =
None,
281 """Set up the ComfoConnect sensor platform."""
282 ccb = hass.data[DOMAIN]
286 for description
in SENSOR_TYPES
287 if description.key
in config[CONF_RESOURCES]
294 """Representation of a ComfoConnect sensor."""
296 _attr_should_poll =
False
297 entity_description: ComfoconnectSensorEntityDescription
301 ccb: ComfoConnectBridge,
302 description: ComfoconnectSensorEntityDescription,
304 """Initialize the ComfoConnect sensor."""
311 """Register for sensor updates."""
313 "Registering for sensor %s (%d)",
320 SIGNAL_COMFOCONNECT_UPDATE_RECEIVED.format(
326 await self.
hasshass.async_add_executor_job(
331 """Handle update callbacks."""
333 "Handle update for sensor %s (%d): %s",
None __init__(self, ComfoConnectBridge ccb, ComfoconnectSensorEntityDescription description)
None _handle_update(self, float value)
None async_added_to_hass(self)
None async_on_remove(self, CALLBACK_TYPE func)
None schedule_update_ha_state(self, bool force_refresh=False)
None setup_platform(HomeAssistant hass, ConfigType config, AddEntitiesCallback add_entities, DiscoveryInfoType|None discovery_info=None)
def add_entities(account, async_add_entities, tracked)
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)