[ota-esphome] Merge configurations by port (#7001)

This commit is contained in:
Keith Burzinski 2024-06-26 20:07:07 -05:00 committed by Jesse Hills
parent 04225d5717
commit 0e50cac399
No known key found for this signature in database
GPG key ID: BEAAE804EFD8E83A

View file

@ -1,7 +1,10 @@
import logging
import esphome.codegen as cg import esphome.codegen as cg
import esphome.config_validation as cv import esphome.config_validation as cv
import esphome.final_validate as fv import esphome.final_validate as fv
from esphome.components.ota import BASE_OTA_SCHEMA, ota_to_code, OTAComponent from esphome.components.ota import BASE_OTA_SCHEMA, ota_to_code, OTAComponent
from esphome.config_helpers import merge_config
from esphome.const import ( from esphome.const import (
CONF_ESPHOME, CONF_ESPHOME,
CONF_ID, CONF_ID,
@ -16,6 +19,8 @@ from esphome.const import (
) )
from esphome.core import coroutine_with_priority from esphome.core import coroutine_with_priority
_LOGGER = logging.getLogger(__name__)
CODEOWNERS = ["@esphome/core"] CODEOWNERS = ["@esphome/core"]
AUTO_LOAD = ["md5", "socket"] AUTO_LOAD = ["md5", "socket"]
@ -26,15 +31,61 @@ ESPHomeOTAComponent = esphome.class_("ESPHomeOTAComponent", OTAComponent)
def ota_esphome_final_validate(config): def ota_esphome_final_validate(config):
fconf = fv.full_config.get()[CONF_OTA] full_conf = fv.full_config.get()
used_ports = [] full_ota_conf = full_conf[CONF_OTA]
for ota_conf in fconf: new_ota_conf = []
merged_ota_esphome_configs_by_port = {}
ports_with_merged_configs = []
for ota_conf in full_ota_conf:
if ota_conf.get(CONF_PLATFORM) == CONF_ESPHOME: if ota_conf.get(CONF_PLATFORM) == CONF_ESPHOME:
if (plat_port := ota_conf.get(CONF_PORT)) not in used_ports: if (
used_ports.append(plat_port) conf_port := ota_conf.get(CONF_PORT)
) not in merged_ota_esphome_configs_by_port:
merged_ota_esphome_configs_by_port[conf_port] = ota_conf
else: else:
if merged_ota_esphome_configs_by_port[conf_port][
CONF_VERSION
] != ota_conf.get(CONF_VERSION):
raise cv.Invalid( raise cv.Invalid(
f"Only one instance of the {CONF_ESPHOME} {CONF_OTA} {CONF_PLATFORM} is allowed per port. Note that this error may result from OTA specified in packages" f"Found multiple configurations but {CONF_VERSION} is inconsistent"
)
if (
merged_ota_esphome_configs_by_port[conf_port][CONF_ID].is_manual
and ota_conf.get(CONF_ID).is_manual
):
raise cv.Invalid(
f"Found multiple configurations but {CONF_ID} is inconsistent"
)
if (
CONF_PASSWORD in merged_ota_esphome_configs_by_port[conf_port]
and CONF_PASSWORD in ota_conf
and merged_ota_esphome_configs_by_port[conf_port][CONF_PASSWORD]
!= ota_conf.get(CONF_PASSWORD)
):
raise cv.Invalid(
f"Found multiple configurations but {CONF_PASSWORD} is inconsistent"
)
ports_with_merged_configs.append(conf_port)
merged_ota_esphome_configs_by_port[conf_port] = merge_config(
merged_ota_esphome_configs_by_port[conf_port], ota_conf
)
else:
new_ota_conf.append(ota_conf)
for port_conf in merged_ota_esphome_configs_by_port.values():
new_ota_conf.append(port_conf)
full_conf[CONF_OTA] = new_ota_conf
fv.full_config.set(full_conf)
if len(ports_with_merged_configs) > 0:
_LOGGER.warning(
"Found and merged multiple configurations for %s %s %s port(s) %s",
CONF_OTA,
CONF_PLATFORM,
CONF_ESPHOME,
ports_with_merged_configs,
) )