mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	Merge branch 'esp32_tracker_touch_ups' into integration
This commit is contained in:
		| @@ -5,7 +5,7 @@ from esphome.const import ( | ||||
|     CONF_EQUATION, | ||||
|     CONF_HUMIDITY, | ||||
|     CONF_TEMPERATURE, | ||||
|     ICON_WATER, | ||||
|     DEVICE_CLASS_ABSOLUTE_HUMIDITY, | ||||
|     STATE_CLASS_MEASUREMENT, | ||||
|     UNIT_GRAMS_PER_CUBIC_METER, | ||||
| ) | ||||
| @@ -27,8 +27,8 @@ EQUATION = { | ||||
| CONFIG_SCHEMA = ( | ||||
|     sensor.sensor_schema( | ||||
|         unit_of_measurement=UNIT_GRAMS_PER_CUBIC_METER, | ||||
|         icon=ICON_WATER, | ||||
|         accuracy_decimals=2, | ||||
|         device_class=DEVICE_CLASS_ABSOLUTE_HUMIDITY, | ||||
|         state_class=STATE_CLASS_MEASUREMENT, | ||||
|     ) | ||||
|     .extend( | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| #ifdef USE_ESP32 | ||||
|  | ||||
| #include "ble.h" | ||||
|  | ||||
| #ifdef USE_ESP32 | ||||
|  | ||||
| #include "esphome/core/application.h" | ||||
| #include "esphome/core/helpers.h" | ||||
| #include "esphome/core/log.h" | ||||
|   | ||||
| @@ -1,5 +1,7 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "esphome/core/defines.h" | ||||
|  | ||||
| #include <array> | ||||
| #include <functional> | ||||
| #include <vector> | ||||
|   | ||||
| @@ -333,33 +333,37 @@ class ESP32BLETracker : public Component, | ||||
|     return counts; | ||||
|   } | ||||
|  | ||||
|   uint8_t app_id_{0}; | ||||
|  | ||||
|   // Group 1: Large objects (12+ bytes) - vectors and callback manager | ||||
|   std::vector<ESPBTDeviceListener *> listeners_; | ||||
|   std::vector<ESPBTClient *> clients_; | ||||
|   CallbackManager<void(ScannerState)> scanner_state_callbacks_; | ||||
| #ifdef USE_ESP32_BLE_DEVICE | ||||
|   /// Vector of addresses that have already been printed in print_bt_device_info | ||||
|   std::vector<uint64_t> already_discovered_; | ||||
| #endif | ||||
|   std::vector<ESPBTDeviceListener *> listeners_; | ||||
|   /// Client parameters. | ||||
|   std::vector<ESPBTClient *> clients_; | ||||
|  | ||||
|   // Group 2: Structs (aligned to 4 bytes) | ||||
|   /// A structure holding the ESP BLE scan parameters. | ||||
|   esp_ble_scan_params_t scan_params_; | ||||
|   ClientStateCounts client_state_counts_; | ||||
|  | ||||
|   // Group 3: 4-byte types | ||||
|   /// The interval in seconds to perform scans. | ||||
|   uint32_t scan_duration_; | ||||
|   uint32_t scan_interval_; | ||||
|   uint32_t scan_window_; | ||||
|   esp_bt_status_t scan_start_failed_{ESP_BT_STATUS_SUCCESS}; | ||||
|   esp_bt_status_t scan_set_param_failed_{ESP_BT_STATUS_SUCCESS}; | ||||
|  | ||||
|   // Group 4: 1-byte types (enums, uint8_t, bool) | ||||
|   uint8_t app_id_{0}; | ||||
|   uint8_t scan_start_fail_count_{0}; | ||||
|   ScannerState scanner_state_{ScannerState::IDLE}; | ||||
|   bool scan_continuous_; | ||||
|   bool scan_active_; | ||||
|   ScannerState scanner_state_{ScannerState::IDLE}; | ||||
|   CallbackManager<void(ScannerState)> scanner_state_callbacks_; | ||||
|   bool ble_was_disabled_{true}; | ||||
|   bool raw_advertisements_{false}; | ||||
|   bool parse_advertisements_{false}; | ||||
|  | ||||
|   esp_bt_status_t scan_start_failed_{ESP_BT_STATUS_SUCCESS}; | ||||
|   esp_bt_status_t scan_set_param_failed_{ESP_BT_STATUS_SUCCESS}; | ||||
|   ClientStateCounts client_state_counts_; | ||||
| #ifdef USE_ESP32_BLE_SOFTWARE_COEXISTENCE | ||||
|   bool coex_prefer_ble_{false}; | ||||
| #endif | ||||
|   | ||||
| @@ -171,8 +171,8 @@ class ESP32TouchComponent : public Component { | ||||
|   // based on the filter configuration | ||||
|   uint32_t read_touch_value(touch_pad_t pad) const; | ||||
|  | ||||
|   // Helper to update touch state with a known state | ||||
|   void update_touch_state_(ESP32TouchBinarySensor *child, bool is_touched); | ||||
|   // Helper to update touch state with a known state and value | ||||
|   void update_touch_state_(ESP32TouchBinarySensor *child, bool is_touched, uint32_t value); | ||||
|  | ||||
|   // Helper to read touch value and update state for a given child | ||||
|   bool check_and_update_touch_state_(ESP32TouchBinarySensor *child); | ||||
| @@ -234,9 +234,13 @@ class ESP32TouchBinarySensor : public binary_sensor::BinarySensor { | ||||
|   touch_pad_t get_touch_pad() const { return this->touch_pad_; } | ||||
|   uint32_t get_threshold() const { return this->threshold_; } | ||||
|   void set_threshold(uint32_t threshold) { this->threshold_ = threshold; } | ||||
| #ifdef USE_ESP32_VARIANT_ESP32 | ||||
|  | ||||
|   /// Get the raw touch measurement value. | ||||
|   /// @note Although this method may appear unused within the component, it is a public API | ||||
|   /// used by lambdas in user configurations for custom touch value processing. | ||||
|   /// @return The current raw touch sensor reading | ||||
|   uint32_t get_value() const { return this->value_; } | ||||
| #endif | ||||
|  | ||||
|   uint32_t get_wakeup_threshold() const { return this->wakeup_threshold_; } | ||||
|  | ||||
|  protected: | ||||
| @@ -245,9 +249,8 @@ class ESP32TouchBinarySensor : public binary_sensor::BinarySensor { | ||||
|   touch_pad_t touch_pad_{TOUCH_PAD_MAX}; | ||||
|   uint32_t threshold_{0}; | ||||
|   uint32_t benchmark_{}; | ||||
| #ifdef USE_ESP32_VARIANT_ESP32 | ||||
|   /// Stores the last raw touch measurement value. | ||||
|   uint32_t value_{0}; | ||||
| #endif | ||||
|   bool last_state_{false}; | ||||
|   const uint32_t wakeup_threshold_{0}; | ||||
|  | ||||
|   | ||||
| @@ -100,6 +100,8 @@ void ESP32TouchComponent::process_setup_mode_logging_(uint32_t now) { | ||||
| #else | ||||
|       // Read the value being used for touch detection | ||||
|       uint32_t value = this->read_touch_value(child->get_touch_pad()); | ||||
|       // Store the value for get_value() access in lambdas | ||||
|       child->value_ = value; | ||||
|       ESP_LOGD(TAG, "Touch Pad '%s' (T%d): %d", child->get_name().c_str(), child->get_touch_pad(), value); | ||||
| #endif | ||||
|     } | ||||
|   | ||||
| @@ -10,8 +10,11 @@ namespace esp32_touch { | ||||
|  | ||||
| static const char *const TAG = "esp32_touch"; | ||||
|  | ||||
| // Helper to update touch state with a known state | ||||
| void ESP32TouchComponent::update_touch_state_(ESP32TouchBinarySensor *child, bool is_touched) { | ||||
| // Helper to update touch state with a known state and value | ||||
| void ESP32TouchComponent::update_touch_state_(ESP32TouchBinarySensor *child, bool is_touched, uint32_t value) { | ||||
|   // Store the value for get_value() access in lambdas | ||||
|   child->value_ = value; | ||||
|  | ||||
|   // Always update timer when touched | ||||
|   if (is_touched) { | ||||
|     child->last_touch_time_ = App.get_loop_component_start_time(); | ||||
| @@ -21,9 +24,8 @@ void ESP32TouchComponent::update_touch_state_(ESP32TouchBinarySensor *child, boo | ||||
|     child->last_state_ = is_touched; | ||||
|     child->publish_state(is_touched); | ||||
|     if (is_touched) { | ||||
|       // ESP32-S2/S3 v2: touched when value > threshold | ||||
|       ESP_LOGV(TAG, "Touch Pad '%s' state: ON (value: %" PRIu32 " > threshold: %" PRIu32 ")", child->get_name().c_str(), | ||||
|                this->read_touch_value(child->touch_pad_), child->threshold_ + child->benchmark_); | ||||
|                value, child->threshold_ + child->benchmark_); | ||||
|     } else { | ||||
|       ESP_LOGV(TAG, "Touch Pad '%s' state: OFF", child->get_name().c_str()); | ||||
|     } | ||||
| @@ -41,7 +43,7 @@ bool ESP32TouchComponent::check_and_update_touch_state_(ESP32TouchBinarySensor * | ||||
|            child->get_name().c_str(), child->touch_pad_, value, child->threshold_, child->benchmark_); | ||||
|   bool is_touched = value > child->benchmark_ + child->threshold_; | ||||
|  | ||||
|   this->update_touch_state_(child, is_touched); | ||||
|   this->update_touch_state_(child, is_touched, value); | ||||
|   return is_touched; | ||||
| } | ||||
|  | ||||
| @@ -296,7 +298,9 @@ void ESP32TouchComponent::loop() { | ||||
|           this->check_and_update_touch_state_(child); | ||||
|         } else if (event.intr_mask & TOUCH_PAD_INTR_MASK_ACTIVE) { | ||||
|           // We only get ACTIVE interrupts now, releases are detected by timeout | ||||
|           this->update_touch_state_(child, true);  // Always touched for ACTIVE interrupts | ||||
|           // Read the current value | ||||
|           uint32_t value = this->read_touch_value(child->touch_pad_); | ||||
|           this->update_touch_state_(child, true, value);  // Always touched for ACTIVE interrupts | ||||
|         } | ||||
|         break; | ||||
|       } | ||||
|   | ||||
| @@ -14,18 +14,16 @@ ld2410_ns = cg.esphome_ns.namespace("ld2410") | ||||
| LD2410Component = ld2410_ns.class_("LD2410Component", cg.Component, uart.UARTDevice) | ||||
|  | ||||
| CONF_LD2410_ID = "ld2410_id" | ||||
|  | ||||
| CONF_MAX_MOVE_DISTANCE = "max_move_distance" | ||||
| CONF_MAX_STILL_DISTANCE = "max_still_distance" | ||||
| CONF_STILL_THRESHOLDS = [f"g{x}_still_threshold" for x in range(9)] | ||||
| CONF_MOVE_THRESHOLDS = [f"g{x}_move_threshold" for x in range(9)] | ||||
| CONF_STILL_THRESHOLDS = [f"g{x}_still_threshold" for x in range(9)] | ||||
|  | ||||
| CONFIG_SCHEMA = cv.Schema( | ||||
|     { | ||||
|         cv.GenerateID(): cv.declare_id(LD2410Component), | ||||
|         cv.Optional(CONF_THROTTLE, default="1000ms"): cv.All( | ||||
|             cv.positive_time_period_milliseconds, | ||||
|             cv.Range(min=cv.TimePeriod(milliseconds=1)), | ||||
|         cv.Optional(CONF_THROTTLE): cv.invalid( | ||||
|             f"{CONF_THROTTLE} has been removed; use per-sensor filters, instead" | ||||
|         ), | ||||
|         cv.Optional(CONF_MAX_MOVE_DISTANCE): cv.invalid( | ||||
|             f"The '{CONF_MAX_MOVE_DISTANCE}' option has been moved to the '{CONF_MAX_MOVE_DISTANCE}'" | ||||
| @@ -75,7 +73,6 @@ async def to_code(config): | ||||
|     var = cg.new_Pvariable(config[CONF_ID]) | ||||
|     await cg.register_component(var, config) | ||||
|     await uart.register_uart_device(var, config) | ||||
|     cg.add(var.set_throttle(config[CONF_THROTTLE])) | ||||
|  | ||||
|  | ||||
| CALIBRATION_ACTION_SCHEMA = maybe_simple_id( | ||||
|   | ||||
| @@ -22,19 +22,23 @@ CONFIG_SCHEMA = { | ||||
|     cv.GenerateID(CONF_LD2410_ID): cv.use_id(LD2410Component), | ||||
|     cv.Optional(CONF_HAS_TARGET): binary_sensor.binary_sensor_schema( | ||||
|         device_class=DEVICE_CLASS_OCCUPANCY, | ||||
|         filters=[{"settle": cv.TimePeriod(milliseconds=1000)}], | ||||
|         icon=ICON_ACCOUNT, | ||||
|     ), | ||||
|     cv.Optional(CONF_HAS_MOVING_TARGET): binary_sensor.binary_sensor_schema( | ||||
|         device_class=DEVICE_CLASS_MOTION, | ||||
|         filters=[{"settle": cv.TimePeriod(milliseconds=1000)}], | ||||
|         icon=ICON_MOTION_SENSOR, | ||||
|     ), | ||||
|     cv.Optional(CONF_HAS_STILL_TARGET): binary_sensor.binary_sensor_schema( | ||||
|         device_class=DEVICE_CLASS_OCCUPANCY, | ||||
|         filters=[{"settle": cv.TimePeriod(milliseconds=1000)}], | ||||
|         icon=ICON_MOTION_SENSOR, | ||||
|     ), | ||||
|     cv.Optional(CONF_OUT_PIN_PRESENCE_STATUS): binary_sensor.binary_sensor_schema( | ||||
|         device_class=DEVICE_CLASS_PRESENCE, | ||||
|         entity_category=ENTITY_CATEGORY_DIAGNOSTIC, | ||||
|         filters=[{"settle": cv.TimePeriod(milliseconds=1000)}], | ||||
|         icon=ICON_ACCOUNT, | ||||
|     ), | ||||
| } | ||||
|   | ||||
| @@ -188,9 +188,8 @@ void LD2410Component::dump_config() { | ||||
|   ESP_LOGCONFIG(TAG, | ||||
|                 "LD2410:\n" | ||||
|                 "  Firmware version: %s\n" | ||||
|                 "  MAC address: %s\n" | ||||
|                 "  Throttle: %u ms", | ||||
|                 version.c_str(), mac_str.c_str(), this->throttle_); | ||||
|                 "  MAC address: %s", | ||||
|                 version.c_str(), mac_str.c_str()); | ||||
| #ifdef USE_BINARY_SENSOR | ||||
|   ESP_LOGCONFIG(TAG, "Binary Sensors:"); | ||||
|   LOG_BINARY_SENSOR("  ", "Target", this->target_binary_sensor_); | ||||
| @@ -306,11 +305,6 @@ void LD2410Component::send_command_(uint8_t command, const uint8_t *command_valu | ||||
| } | ||||
|  | ||||
| void LD2410Component::handle_periodic_data_() { | ||||
|   // Reduce data update rate to reduce home assistant database growth | ||||
|   // Check this first to prevent unnecessary processing done in later checks/parsing | ||||
|   if (App.get_loop_component_start_time() - this->last_periodic_millis_ < this->throttle_) { | ||||
|     return; | ||||
|   } | ||||
|   // 4 frame header bytes + 2 length bytes + 1 data end byte + 1 crc byte + 4 frame footer bytes | ||||
|   // data header=0xAA, data footer=0x55, crc=0x00 | ||||
|   if (this->buffer_pos_ < 12 || !ld2410::validate_header_footer(DATA_FRAME_HEADER, this->buffer_data_) || | ||||
| @@ -318,9 +312,6 @@ void LD2410Component::handle_periodic_data_() { | ||||
|       this->buffer_data_[this->buffer_pos_ - 5] != CHECK) { | ||||
|     return; | ||||
|   } | ||||
|   // Save the timestamp after validating the frame so, if invalid, we'll take the next frame immediately | ||||
|   this->last_periodic_millis_ = App.get_loop_component_start_time(); | ||||
|  | ||||
|   /* | ||||
|     Data Type: 7th | ||||
|     0x01: Engineering mode | ||||
|   | ||||
| @@ -93,7 +93,6 @@ class LD2410Component : public Component, public uart::UARTDevice { | ||||
|   void set_gate_move_sensor(uint8_t gate, sensor::Sensor *s); | ||||
|   void set_gate_still_sensor(uint8_t gate, sensor::Sensor *s); | ||||
| #endif | ||||
|   void set_throttle(uint16_t value) { this->throttle_ = value; }; | ||||
|   void set_bluetooth_password(const std::string &password); | ||||
|   void set_engineering_mode(bool enable); | ||||
|   void read_all_info(); | ||||
| @@ -116,8 +115,6 @@ class LD2410Component : public Component, public uart::UARTDevice { | ||||
|   void query_light_control_(); | ||||
|   void restart_(); | ||||
|  | ||||
|   uint32_t last_periodic_millis_ = 0; | ||||
|   uint16_t throttle_ = 0; | ||||
|   uint8_t light_function_ = 0; | ||||
|   uint8_t light_threshold_ = 0; | ||||
|   uint8_t out_pin_level_ = 0; | ||||
|   | ||||
| @@ -18,42 +18,50 @@ from esphome.const import ( | ||||
| from . import CONF_LD2410_ID, LD2410Component | ||||
|  | ||||
| DEPENDENCIES = ["ld2410"] | ||||
| CONF_STILL_DISTANCE = "still_distance" | ||||
| CONF_MOVING_ENERGY = "moving_energy" | ||||
| CONF_STILL_ENERGY = "still_energy" | ||||
|  | ||||
| CONF_DETECTION_DISTANCE = "detection_distance" | ||||
| CONF_MOVE_ENERGY = "move_energy" | ||||
| CONF_MOVING_ENERGY = "moving_energy" | ||||
| CONF_STILL_DISTANCE = "still_distance" | ||||
| CONF_STILL_ENERGY = "still_energy" | ||||
|  | ||||
|  | ||||
| CONFIG_SCHEMA = cv.Schema( | ||||
|     { | ||||
|         cv.GenerateID(CONF_LD2410_ID): cv.use_id(LD2410Component), | ||||
|         cv.Optional(CONF_MOVING_DISTANCE): sensor.sensor_schema( | ||||
|             device_class=DEVICE_CLASS_DISTANCE, | ||||
|             unit_of_measurement=UNIT_CENTIMETER, | ||||
|             filters=[{"throttle_with_priority": cv.TimePeriod(milliseconds=1000)}], | ||||
|             icon=ICON_SIGNAL, | ||||
|             unit_of_measurement=UNIT_CENTIMETER, | ||||
|         ), | ||||
|         cv.Optional(CONF_STILL_DISTANCE): sensor.sensor_schema( | ||||
|             device_class=DEVICE_CLASS_DISTANCE, | ||||
|             unit_of_measurement=UNIT_CENTIMETER, | ||||
|             filters=[{"throttle_with_priority": cv.TimePeriod(milliseconds=1000)}], | ||||
|             icon=ICON_SIGNAL, | ||||
|             unit_of_measurement=UNIT_CENTIMETER, | ||||
|         ), | ||||
|         cv.Optional(CONF_MOVING_ENERGY): sensor.sensor_schema( | ||||
|             unit_of_measurement=UNIT_PERCENT, | ||||
|             filters=[{"throttle_with_priority": cv.TimePeriod(milliseconds=1000)}], | ||||
|             icon=ICON_MOTION_SENSOR, | ||||
|             unit_of_measurement=UNIT_PERCENT, | ||||
|         ), | ||||
|         cv.Optional(CONF_STILL_ENERGY): sensor.sensor_schema( | ||||
|             unit_of_measurement=UNIT_PERCENT, | ||||
|             filters=[{"throttle_with_priority": cv.TimePeriod(milliseconds=1000)}], | ||||
|             icon=ICON_FLASH, | ||||
|             unit_of_measurement=UNIT_PERCENT, | ||||
|         ), | ||||
|         cv.Optional(CONF_LIGHT): sensor.sensor_schema( | ||||
|             device_class=DEVICE_CLASS_ILLUMINANCE, | ||||
|             entity_category=ENTITY_CATEGORY_DIAGNOSTIC, | ||||
|             filters=[{"throttle_with_priority": cv.TimePeriod(milliseconds=1000)}], | ||||
|             icon=ICON_LIGHTBULB, | ||||
|         ), | ||||
|         cv.Optional(CONF_DETECTION_DISTANCE): sensor.sensor_schema( | ||||
|             device_class=DEVICE_CLASS_DISTANCE, | ||||
|             unit_of_measurement=UNIT_CENTIMETER, | ||||
|             filters=[{"throttle_with_priority": cv.TimePeriod(milliseconds=1000)}], | ||||
|             icon=ICON_SIGNAL, | ||||
|             unit_of_measurement=UNIT_CENTIMETER, | ||||
|         ), | ||||
|     } | ||||
| ) | ||||
| @@ -63,14 +71,20 @@ CONFIG_SCHEMA = CONFIG_SCHEMA.extend( | ||||
|         cv.Optional(f"g{x}"): cv.Schema( | ||||
|             { | ||||
|                 cv.Optional(CONF_MOVE_ENERGY): sensor.sensor_schema( | ||||
|                     unit_of_measurement=UNIT_PERCENT, | ||||
|                     entity_category=ENTITY_CATEGORY_DIAGNOSTIC, | ||||
|                     filters=[ | ||||
|                         {"throttle_with_priority": cv.TimePeriod(milliseconds=1000)} | ||||
|                     ], | ||||
|                     icon=ICON_MOTION_SENSOR, | ||||
|                     unit_of_measurement=UNIT_PERCENT, | ||||
|                 ), | ||||
|                 cv.Optional(CONF_STILL_ENERGY): sensor.sensor_schema( | ||||
|                     unit_of_measurement=UNIT_PERCENT, | ||||
|                     entity_category=ENTITY_CATEGORY_DIAGNOSTIC, | ||||
|                     filters=[ | ||||
|                         {"throttle_with_priority": cv.TimePeriod(milliseconds=1000)} | ||||
|                     ], | ||||
|                     icon=ICON_FLASH, | ||||
|                     unit_of_measurement=UNIT_PERCENT, | ||||
|                 ), | ||||
|             } | ||||
|         ) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user