diff --git a/esphome/components/ethernet/__init__.py b/esphome/components/ethernet/__init__.py index cd77ea6053..8eec9510cc 100644 --- a/esphome/components/ethernet/__init__.py +++ b/esphome/components/ethernet/__init__.py @@ -66,9 +66,10 @@ ETHERNET_TYPES = { "KSZ8081RNA": EthernetType.ETHERNET_TYPE_KSZ8081RNA, "W5500": EthernetType.ETHERNET_TYPE_W5500, "OPENETH": EthernetType.ETHERNET_TYPE_OPENETH, + "DM9051": EthernetType.ETHERNET_TYPE_DM9051, } -SPI_ETHERNET_TYPES = ["W5500"] +SPI_ETHERNET_TYPES = ["W5500", "DM9051"] SPI_ETHERNET_DEFAULT_POLLING_INTERVAL = TimePeriodMilliseconds(milliseconds=10) emac_rmii_clock_mode_t = cg.global_ns.enum("emac_rmii_clock_mode_t") @@ -224,6 +225,7 @@ CONFIG_SCHEMA = cv.All( "KSZ8081RNA": RMII_SCHEMA, "W5500": SPI_SCHEMA, "OPENETH": BASE_SCHEMA, + "DM9051": SPI_SCHEMA, }, upper=True, ), @@ -278,7 +280,7 @@ async def to_code(config): var = cg.new_Pvariable(config[CONF_ID]) await cg.register_component(var, config) - if config[CONF_TYPE] == "W5500": + if config[CONF_TYPE] in SPI_ETHERNET_TYPES: cg.add(var.set_clk_pin(config[CONF_CLK_PIN])) cg.add(var.set_miso_pin(config[CONF_MISO_PIN])) cg.add(var.set_mosi_pin(config[CONF_MOSI_PIN])) @@ -296,7 +298,9 @@ async def to_code(config): cg.add_define("USE_ETHERNET_SPI") if CORE.using_esp_idf: add_idf_sdkconfig_option("CONFIG_ETH_USE_SPI_ETHERNET", True) - add_idf_sdkconfig_option("CONFIG_ETH_SPI_ETHERNET_W5500", True) + add_idf_sdkconfig_option( + f"CONFIG_ETH_SPI_ETHERNET_{config[CONF_TYPE]}", True + ) elif config[CONF_TYPE] == "OPENETH": cg.add_define("USE_ETHERNET_OPENETH") add_idf_sdkconfig_option("CONFIG_ETH_USE_OPENETH", True) diff --git a/esphome/components/ethernet/ethernet_component.cpp b/esphome/components/ethernet/ethernet_component.cpp index 180a72ec7e..8739269f4a 100644 --- a/esphome/components/ethernet/ethernet_component.cpp +++ b/esphome/components/ethernet/ethernet_component.cpp @@ -90,8 +90,8 @@ void EthernetComponent::setup() { #ifdef USE_ETHERNET_SPI // Configure SPI interface and Ethernet driver for specific SPI module spi_device_interface_config_t devcfg = { - .command_bits = 16, // Actually it's the address phase in W5500 SPI frame - .address_bits = 8, // Actually it's the control phase in W5500 SPI frame + .command_bits = 0, + .address_bits = 0, .dummy_bits = 0, .mode = 0, .duty_cycle_pos = 0, @@ -107,22 +107,43 @@ void EthernetComponent::setup() { }; #if ESP_IDF_VERSION_MAJOR >= 5 +#if CONFIG_ETH_SPI_ETHERNET_W5500 eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(host, &devcfg); +#endif +#if CONFIG_ETH_SPI_ETHERNET_DM9051 + eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(host, &devcfg); +#endif #else spi_device_handle_t spi_handle = nullptr; err = spi_bus_add_device(host, &devcfg, &spi_handle); ESPHL_ERROR_CHECK(err, "SPI bus add device error"); +#if CONFIG_ETH_SPI_ETHERNET_W5500 eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(spi_handle); #endif +#if CONFIG_ETH_SPI_ETHERNET_DM9051 + eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(spi_handle); +#endif +#endif // ESP_IDF_VERSION_MAJOR >= 5 + +#if CONFIG_ETH_SPI_ETHERNET_W5500 w5500_config.int_gpio_num = this->interrupt_pin_; #ifdef USE_ETHERNET_SPI_POLLING_SUPPORT w5500_config.poll_period_ms = this->polling_interval_; #endif +#endif + +#if CONFIG_ETH_SPI_ETHERNET_DM9051 + dm9051_config.int_gpio_num = this->interrupt_pin_; +#ifdef USE_ETHERNET_SPI_POLLING_SUPPORT + dm9051_config.poll_period_ms = this->polling_interval_; +#endif +#endif + phy_config.phy_addr = this->phy_addr_spi_; phy_config.reset_gpio_num = this->reset_pin_; - esp_eth_mac_t *mac = esp_eth_mac_new_w5500(&w5500_config, &mac_config); + esp_eth_mac_t *mac = nullptr; #elif defined(USE_ETHERNET_OPENETH) esp_eth_mac_t *mac = esp_eth_mac_new_openeth(&mac_config); #else @@ -187,10 +208,20 @@ void EthernetComponent::setup() { } #endif #ifdef USE_ETHERNET_SPI +#if CONFIG_ETH_SPI_ETHERNET_W5500 case ETHERNET_TYPE_W5500: { + mac = esp_eth_mac_new_w5500(&w5500_config, &mac_config); this->phy_ = esp_eth_phy_new_w5500(&phy_config); break; } +#endif +#if CONFIG_ETH_SPI_ETHERNET_DM9051 + case ETHERNET_TYPE_DM9051: { + mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config); + this->phy_ = esp_eth_phy_new_dm9051(&phy_config); + break; + } +#endif #endif default: { this->mark_failed(); @@ -321,6 +352,10 @@ void EthernetComponent::dump_config() { eth_type = "OPENETH"; break; + case ETHERNET_TYPE_DM9051: + eth_type = "DM9051"; + break; + default: eth_type = "Unknown"; break; diff --git a/esphome/components/ethernet/ethernet_component.h b/esphome/components/ethernet/ethernet_component.h index 0f0eff5ded..6cdc113aa8 100644 --- a/esphome/components/ethernet/ethernet_component.h +++ b/esphome/components/ethernet/ethernet_component.h @@ -26,6 +26,7 @@ enum EthernetType : uint8_t { ETHERNET_TYPE_KSZ8081RNA, ETHERNET_TYPE_W5500, ETHERNET_TYPE_OPENETH, + ETHERNET_TYPE_DM9051, }; struct ManualIP { diff --git a/esphome/components/ld2420/ld2420.cpp b/esphome/components/ld2420/ld2420.cpp index 62f1685598..8a7d7de23b 100644 --- a/esphome/components/ld2420/ld2420.cpp +++ b/esphome/components/ld2420/ld2420.cpp @@ -63,38 +63,105 @@ namespace ld2420 { static const char *const TAG = "ld2420"; -float LD2420Component::get_setup_priority() const { return setup_priority::BUS; } +// Local const's +static const uint16_t REFRESH_RATE_MS = 1000; -void LD2420Component::dump_config() { - ESP_LOGCONFIG(TAG, - "LD2420:\n" - " Firmware version: %7s", - this->ld2420_firmware_ver_); -#ifdef USE_NUMBER - ESP_LOGCONFIG(TAG, "Number:"); - LOG_NUMBER(TAG, " Gate Timeout:", this->gate_timeout_number_); - LOG_NUMBER(TAG, " Gate Max Distance:", this->max_gate_distance_number_); - LOG_NUMBER(TAG, " Gate Min Distance:", this->min_gate_distance_number_); - LOG_NUMBER(TAG, " Gate Select:", this->gate_select_number_); - for (uint8_t gate = 0; gate < LD2420_TOTAL_GATES; gate++) { - LOG_NUMBER(TAG, " Gate Move Threshold:", this->gate_move_threshold_numbers_[gate]); - LOG_NUMBER(TAG, " Gate Still Threshold::", this->gate_still_threshold_numbers_[gate]); - } -#endif -#ifdef USE_BUTTON - LOG_BUTTON(TAG, " Apply Config:", this->apply_config_button_); - LOG_BUTTON(TAG, " Revert Edits:", this->revert_config_button_); - LOG_BUTTON(TAG, " Factory Reset:", this->factory_reset_button_); - LOG_BUTTON(TAG, " Restart Module:", this->restart_module_button_); -#endif - ESP_LOGCONFIG(TAG, "Select:"); - LOG_SELECT(TAG, " Operating Mode", this->operating_selector_); - if (LD2420Component::get_firmware_int(this->ld2420_firmware_ver_) < CALIBRATE_VERSION_MIN) { - ESP_LOGW(TAG, "Firmware version %s and older supports Simple Mode only", this->ld2420_firmware_ver_); +// Command sets +static const uint16_t CMD_DISABLE_CONF = 0x00FE; +static const uint16_t CMD_ENABLE_CONF = 0x00FF; +static const uint16_t CMD_PARM_HIGH_TRESH = 0x0012; +static const uint16_t CMD_PARM_LOW_TRESH = 0x0021; +static const uint16_t CMD_PROTOCOL_VER = 0x0002; +static const uint16_t CMD_READ_ABD_PARAM = 0x0008; +static const uint16_t CMD_READ_REG_ADDR = 0x0020; +static const uint16_t CMD_READ_REGISTER = 0x0002; +static const uint16_t CMD_READ_SERIAL_NUM = 0x0011; +static const uint16_t CMD_READ_SYS_PARAM = 0x0013; +static const uint16_t CMD_READ_VERSION = 0x0000; +static const uint16_t CMD_RESTART = 0x0068; +static const uint16_t CMD_SYSTEM_MODE = 0x0000; +static const uint16_t CMD_SYSTEM_MODE_GR = 0x0003; +static const uint16_t CMD_SYSTEM_MODE_MTT = 0x0001; +static const uint16_t CMD_SYSTEM_MODE_SIMPLE = 0x0064; +static const uint16_t CMD_SYSTEM_MODE_DEBUG = 0x0000; +static const uint16_t CMD_SYSTEM_MODE_ENERGY = 0x0004; +static const uint16_t CMD_SYSTEM_MODE_VS = 0x0002; +static const uint16_t CMD_WRITE_ABD_PARAM = 0x0007; +static const uint16_t CMD_WRITE_REGISTER = 0x0001; +static const uint16_t CMD_WRITE_SYS_PARAM = 0x0012; + +static const uint8_t CMD_ABD_DATA_REPLY_SIZE = 0x04; +static const uint8_t CMD_ABD_DATA_REPLY_START = 0x0A; +static const uint8_t CMD_MAX_BYTES = 0x64; +static const uint8_t CMD_REG_DATA_REPLY_SIZE = 0x02; + +static const uint8_t LD2420_ERROR_NONE = 0x00; +static const uint8_t LD2420_ERROR_TIMEOUT = 0x02; +static const uint8_t LD2420_ERROR_UNKNOWN = 0x01; + +// Register address values +static const uint16_t CMD_MIN_GATE_REG = 0x0000; +static const uint16_t CMD_MAX_GATE_REG = 0x0001; +static const uint16_t CMD_TIMEOUT_REG = 0x0004; +static const uint16_t CMD_GATE_MOVE_THRESH[TOTAL_GATES] = {0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, + 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, + 0x001C, 0x001D, 0x001E, 0x001F}; +static const uint16_t CMD_GATE_STILL_THRESH[TOTAL_GATES] = {0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, + 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, + 0x002C, 0x002D, 0x002E, 0x002F}; +static const uint32_t FACTORY_MOVE_THRESH[TOTAL_GATES] = {60000, 30000, 400, 250, 250, 250, 250, 250, + 250, 250, 250, 250, 250, 250, 250, 250}; +static const uint32_t FACTORY_STILL_THRESH[TOTAL_GATES] = {40000, 20000, 200, 200, 200, 200, 200, 150, + 150, 100, 100, 100, 100, 100, 100, 100}; +static const uint16_t FACTORY_TIMEOUT = 120; +static const uint16_t FACTORY_MIN_GATE = 1; +static const uint16_t FACTORY_MAX_GATE = 12; + +// COMMAND_BYTE Header & Footer +static const uint32_t CMD_FRAME_FOOTER = 0x01020304; +static const uint32_t CMD_FRAME_HEADER = 0xFAFBFCFD; +static const uint32_t DEBUG_FRAME_FOOTER = 0xFAFBFCFD; +static const uint32_t DEBUG_FRAME_HEADER = 0x1410BFAA; +static const uint32_t ENERGY_FRAME_FOOTER = 0xF5F6F7F8; +static const uint32_t ENERGY_FRAME_HEADER = 0xF1F2F3F4; +static const int CALIBRATE_VERSION_MIN = 154; +static const uint8_t CMD_FRAME_COMMAND = 6; +static const uint8_t CMD_FRAME_DATA_LENGTH = 4; +static const uint8_t CMD_FRAME_STATUS = 7; +static const uint8_t CMD_ERROR_WORD = 8; +static const uint8_t ENERGY_SENSOR_START = 9; +static const uint8_t CALIBRATE_REPORT_INTERVAL = 4; +static const std::string OP_NORMAL_MODE_STRING = "Normal"; +static const std::string OP_SIMPLE_MODE_STRING = "Simple"; + +// Memory-efficient lookup tables +struct StringToUint8 { + const char *str; + uint8_t value; +}; + +static constexpr StringToUint8 OP_MODE_BY_STR[] = { + {"Normal", OP_NORMAL_MODE}, + {"Calibrate", OP_CALIBRATE_MODE}, + {"Simple", OP_SIMPLE_MODE}, +}; + +static constexpr const char *ERR_MESSAGE[] = { + "None", + "Unknown", + "Timeout", +}; + +// Helper function for lookups +template uint8_t find_uint8(const StringToUint8 (&arr)[N], const std::string &str) { + for (const auto &entry : arr) { + if (str == entry.str) + return entry.value; } + return 0xFF; // Not found } -uint8_t LD2420Component::calc_checksum(void *data, size_t size) { +static uint8_t calc_checksum(void *data, size_t size) { uint8_t checksum = 0; uint8_t *data_bytes = (uint8_t *) data; for (size_t i = 0; i < size; i++) { @@ -103,7 +170,7 @@ uint8_t LD2420Component::calc_checksum(void *data, size_t size) { return checksum; } -int LD2420Component::get_firmware_int(const char *version_string) { +static int get_firmware_int(const char *version_string) { std::string version_str = version_string; if (version_str[0] == 'v') { version_str = version_str.substr(1); @@ -113,6 +180,37 @@ int LD2420Component::get_firmware_int(const char *version_string) { return version_integer; } +float LD2420Component::get_setup_priority() const { return setup_priority::BUS; } + +void LD2420Component::dump_config() { + ESP_LOGCONFIG(TAG, + "LD2420:\n" + " Firmware version: %7s", + this->firmware_ver_); +#ifdef USE_NUMBER + ESP_LOGCONFIG(TAG, "Number:"); + LOG_NUMBER(" ", "Gate Timeout:", this->gate_timeout_number_); + LOG_NUMBER(" ", "Gate Max Distance:", this->max_gate_distance_number_); + LOG_NUMBER(" ", "Gate Min Distance:", this->min_gate_distance_number_); + LOG_NUMBER(" ", "Gate Select:", this->gate_select_number_); + for (uint8_t gate = 0; gate < TOTAL_GATES; gate++) { + LOG_NUMBER(" ", "Gate Move Threshold:", this->gate_move_threshold_numbers_[gate]); + LOG_NUMBER(" ", "Gate Still Threshold::", this->gate_still_threshold_numbers_[gate]); + } +#endif +#ifdef USE_BUTTON + LOG_BUTTON(" ", "Apply Config:", this->apply_config_button_); + LOG_BUTTON(" ", "Revert Edits:", this->revert_config_button_); + LOG_BUTTON(" ", "Factory Reset:", this->factory_reset_button_); + LOG_BUTTON(" ", "Restart Module:", this->restart_module_button_); +#endif + ESP_LOGCONFIG(TAG, "Select:"); + LOG_SELECT(" ", "Operating Mode", this->operating_selector_); + if (ld2420::get_firmware_int(this->firmware_ver_) < CALIBRATE_VERSION_MIN) { + ESP_LOGW(TAG, "Firmware version %s and older supports Simple Mode only", this->firmware_ver_); + } +} + void LD2420Component::setup() { ESP_LOGCONFIG(TAG, "Running setup"); if (this->set_config_mode(true) == LD2420_ERROR_TIMEOUT) { @@ -125,24 +223,24 @@ void LD2420Component::setup() { this->init_gate_config_numbers(); #endif this->get_firmware_version_(); - const char *pfw = this->ld2420_firmware_ver_; + const char *pfw = this->firmware_ver_; std::string fw_str(pfw); for (auto &listener : this->listeners_) { listener->on_fw_version(fw_str); } - for (uint8_t gate = 0; gate < LD2420_TOTAL_GATES; gate++) { + for (uint8_t gate = 0; gate < TOTAL_GATES; gate++) { delay_microseconds_safe(125); this->get_gate_threshold_(gate); } memcpy(&this->new_config, &this->current_config, sizeof(this->current_config)); - if (LD2420Component::get_firmware_int(this->ld2420_firmware_ver_) < CALIBRATE_VERSION_MIN) { + if (ld2420::get_firmware_int(this->firmware_ver_) < CALIBRATE_VERSION_MIN) { this->set_operating_mode(OP_SIMPLE_MODE_STRING); this->operating_selector_->publish_state(OP_SIMPLE_MODE_STRING); this->set_mode_(CMD_SYSTEM_MODE_SIMPLE); - ESP_LOGW(TAG, "Firmware version %s and older supports Simple Mode only", this->ld2420_firmware_ver_); + ESP_LOGW(TAG, "Firmware version %s and older supports Simple Mode only", this->firmware_ver_); } else { this->set_mode_(CMD_SYSTEM_MODE_ENERGY); this->operating_selector_->publish_state(OP_NORMAL_MODE_STRING); @@ -167,7 +265,7 @@ void LD2420Component::apply_config_action() { return; } this->set_min_max_distances_timeout(this->new_config.max_gate, this->new_config.min_gate, this->new_config.timeout); - for (uint8_t gate = 0; gate < LD2420_TOTAL_GATES; gate++) { + for (uint8_t gate = 0; gate < TOTAL_GATES; gate++) { delay_microseconds_safe(125); this->set_gate_threshold(gate); } @@ -193,7 +291,7 @@ void LD2420Component::factory_reset_action() { this->min_gate_distance_number_->state = FACTORY_MIN_GATE; this->max_gate_distance_number_->state = FACTORY_MAX_GATE; #endif - for (uint8_t gate = 0; gate < LD2420_TOTAL_GATES; gate++) { + for (uint8_t gate = 0; gate < TOTAL_GATES; gate++) { this->new_config.move_thresh[gate] = FACTORY_MOVE_THRESH[gate]; this->new_config.still_thresh[gate] = FACTORY_STILL_THRESH[gate]; delay_microseconds_safe(125); @@ -241,7 +339,7 @@ void LD2420Component::loop() { } void LD2420Component::update_radar_data(uint16_t const *gate_energy, uint8_t sample_number) { - for (uint8_t gate = 0; gate < LD2420_TOTAL_GATES; ++gate) { + for (uint8_t gate = 0; gate < TOTAL_GATES; ++gate) { this->radar_data[gate][sample_number] = gate_energy[gate]; } this->total_sample_number_counter++; @@ -251,7 +349,7 @@ void LD2420Component::auto_calibrate_sensitivity() { // Calculate average and peak values for each gate const float move_factor = gate_move_sensitivity_factor + 1; const float still_factor = (gate_still_sensitivity_factor / 2) + 1; - for (uint8_t gate = 0; gate < LD2420_TOTAL_GATES; ++gate) { + for (uint8_t gate = 0; gate < TOTAL_GATES; ++gate) { uint32_t sum = 0; uint16_t peak = 0; @@ -280,7 +378,7 @@ void LD2420Component::auto_calibrate_sensitivity() { } void LD2420Component::report_gate_data() { - for (uint8_t gate = 0; gate < LD2420_TOTAL_GATES; ++gate) { + for (uint8_t gate = 0; gate < TOTAL_GATES; ++gate) { // Output results ESP_LOGI(TAG, "Gate: %2d Avg: %5d Peak: %5d", gate, this->gate_avg[gate], this->gate_peak[gate]); } @@ -289,13 +387,13 @@ void LD2420Component::report_gate_data() { void LD2420Component::set_operating_mode(const std::string &state) { // If unsupported firmware ignore mode select - if (LD2420Component::get_firmware_int(ld2420_firmware_ver_) >= CALIBRATE_VERSION_MIN) { - this->current_operating_mode = OP_MODE_TO_UINT.at(state); + if (ld2420::get_firmware_int(firmware_ver_) >= CALIBRATE_VERSION_MIN) { + this->current_operating_mode = find_uint8(OP_MODE_BY_STR, state); // Entering Auto Calibrate we need to clear the privoiuos data collection this->operating_selector_->publish_state(state); if (current_operating_mode == OP_CALIBRATE_MODE) { this->set_calibration_(true); - for (uint8_t gate = 0; gate < LD2420_TOTAL_GATES; gate++) { + for (uint8_t gate = 0; gate < TOTAL_GATES; gate++) { this->gate_avg[gate] = 0; this->gate_peak[gate] = 0; for (uint8_t i = 0; i < CALIBRATE_SAMPLES; i++) { @@ -330,11 +428,12 @@ void LD2420Component::readline_(int rx_data, uint8_t *buffer, int len) { this->set_cmd_active_(false); // Set command state to inactive after responce. this->handle_ack_data_(buffer, pos); pos = 0; - } else if ((buffer[pos - 2] == 0x0D && buffer[pos - 1] == 0x0A) && (get_mode_() == CMD_SYSTEM_MODE_SIMPLE)) { + } else if ((buffer[pos - 2] == 0x0D && buffer[pos - 1] == 0x0A) && + (this->get_mode_() == CMD_SYSTEM_MODE_SIMPLE)) { this->handle_simple_mode_(buffer, pos); pos = 0; } else if ((memcmp(&buffer[pos - 4], &ENERGY_FRAME_FOOTER, sizeof(ENERGY_FRAME_FOOTER)) == 0) && - (get_mode_() == CMD_SYSTEM_MODE_ENERGY)) { + (this->get_mode_() == CMD_SYSTEM_MODE_ENERGY)) { this->handle_energy_mode_(buffer, pos); pos = 0; } @@ -483,8 +582,8 @@ void LD2420Component::handle_ack_data_(uint8_t *buffer, int len) { ESP_LOGV(TAG, "Set system parameter(s): %2X %s", CMD_WRITE_SYS_PARAM, result); break; case (CMD_READ_VERSION): - memcpy(this->ld2420_firmware_ver_, &buffer[12], buffer[10]); - ESP_LOGV(TAG, "Firmware version: %7s %s", this->ld2420_firmware_ver_, result); + memcpy(this->firmware_ver_, &buffer[12], buffer[10]); + ESP_LOGV(TAG, "Firmware version: %7s %s", this->firmware_ver_, result); break; default: break; @@ -753,7 +852,7 @@ void LD2420Component::init_gate_config_numbers() { this->gate_move_sensitivity_factor_number_->publish_state(this->gate_move_sensitivity_factor); if (this->gate_still_sensitivity_factor_number_ != nullptr) this->gate_still_sensitivity_factor_number_->publish_state(this->gate_still_sensitivity_factor); - for (uint8_t gate = 0; gate < LD2420_TOTAL_GATES; gate++) { + for (uint8_t gate = 0; gate < TOTAL_GATES; gate++) { if (this->gate_still_threshold_numbers_[gate] != nullptr) { this->gate_still_threshold_numbers_[gate]->publish_state( static_cast(this->current_config.still_thresh[gate])); diff --git a/esphome/components/ld2420/ld2420.h b/esphome/components/ld2420/ld2420.h index 5e011100e6..d574a25c89 100644 --- a/esphome/components/ld2420/ld2420.h +++ b/esphome/components/ld2420/ld2420.h @@ -16,88 +16,18 @@ #ifdef USE_BUTTON #include "esphome/components/button/button.h" #endif -#include -#include namespace esphome { namespace ld2420 { -// Local const's -static const uint16_t REFRESH_RATE_MS = 1000; - -// Command sets -static const uint8_t CMD_ABD_DATA_REPLY_SIZE = 0x04; -static const uint8_t CMD_ABD_DATA_REPLY_START = 0x0A; -static const uint16_t CMD_DISABLE_CONF = 0x00FE; -static const uint16_t CMD_ENABLE_CONF = 0x00FF; -static const uint8_t CMD_MAX_BYTES = 0x64; -static const uint16_t CMD_PARM_HIGH_TRESH = 0x0012; -static const uint16_t CMD_PARM_LOW_TRESH = 0x0021; -static const uint16_t CMD_PROTOCOL_VER = 0x0002; -static const uint16_t CMD_READ_ABD_PARAM = 0x0008; -static const uint16_t CMD_READ_REG_ADDR = 0x0020; -static const uint16_t CMD_READ_REGISTER = 0x0002; -static const uint16_t CMD_READ_SERIAL_NUM = 0x0011; -static const uint16_t CMD_READ_SYS_PARAM = 0x0013; -static const uint16_t CMD_READ_VERSION = 0x0000; -static const uint8_t CMD_REG_DATA_REPLY_SIZE = 0x02; -static const uint16_t CMD_RESTART = 0x0068; -static const uint16_t CMD_SYSTEM_MODE = 0x0000; -static const uint16_t CMD_SYSTEM_MODE_GR = 0x0003; -static const uint16_t CMD_SYSTEM_MODE_MTT = 0x0001; -static const uint16_t CMD_SYSTEM_MODE_SIMPLE = 0x0064; -static const uint16_t CMD_SYSTEM_MODE_DEBUG = 0x0000; -static const uint16_t CMD_SYSTEM_MODE_ENERGY = 0x0004; -static const uint16_t CMD_SYSTEM_MODE_VS = 0x0002; -static const uint16_t CMD_WRITE_ABD_PARAM = 0x0007; -static const uint16_t CMD_WRITE_REGISTER = 0x0001; -static const uint16_t CMD_WRITE_SYS_PARAM = 0x0012; - -static const uint8_t LD2420_ERROR_NONE = 0x00; -static const uint8_t LD2420_ERROR_TIMEOUT = 0x02; -static const uint8_t LD2420_ERROR_UNKNOWN = 0x01; -static const uint8_t LD2420_TOTAL_GATES = 16; +static const uint8_t TOTAL_GATES = 16; static const uint8_t CALIBRATE_SAMPLES = 64; -// Register address values -static const uint16_t CMD_MIN_GATE_REG = 0x0000; -static const uint16_t CMD_MAX_GATE_REG = 0x0001; -static const uint16_t CMD_TIMEOUT_REG = 0x0004; -static const uint16_t CMD_GATE_MOVE_THRESH[LD2420_TOTAL_GATES] = {0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, - 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, - 0x001C, 0x001D, 0x001E, 0x001F}; -static const uint16_t CMD_GATE_STILL_THRESH[LD2420_TOTAL_GATES] = {0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, - 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, - 0x002C, 0x002D, 0x002E, 0x002F}; -static const uint32_t FACTORY_MOVE_THRESH[LD2420_TOTAL_GATES] = {60000, 30000, 400, 250, 250, 250, 250, 250, - 250, 250, 250, 250, 250, 250, 250, 250}; -static const uint32_t FACTORY_STILL_THRESH[LD2420_TOTAL_GATES] = {40000, 20000, 200, 200, 200, 200, 200, 150, - 150, 100, 100, 100, 100, 100, 100, 100}; -static const uint16_t FACTORY_TIMEOUT = 120; -static const uint16_t FACTORY_MIN_GATE = 1; -static const uint16_t FACTORY_MAX_GATE = 12; - -// COMMAND_BYTE Header & Footer -static const uint8_t CMD_FRAME_COMMAND = 6; -static const uint8_t CMD_FRAME_DATA_LENGTH = 4; -static const uint32_t CMD_FRAME_FOOTER = 0x01020304; -static const uint32_t CMD_FRAME_HEADER = 0xFAFBFCFD; -static const uint32_t DEBUG_FRAME_FOOTER = 0xFAFBFCFD; -static const uint32_t DEBUG_FRAME_HEADER = 0x1410BFAA; -static const uint32_t ENERGY_FRAME_FOOTER = 0xF5F6F7F8; -static const uint32_t ENERGY_FRAME_HEADER = 0xF1F2F3F4; -static const uint8_t CMD_FRAME_STATUS = 7; -static const uint8_t CMD_ERROR_WORD = 8; -static const uint8_t ENERGY_SENSOR_START = 9; -static const uint8_t CALIBRATE_REPORT_INTERVAL = 4; -static const int CALIBRATE_VERSION_MIN = 154; -static const std::string OP_NORMAL_MODE_STRING = "Normal"; -static const std::string OP_SIMPLE_MODE_STRING = "Simple"; - -enum OpModeStruct : uint8_t { OP_NORMAL_MODE = 1, OP_CALIBRATE_MODE = 2, OP_SIMPLE_MODE = 3 }; -static const std::map OP_MODE_TO_UINT{ - {"Normal", OP_NORMAL_MODE}, {"Calibrate", OP_CALIBRATE_MODE}, {"Simple", OP_SIMPLE_MODE}}; -static constexpr const char *ERR_MESSAGE[] = {"None", "Unknown", "Timeout"}; +enum OpMode : uint8_t { + OP_NORMAL_MODE = 1, + OP_CALIBRATE_MODE = 2, + OP_SIMPLE_MODE = 3, +}; class LD2420Listener { public: @@ -109,6 +39,23 @@ class LD2420Listener { class LD2420Component : public Component, public uart::UARTDevice { public: + struct CmdFrameT { + uint32_t header{0}; + uint32_t footer{0}; + uint16_t length{0}; + uint16_t command{0}; + uint16_t data_length{0}; + uint8_t data[18]; + }; + + struct RegConfigT { + uint32_t move_thresh[TOTAL_GATES]; + uint32_t still_thresh[TOTAL_GATES]; + uint16_t min_gate{0}; + uint16_t max_gate{0}; + uint16_t timeout{0}; + }; + void setup() override; void dump_config() override; void loop() override; @@ -150,23 +97,6 @@ class LD2420Component : public Component, public uart::UARTDevice { #endif void register_listener(LD2420Listener *listener) { this->listeners_.push_back(listener); } - struct CmdFrameT { - uint32_t header{0}; - uint16_t length{0}; - uint16_t command{0}; - uint8_t data[18]; - uint16_t data_length{0}; - uint32_t footer{0}; - }; - - struct RegConfigT { - uint16_t min_gate{0}; - uint16_t max_gate{0}; - uint16_t timeout{0}; - uint32_t move_thresh[LD2420_TOTAL_GATES]; - uint32_t still_thresh[LD2420_TOTAL_GATES]; - }; - void send_module_restart(); void restart_module_action(); void apply_config_action(); @@ -179,23 +109,28 @@ class LD2420Component : public Component, public uart::UARTDevice { void set_operating_mode(const std::string &state); void auto_calibrate_sensitivity(); void update_radar_data(uint16_t const *gate_energy, uint8_t sample_number); - static uint8_t calc_checksum(void *data, size_t size); + uint8_t set_config_mode(bool enable); + void set_min_max_distances_timeout(uint32_t max_gate_distance, uint32_t min_gate_distance, uint32_t timeout); + void set_gate_threshold(uint8_t gate); + void set_reg_value(uint16_t reg, uint16_t value); + void set_system_mode(uint16_t mode); + void ld2420_restart(); - RegConfigT current_config; - RegConfigT new_config; + float gate_move_sensitivity_factor{0.5}; + float gate_still_sensitivity_factor{0.5}; int32_t last_periodic_millis = millis(); int32_t report_periodic_millis = millis(); int32_t monitor_periodic_millis = millis(); int32_t last_normal_periodic_millis = millis(); - bool output_energy_state{false}; - uint8_t current_operating_mode{OP_NORMAL_MODE}; - uint16_t radar_data[LD2420_TOTAL_GATES][CALIBRATE_SAMPLES]; - uint16_t gate_avg[LD2420_TOTAL_GATES]; - uint16_t gate_peak[LD2420_TOTAL_GATES]; - uint8_t sample_number_counter{0}; + uint16_t radar_data[TOTAL_GATES][CALIBRATE_SAMPLES]; + uint16_t gate_avg[TOTAL_GATES]; + uint16_t gate_peak[TOTAL_GATES]; uint16_t total_sample_number_counter{0}; - float gate_move_sensitivity_factor{0.5}; - float gate_still_sensitivity_factor{0.5}; + uint8_t current_operating_mode{OP_NORMAL_MODE}; + uint8_t sample_number_counter{0}; + bool output_energy_state{false}; + RegConfigT current_config; + RegConfigT new_config; #ifdef USE_SELECT select::Select *operating_selector_{nullptr}; #endif @@ -205,24 +140,17 @@ class LD2420Component : public Component, public uart::UARTDevice { button::Button *restart_module_button_{nullptr}; button::Button *factory_reset_button_{nullptr}; #endif - void set_min_max_distances_timeout(uint32_t max_gate_distance, uint32_t min_gate_distance, uint32_t timeout); - void set_gate_threshold(uint8_t gate); - void set_reg_value(uint16_t reg, uint16_t value); - uint8_t set_config_mode(bool enable); - void set_system_mode(uint16_t mode); - void ld2420_restart(); protected: struct CmdReplyT { + uint32_t data[4]; + uint16_t error; uint8_t command; uint8_t status; - uint32_t data[4]; uint8_t length; - uint16_t error; volatile bool ack; }; - static int get_firmware_int(const char *version_string); void get_firmware_version_(); int get_gate_threshold_(uint8_t gate); void get_reg_value_(uint16_t reg); @@ -253,17 +181,17 @@ class LD2420Component : public Component, public uart::UARTDevice { std::vector gate_move_threshold_numbers_ = std::vector(16); #endif - uint16_t gate_energy_[LD2420_TOTAL_GATES]; - CmdReplyT cmd_reply_; uint32_t max_distance_gate_; uint32_t min_distance_gate_; - uint16_t system_mode_{CMD_SYSTEM_MODE_ENERGY}; - bool cmd_active_{false}; - char ld2420_firmware_ver_[8]{"v0.0.0"}; - bool presence_{false}; - bool calibration_{false}; + uint16_t system_mode_; + uint16_t gate_energy_[TOTAL_GATES]; uint16_t distance_{0}; uint8_t config_checksum_{0}; + char firmware_ver_[8]{"v0.0.0"}; + bool cmd_active_{false}; + bool presence_{false}; + bool calibration_{false}; + CmdReplyT cmd_reply_; std::vector listeners_{}; }; diff --git a/esphome/components/ld2420/sensor/ld2420_sensor.h b/esphome/components/ld2420/sensor/ld2420_sensor.h index 4eebefe0e3..82730d60e3 100644 --- a/esphome/components/ld2420/sensor/ld2420_sensor.h +++ b/esphome/components/ld2420/sensor/ld2420_sensor.h @@ -27,7 +27,7 @@ class LD2420Sensor : public LD2420Listener, public Component, sensor::Sensor { protected: sensor::Sensor *distance_sensor_{nullptr}; - std::vector energy_sensors_ = std::vector(LD2420_TOTAL_GATES); + std::vector energy_sensors_ = std::vector(TOTAL_GATES); }; } // namespace ld2420 diff --git a/esphome/components/light/light_color_values.h b/esphome/components/light/light_color_values.h index ca32b9c571..d8eaa6ae24 100644 --- a/esphome/components/light/light_color_values.h +++ b/esphome/components/light/light_color_values.h @@ -86,16 +86,16 @@ class LightColorValues { static LightColorValues lerp(const LightColorValues &start, const LightColorValues &end, float completion) { LightColorValues v; v.set_color_mode(end.color_mode_); - v.set_state(esphome::lerp(completion, start.get_state(), end.get_state())); - v.set_brightness(esphome::lerp(completion, start.get_brightness(), end.get_brightness())); - v.set_color_brightness(esphome::lerp(completion, start.get_color_brightness(), end.get_color_brightness())); - v.set_red(esphome::lerp(completion, start.get_red(), end.get_red())); - v.set_green(esphome::lerp(completion, start.get_green(), end.get_green())); - v.set_blue(esphome::lerp(completion, start.get_blue(), end.get_blue())); - v.set_white(esphome::lerp(completion, start.get_white(), end.get_white())); - v.set_color_temperature(esphome::lerp(completion, start.get_color_temperature(), end.get_color_temperature())); - v.set_cold_white(esphome::lerp(completion, start.get_cold_white(), end.get_cold_white())); - v.set_warm_white(esphome::lerp(completion, start.get_warm_white(), end.get_warm_white())); + v.set_state(std::lerp(start.get_state(), end.get_state(), completion)); + v.set_brightness(std::lerp(start.get_brightness(), end.get_brightness(), completion)); + v.set_color_brightness(std::lerp(start.get_color_brightness(), end.get_color_brightness(), completion)); + v.set_red(std::lerp(start.get_red(), end.get_red(), completion)); + v.set_green(std::lerp(start.get_green(), end.get_green(), completion)); + v.set_blue(std::lerp(start.get_blue(), end.get_blue(), completion)); + v.set_white(std::lerp(start.get_white(), end.get_white(), completion)); + v.set_color_temperature(std::lerp(start.get_color_temperature(), end.get_color_temperature(), completion)); + v.set_cold_white(std::lerp(start.get_cold_white(), end.get_cold_white(), completion)); + v.set_warm_white(std::lerp(start.get_warm_white(), end.get_warm_white(), completion)); return v; } diff --git a/esphome/components/ota/ota_backend_esp_idf.h b/esphome/components/ota/ota_backend_esp_idf.h index deed354499..51d9563112 100644 --- a/esphome/components/ota/ota_backend_esp_idf.h +++ b/esphome/components/ota/ota_backend_esp_idf.h @@ -12,7 +12,7 @@ namespace ota { class IDFOTABackend : public OTABackend { public: - IDFOTABackend() : md5_set_(false), expected_bin_md5_{} {} + IDFOTABackend() : expected_bin_md5_{}, md5_set_(false) {} OTAResponseTypes begin(size_t image_size) override; void set_update_md5(const char *md5) override; OTAResponseTypes write(uint8_t *data, size_t len) override; diff --git a/esphome/components/remote_base/__init__.py b/esphome/components/remote_base/__init__.py index 836b98104b..fc824ef704 100644 --- a/esphome/components/remote_base/__init__.py +++ b/esphome/components/remote_base/__init__.py @@ -57,7 +57,7 @@ RemoteReceiverBinarySensorBase = ns.class_( RemoteReceiverTrigger = ns.class_( "RemoteReceiverTrigger", automation.Trigger, RemoteReceiverListener ) -RemoteTransmitterDumper = ns.class_("RemoteTransmitterDumper") +RemoteReceiverDumperBase = ns.class_("RemoteReceiverDumperBase") RemoteTransmittable = ns.class_("RemoteTransmittable") RemoteTransmitterActionBase = ns.class_( "RemoteTransmitterActionBase", RemoteTransmittable, automation.Action @@ -126,8 +126,10 @@ def register_trigger(name, type, data_type): return decorator -def register_dumper(name, type): - registerer = DUMPER_REGISTRY.register(name, type, {}) +def register_dumper(name, type, schema=None): + if schema is None: + schema = {} + registerer = DUMPER_REGISTRY.register(name, type, schema) def decorator(func): async def new_func(config, dumper_id): @@ -189,7 +191,7 @@ def declare_protocol(name): binary_sensor_ = ns.class_(f"{name}BinarySensor", RemoteReceiverBinarySensorBase) trigger = ns.class_(f"{name}Trigger", RemoteReceiverTrigger) action = ns.class_(f"{name}Action", RemoteTransmitterActionBase) - dumper = ns.class_(f"{name}Dumper", RemoteTransmitterDumper) + dumper = ns.class_(f"{name}Dumper", RemoteReceiverDumperBase) return data, binary_sensor_, trigger, action, dumper @@ -1405,7 +1407,7 @@ rc_switch_protocols = ns.RC_SWITCH_PROTOCOLS RCSwitchData = ns.struct("RCSwitchData") RCSwitchBase = ns.class_("RCSwitchBase") RCSwitchTrigger = ns.class_("RCSwitchTrigger", RemoteReceiverTrigger) -RCSwitchDumper = ns.class_("RCSwitchDumper", RemoteTransmitterDumper) +RCSwitchDumper = ns.class_("RCSwitchDumper", RemoteReceiverDumperBase) RCSwitchRawAction = ns.class_("RCSwitchRawAction", RemoteTransmitterActionBase) RCSwitchTypeAAction = ns.class_("RCSwitchTypeAAction", RemoteTransmitterActionBase) RCSwitchTypeBAction = ns.class_("RCSwitchTypeBAction", RemoteTransmitterActionBase) diff --git a/esphome/components/remote_base/remote_base.cpp b/esphome/components/remote_base/remote_base.cpp index 987286b345..34aba236b3 100644 --- a/esphome/components/remote_base/remote_base.cpp +++ b/esphome/components/remote_base/remote_base.cpp @@ -19,6 +19,22 @@ bool RemoteReceiveData::peek_mark(uint32_t length, uint32_t offset) const { return value >= 0 && lo <= value && value <= hi; } +bool RemoteReceiveData::peek_mark_at_least(uint32_t length, uint32_t offset) const { + if (!this->is_valid(offset)) + return false; + const int32_t value = this->peek(offset); + const int32_t lo = this->lower_bound_(length); + return value >= 0 && lo <= value; +} + +bool RemoteReceiveData::peek_mark_at_most(uint32_t length, uint32_t offset) const { + if (!this->is_valid(offset)) + return false; + const int32_t value = this->peek(offset); + const int32_t hi = this->upper_bound_(length); + return value >= 0 && value <= hi; +} + bool RemoteReceiveData::peek_space(uint32_t length, uint32_t offset) const { if (!this->is_valid(offset)) return false; @@ -36,6 +52,14 @@ bool RemoteReceiveData::peek_space_at_least(uint32_t length, uint32_t offset) co return value <= 0 && lo <= -value; } +bool RemoteReceiveData::peek_space_at_most(uint32_t length, uint32_t offset) const { + if (!this->is_valid(offset)) + return false; + const int32_t value = this->peek(offset); + const int32_t hi = this->upper_bound_(length); + return value <= 0 && -value <= hi; +} + bool RemoteReceiveData::expect_mark(uint32_t length) { if (!this->peek_mark(length)) return false; diff --git a/esphome/components/remote_base/remote_base.h b/esphome/components/remote_base/remote_base.h index a18dd0ed7e..b740ba8085 100644 --- a/esphome/components/remote_base/remote_base.h +++ b/esphome/components/remote_base/remote_base.h @@ -53,8 +53,11 @@ class RemoteReceiveData { bool is_valid(uint32_t offset = 0) const { return this->index_ + offset < this->data_.size(); } int32_t peek(uint32_t offset = 0) const { return this->data_[this->index_ + offset]; } bool peek_mark(uint32_t length, uint32_t offset = 0) const; + bool peek_mark_at_least(uint32_t length, uint32_t offset = 0) const; + bool peek_mark_at_most(uint32_t length, uint32_t offset = 0) const; bool peek_space(uint32_t length, uint32_t offset = 0) const; bool peek_space_at_least(uint32_t length, uint32_t offset = 0) const; + bool peek_space_at_most(uint32_t length, uint32_t offset = 0) const; bool peek_item(uint32_t mark, uint32_t space, uint32_t offset = 0) const { return this->peek_space(space, offset + 1) && this->peek_mark(mark, offset); } diff --git a/esphome/components/web_server/__init__.py b/esphome/components/web_server/__init__.py index 9f6946b181..bf9685e4a2 100644 --- a/esphome/components/web_server/__init__.py +++ b/esphome/components/web_server/__init__.py @@ -34,11 +34,21 @@ from esphome.const import ( from esphome.core import CORE, coroutine_with_priority import esphome.final_validate as fv -AUTO_LOAD = ["json", "web_server_base"] - CONF_SORTING_GROUP_ID = "sorting_group_id" CONF_SORTING_GROUPS = "sorting_groups" CONF_SORTING_WEIGHT = "sorting_weight" +OTA_DEFAULT = True + + +def AUTO_LOAD() -> list[str]: + """Return the components that should be automatically loaded.""" + components = ["json", "web_server_base"] + if CORE.using_esp_idf and CORE.config is not None: + web_server_conf = CORE.config.get(CONF_WEB_SERVER, {}) + if web_server_conf.get(CONF_OTA, OTA_DEFAULT): + components.append("ota") + return components + web_server_ns = cg.esphome_ns.namespace("web_server") WebServer = web_server_ns.class_("WebServer", cg.Component, cg.Controller) @@ -169,7 +179,7 @@ CONFIG_SCHEMA = cv.All( web_server_base.WebServerBase ), cv.Optional(CONF_INCLUDE_INTERNAL, default=False): cv.boolean, - cv.Optional(CONF_OTA, default=True): cv.boolean, + cv.Optional(CONF_OTA, default=OTA_DEFAULT): cv.boolean, cv.Optional(CONF_LOG, default=True): cv.boolean, cv.Optional(CONF_LOCAL): cv.boolean, cv.Optional(CONF_SORTING_GROUPS): cv.ensure_list(sorting_group), @@ -271,7 +281,7 @@ async def to_code(config): cg.add(var.set_css_url(config[CONF_CSS_URL])) cg.add(var.set_js_url(config[CONF_JS_URL])) cg.add(var.set_allow_ota(config[CONF_OTA])) - if config[CONF_OTA] and "ota" in CORE.config: + if config[CONF_OTA]: cg.add_define("USE_WEBSERVER_OTA") cg.add(var.set_expose_log(config[CONF_LOG])) if config[CONF_ENABLE_PRIVATE_NETWORK_ACCESS]: diff --git a/esphome/components/web_server_base/web_server_base.cpp b/esphome/components/web_server_base/web_server_base.cpp index 39cae36b2d..f0a8ea58e6 100644 --- a/esphome/components/web_server_base/web_server_base.cpp +++ b/esphome/components/web_server_base/web_server_base.cpp @@ -51,7 +51,7 @@ void OTARequestHandler::report_ota_progress_(AsyncWebServerRequest *request) { void OTARequestHandler::schedule_ota_reboot_() { ESP_LOGI(TAG, "OTA update successful!"); - this->parent_->set_timeout(100, [this]() { + this->parent_->set_timeout(100, []() { ESP_LOGI(TAG, "Performing OTA reboot now"); App.safe_reboot(); }); diff --git a/esphome/components/web_server_idf/multipart.h b/esphome/components/web_server_idf/multipart.h index 073e1e7c2b..967c72ffa5 100644 --- a/esphome/components/web_server_idf/multipart.h +++ b/esphome/components/web_server_idf/multipart.h @@ -2,12 +2,13 @@ #include "esphome/core/defines.h" #if defined(USE_ESP_IDF) && defined(USE_WEBSERVER_OTA) -#include -#include -#include -#include #include #include +#include +#include +#include +#include +#include namespace esphome { namespace web_server_idf { @@ -33,8 +34,8 @@ class MultipartReader { ~MultipartReader(); // Set callbacks for handling data - void set_data_callback(DataCallback callback) { data_callback_ = callback; } - void set_part_complete_callback(PartCompleteCallback callback) { part_complete_callback_ = callback; } + void set_data_callback(DataCallback callback) { data_callback_ = std::move(callback); } + void set_part_complete_callback(PartCompleteCallback callback) { part_complete_callback_ = std::move(callback); } // Parse incoming data size_t parse(const char *data, size_t len); diff --git a/tests/components/ethernet/common-dm9051.yaml b/tests/components/ethernet/common-dm9051.yaml new file mode 100644 index 0000000000..c878ca6e59 --- /dev/null +++ b/tests/components/ethernet/common-dm9051.yaml @@ -0,0 +1,14 @@ +ethernet: + type: DM9051 + clk_pin: 19 + mosi_pin: 21 + miso_pin: 23 + cs_pin: 18 + interrupt_pin: 36 + reset_pin: 22 + clock_speed: 10Mhz + manual_ip: + static_ip: 192.168.178.56 + gateway: 192.168.178.1 + subnet: 255.255.255.0 + domain: .local diff --git a/tests/components/ethernet/test-dm9051.esp32-ard.yaml b/tests/components/ethernet/test-dm9051.esp32-ard.yaml new file mode 100644 index 0000000000..23e3b97740 --- /dev/null +++ b/tests/components/ethernet/test-dm9051.esp32-ard.yaml @@ -0,0 +1 @@ +<<: !include common-dm9051.yaml diff --git a/tests/components/ethernet/test-dm9051.esp32-idf.yaml b/tests/components/ethernet/test-dm9051.esp32-idf.yaml new file mode 100644 index 0000000000..23e3b97740 --- /dev/null +++ b/tests/components/ethernet/test-dm9051.esp32-idf.yaml @@ -0,0 +1 @@ +<<: !include common-dm9051.yaml