[core] Defer entity automation codegen to prevent sibling ID deadlocks (#14381)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Jonathan Swoboda
2026-02-28 13:10:53 -10:00
committed by GitHub
co-authored by Copilot
parent 757e8d90e6
commit b7d651dd17
5 changed files with 83 additions and 57 deletions
+21 -16
View File
@@ -550,22 +550,8 @@ def binary_sensor_schema(
return _BINARY_SENSOR_SCHEMA.extend(schema)
async def setup_binary_sensor_core_(var, config):
await setup_entity(var, config, "binary_sensor")
if (device_class := config.get(CONF_DEVICE_CLASS)) is not None:
cg.add(var.set_device_class(device_class))
trigger = config.get(CONF_TRIGGER_ON_INITIAL_STATE, False) or config.get(
CONF_PUBLISH_INITIAL_STATE, False
)
cg.add(var.set_trigger_on_initial_state(trigger))
if inverted := config.get(CONF_INVERTED):
cg.add(var.set_inverted(inverted))
if filters_config := config.get(CONF_FILTERS):
cg.add_define("USE_BINARY_SENSOR_FILTER")
filters = await cg.build_registry_list(FILTER_REGISTRY, filters_config)
cg.add(var.add_filters(filters))
@coroutine_with_priority(CoroPriority.AUTOMATION)
async def _build_binary_sensor_automations(var, config):
for conf in config.get(CONF_ON_PRESS, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [], conf)
@@ -617,6 +603,25 @@ async def setup_binary_sensor_core_(var, config):
conf,
)
async def setup_binary_sensor_core_(var, config):
await setup_entity(var, config, "binary_sensor")
if (device_class := config.get(CONF_DEVICE_CLASS)) is not None:
cg.add(var.set_device_class(device_class))
trigger = config.get(CONF_TRIGGER_ON_INITIAL_STATE, False) or config.get(
CONF_PUBLISH_INITIAL_STATE, False
)
cg.add(var.set_trigger_on_initial_state(trigger))
if inverted := config.get(CONF_INVERTED):
cg.add(var.set_inverted(inverted))
if filters_config := config.get(CONF_FILTERS):
cg.add_define("USE_BINARY_SENSOR_FILTER")
filters = await cg.build_registry_list(FILTER_REGISTRY, filters_config)
cg.add(var.add_filters(filters))
CORE.add_job(_build_binary_sensor_automations, var, config)
if mqtt_id := config.get(CONF_MQTT_ID):
mqtt_ = cg.new_Pvariable(mqtt_id, var)
await mqtt.register_mqtt_component(mqtt_, config)
+18 -13
View File
@@ -240,6 +240,23 @@ def number_schema(
return _NUMBER_SCHEMA.extend(schema)
@coroutine_with_priority(CoroPriority.AUTOMATION)
async def _build_number_automations(var, config):
for conf in config.get(CONF_ON_VALUE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(float, "x")], conf)
for conf in config.get(CONF_ON_VALUE_RANGE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await cg.register_component(trigger, conf)
if CONF_ABOVE in conf:
template_ = await cg.templatable(conf[CONF_ABOVE], [(float, "x")], float)
cg.add(trigger.set_min(template_))
if CONF_BELOW in conf:
template_ = await cg.templatable(conf[CONF_BELOW], [(float, "x")], float)
cg.add(trigger.set_max(template_))
await automation.build_automation(trigger, [(float, "x")], conf)
async def setup_number_core_(
var, config, *, min_value: float, max_value: float, step: float
):
@@ -254,19 +271,7 @@ async def setup_number_core_(
if config[CONF_MODE] != NumberMode.NUMBER_MODE_AUTO:
cg.add(var.traits.set_mode(config[CONF_MODE]))
for conf in config.get(CONF_ON_VALUE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(float, "x")], conf)
for conf in config.get(CONF_ON_VALUE_RANGE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await cg.register_component(trigger, conf)
if CONF_ABOVE in conf:
template_ = await cg.templatable(conf[CONF_ABOVE], [(float, "x")], float)
cg.add(trigger.set_min(template_))
if CONF_BELOW in conf:
template_ = await cg.templatable(conf[CONF_BELOW], [(float, "x")], float)
cg.add(trigger.set_max(template_))
await automation.build_automation(trigger, [(float, "x")], conf)
CORE.add_job(_build_number_automations, var, config)
if (unit_of_measurement := config.get(CONF_UNIT_OF_MEASUREMENT)) is not None:
cg.add(var.traits.set_unit_of_measurement(unit_of_measurement))
+21 -16
View File
@@ -888,6 +888,26 @@ async def build_filters(config):
return await cg.build_registry_list(FILTER_REGISTRY, config)
@coroutine_with_priority(CoroPriority.AUTOMATION)
async def _build_sensor_automations(var, config):
for conf in config.get(CONF_ON_VALUE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(float, "x")], conf)
for conf in config.get(CONF_ON_RAW_VALUE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(float, "x")], conf)
for conf in config.get(CONF_ON_VALUE_RANGE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await cg.register_component(trigger, conf)
if (above := conf.get(CONF_ABOVE)) is not None:
template_ = await cg.templatable(above, [(float, "x")], float)
cg.add(trigger.set_min(template_))
if (below := conf.get(CONF_BELOW)) is not None:
template_ = await cg.templatable(below, [(float, "x")], float)
cg.add(trigger.set_max(template_))
await automation.build_automation(trigger, [(float, "x")], conf)
async def setup_sensor_core_(var, config):
await setup_entity(var, config, "sensor")
@@ -907,22 +927,7 @@ async def setup_sensor_core_(var, config):
filters = await build_filters(config[CONF_FILTERS])
cg.add(var.set_filters(filters))
for conf in config.get(CONF_ON_VALUE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(float, "x")], conf)
for conf in config.get(CONF_ON_RAW_VALUE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(float, "x")], conf)
for conf in config.get(CONF_ON_VALUE_RANGE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await cg.register_component(trigger, conf)
if (above := conf.get(CONF_ABOVE)) is not None:
template_ = await cg.templatable(above, [(float, "x")], float)
cg.add(trigger.set_min(template_))
if (below := conf.get(CONF_BELOW)) is not None:
template_ = await cg.templatable(below, [(float, "x")], float)
cg.add(trigger.set_max(template_))
await automation.build_automation(trigger, [(float, "x")], conf)
CORE.add_job(_build_sensor_automations, var, config)
if (mqtt_id := config.get(CONF_MQTT_ID)) is not None:
mqtt_ = cg.new_Pvariable(mqtt_id, var)
+11 -5
View File
@@ -141,11 +141,8 @@ def switch_schema(
return _SWITCH_SCHEMA.extend(schema)
async def setup_switch_core_(var, config):
await setup_entity(var, config, "switch")
if (inverted := config.get(CONF_INVERTED)) is not None:
cg.add(var.set_inverted(inverted))
@coroutine_with_priority(CoroPriority.AUTOMATION)
async def _build_switch_automations(var, config):
for conf in config.get(CONF_ON_STATE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(bool, "x")], conf)
@@ -156,6 +153,15 @@ async def setup_switch_core_(var, config):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [], conf)
async def setup_switch_core_(var, config):
await setup_entity(var, config, "switch")
if (inverted := config.get(CONF_INVERTED)) is not None:
cg.add(var.set_inverted(inverted))
CORE.add_job(_build_switch_automations, var, config)
if (mqtt_id := config.get(CONF_MQTT_ID)) is not None:
mqtt_ = cg.new_Pvariable(mqtt_id, var)
await mqtt.register_mqtt_component(mqtt_, config)
+12 -7
View File
@@ -197,6 +197,17 @@ async def build_filters(config):
return await cg.build_registry_list(FILTER_REGISTRY, config)
@coroutine_with_priority(CoroPriority.AUTOMATION)
async def _build_text_sensor_automations(var, config):
for conf in config.get(CONF_ON_VALUE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(cg.std_string, "x")], conf)
for conf in config.get(CONF_ON_RAW_VALUE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(cg.std_string, "x")], conf)
async def setup_text_sensor_core_(var, config):
await setup_entity(var, config, "text_sensor")
@@ -208,13 +219,7 @@ async def setup_text_sensor_core_(var, config):
filters = await build_filters(config[CONF_FILTERS])
cg.add(var.set_filters(filters))
for conf in config.get(CONF_ON_VALUE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(cg.std_string, "x")], conf)
for conf in config.get(CONF_ON_RAW_VALUE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(cg.std_string, "x")], conf)
CORE.add_job(_build_text_sensor_automations, var, config)
if (mqtt_id := config.get(CONF_MQTT_ID)) is not None:
mqtt_ = cg.new_Pvariable(mqtt_id, var)