[openthread] add poll period for mtd devices (#11374)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
@@ -9,7 +9,7 @@ from esphome.components.esp32 import (
|
||||
from esphome.components.mdns import MDNSComponent, enable_mdns_storage
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_CHANNEL, CONF_ENABLE_IPV6, CONF_ID, CONF_USE_ADDRESS
|
||||
from esphome.core import CORE
|
||||
from esphome.core import CORE, TimePeriodMilliseconds
|
||||
import esphome.final_validate as fv
|
||||
from esphome.types import ConfigType
|
||||
|
||||
@@ -22,6 +22,7 @@ from .const import (
|
||||
CONF_NETWORK_KEY,
|
||||
CONF_NETWORK_NAME,
|
||||
CONF_PAN_ID,
|
||||
CONF_POLL_PERIOD,
|
||||
CONF_PSKC,
|
||||
CONF_SRP_ID,
|
||||
CONF_TLV,
|
||||
@@ -89,7 +90,7 @@ def set_sdkconfig_options(config):
|
||||
add_idf_sdkconfig_option("CONFIG_OPENTHREAD_SRP_CLIENT", True)
|
||||
add_idf_sdkconfig_option("CONFIG_OPENTHREAD_SRP_CLIENT_MAX_SERVICES", 5)
|
||||
|
||||
# TODO: Add suport for sleepy end devices
|
||||
# TODO: Add suport for synchronized sleepy end devices (SSED)
|
||||
add_idf_sdkconfig_option(f"CONFIG_OPENTHREAD_{config.get(CONF_DEVICE_TYPE)}", True)
|
||||
|
||||
|
||||
@@ -113,6 +114,17 @@ _CONNECTION_SCHEMA = cv.Schema(
|
||||
def _validate(config: ConfigType) -> ConfigType:
|
||||
if CONF_USE_ADDRESS not in config:
|
||||
config[CONF_USE_ADDRESS] = f"{CORE.name}.local"
|
||||
device_type = config.get(CONF_DEVICE_TYPE)
|
||||
poll_period = config.get(CONF_POLL_PERIOD)
|
||||
if (
|
||||
device_type == "FTD"
|
||||
and poll_period
|
||||
and poll_period > TimePeriodMilliseconds(milliseconds=0)
|
||||
):
|
||||
raise cv.Invalid(
|
||||
f"{CONF_POLL_PERIOD} can only be used with {CONF_DEVICE_TYPE}: MTD"
|
||||
)
|
||||
|
||||
return config
|
||||
|
||||
|
||||
@@ -135,6 +147,7 @@ CONFIG_SCHEMA = cv.All(
|
||||
cv.Optional(CONF_FORCE_DATASET): cv.boolean,
|
||||
cv.Optional(CONF_TLV): cv.string_strict,
|
||||
cv.Optional(CONF_USE_ADDRESS): cv.string_strict,
|
||||
cv.Optional(CONF_POLL_PERIOD): cv.positive_time_period_milliseconds,
|
||||
}
|
||||
).extend(_CONNECTION_SCHEMA),
|
||||
cv.has_exactly_one_key(CONF_NETWORK_KEY, CONF_TLV),
|
||||
@@ -167,6 +180,8 @@ async def to_code(config):
|
||||
ot = cg.new_Pvariable(config[CONF_ID])
|
||||
cg.add(ot.set_use_address(config[CONF_USE_ADDRESS]))
|
||||
await cg.register_component(ot, config)
|
||||
if (poll_period := config.get(CONF_POLL_PERIOD)) is not None:
|
||||
cg.add(ot.set_poll_period(poll_period))
|
||||
|
||||
srp = cg.new_Pvariable(config[CONF_SRP_ID])
|
||||
mdns_component = await cg.get_variable(config[CONF_MDNS_ID])
|
||||
|
||||
@@ -6,6 +6,7 @@ CONF_MESH_LOCAL_PREFIX = "mesh_local_prefix"
|
||||
CONF_NETWORK_NAME = "network_name"
|
||||
CONF_NETWORK_KEY = "network_key"
|
||||
CONF_PAN_ID = "pan_id"
|
||||
CONF_POLL_PERIOD = "poll_period"
|
||||
CONF_PSKC = "pskc"
|
||||
CONF_SRP_ID = "srp_id"
|
||||
CONF_TLV = "tlv"
|
||||
|
||||
@@ -29,6 +29,23 @@ OpenThreadComponent *global_openthread_component = // NOLINT(cppcoreguidelines-
|
||||
|
||||
OpenThreadComponent::OpenThreadComponent() { global_openthread_component = this; }
|
||||
|
||||
void OpenThreadComponent::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "Open Thread:");
|
||||
#if CONFIG_OPENTHREAD_FTD
|
||||
ESP_LOGCONFIG(TAG, " Device Type: FTD");
|
||||
#elif CONFIG_OPENTHREAD_MTD
|
||||
ESP_LOGCONFIG(TAG, " Device Type: MTD");
|
||||
// TBD: Synchronized Sleepy End Device
|
||||
if (this->poll_period > 0) {
|
||||
ESP_LOGCONFIG(TAG, " Device is configured as Sleepy End Device (SED)");
|
||||
uint32_t duration = this->poll_period / 1000;
|
||||
ESP_LOGCONFIG(TAG, " Poll Period: %" PRIu32 "s", duration);
|
||||
} else {
|
||||
ESP_LOGCONFIG(TAG, " Device is configured as Minimal End Device (MED)");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool OpenThreadComponent::is_connected() {
|
||||
auto lock = InstanceLock::try_acquire(100);
|
||||
if (!lock) {
|
||||
|
||||
@@ -22,6 +22,7 @@ class OpenThreadComponent : public Component {
|
||||
public:
|
||||
OpenThreadComponent();
|
||||
~OpenThreadComponent();
|
||||
void dump_config() override;
|
||||
void setup() override;
|
||||
bool teardown() override;
|
||||
float get_setup_priority() const override { return setup_priority::WIFI; }
|
||||
@@ -35,6 +36,9 @@ class OpenThreadComponent : public Component {
|
||||
|
||||
const char *get_use_address() const;
|
||||
void set_use_address(const char *use_address);
|
||||
#if CONFIG_OPENTHREAD_MTD
|
||||
void set_poll_period(uint32_t poll_period) { this->poll_period = poll_period; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
std::optional<otIp6Address> get_omr_address_(InstanceLock &lock);
|
||||
@@ -46,6 +50,9 @@ class OpenThreadComponent : public Component {
|
||||
// Stores a pointer to a string literal (static storage duration).
|
||||
// ONLY set from Python-generated code with string literals - never dynamic strings.
|
||||
const char *use_address_{""};
|
||||
#if CONFIG_OPENTHREAD_MTD
|
||||
uint32_t poll_period{0};
|
||||
#endif
|
||||
};
|
||||
|
||||
extern OpenThreadComponent *global_openthread_component; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
|
||||
@@ -105,6 +105,32 @@ void OpenThreadComponent::ot_main() {
|
||||
esp_cli_custom_command_init();
|
||||
#endif // CONFIG_OPENTHREAD_CLI_ESP_EXTENSION
|
||||
|
||||
otLinkModeConfig link_mode_config = {0};
|
||||
#if CONFIG_OPENTHREAD_FTD
|
||||
link_mode_config.mRxOnWhenIdle = true;
|
||||
link_mode_config.mDeviceType = true;
|
||||
link_mode_config.mNetworkData = true;
|
||||
#elif CONFIG_OPENTHREAD_MTD
|
||||
if (this->poll_period > 0) {
|
||||
if (otLinkSetPollPeriod(esp_openthread_get_instance(), this->poll_period) != OT_ERROR_NONE) {
|
||||
ESP_LOGE(TAG, "Failed to set OpenThread pollperiod.");
|
||||
}
|
||||
uint32_t link_polling_period = otLinkGetPollPeriod(esp_openthread_get_instance());
|
||||
ESP_LOGD(TAG, "Link Polling Period: %d", link_polling_period);
|
||||
}
|
||||
link_mode_config.mRxOnWhenIdle = this->poll_period == 0;
|
||||
link_mode_config.mDeviceType = false;
|
||||
link_mode_config.mNetworkData = false;
|
||||
#endif
|
||||
|
||||
if (otThreadSetLinkMode(esp_openthread_get_instance(), link_mode_config) != OT_ERROR_NONE) {
|
||||
ESP_LOGE(TAG, "Failed to set OpenThread linkmode.");
|
||||
}
|
||||
link_mode_config = otThreadGetLinkMode(esp_openthread_get_instance());
|
||||
ESP_LOGD(TAG, "Link Mode Device Type: %s", link_mode_config.mDeviceType ? "true" : "false");
|
||||
ESP_LOGD(TAG, "Link Mode Network Data: %s", link_mode_config.mNetworkData ? "true" : "false");
|
||||
ESP_LOGD(TAG, "Link Mode RX On When Idle: %s", link_mode_config.mRxOnWhenIdle ? "true" : "false");
|
||||
|
||||
// Run the main loop
|
||||
#if CONFIG_OPENTHREAD_CLI
|
||||
esp_openthread_cli_create_task();
|
||||
|
||||
@@ -2,7 +2,7 @@ network:
|
||||
enable_ipv6: true
|
||||
|
||||
openthread:
|
||||
device_type: FTD
|
||||
device_type: MTD
|
||||
channel: 13
|
||||
network_name: OpenThread-8f28
|
||||
network_key: 0xdfd34f0f05cad978ec4e32b0413038ff
|
||||
@@ -11,3 +11,5 @@ openthread:
|
||||
pskc: 0xc23a76e98f1a6483639b1ac1271e2e27
|
||||
mesh_local_prefix: fd53:145f:ed22:ad81::/64
|
||||
force_dataset: true
|
||||
use_address: open-thread-test.local
|
||||
poll_period: 20sec
|
||||
|
||||
Reference in New Issue
Block a user