Home IO Control
ESPHome add-on for IO-Homecontrol devices
Toggle main menu visibility
Loading...
Searching...
No Matches
button.py
Go to the documentation of this file.
1
## @file
2
## @brief Deprecated `button:` platform for the pairing button -- use
3
## `home_io_control.discover_and_pair_button: true` instead.
4
## @ingroup hioc_codegen
5
##
6
## Exposes the same Home Assistant button entity and companion "Last Pairing Result" diagnostic
7
## text sensor that `home_io_control.discover_and_pair_button: true` now creates directly (see
8
## hub_entities.py's `create_discover_and_pair_button()`). Kept working, with a deprecation warning,
9
## for configs that predate that flag -- see `_warn_deprecated_platform()` below and ADR 0036.
10
11
import
logging
12
13
import
esphome.codegen
as
cg
14
from
esphome.components
import
button, text_sensor
15
import
esphome.config_validation
as
cv
16
import
esphome.final_validate
as
fv
17
from
esphome.const
import
(
18
CONF_DISABLED_BY_DEFAULT,
19
CONF_ENTITY_CATEGORY,
20
CONF_ID,
21
CONF_NAME,
22
ENTITY_CATEGORY_CONFIG,
23
ENTITY_CATEGORY_DIAGNOSTIC,
24
)
25
from
esphome.core
import
ID
26
27
from
.
import
(
28
IOHomeControlComponent,
29
IOHomeDiscoverButton,
30
IOHomePairingResultTextSensor,
31
CONF_DISCOVER_AND_PAIR_BUTTON,
32
CONF_HOME_IO_CONTROL_ID,
33
inherit_esphome_device,
34
)
35
36
_LOGGER = logging.getLogger(__name__)
37
38
DEPENDENCIES = [
"home_io_control"
]
39
40
# Internal config key for the companion pairing-result sensor ID (injected by post-validator).
41
CONF_PAIRING_RESULT_SENSOR_ID =
"_pairing_result_sensor_id"
42
43
44
def
_inject_pairing_result_sensor_id
(config):
45
"""Declare the companion pairing-result sensor ID during schema validation.
46
47
ESPHome 2026.x sizes its runtime component vector from the number of component IDs
48
known at the end of schema validation — before to_code() runs. A companion entity
49
created only in to_code() is not counted and silently drops at runtime. See the
50
identical pattern (and its full rationale) in platform_common.py::companion_id_base().
51
"""
52
from
esphome.helpers
import
sanitize
53
54
parent_id = config[CONF_ID]
55
base = parent_id.id
if
parent_id.id
else
sanitize(config.get(CONF_NAME,
""
)).lower()
56
config[CONF_PAIRING_RESULT_SENSOR_ID] = ID(
57
f
"{base}_pairing_result_sensor"
,
58
is_declaration=
True
,
59
type=IOHomePairingResultTextSensor,
60
)
61
return
config
62
63
64
def
_warn_deprecated_platform
(config):
65
"""Warn that this platform is superseded by home_io_control.discover_and_pair_button.
66
67
Placed FIRST in CONFIG_SCHEMA's cv.All() chain so the warning still reaches a user whose entry
68
also has an unrelated validation error. ESPHome runs each entry's schema exactly once per
69
`esphome config|compile|run`, so this fires once per legacy entry per invocation -- no dedupe
70
flag needed. A validator rather than to_code()'s first line (ESPHome's own precedent for a
71
whole-component deprecation) so `esphome config` and the dashboard's validate-only pass show it
72
too, and to match this component's existing convention of warning from validators.
73
"""
74
_LOGGER.warning(
75
"The 'home_io_control' button platform is deprecated. Set "
76
"'discover_and_pair_button: true' in the 'home_io_control:' block instead and delete this "
77
"'button:' entry; the hub then creates the 'Discover & Pair' button and its 'Last Pairing "
78
"Result' sensor itself. This entry still works, but will become a hard error in a future "
79
"release."
80
)
81
return
config
82
83
84
CONFIG_SCHEMA = cv.All(
85
_warn_deprecated_platform,
86
button.button_schema(
87
IOHomeDiscoverButton,
88
entity_category=ENTITY_CATEGORY_CONFIG,
89
)
90
.extend(
91
{
92
cv.GenerateID(CONF_HOME_IO_CONTROL_ID): cv.use_id(
93
IOHomeControlComponent
94
),
95
}
96
)
97
.extend(cv.COMPONENT_SCHEMA),
98
_inject_pairing_result_sensor_id,
99
)
100
101
102
def
_reject_duplicate_with_hub_flag
(config):
103
"""Reject having both this legacy entry and the hub's own discover_and_pair_button: true.
104
105
Rejected unconditionally, regardless of this entry's own name/device_id -- by default both
106
create a button named "Discover & Pair" on the same device, which ESPHome's entity-duplicate
107
validator refuses, but it only notices inside the hub's to_code(), where the resulting
108
cv.Invalid surfaces as an uncaught traceback rather than a validation message. A renamed or
109
re-homed entry could in principle coexist without colliding, but forcing the choice here keeps
110
the guard simple and the migration unambiguous: one pairing trigger, not "two unless you were
111
careful". Platform modules get their own FINAL_VALIDATE_SCHEMA slot, so this does not touch
112
__init__.py's (already used for address-collision detection).
113
"""
114
hub_config = fv.full_config.get().get(
"home_io_control"
)
or
{}
115
if
isinstance(hub_config, dict)
and
hub_config.get(CONF_DISCOVER_AND_PAIR_BUTTON):
116
raise
cv.Invalid(
117
"Both 'home_io_control.discover_and_pair_button: true' and a legacy "
118
"'button: - platform: home_io_control' entry are configured. Delete this 'button:' "
119
"entry -- the hub flag replaces it and creates the same button and sensor itself."
120
)
121
return
config
122
123
124
FINAL_VALIDATE_SCHEMA = _reject_duplicate_with_hub_flag
125
126
127
async def
to_code
(config):
128
var = cg.new_Pvariable(config[CONF_ID])
129
await cg.register_component(var, config)
130
await button.register_button(var, config)
131
132
parent = await cg.get_variable(config[CONF_HOME_IO_CONTROL_ID])
133
cg.add(var.set_parent(parent))
134
135
result_sensor_config = inherit_esphome_device(
136
{
137
CONF_ID: config[CONF_PAIRING_RESULT_SENSOR_ID],
138
CONF_NAME:
"Last Pairing Result"
,
139
CONF_DISABLED_BY_DEFAULT:
False
,
140
CONF_ENTITY_CATEGORY: ENTITY_CATEGORY_DIAGNOSTIC,
141
},
142
config,
143
)
144
result_sensor = await text_sensor.new_text_sensor(result_sensor_config)
145
await cg.register_component(result_sensor, result_sensor_config)
146
cg.add(result_sensor.set_parent(parent))
home_io_control.button._inject_pairing_result_sensor_id
_inject_pairing_result_sensor_id(config)
Definition
button.py:44
home_io_control.button._warn_deprecated_platform
_warn_deprecated_platform(config)
Definition
button.py:64
home_io_control.button._reject_duplicate_with_hub_flag
_reject_duplicate_with_hub_flag(config)
Definition
button.py:102
home_io_control.button.to_code
to_code(config)
Definition
button.py:127
components
home_io_control
button.py
Generated by
1.18.0