148 """Declare cover companion entity IDs during schema validation for StaticVector sizing.
150 The favorite and ventilation buttons are cover-only and gated on device capability, so
151 their injection stays here. The always-present companion sensor IDs are delegated to the
152 shared helper. See platform_common.companion_id_base() for the StaticVector rationale.
154 base = companion_id_base(config, CONF_ID)
158 config[CONF_DEVICE_TYPE]
160 config[CONF_FAVORITE_BUTTON_ID] = ID(
161 f
"{base}_favorite_button",
163 type=IOHomeCoverCommandButton,
168 config[CONF_VENT_BUTTON_ID] = ID(
169 f
"{base}_vent_button",
171 type=IOHomeCoverCommandButton,
177 if CONF_SILENT
in config:
178 config[CONF_SILENT_SWITCH_ID] = ID(
179 f
"{base}_silent_switch",
181 type=IOHomeCoverSilentSwitch,
186 if CONF_RAIN_SENSOR_POLL_INTERVAL
in config:
187 config[CONF_RAIN_SENSOR_ID] = ID(
188 f
"{base}_rain_sensor",
190 type=IOHomeRainBinarySensor,
195 if config.get(CONF_BATTERY,
False):
196 config[CONF_BATTERY_LOW_SENSOR_ID] = ID(
197 f
"{base}_battery_low_sensor",
199 type=IOHomeBatteryLowBinarySensor,
201 config[CONF_BATTERY_SENSOR_ID] = ID(
202 f
"{base}_battery_sensor",
204 type=IOHomeBatteryTextSensor,
208 return inject_companion_sensor_ids(config, CONF_ID)
231 var = await cover.new_cover(config)
232 await cg.register_component(var, config)
234 parent = await cg.get_variable(config[CONF_HOME_IO_CONTROL_ID])
235 await wire_device_binding(var, parent, config)
237 if CONF_INVERT_POSITION
in config:
238 cg.add(var.set_invert_position(config[CONF_INVERT_POSITION]))
240 cg.add(var.set_optimistic_state(config[CONF_OPTIMISTIC_STATE]))
241 if CONF_SILENT
in config:
242 cg.add(var.set_silent(config[CONF_SILENT]))
244 if CONF_SILENT_SWITCH_ID
in config:
250 silent_config = switch.switch_schema(
251 IOHomeCoverSilentSwitch,
252 default_restore_mode=
"DISABLED",
253 entity_category=ENTITY_CATEGORY_CONFIG,
254 ).extend(cv.COMPONENT_SCHEMA)(
255 inherit_esphome_device(
257 CONF_ID: config[CONF_SILENT_SWITCH_ID],
263 silent_switch = await switch.new_switch(silent_config)
264 await cg.register_component(silent_switch, silent_config)
265 cg.add(silent_switch.set_parent(parent))
266 cg.add(silent_switch.set_device_id(config[CONF_IO_DEVICE_ID]))
268 if CONF_RAIN_SENSOR_ID
in config:
270 var.set_rain_sensor_poll_interval(
271 config[CONF_RAIN_SENSOR_POLL_INTERVAL].total_milliseconds
274 rain_config = binary_sensor.binary_sensor_schema(
275 IOHomeRainBinarySensor, device_class=DEVICE_CLASS_MOISTURE
276 ).extend(cv.COMPONENT_SCHEMA)(
277 inherit_esphome_device(
279 CONF_ID: config[CONF_RAIN_SENSOR_ID],
285 rain_sensor = await binary_sensor.new_binary_sensor(rain_config)
286 await cg.register_component(rain_sensor, rain_config)
287 cg.add(rain_sensor.set_parent(parent))
288 cg.add(rain_sensor.set_device_id(config[CONF_IO_DEVICE_ID]))
290 if CONF_BATTERY_LOW_SENSOR_ID
in config:
291 cg.add(var.set_battery_entities(
True))
294 if CONF_FAVORITE_BUTTON_ID
in config:
295 favorite_config = inherit_esphome_device(
297 CONF_ID: config[CONF_FAVORITE_BUTTON_ID],
299 CONF_DISABLED_BY_DEFAULT:
False,
303 favorite = await button.new_button(favorite_config)
304 await cg.register_component(favorite, favorite_config)
305 cg.add(favorite.set_parent(parent))
306 cg.add(favorite.set_device_id(config[CONF_IO_DEVICE_ID]))
307 cg.add(favorite.set_command(CoverCommand.FAVORITE))
309 if CONF_VENT_BUTTON_ID
in config:
310 vent_config = inherit_esphome_device(
312 CONF_ID: config[CONF_VENT_BUTTON_ID],
314 CONF_DISABLED_BY_DEFAULT:
False,
318 vent = await button.new_button(vent_config)
319 await cg.register_component(vent, vent_config)
320 cg.add(vent.set_parent(parent))
321 cg.add(vent.set_device_id(config[CONF_IO_DEVICE_ID]))
322 cg.add(vent.set_command(CoverCommand.VENT))
324 await create_companion_sensors(config, parent)
328 """Create the two `battery: true` companions.
330 Battery Low is the enabled one: a `device_class: battery` binary sensor is Home Assistant's own
331 low-battery signal. Battery (full/normal/low) is diagnostic and disabled by default; ESPHome
332 text sensors carry no battery device class, so nothing generic reads it.
334 low_config = binary_sensor.binary_sensor_schema(
335 IOHomeBatteryLowBinarySensor,
336 device_class=DEVICE_CLASS_BATTERY,
337 entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
338 ).extend(cv.COMPONENT_SCHEMA)(
339 inherit_esphome_device(
341 CONF_ID: config[CONF_BATTERY_LOW_SENSOR_ID],
347 low_sensor = await binary_sensor.new_binary_sensor(low_config)
348 await cg.register_component(low_sensor, low_config)
349 cg.add(low_sensor.set_parent(parent))
350 cg.add(low_sensor.set_device_id(config[CONF_IO_DEVICE_ID]))
352 level_config = text_sensor.text_sensor_schema(
353 IOHomeBatteryTextSensor,
354 entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
356 ).extend(cv.COMPONENT_SCHEMA)(
357 inherit_esphome_device(
359 CONF_ID: config[CONF_BATTERY_SENSOR_ID],
361 CONF_DISABLED_BY_DEFAULT:
True,
366 level_sensor = await text_sensor.new_text_sensor(level_config)
367 await cg.register_component(level_sensor, level_config)
368 cg.add(level_sensor.set_parent(parent))
369 cg.add(level_sensor.set_device_id(config[CONF_IO_DEVICE_ID]))