9import esphome.codegen
as cg
10from esphome.components
import button, text_sensor
11import esphome.config_validation
as cv
12from esphome.const
import (
13 CONF_DISABLED_BY_DEFAULT,
17 ENTITY_CATEGORY_CONFIG,
18 ENTITY_CATEGORY_DIAGNOSTIC,
20from esphome.core
import ID
24 IOHomeControlComponent,
25 CONF_HOME_IO_CONTROL_ID,
26 inherit_esphome_device,
29DEPENDENCIES = [
"home_io_control"]
31IOHomeDiscoverButton = home_io_control_ns.class_(
32 "IOHomeDiscoverButton", button.Button, cg.Component
34IOHomePairingResultTextSensor = home_io_control_ns.class_(
35 "IOHomePairingResultTextSensor", text_sensor.TextSensor, cg.Component
39CONF_PAIRING_RESULT_SENSOR_ID =
"_pairing_result_sensor_id"
43 """Declare the companion pairing-result sensor ID during schema validation.
45 ESPHome 2026.x sizes its runtime component vector from the number of component IDs
46 known at the end of schema validation — before to_code() runs. A companion entity
47 created only in to_code() is not counted and silently drops at runtime. See the
48 identical pattern (and its full rationale) in platform_common.py::companion_id_base().
50 from esphome.helpers
import sanitize
52 parent_id = config[CONF_ID]
53 base = parent_id.id
if parent_id.id
else sanitize(config.get(CONF_NAME,
"")).lower()
54 config[CONF_PAIRING_RESULT_SENSOR_ID] = ID(
55 f
"{base}_pairing_result_sensor",
57 type=IOHomePairingResultTextSensor,
62CONFIG_SCHEMA = cv.All(
65 entity_category=ENTITY_CATEGORY_CONFIG,
69 cv.GenerateID(CONF_HOME_IO_CONTROL_ID): cv.use_id(
70 IOHomeControlComponent
74 .extend(cv.COMPONENT_SCHEMA),
75 _inject_pairing_result_sensor_id,
80 var = cg.new_Pvariable(config[CONF_ID])
81 await cg.register_component(var, config)
82 await button.register_button(var, config)
84 parent = await cg.get_variable(config[CONF_HOME_IO_CONTROL_ID])
85 cg.add(var.set_parent(parent))
87 result_sensor_config = inherit_esphome_device(
89 CONF_ID: config[CONF_PAIRING_RESULT_SENSOR_ID],
90 CONF_NAME:
"Last Pairing Result",
91 CONF_DISABLED_BY_DEFAULT:
False,
92 CONF_ENTITY_CATEGORY: ENTITY_CATEGORY_DIAGNOSTIC,
96 result_sensor = await text_sensor.new_text_sensor(result_sensor_config)
97 await cg.register_component(result_sensor, result_sensor_config)
98 cg.add(result_sensor.set_parent(parent))