mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	Merge branch 'integration' into memory_api
This commit is contained in:
		| @@ -246,6 +246,7 @@ esphome/components/lcd_menu/* @numo68 | |||||||
| esphome/components/ld2410/* @regevbr @sebcaps | esphome/components/ld2410/* @regevbr @sebcaps | ||||||
| esphome/components/ld2420/* @descipher | esphome/components/ld2420/* @descipher | ||||||
| esphome/components/ld2450/* @hareeshmu | esphome/components/ld2450/* @hareeshmu | ||||||
|  | esphome/components/ld24xx/* @kbx81 | ||||||
| esphome/components/ledc/* @OttoWinter | esphome/components/ledc/* @OttoWinter | ||||||
| esphome/components/libretiny/* @kuba2k2 | esphome/components/libretiny/* @kuba2k2 | ||||||
| esphome/components/libretiny_pwm/* @kuba2k2 | esphome/components/libretiny_pwm/* @kuba2k2 | ||||||
|   | |||||||
| @@ -31,7 +31,7 @@ from esphome.const import ( | |||||||
|     KEY_TARGET_FRAMEWORK, |     KEY_TARGET_FRAMEWORK, | ||||||
|     KEY_TARGET_PLATFORM, |     KEY_TARGET_PLATFORM, | ||||||
|     PLATFORM_ESP32, |     PLATFORM_ESP32, | ||||||
|     CoreModel, |     ThreadModel, | ||||||
|     __version__, |     __version__, | ||||||
| ) | ) | ||||||
| from esphome.core import CORE, HexInt, TimePeriod | from esphome.core import CORE, HexInt, TimePeriod | ||||||
| @@ -98,16 +98,6 @@ ARDUINO_ALLOWED_VARIANTS = [ | |||||||
|     VARIANT_ESP32S3, |     VARIANT_ESP32S3, | ||||||
| ] | ] | ||||||
|  |  | ||||||
| # Single-core ESP32 variants |  | ||||||
| SINGLE_CORE_VARIANTS = frozenset( |  | ||||||
|     [ |  | ||||||
|         VARIANT_ESP32S2, |  | ||||||
|         VARIANT_ESP32C3, |  | ||||||
|         VARIANT_ESP32C6, |  | ||||||
|         VARIANT_ESP32H2, |  | ||||||
|     ] |  | ||||||
| ) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def get_cpu_frequencies(*frequencies): | def get_cpu_frequencies(*frequencies): | ||||||
|     return [str(x) + "MHZ" for x in frequencies] |     return [str(x) + "MHZ" for x in frequencies] | ||||||
| @@ -732,11 +722,7 @@ async def to_code(config): | |||||||
|     cg.add_define("ESPHOME_BOARD", config[CONF_BOARD]) |     cg.add_define("ESPHOME_BOARD", config[CONF_BOARD]) | ||||||
|     cg.add_build_flag(f"-DUSE_ESP32_VARIANT_{config[CONF_VARIANT]}") |     cg.add_build_flag(f"-DUSE_ESP32_VARIANT_{config[CONF_VARIANT]}") | ||||||
|     cg.add_define("ESPHOME_VARIANT", VARIANT_FRIENDLY[config[CONF_VARIANT]]) |     cg.add_define("ESPHOME_VARIANT", VARIANT_FRIENDLY[config[CONF_VARIANT]]) | ||||||
|     # Set threading model based on core count |     cg.add_define(ThreadModel.MULTI_ATOMICS) | ||||||
|     if config[CONF_VARIANT] in SINGLE_CORE_VARIANTS: |  | ||||||
|         cg.add_define(CoreModel.SINGLE) |  | ||||||
|     else: |  | ||||||
|         cg.add_define(CoreModel.MULTI_ATOMICS) |  | ||||||
|  |  | ||||||
|     cg.add_platformio_option("lib_ldf_mode", "off") |     cg.add_platformio_option("lib_ldf_mode", "off") | ||||||
|     cg.add_platformio_option("lib_compat_mode", "strict") |     cg.add_platformio_option("lib_compat_mode", "strict") | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ from esphome.const import ( | |||||||
|     KEY_TARGET_FRAMEWORK, |     KEY_TARGET_FRAMEWORK, | ||||||
|     KEY_TARGET_PLATFORM, |     KEY_TARGET_PLATFORM, | ||||||
|     PLATFORM_ESP8266, |     PLATFORM_ESP8266, | ||||||
|     CoreModel, |     ThreadModel, | ||||||
| ) | ) | ||||||
| from esphome.core import CORE, coroutine_with_priority | from esphome.core import CORE, coroutine_with_priority | ||||||
| from esphome.helpers import copy_file_if_changed | from esphome.helpers import copy_file_if_changed | ||||||
| @@ -188,7 +188,7 @@ async def to_code(config): | |||||||
|     cg.set_cpp_standard("gnu++20") |     cg.set_cpp_standard("gnu++20") | ||||||
|     cg.add_define("ESPHOME_BOARD", config[CONF_BOARD]) |     cg.add_define("ESPHOME_BOARD", config[CONF_BOARD]) | ||||||
|     cg.add_define("ESPHOME_VARIANT", "ESP8266") |     cg.add_define("ESPHOME_VARIANT", "ESP8266") | ||||||
|     cg.add_define(CoreModel.SINGLE) |     cg.add_define(ThreadModel.SINGLE) | ||||||
|  |  | ||||||
|     cg.add_platformio_option("extra_scripts", ["post:post_build.py"]) |     cg.add_platformio_option("extra_scripts", ["post:post_build.py"]) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ from esphome.const import ( | |||||||
|     KEY_TARGET_FRAMEWORK, |     KEY_TARGET_FRAMEWORK, | ||||||
|     KEY_TARGET_PLATFORM, |     KEY_TARGET_PLATFORM, | ||||||
|     PLATFORM_HOST, |     PLATFORM_HOST, | ||||||
|     CoreModel, |     ThreadModel, | ||||||
| ) | ) | ||||||
| from esphome.core import CORE | from esphome.core import CORE | ||||||
|  |  | ||||||
| @@ -44,7 +44,7 @@ async def to_code(config): | |||||||
|     cg.add_define("USE_ESPHOME_HOST_MAC_ADDRESS", config[CONF_MAC_ADDRESS].parts) |     cg.add_define("USE_ESPHOME_HOST_MAC_ADDRESS", config[CONF_MAC_ADDRESS].parts) | ||||||
|     cg.add_build_flag("-std=gnu++20") |     cg.add_build_flag("-std=gnu++20") | ||||||
|     cg.add_define("ESPHOME_BOARD", "host") |     cg.add_define("ESPHOME_BOARD", "host") | ||||||
|     cg.add_define(CoreModel.MULTI_ATOMICS) |     cg.add_define(ThreadModel.MULTI_ATOMICS) | ||||||
|     cg.add_platformio_option("platform", "platformio/native") |     cg.add_platformio_option("platform", "platformio/native") | ||||||
|     cg.add_platformio_option("lib_ldf_mode", "off") |     cg.add_platformio_option("lib_ldf_mode", "off") | ||||||
|     cg.add_platformio_option("lib_compat_mode", "strict") |     cg.add_platformio_option("lib_compat_mode", "strict") | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ from esphome.components import uart | |||||||
| import esphome.config_validation as cv | import esphome.config_validation as cv | ||||||
| from esphome.const import CONF_ID, CONF_PASSWORD, CONF_THROTTLE, CONF_TIMEOUT | from esphome.const import CONF_ID, CONF_PASSWORD, CONF_THROTTLE, CONF_TIMEOUT | ||||||
|  |  | ||||||
|  | AUTO_LOAD = ["ld24xx"] | ||||||
| DEPENDENCIES = ["uart"] | DEPENDENCIES = ["uart"] | ||||||
| CODEOWNERS = ["@sebcaps", "@regevbr"] | CODEOWNERS = ["@sebcaps", "@regevbr"] | ||||||
| MULTI_CONF = True | MULTI_CONF = True | ||||||
|   | |||||||
| @@ -1,6 +1,5 @@ | |||||||
| #include "ld2410.h" | #include "ld2410.h" | ||||||
|  |  | ||||||
| #include <utility> |  | ||||||
| #ifdef USE_NUMBER | #ifdef USE_NUMBER | ||||||
| #include "esphome/components/number/number.h" | #include "esphome/components/number/number.h" | ||||||
| #endif | #endif | ||||||
| @@ -10,10 +9,6 @@ | |||||||
|  |  | ||||||
| #include "esphome/core/application.h" | #include "esphome/core/application.h" | ||||||
|  |  | ||||||
| #define CHECK_BIT(var, pos) (((var) >> (pos)) & 1) |  | ||||||
| #define highbyte(val) (uint8_t)((val) >> 8) |  | ||||||
| #define lowbyte(val) (uint8_t)((val) &0xff) |  | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace ld2410 { | namespace ld2410 { | ||||||
|  |  | ||||||
| @@ -165,6 +160,9 @@ static constexpr uint8_t CMD_BLUETOOTH = 0xA4; | |||||||
| static constexpr uint8_t CMD_MAX_MOVE_VALUE = 0x00; | static constexpr uint8_t CMD_MAX_MOVE_VALUE = 0x00; | ||||||
| static constexpr uint8_t CMD_MAX_STILL_VALUE = 0x01; | static constexpr uint8_t CMD_MAX_STILL_VALUE = 0x01; | ||||||
| static constexpr uint8_t CMD_DURATION_VALUE = 0x02; | static constexpr uint8_t CMD_DURATION_VALUE = 0x02; | ||||||
|  | // Bitmasks for target states | ||||||
|  | static constexpr uint8_t MOVE_BITMASK = 0x01; | ||||||
|  | static constexpr uint8_t STILL_BITMASK = 0x02; | ||||||
| // Header & Footer size | // Header & Footer size | ||||||
| static constexpr uint8_t HEADER_FOOTER_SIZE = 4; | static constexpr uint8_t HEADER_FOOTER_SIZE = 4; | ||||||
| // Command Header & Footer | // Command Header & Footer | ||||||
| @@ -202,17 +200,17 @@ void LD2410Component::dump_config() { | |||||||
| #endif | #endif | ||||||
| #ifdef USE_SENSOR | #ifdef USE_SENSOR | ||||||
|   ESP_LOGCONFIG(TAG, "Sensors:"); |   ESP_LOGCONFIG(TAG, "Sensors:"); | ||||||
|   LOG_SENSOR("  ", "Light", this->light_sensor_); |   LOG_SENSOR_WITH_DEDUP_SAFE("  ", "Light", this->light_sensor_); | ||||||
|   LOG_SENSOR("  ", "DetectionDistance", this->detection_distance_sensor_); |   LOG_SENSOR_WITH_DEDUP_SAFE("  ", "DetectionDistance", this->detection_distance_sensor_); | ||||||
|   LOG_SENSOR("  ", "MovingTargetDistance", this->moving_target_distance_sensor_); |   LOG_SENSOR_WITH_DEDUP_SAFE("  ", "MovingTargetDistance", this->moving_target_distance_sensor_); | ||||||
|   LOG_SENSOR("  ", "MovingTargetEnergy", this->moving_target_energy_sensor_); |   LOG_SENSOR_WITH_DEDUP_SAFE("  ", "MovingTargetEnergy", this->moving_target_energy_sensor_); | ||||||
|   LOG_SENSOR("  ", "StillTargetDistance", this->still_target_distance_sensor_); |   LOG_SENSOR_WITH_DEDUP_SAFE("  ", "StillTargetDistance", this->still_target_distance_sensor_); | ||||||
|   LOG_SENSOR("  ", "StillTargetEnergy", this->still_target_energy_sensor_); |   LOG_SENSOR_WITH_DEDUP_SAFE("  ", "StillTargetEnergy", this->still_target_energy_sensor_); | ||||||
|   for (sensor::Sensor *s : this->gate_move_sensors_) { |   for (auto &s : this->gate_move_sensors_) { | ||||||
|     LOG_SENSOR("  ", "GateMove", s); |     LOG_SENSOR_WITH_DEDUP_SAFE("  ", "GateMove", s); | ||||||
|   } |   } | ||||||
|   for (sensor::Sensor *s : this->gate_still_sensors_) { |   for (auto &s : this->gate_still_sensors_) { | ||||||
|     LOG_SENSOR("  ", "GateStill", s); |     LOG_SENSOR_WITH_DEDUP_SAFE("  ", "GateStill", s); | ||||||
|   } |   } | ||||||
| #endif | #endif | ||||||
| #ifdef USE_TEXT_SENSOR | #ifdef USE_TEXT_SENSOR | ||||||
| @@ -304,8 +302,10 @@ void LD2410Component::send_command_(uint8_t command, const uint8_t *command_valu | |||||||
|   } |   } | ||||||
|   // frame footer bytes |   // frame footer bytes | ||||||
|   this->write_array(CMD_FRAME_FOOTER, sizeof(CMD_FRAME_FOOTER)); |   this->write_array(CMD_FRAME_FOOTER, sizeof(CMD_FRAME_FOOTER)); | ||||||
|   // FIXME to remove |  | ||||||
|   delay(50);  // NOLINT |   if (command != CMD_ENABLE_CONF && command != CMD_DISABLE_CONF) { | ||||||
|  |     delay(50);  // NOLINT | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void LD2410Component::handle_periodic_data_() { | void LD2410Component::handle_periodic_data_() { | ||||||
| @@ -348,10 +348,10 @@ void LD2410Component::handle_periodic_data_() { | |||||||
|     this->target_binary_sensor_->publish_state(target_state != 0x00); |     this->target_binary_sensor_->publish_state(target_state != 0x00); | ||||||
|   } |   } | ||||||
|   if (this->moving_target_binary_sensor_ != nullptr) { |   if (this->moving_target_binary_sensor_ != nullptr) { | ||||||
|     this->moving_target_binary_sensor_->publish_state(CHECK_BIT(target_state, 0)); |     this->moving_target_binary_sensor_->publish_state(target_state & MOVE_BITMASK); | ||||||
|   } |   } | ||||||
|   if (this->still_target_binary_sensor_ != nullptr) { |   if (this->still_target_binary_sensor_ != nullptr) { | ||||||
|     this->still_target_binary_sensor_->publish_state(CHECK_BIT(target_state, 1)); |     this->still_target_binary_sensor_->publish_state(target_state & STILL_BITMASK); | ||||||
|   } |   } | ||||||
| #endif | #endif | ||||||
|   /* |   /* | ||||||
| @@ -362,89 +362,51 @@ void LD2410Component::handle_periodic_data_() { | |||||||
|     Detect distance: 16~17th bytes |     Detect distance: 16~17th bytes | ||||||
|   */ |   */ | ||||||
| #ifdef USE_SENSOR | #ifdef USE_SENSOR | ||||||
|   if (this->moving_target_distance_sensor_ != nullptr) { |   SAFE_PUBLISH_SENSOR( | ||||||
|     int new_moving_target_distance = |       this->moving_target_distance_sensor_, | ||||||
|         ld2410::two_byte_to_int(this->buffer_data_[MOVING_TARGET_LOW], this->buffer_data_[MOVING_TARGET_HIGH]); |       ld2410::two_byte_to_int(this->buffer_data_[MOVING_TARGET_LOW], this->buffer_data_[MOVING_TARGET_HIGH])) | ||||||
|     if (this->moving_target_distance_sensor_->get_state() != new_moving_target_distance) |   SAFE_PUBLISH_SENSOR(this->moving_target_energy_sensor_, this->buffer_data_[MOVING_ENERGY]) | ||||||
|       this->moving_target_distance_sensor_->publish_state(new_moving_target_distance); |   SAFE_PUBLISH_SENSOR( | ||||||
|   } |       this->still_target_distance_sensor_, | ||||||
|   if (this->moving_target_energy_sensor_ != nullptr) { |       ld2410::two_byte_to_int(this->buffer_data_[STILL_TARGET_LOW], this->buffer_data_[STILL_TARGET_HIGH])); | ||||||
|     int new_moving_target_energy = this->buffer_data_[MOVING_ENERGY]; |   SAFE_PUBLISH_SENSOR(this->still_target_energy_sensor_, this->buffer_data_[STILL_ENERGY]); | ||||||
|     if (this->moving_target_energy_sensor_->get_state() != new_moving_target_energy) |   SAFE_PUBLISH_SENSOR( | ||||||
|       this->moving_target_energy_sensor_->publish_state(new_moving_target_energy); |       this->detection_distance_sensor_, | ||||||
|   } |       ld2410::two_byte_to_int(this->buffer_data_[DETECT_DISTANCE_LOW], this->buffer_data_[DETECT_DISTANCE_HIGH])); | ||||||
|   if (this->still_target_distance_sensor_ != nullptr) { |  | ||||||
|     int new_still_target_distance = |  | ||||||
|         ld2410::two_byte_to_int(this->buffer_data_[STILL_TARGET_LOW], this->buffer_data_[STILL_TARGET_HIGH]); |  | ||||||
|     if (this->still_target_distance_sensor_->get_state() != new_still_target_distance) |  | ||||||
|       this->still_target_distance_sensor_->publish_state(new_still_target_distance); |  | ||||||
|   } |  | ||||||
|   if (this->still_target_energy_sensor_ != nullptr) { |  | ||||||
|     int new_still_target_energy = this->buffer_data_[STILL_ENERGY]; |  | ||||||
|     if (this->still_target_energy_sensor_->get_state() != new_still_target_energy) |  | ||||||
|       this->still_target_energy_sensor_->publish_state(new_still_target_energy); |  | ||||||
|   } |  | ||||||
|   if (this->detection_distance_sensor_ != nullptr) { |  | ||||||
|     int new_detect_distance = |  | ||||||
|         ld2410::two_byte_to_int(this->buffer_data_[DETECT_DISTANCE_LOW], this->buffer_data_[DETECT_DISTANCE_HIGH]); |  | ||||||
|     if (this->detection_distance_sensor_->get_state() != new_detect_distance) |  | ||||||
|       this->detection_distance_sensor_->publish_state(new_detect_distance); |  | ||||||
|   } |  | ||||||
|   if (engineering_mode) { |   if (engineering_mode) { | ||||||
|     /* |     /* | ||||||
|       Moving distance range: 18th byte |       Moving distance range: 18th byte | ||||||
|       Still distance range: 19th byte |       Still distance range: 19th byte | ||||||
|       Moving energy: 20~28th bytes |       Moving energy: 20~28th bytes | ||||||
|     */ |     */ | ||||||
|     for (std::vector<sensor::Sensor *>::size_type i = 0; i != this->gate_move_sensors_.size(); i++) { |     for (uint8_t i = 0; i < TOTAL_GATES; i++) { | ||||||
|       sensor::Sensor *s = this->gate_move_sensors_[i]; |       SAFE_PUBLISH_SENSOR(this->gate_move_sensors_[i], this->buffer_data_[MOVING_SENSOR_START + i]) | ||||||
|       if (s != nullptr) { |  | ||||||
|         s->publish_state(this->buffer_data_[MOVING_SENSOR_START + i]); |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|     /* |     /* | ||||||
|       Still energy: 29~37th bytes |       Still energy: 29~37th bytes | ||||||
|     */ |     */ | ||||||
|     for (std::vector<sensor::Sensor *>::size_type i = 0; i != this->gate_still_sensors_.size(); i++) { |     for (uint8_t i = 0; i < TOTAL_GATES; i++) { | ||||||
|       sensor::Sensor *s = this->gate_still_sensors_[i]; |       SAFE_PUBLISH_SENSOR(this->gate_still_sensors_[i], this->buffer_data_[STILL_SENSOR_START + i]) | ||||||
|       if (s != nullptr) { |  | ||||||
|         s->publish_state(this->buffer_data_[STILL_SENSOR_START + i]); |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|     /* |     /* | ||||||
|       Light sensor: 38th bytes |       Light sensor: 38th bytes | ||||||
|     */ |     */ | ||||||
|     if (this->light_sensor_ != nullptr) { |     SAFE_PUBLISH_SENSOR(this->light_sensor_, this->buffer_data_[LIGHT_SENSOR]) | ||||||
|       int new_light_sensor = this->buffer_data_[LIGHT_SENSOR]; |  | ||||||
|       if (this->light_sensor_->get_state() != new_light_sensor) { |  | ||||||
|         this->light_sensor_->publish_state(new_light_sensor); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } else { |   } else { | ||||||
|     for (auto *s : this->gate_move_sensors_) { |     for (auto &gate_move_sensor : this->gate_move_sensors_) { | ||||||
|       if (s != nullptr && !std::isnan(s->get_state())) { |       SAFE_PUBLISH_SENSOR_UNKNOWN(gate_move_sensor) | ||||||
|         s->publish_state(NAN); |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|     for (auto *s : this->gate_still_sensors_) { |     for (auto &gate_still_sensor : this->gate_still_sensors_) { | ||||||
|       if (s != nullptr && !std::isnan(s->get_state())) { |       SAFE_PUBLISH_SENSOR_UNKNOWN(gate_still_sensor) | ||||||
|         s->publish_state(NAN); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     if (this->light_sensor_ != nullptr && !std::isnan(this->light_sensor_->get_state())) { |  | ||||||
|       this->light_sensor_->publish_state(NAN); |  | ||||||
|     } |     } | ||||||
|  |     SAFE_PUBLISH_SENSOR_UNKNOWN(this->light_sensor_) | ||||||
|   } |   } | ||||||
| #endif | #endif | ||||||
| #ifdef USE_BINARY_SENSOR | #ifdef USE_BINARY_SENSOR | ||||||
|   if (engineering_mode) { |   if (this->out_pin_presence_status_binary_sensor_ != nullptr) { | ||||||
|     if (this->out_pin_presence_status_binary_sensor_ != nullptr) { |     this->out_pin_presence_status_binary_sensor_->publish_state( | ||||||
|       this->out_pin_presence_status_binary_sensor_->publish_state(this->buffer_data_[OUT_PIN_SENSOR] == 0x01); |         engineering_mode ? this->buffer_data_[OUT_PIN_SENSOR] == 0x01 : false); | ||||||
|     } |  | ||||||
|   } else { |  | ||||||
|     if (this->out_pin_presence_status_binary_sensor_ != nullptr) { |  | ||||||
|       this->out_pin_presence_status_binary_sensor_->publish_state(false); |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| @@ -824,8 +786,14 @@ void LD2410Component::set_light_out_control() { | |||||||
| } | } | ||||||
|  |  | ||||||
| #ifdef USE_SENSOR | #ifdef USE_SENSOR | ||||||
| void LD2410Component::set_gate_move_sensor(uint8_t gate, sensor::Sensor *s) { this->gate_move_sensors_[gate] = s; } | // These could leak memory, but they are only set once prior to 'setup()' and should never be used again. | ||||||
| void LD2410Component::set_gate_still_sensor(uint8_t gate, sensor::Sensor *s) { this->gate_still_sensors_[gate] = s; } | void LD2410Component::set_gate_move_sensor(uint8_t gate, sensor::Sensor *s) { | ||||||
|  |   this->gate_move_sensors_[gate] = new SensorWithDedup<uint8_t>(s); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void LD2410Component::set_gate_still_sensor(uint8_t gate, sensor::Sensor *s) { | ||||||
|  |   this->gate_still_sensors_[gate] = new SensorWithDedup<uint8_t>(s); | ||||||
|  | } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| }  // namespace ld2410 | }  // namespace ld2410 | ||||||
|   | |||||||
| @@ -22,15 +22,20 @@ | |||||||
| #ifdef USE_TEXT_SENSOR | #ifdef USE_TEXT_SENSOR | ||||||
| #include "esphome/components/text_sensor/text_sensor.h" | #include "esphome/components/text_sensor/text_sensor.h" | ||||||
| #endif | #endif | ||||||
|  | #include "esphome/components/ld24xx/ld24xx.h" | ||||||
| #include "esphome/components/uart/uart.h" | #include "esphome/components/uart/uart.h" | ||||||
| #include "esphome/core/automation.h" | #include "esphome/core/automation.h" | ||||||
| #include "esphome/core/helpers.h" | #include "esphome/core/helpers.h" | ||||||
|  |  | ||||||
|  | #include <array> | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace ld2410 { | namespace ld2410 { | ||||||
|  |  | ||||||
| static const uint8_t MAX_LINE_LENGTH = 46;  // Max characters for serial buffer | using namespace ld24xx; | ||||||
| static const uint8_t TOTAL_GATES = 9;       // Total number of gates supported by the LD2410 |  | ||||||
|  | static constexpr uint8_t MAX_LINE_LENGTH = 46;  // Max characters for serial buffer | ||||||
|  | static constexpr uint8_t TOTAL_GATES = 9;       // Total number of gates supported by the LD2410 | ||||||
|  |  | ||||||
| class LD2410Component : public Component, public uart::UARTDevice { | class LD2410Component : public Component, public uart::UARTDevice { | ||||||
| #ifdef USE_BINARY_SENSOR | #ifdef USE_BINARY_SENSOR | ||||||
| @@ -40,12 +45,12 @@ class LD2410Component : public Component, public uart::UARTDevice { | |||||||
|   SUB_BINARY_SENSOR(target) |   SUB_BINARY_SENSOR(target) | ||||||
| #endif | #endif | ||||||
| #ifdef USE_SENSOR | #ifdef USE_SENSOR | ||||||
|   SUB_SENSOR(light) |   SUB_SENSOR_WITH_DEDUP(light, uint8_t) | ||||||
|   SUB_SENSOR(detection_distance) |   SUB_SENSOR_WITH_DEDUP(detection_distance, int) | ||||||
|   SUB_SENSOR(moving_target_distance) |   SUB_SENSOR_WITH_DEDUP(moving_target_distance, int) | ||||||
|   SUB_SENSOR(moving_target_energy) |   SUB_SENSOR_WITH_DEDUP(moving_target_energy, uint8_t) | ||||||
|   SUB_SENSOR(still_target_distance) |   SUB_SENSOR_WITH_DEDUP(still_target_distance, int) | ||||||
|   SUB_SENSOR(still_target_energy) |   SUB_SENSOR_WITH_DEDUP(still_target_energy, uint8_t) | ||||||
| #endif | #endif | ||||||
| #ifdef USE_TEXT_SENSOR | #ifdef USE_TEXT_SENSOR | ||||||
|   SUB_TEXT_SENSOR(version) |   SUB_TEXT_SENSOR(version) | ||||||
| @@ -122,12 +127,12 @@ class LD2410Component : public Component, public uart::UARTDevice { | |||||||
|   uint8_t version_[6] = {0, 0, 0, 0, 0, 0}; |   uint8_t version_[6] = {0, 0, 0, 0, 0, 0}; | ||||||
|   bool bluetooth_on_{false}; |   bool bluetooth_on_{false}; | ||||||
| #ifdef USE_NUMBER | #ifdef USE_NUMBER | ||||||
|   std::vector<number::Number *> gate_move_threshold_numbers_ = std::vector<number::Number *>(TOTAL_GATES); |   std::array<number::Number *, TOTAL_GATES> gate_move_threshold_numbers_{}; | ||||||
|   std::vector<number::Number *> gate_still_threshold_numbers_ = std::vector<number::Number *>(TOTAL_GATES); |   std::array<number::Number *, TOTAL_GATES> gate_still_threshold_numbers_{}; | ||||||
| #endif | #endif | ||||||
| #ifdef USE_SENSOR | #ifdef USE_SENSOR | ||||||
|   std::vector<sensor::Sensor *> gate_move_sensors_ = std::vector<sensor::Sensor *>(TOTAL_GATES); |   std::array<SensorWithDedup<uint8_t> *, TOTAL_GATES> gate_move_sensors_{}; | ||||||
|   std::vector<sensor::Sensor *> gate_still_sensors_ = std::vector<sensor::Sensor *>(TOTAL_GATES); |   std::array<SensorWithDedup<uint8_t> *, TOTAL_GATES> gate_still_sensors_{}; | ||||||
| #endif | #endif | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								esphome/components/ld24xx/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								esphome/components/ld24xx/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | CODEOWNERS = ["@kbx81"] | ||||||
							
								
								
									
										65
									
								
								esphome/components/ld24xx/ld24xx.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								esphome/components/ld24xx/ld24xx.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "esphome/core/defines.h" | ||||||
|  |  | ||||||
|  | #include <memory> | ||||||
|  |  | ||||||
|  | #ifdef USE_SENSOR | ||||||
|  | #include "esphome/core/helpers.h" | ||||||
|  | #include "esphome/components/sensor/sensor.h" | ||||||
|  |  | ||||||
|  | #define SUB_SENSOR_WITH_DEDUP(name, dedup_type) \ | ||||||
|  |  protected: \ | ||||||
|  |   ld24xx::SensorWithDedup<dedup_type> *name##_sensor_{nullptr}; \ | ||||||
|  | \ | ||||||
|  |  public: \ | ||||||
|  |   void set_##name##_sensor(sensor::Sensor *sensor) { \ | ||||||
|  |     this->name##_sensor_ = new ld24xx::SensorWithDedup<dedup_type>(sensor); \ | ||||||
|  |   } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #define LOG_SENSOR_WITH_DEDUP_SAFE(tag, name, sensor) \ | ||||||
|  |   if ((sensor) != nullptr) { \ | ||||||
|  |     LOG_SENSOR(tag, name, (sensor)->sens); \ | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | #define SAFE_PUBLISH_SENSOR(sensor, value) \ | ||||||
|  |   if ((sensor) != nullptr) { \ | ||||||
|  |     (sensor)->publish_state_if_not_dup(value); \ | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | #define SAFE_PUBLISH_SENSOR_UNKNOWN(sensor) \ | ||||||
|  |   if ((sensor) != nullptr) { \ | ||||||
|  |     (sensor)->publish_state_unknown(); \ | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | #define highbyte(val) (uint8_t)((val) >> 8) | ||||||
|  | #define lowbyte(val) (uint8_t)((val) &0xff) | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace ld24xx { | ||||||
|  |  | ||||||
|  | #ifdef USE_SENSOR | ||||||
|  | // Helper class to store a sensor with a deduplicator & publish state only when the value changes | ||||||
|  | template<typename T> class SensorWithDedup { | ||||||
|  |  public: | ||||||
|  |   SensorWithDedup(sensor::Sensor *sens) : sens(sens) {} | ||||||
|  |  | ||||||
|  |   void publish_state_if_not_dup(T state) { | ||||||
|  |     if (this->publish_dedup.next(state)) { | ||||||
|  |       this->sens->publish_state(static_cast<float>(state)); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void publish_state_unknown() { | ||||||
|  |     if (this->publish_dedup.next_unknown()) { | ||||||
|  |       this->sens->publish_state(NAN); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   sensor::Sensor *sens; | ||||||
|  |   Deduplicator<T> publish_dedup; | ||||||
|  | }; | ||||||
|  | #endif | ||||||
|  | }  // namespace ld24xx | ||||||
|  | }  // namespace esphome | ||||||
| @@ -20,7 +20,7 @@ from esphome.const import ( | |||||||
|     KEY_FRAMEWORK_VERSION, |     KEY_FRAMEWORK_VERSION, | ||||||
|     KEY_TARGET_FRAMEWORK, |     KEY_TARGET_FRAMEWORK, | ||||||
|     KEY_TARGET_PLATFORM, |     KEY_TARGET_PLATFORM, | ||||||
|     CoreModel, |     ThreadModel, | ||||||
|     __version__, |     __version__, | ||||||
| ) | ) | ||||||
| from esphome.core import CORE | from esphome.core import CORE | ||||||
| @@ -261,7 +261,7 @@ async def component_to_code(config): | |||||||
|     cg.add_build_flag(f"-DUSE_LIBRETINY_VARIANT_{config[CONF_FAMILY]}") |     cg.add_build_flag(f"-DUSE_LIBRETINY_VARIANT_{config[CONF_FAMILY]}") | ||||||
|     cg.add_define("ESPHOME_BOARD", config[CONF_BOARD]) |     cg.add_define("ESPHOME_BOARD", config[CONF_BOARD]) | ||||||
|     cg.add_define("ESPHOME_VARIANT", FAMILY_FRIENDLY[config[CONF_FAMILY]]) |     cg.add_define("ESPHOME_VARIANT", FAMILY_FRIENDLY[config[CONF_FAMILY]]) | ||||||
|     cg.add_define(CoreModel.MULTI_NO_ATOMICS) |     cg.add_define(ThreadModel.MULTI_NO_ATOMICS) | ||||||
|  |  | ||||||
|     # force using arduino framework |     # force using arduino framework | ||||||
|     cg.add_platformio_option("framework", "arduino") |     cg.add_platformio_option("framework", "arduino") | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ from esphome.const import ( | |||||||
|     KEY_TARGET_FRAMEWORK, |     KEY_TARGET_FRAMEWORK, | ||||||
|     KEY_TARGET_PLATFORM, |     KEY_TARGET_PLATFORM, | ||||||
|     PLATFORM_NRF52, |     PLATFORM_NRF52, | ||||||
|     CoreModel, |     ThreadModel, | ||||||
| ) | ) | ||||||
| from esphome.core import CORE, EsphomeError, coroutine_with_priority | from esphome.core import CORE, EsphomeError, coroutine_with_priority | ||||||
| from esphome.storage_json import StorageJSON | from esphome.storage_json import StorageJSON | ||||||
| @@ -110,7 +110,7 @@ async def to_code(config: ConfigType) -> None: | |||||||
|     cg.add_define("ESPHOME_BOARD", config[CONF_BOARD]) |     cg.add_define("ESPHOME_BOARD", config[CONF_BOARD]) | ||||||
|     cg.add_define("ESPHOME_VARIANT", "NRF52") |     cg.add_define("ESPHOME_VARIANT", "NRF52") | ||||||
|     # nRF52 processors are single-core |     # nRF52 processors are single-core | ||||||
|     cg.add_define(CoreModel.SINGLE) |     cg.add_define(ThreadModel.SINGLE) | ||||||
|     cg.add_platformio_option(CONF_FRAMEWORK, CORE.data[KEY_CORE][KEY_TARGET_FRAMEWORK]) |     cg.add_platformio_option(CONF_FRAMEWORK, CORE.data[KEY_CORE][KEY_TARGET_FRAMEWORK]) | ||||||
|     cg.add_platformio_option( |     cg.add_platformio_option( | ||||||
|         "platform", |         "platform", | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ from esphome.const import ( | |||||||
|     KEY_TARGET_FRAMEWORK, |     KEY_TARGET_FRAMEWORK, | ||||||
|     KEY_TARGET_PLATFORM, |     KEY_TARGET_PLATFORM, | ||||||
|     PLATFORM_RP2040, |     PLATFORM_RP2040, | ||||||
|     CoreModel, |     ThreadModel, | ||||||
| ) | ) | ||||||
| from esphome.core import CORE, EsphomeError, coroutine_with_priority | from esphome.core import CORE, EsphomeError, coroutine_with_priority | ||||||
| from esphome.helpers import copy_file_if_changed, mkdir_p, read_file, write_file | from esphome.helpers import copy_file_if_changed, mkdir_p, read_file, write_file | ||||||
| @@ -172,7 +172,7 @@ async def to_code(config): | |||||||
|     cg.set_cpp_standard("gnu++20") |     cg.set_cpp_standard("gnu++20") | ||||||
|     cg.add_define("ESPHOME_BOARD", config[CONF_BOARD]) |     cg.add_define("ESPHOME_BOARD", config[CONF_BOARD]) | ||||||
|     cg.add_define("ESPHOME_VARIANT", "RP2040") |     cg.add_define("ESPHOME_VARIANT", "RP2040") | ||||||
|     cg.add_define(CoreModel.SINGLE) |     cg.add_define(ThreadModel.SINGLE) | ||||||
|  |  | ||||||
|     cg.add_platformio_option("extra_scripts", ["post:post_build.py"]) |     cg.add_platformio_option("extra_scripts", ["post:post_build.py"]) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -35,12 +35,12 @@ class Framework(StrEnum): | |||||||
|     ZEPHYR = "zephyr" |     ZEPHYR = "zephyr" | ||||||
|  |  | ||||||
|  |  | ||||||
| class CoreModel(StrEnum): | class ThreadModel(StrEnum): | ||||||
|     """Core model identifiers for ESPHome scheduler.""" |     """Threading model identifiers for ESPHome scheduler.""" | ||||||
|  |  | ||||||
|     SINGLE = "ESPHOME_CORES_SINGLE" |     SINGLE = "ESPHOME_THREAD_SINGLE" | ||||||
|     MULTI_NO_ATOMICS = "ESPHOME_CORES_MULTI_NO_ATOMICS" |     MULTI_NO_ATOMICS = "ESPHOME_THREAD_MULTI_NO_ATOMICS" | ||||||
|     MULTI_ATOMICS = "ESPHOME_CORES_MULTI_ATOMICS" |     MULTI_ATOMICS = "ESPHOME_THREAD_MULTI_ATOMICS" | ||||||
|  |  | ||||||
|  |  | ||||||
| class PlatformFramework(Enum): | class PlatformFramework(Enum): | ||||||
|   | |||||||
| @@ -15,8 +15,8 @@ | |||||||
| #define ESPHOME_VARIANT "ESP32" | #define ESPHOME_VARIANT "ESP32" | ||||||
| #define ESPHOME_DEBUG_SCHEDULER | #define ESPHOME_DEBUG_SCHEDULER | ||||||
|  |  | ||||||
| // Default threading model for static analysis (ESP32 is multi-core with atomics) | // Default threading model for static analysis (ESP32 is multi-threaded with atomics) | ||||||
| #define ESPHOME_CORES_MULTI_ATOMICS | #define ESPHOME_THREAD_MULTI_ATOMICS | ||||||
|  |  | ||||||
| // logger | // logger | ||||||
| #define ESPHOME_LOG_LEVEL ESPHOME_LOG_LEVEL_VERY_VERBOSE | #define ESPHOME_LOG_LEVEL ESPHOME_LOG_LEVEL_VERY_VERBOSE | ||||||
|   | |||||||
| @@ -84,7 +84,7 @@ void HOT Scheduler::set_timer_common_(Component *component, SchedulerItem::Type | |||||||
|   item->callback = std::move(func); |   item->callback = std::move(func); | ||||||
|   item->remove = false; |   item->remove = false; | ||||||
|  |  | ||||||
| #ifndef ESPHOME_CORES_SINGLE | #ifndef ESPHOME_THREAD_SINGLE | ||||||
|   // Special handling for defer() (delay = 0, type = TIMEOUT) |   // Special handling for defer() (delay = 0, type = TIMEOUT) | ||||||
|   // Single-core platforms don't need thread-safe defer handling |   // Single-core platforms don't need thread-safe defer handling | ||||||
|   if (delay == 0 && type == SchedulerItem::TIMEOUT) { |   if (delay == 0 && type == SchedulerItem::TIMEOUT) { | ||||||
| @@ -94,7 +94,7 @@ void HOT Scheduler::set_timer_common_(Component *component, SchedulerItem::Type | |||||||
|     this->defer_queue_.push_back(std::move(item)); |     this->defer_queue_.push_back(std::move(item)); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
| #endif /* not ESPHOME_CORES_SINGLE */ | #endif /* not ESPHOME_THREAD_SINGLE */ | ||||||
|  |  | ||||||
|   // Get fresh timestamp for new timer/interval - ensures accurate scheduling |   // Get fresh timestamp for new timer/interval - ensures accurate scheduling | ||||||
|   const auto now = this->millis_64_(millis());  // Fresh millis() call |   const auto now = this->millis_64_(millis());  // Fresh millis() call | ||||||
| @@ -238,7 +238,7 @@ optional<uint32_t> HOT Scheduler::next_schedule_in(uint32_t now) { | |||||||
|   return item->next_execution_ - now_64; |   return item->next_execution_ - now_64; | ||||||
| } | } | ||||||
| void HOT Scheduler::call(uint32_t now) { | void HOT Scheduler::call(uint32_t now) { | ||||||
| #ifndef ESPHOME_CORES_SINGLE | #ifndef ESPHOME_THREAD_SINGLE | ||||||
|   // Process defer queue first to guarantee FIFO execution order for deferred items. |   // Process defer queue first to guarantee FIFO execution order for deferred items. | ||||||
|   // Previously, defer() used the heap which gave undefined order for equal timestamps, |   // Previously, defer() used the heap which gave undefined order for equal timestamps, | ||||||
|   // causing race conditions on multi-core systems (ESP32, BK7200). |   // causing race conditions on multi-core systems (ESP32, BK7200). | ||||||
| @@ -268,7 +268,7 @@ void HOT Scheduler::call(uint32_t now) { | |||||||
|       this->execute_item_(item.get(), now); |       this->execute_item_(item.get(), now); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| #endif /* not ESPHOME_CORES_SINGLE */ | #endif /* not ESPHOME_THREAD_SINGLE */ | ||||||
|  |  | ||||||
|   // Convert the fresh timestamp from main loop to 64-bit for scheduler operations |   // Convert the fresh timestamp from main loop to 64-bit for scheduler operations | ||||||
|   const auto now_64 = this->millis_64_(now);  // 'now' from parameter - fresh from Application::loop() |   const auto now_64 = this->millis_64_(now);  // 'now' from parameter - fresh from Application::loop() | ||||||
| @@ -280,15 +280,15 @@ void HOT Scheduler::call(uint32_t now) { | |||||||
|   if (now_64 - last_print > 2000) { |   if (now_64 - last_print > 2000) { | ||||||
|     last_print = now_64; |     last_print = now_64; | ||||||
|     std::vector<std::unique_ptr<SchedulerItem>> old_items; |     std::vector<std::unique_ptr<SchedulerItem>> old_items; | ||||||
| #ifdef ESPHOME_CORES_MULTI_ATOMICS | #ifdef ESPHOME_THREAD_MULTI_ATOMICS | ||||||
|     const auto last_dbg = this->last_millis_.load(std::memory_order_relaxed); |     const auto last_dbg = this->last_millis_.load(std::memory_order_relaxed); | ||||||
|     const auto major_dbg = this->millis_major_.load(std::memory_order_relaxed); |     const auto major_dbg = this->millis_major_.load(std::memory_order_relaxed); | ||||||
|     ESP_LOGD(TAG, "Items: count=%zu, now=%" PRIu64 " (%" PRIu16 ", %" PRIu32 ")", this->items_.size(), now_64, |     ESP_LOGD(TAG, "Items: count=%zu, now=%" PRIu64 " (%" PRIu16 ", %" PRIu32 ")", this->items_.size(), now_64, | ||||||
|              major_dbg, last_dbg); |              major_dbg, last_dbg); | ||||||
| #else  /* not ESPHOME_CORES_MULTI_ATOMICS */ | #else  /* not ESPHOME_THREAD_MULTI_ATOMICS */ | ||||||
|     ESP_LOGD(TAG, "Items: count=%zu, now=%" PRIu64 " (%" PRIu16 ", %" PRIu32 ")", this->items_.size(), now_64, |     ESP_LOGD(TAG, "Items: count=%zu, now=%" PRIu64 " (%" PRIu16 ", %" PRIu32 ")", this->items_.size(), now_64, | ||||||
|              this->millis_major_, this->last_millis_); |              this->millis_major_, this->last_millis_); | ||||||
| #endif /* else ESPHOME_CORES_MULTI_ATOMICS */ | #endif /* else ESPHOME_THREAD_MULTI_ATOMICS */ | ||||||
|     // Cleanup before debug output |     // Cleanup before debug output | ||||||
|     this->cleanup_(); |     this->cleanup_(); | ||||||
|     while (!this->items_.empty()) { |     while (!this->items_.empty()) { | ||||||
| @@ -473,7 +473,7 @@ bool HOT Scheduler::cancel_item_locked_(Component *component, const char *name_c | |||||||
|   size_t total_cancelled = 0; |   size_t total_cancelled = 0; | ||||||
|  |  | ||||||
|   // Check all containers for matching items |   // Check all containers for matching items | ||||||
| #ifndef ESPHOME_CORES_SINGLE | #ifndef ESPHOME_THREAD_SINGLE | ||||||
|   // Only check defer queue for timeouts (intervals never go there) |   // Only check defer queue for timeouts (intervals never go there) | ||||||
|   if (type == SchedulerItem::TIMEOUT) { |   if (type == SchedulerItem::TIMEOUT) { | ||||||
|     for (auto &item : this->defer_queue_) { |     for (auto &item : this->defer_queue_) { | ||||||
| @@ -483,7 +483,7 @@ bool HOT Scheduler::cancel_item_locked_(Component *component, const char *name_c | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| #endif /* not ESPHOME_CORES_SINGLE */ | #endif /* not ESPHOME_THREAD_SINGLE */ | ||||||
|  |  | ||||||
|   // Cancel items in the main heap |   // Cancel items in the main heap | ||||||
|   for (auto &item : this->items_) { |   for (auto &item : this->items_) { | ||||||
| @@ -509,9 +509,9 @@ bool HOT Scheduler::cancel_item_locked_(Component *component, const char *name_c | |||||||
| uint64_t Scheduler::millis_64_(uint32_t now) { | uint64_t Scheduler::millis_64_(uint32_t now) { | ||||||
|   // THREAD SAFETY NOTE: |   // THREAD SAFETY NOTE: | ||||||
|   // This function has three implementations, based on the precompiler flags |   // This function has three implementations, based on the precompiler flags | ||||||
|   // - ESPHOME_CORES_SINGLE - Runs on single-core platforms (ESP8266, RP2040, etc.) |   // - ESPHOME_THREAD_SINGLE - Runs on single-threaded platforms (ESP8266, RP2040, etc.) | ||||||
|   // - ESPHOME_CORES_MULTI_NO_ATOMICS - Runs on multi-core platforms without atomics (LibreTiny) |   // - ESPHOME_THREAD_MULTI_NO_ATOMICS - Runs on multi-threaded platforms without atomics (LibreTiny) | ||||||
|   // - ESPHOME_CORES_MULTI_ATOMICS - Runs on multi-core platforms with atomics (ESP32, HOST, etc.) |   // - ESPHOME_THREAD_MULTI_ATOMICS - Runs on multi-threaded platforms with atomics (ESP32, HOST, etc.) | ||||||
|   // |   // | ||||||
|   // Make sure all changes are synchronized if you edit this function. |   // Make sure all changes are synchronized if you edit this function. | ||||||
|   // |   // | ||||||
| @@ -520,7 +520,7 @@ uint64_t Scheduler::millis_64_(uint32_t now) { | |||||||
|   // helps maintain accuracy. |   // helps maintain accuracy. | ||||||
|   // |   // | ||||||
|  |  | ||||||
| #ifdef ESPHOME_CORES_SINGLE | #ifdef ESPHOME_THREAD_SINGLE | ||||||
|   // This is the single core implementation. |   // This is the single core implementation. | ||||||
|   // |   // | ||||||
|   // Single-core platforms have no concurrency, so this is a simple implementation |   // Single-core platforms have no concurrency, so this is a simple implementation | ||||||
| @@ -546,7 +546,7 @@ uint64_t Scheduler::millis_64_(uint32_t now) { | |||||||
|   // Combine major (high 32 bits) and now (low 32 bits) into 64-bit time |   // Combine major (high 32 bits) and now (low 32 bits) into 64-bit time | ||||||
|   return now + (static_cast<uint64_t>(major) << 32); |   return now + (static_cast<uint64_t>(major) << 32); | ||||||
|  |  | ||||||
| #elif defined(ESPHOME_CORES_MULTI_NO_ATOMICS) | #elif defined(ESPHOME_THREAD_MULTI_NO_ATOMICS) | ||||||
|   // This is the multi core no atomics implementation. |   // This is the multi core no atomics implementation. | ||||||
|   // |   // | ||||||
|   // Without atomics, this implementation uses locks more aggressively: |   // Without atomics, this implementation uses locks more aggressively: | ||||||
| @@ -595,7 +595,7 @@ uint64_t Scheduler::millis_64_(uint32_t now) { | |||||||
|   // Combine major (high 32 bits) and now (low 32 bits) into 64-bit time |   // Combine major (high 32 bits) and now (low 32 bits) into 64-bit time | ||||||
|   return now + (static_cast<uint64_t>(major) << 32); |   return now + (static_cast<uint64_t>(major) << 32); | ||||||
|  |  | ||||||
| #elif defined(ESPHOME_CORES_MULTI_ATOMICS) | #elif defined(ESPHOME_THREAD_MULTI_ATOMICS) | ||||||
|   // This is the multi core with atomics implementation. |   // This is the multi core with atomics implementation. | ||||||
|   // |   // | ||||||
|   // Uses atomic operations with acquire/release semantics to ensure coherent |   // Uses atomic operations with acquire/release semantics to ensure coherent | ||||||
| @@ -660,7 +660,7 @@ uint64_t Scheduler::millis_64_(uint32_t now) { | |||||||
|  |  | ||||||
| #else | #else | ||||||
| #error \ | #error \ | ||||||
|     "No platform threading model defined. One of ESPHOME_CORES_SINGLE, ESPHOME_CORES_MULTI_NO_ATOMICS, or ESPHOME_CORES_MULTI_ATOMICS must be defined." |     "No platform threading model defined. One of ESPHOME_THREAD_SINGLE, ESPHOME_THREAD_MULTI_NO_ATOMICS, or ESPHOME_THREAD_MULTI_ATOMICS must be defined." | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
| #include <memory> | #include <memory> | ||||||
| #include <cstring> | #include <cstring> | ||||||
| #include <deque> | #include <deque> | ||||||
| #ifdef ESPHOME_CORES_MULTI_ATOMICS | #ifdef ESPHOME_THREAD_MULTI_ATOMICS | ||||||
| #include <atomic> | #include <atomic> | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| @@ -200,13 +200,13 @@ class Scheduler { | |||||||
|   Mutex lock_; |   Mutex lock_; | ||||||
|   std::vector<std::unique_ptr<SchedulerItem>> items_; |   std::vector<std::unique_ptr<SchedulerItem>> items_; | ||||||
|   std::vector<std::unique_ptr<SchedulerItem>> to_add_; |   std::vector<std::unique_ptr<SchedulerItem>> to_add_; | ||||||
| #ifndef ESPHOME_CORES_SINGLE | #ifndef ESPHOME_THREAD_SINGLE | ||||||
|   // Single-core platforms don't need the defer queue and save 40 bytes of RAM |   // Single-core platforms don't need the defer queue and save 40 bytes of RAM | ||||||
|   std::deque<std::unique_ptr<SchedulerItem>> defer_queue_;  // FIFO queue for defer() calls |   std::deque<std::unique_ptr<SchedulerItem>> defer_queue_;  // FIFO queue for defer() calls | ||||||
| #endif                                                      /* ESPHOME_CORES_SINGLE */ | #endif                                                      /* ESPHOME_THREAD_SINGLE */ | ||||||
|   uint32_t to_remove_{0}; |   uint32_t to_remove_{0}; | ||||||
|  |  | ||||||
| #ifdef ESPHOME_CORES_MULTI_ATOMICS | #ifdef ESPHOME_THREAD_MULTI_ATOMICS | ||||||
|   /* |   /* | ||||||
|    * Multi-threaded platforms with atomic support: last_millis_ needs atomic for lock-free updates |    * Multi-threaded platforms with atomic support: last_millis_ needs atomic for lock-free updates | ||||||
|    * |    * | ||||||
| @@ -218,10 +218,10 @@ class Scheduler { | |||||||
|    * it also observes the corresponding increment of `millis_major_`. |    * it also observes the corresponding increment of `millis_major_`. | ||||||
|    */ |    */ | ||||||
|   std::atomic<uint32_t> last_millis_{0}; |   std::atomic<uint32_t> last_millis_{0}; | ||||||
| #else  /* not ESPHOME_CORES_MULTI_ATOMICS */ | #else  /* not ESPHOME_THREAD_MULTI_ATOMICS */ | ||||||
|   // Platforms without atomic support or single-threaded platforms |   // Platforms without atomic support or single-threaded platforms | ||||||
|   uint32_t last_millis_{0}; |   uint32_t last_millis_{0}; | ||||||
| #endif /* else ESPHOME_CORES_MULTI_ATOMICS */ | #endif /* else ESPHOME_THREAD_MULTI_ATOMICS */ | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|    * Upper 16 bits of the 64-bit millis counter. Incremented only while holding |    * Upper 16 bits of the 64-bit millis counter. Incremented only while holding | ||||||
| @@ -229,11 +229,11 @@ class Scheduler { | |||||||
|    * Ordering relative to `last_millis_` is provided by its release store and the |    * Ordering relative to `last_millis_` is provided by its release store and the | ||||||
|    * corresponding acquire loads. |    * corresponding acquire loads. | ||||||
|    */ |    */ | ||||||
| #ifdef ESPHOME_CORES_MULTI_ATOMICS | #ifdef ESPHOME_THREAD_MULTI_ATOMICS | ||||||
|   std::atomic<uint16_t> millis_major_{0}; |   std::atomic<uint16_t> millis_major_{0}; | ||||||
| #else  /* not ESPHOME_CORES_MULTI_ATOMICS */ | #else  /* not ESPHOME_THREAD_MULTI_ATOMICS */ | ||||||
|   uint16_t millis_major_{0}; |   uint16_t millis_major_{0}; | ||||||
| #endif /* else ESPHOME_CORES_MULTI_ATOMICS */ | #endif /* else ESPHOME_THREAD_MULTI_ATOMICS */ | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }  // namespace esphome | }  // namespace esphome | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user