mirror of
https://github.com/esphome/esphome.git
synced 2025-10-26 12:43:48 +00:00
[openthread] Fix OTA by populating CORE.address with device's mDNS address (#11095)
Co-authored-by: J. Nick Koston <nick@home-assistant.io> Co-authored-by: J. Nick Koston <nick@koston.org> Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
This commit is contained in:
@@ -99,7 +99,11 @@ const std::string &get_use_address() {
|
|||||||
return wifi::global_wifi_component->get_use_address();
|
return wifi::global_wifi_component->get_use_address();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(USE_ETHERNET) && !defined(USE_MODEM) && !defined(USE_WIFI)
|
#ifdef USE_OPENTHREAD
|
||||||
|
return openthread::global_openthread_component->get_use_address();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(USE_ETHERNET) && !defined(USE_MODEM) && !defined(USE_WIFI) && !defined(USE_OPENTHREAD)
|
||||||
// Fallback when no network component is defined (e.g., host platform)
|
// Fallback when no network component is defined (e.g., host platform)
|
||||||
static const std::string empty;
|
static const std::string empty;
|
||||||
return empty;
|
return empty;
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ from esphome.components.esp32 import (
|
|||||||
)
|
)
|
||||||
from esphome.components.mdns import MDNSComponent, enable_mdns_storage
|
from esphome.components.mdns import MDNSComponent, enable_mdns_storage
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.const import CONF_CHANNEL, CONF_ENABLE_IPV6, CONF_ID
|
from esphome.const import CONF_CHANNEL, CONF_ENABLE_IPV6, CONF_ID, CONF_USE_ADDRESS
|
||||||
|
from esphome.core import CORE
|
||||||
import esphome.final_validate as fv
|
import esphome.final_validate as fv
|
||||||
|
from esphome.types import ConfigType
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
CONF_DEVICE_TYPE,
|
CONF_DEVICE_TYPE,
|
||||||
@@ -108,6 +110,12 @@ _CONNECTION_SCHEMA = cv.Schema(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _validate(config: ConfigType) -> ConfigType:
|
||||||
|
if CONF_USE_ADDRESS not in config:
|
||||||
|
config[CONF_USE_ADDRESS] = f"{CORE.name}.local"
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
def _require_vfs_select(config):
|
def _require_vfs_select(config):
|
||||||
"""Register VFS select requirement during config validation."""
|
"""Register VFS select requirement during config validation."""
|
||||||
# OpenThread uses esp_vfs_eventfd which requires VFS select support
|
# OpenThread uses esp_vfs_eventfd which requires VFS select support
|
||||||
@@ -126,11 +134,13 @@ CONFIG_SCHEMA = cv.All(
|
|||||||
),
|
),
|
||||||
cv.Optional(CONF_FORCE_DATASET): cv.boolean,
|
cv.Optional(CONF_FORCE_DATASET): cv.boolean,
|
||||||
cv.Optional(CONF_TLV): cv.string_strict,
|
cv.Optional(CONF_TLV): cv.string_strict,
|
||||||
|
cv.Optional(CONF_USE_ADDRESS): cv.string_strict,
|
||||||
}
|
}
|
||||||
).extend(_CONNECTION_SCHEMA),
|
).extend(_CONNECTION_SCHEMA),
|
||||||
cv.has_exactly_one_key(CONF_NETWORK_KEY, CONF_TLV),
|
cv.has_exactly_one_key(CONF_NETWORK_KEY, CONF_TLV),
|
||||||
cv.only_with_esp_idf,
|
cv.only_with_esp_idf,
|
||||||
only_on_variant(supported=[VARIANT_ESP32C6, VARIANT_ESP32H2]),
|
only_on_variant(supported=[VARIANT_ESP32C6, VARIANT_ESP32H2]),
|
||||||
|
_validate,
|
||||||
_require_vfs_select,
|
_require_vfs_select,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -155,6 +165,7 @@ async def to_code(config):
|
|||||||
enable_mdns_storage()
|
enable_mdns_storage()
|
||||||
|
|
||||||
ot = cg.new_Pvariable(config[CONF_ID])
|
ot = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
cg.add(ot.set_use_address(config[CONF_USE_ADDRESS]))
|
||||||
await cg.register_component(ot, config)
|
await cg.register_component(ot, config)
|
||||||
|
|
||||||
srp = cg.new_Pvariable(config[CONF_SRP_ID])
|
srp = cg.new_Pvariable(config[CONF_SRP_ID])
|
||||||
|
|||||||
@@ -252,6 +252,12 @@ void OpenThreadComponent::on_factory_reset(std::function<void()> callback) {
|
|||||||
ESP_LOGD(TAG, "Waiting on Confirmation Removal SRP Host and Services");
|
ESP_LOGD(TAG, "Waiting on Confirmation Removal SRP Host and Services");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set_use_address() is guaranteed to be called during component setup by Python code generation,
|
||||||
|
// so use_address_ will always be valid when get_use_address() is called - no fallback needed.
|
||||||
|
const std::string &OpenThreadComponent::get_use_address() const { return this->use_address_; }
|
||||||
|
|
||||||
|
void OpenThreadComponent::set_use_address(const std::string &use_address) { this->use_address_ = use_address; }
|
||||||
|
|
||||||
} // namespace openthread
|
} // namespace openthread
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
||||||
|
|||||||
@@ -33,11 +33,15 @@ class OpenThreadComponent : public Component {
|
|||||||
void on_factory_reset(std::function<void()> callback);
|
void on_factory_reset(std::function<void()> callback);
|
||||||
void defer_factory_reset_external_callback();
|
void defer_factory_reset_external_callback();
|
||||||
|
|
||||||
|
const std::string &get_use_address() const;
|
||||||
|
void set_use_address(const std::string &use_address);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::optional<otIp6Address> get_omr_address_(InstanceLock &lock);
|
std::optional<otIp6Address> get_omr_address_(InstanceLock &lock);
|
||||||
bool teardown_started_{false};
|
bool teardown_started_{false};
|
||||||
bool teardown_complete_{false};
|
bool teardown_complete_{false};
|
||||||
std::function<void()> factory_reset_external_callback_;
|
std::function<void()> factory_reset_external_callback_;
|
||||||
|
std::string use_address_;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern OpenThreadComponent *global_openthread_component; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
extern OpenThreadComponent *global_openthread_component; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||||
|
|||||||
@@ -636,11 +636,9 @@ class EsphomeCore:
|
|||||||
if self.config is None:
|
if self.config is None:
|
||||||
raise ValueError("Config has not been loaded yet")
|
raise ValueError("Config has not been loaded yet")
|
||||||
|
|
||||||
if CONF_WIFI in self.config:
|
for network_type in (CONF_WIFI, CONF_ETHERNET, CONF_OPENTHREAD):
|
||||||
return self.config[CONF_WIFI][CONF_USE_ADDRESS]
|
if network_type in self.config:
|
||||||
|
return self.config[network_type][CONF_USE_ADDRESS]
|
||||||
if CONF_ETHERNET in self.config:
|
|
||||||
return self.config[CONF_ETHERNET][CONF_USE_ADDRESS]
|
|
||||||
|
|
||||||
if CONF_OPENTHREAD in self.config:
|
if CONF_OPENTHREAD in self.config:
|
||||||
return f"{self.name}.local"
|
return f"{self.name}.local"
|
||||||
|
|||||||
@@ -571,9 +571,11 @@ class TestEsphomeCore:
|
|||||||
assert target.address == "4.3.2.1"
|
assert target.address == "4.3.2.1"
|
||||||
|
|
||||||
def test_address__openthread(self, target):
|
def test_address__openthread(self, target):
|
||||||
target.name = "test-device"
|
|
||||||
target.config = {}
|
target.config = {}
|
||||||
target.config[const.CONF_OPENTHREAD] = {}
|
target.config[const.CONF_OPENTHREAD] = {
|
||||||
|
const.CONF_USE_ADDRESS: "test-device.local"
|
||||||
|
}
|
||||||
|
target.name = "test-device"
|
||||||
|
|
||||||
assert target.address == "test-device.local"
|
assert target.address == "test-device.local"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user