diff --git a/components/LD2450/LD2450.cpp b/components/LD2450/LD2450.cpp index 51ba722..38a6105 100644 --- a/components/LD2450/LD2450.cpp +++ b/components/LD2450/LD2450.cpp @@ -115,8 +115,8 @@ namespace esphome::ld2450 else { command_queue_.erase(command_queue_.begin()); - command_send_retries_ = 0; } + command_send_retries_ = 0; ESP_LOGW(TAG, "Sending command timed out! Is the sensor connected?"); } else @@ -132,36 +132,41 @@ namespace esphome::ld2450 { // Inject leave config command after clearing the queue command_queue_.push_back({COMMAND_LEAVE_CONFIG, 0x00}); + command_send_retries_ = 0; } // Skip stream until start of message and parse header - while (!peek_status_ && available() >= 4) + if (!peek_status_ && available() >= 4) { // Try to read the header and abort on mismatch const uint8_t *header; bool skip = false; - uint8_t target; - if (peek() == update_header[0]) + uint8_t message_type; + uint8_t first_byte = read(); + if (first_byte == update_header[0]) { header = update_header; - target = 1; + message_type = 1; } - else + else if (first_byte == config_header[0]) { header = config_header; - target = 2; + message_type = 2; + } + else + { + skip = true; } - for (int i = 0; i < 4 && !skip; i++) + for (int i = 1; i < 4 && !skip; i++) { if (read() != header[i]) skip = true; } - if (skip) - continue; - // Flag successful header reading - peek_status_ = target; + if (!skip) + // Flag successful header reading + peek_status_ = message_type; } if (peek_status_ == 1 && available() >= 28) @@ -201,10 +206,25 @@ namespace esphome::ld2450 peek_status_ = 0; } } + + if (sensor_available_ && millis() - last_message_received_ > SENSOR_UNAVAILABLE_TIMEOUT) + { + sensor_available_ = false; + + ESP_LOGE(TAG, "LD2450-Sensor stopped sending updates!"); + + // Update zones and related components + for (Zone *zone : zones_) + { + zone->update(targets_, sensor_available_); + } + } } void LD2450::process_message(uint8_t *msg, int len) { + sensor_available_ = true; + last_message_received_ = millis(); for (int i = 0; i < 3; i++) { int offset = 8 * i; @@ -251,7 +271,7 @@ namespace esphome::ld2450 // Update zones and related components for (Zone *zone : zones_) { - zone->update(targets_); + zone->update(targets_, sensor_available_); } } @@ -396,7 +416,7 @@ namespace esphome::ld2450 // Write message length write(static_cast(len)); - write(static_cast(len << 8)); + write(static_cast(len >> 8)); // Write message content write_array(msg, len); diff --git a/components/LD2450/LD2450.h b/components/LD2450/LD2450.h index a014f72..56fe397 100644 --- a/components/LD2450/LD2450.h +++ b/components/LD2450/LD2450.h @@ -21,7 +21,9 @@ #include "esphome/components/button/button.h" #endif -#define COMMAND_MAX_RETRIES 5 +#define SENSOR_UNAVAILABLE_TIMEOUT 1000 + +#define COMMAND_MAX_RETRIES 10 #define COMMAND_RETRY_DELAY 100 #define COMMAND_ENTER_CONFIG 0xFF @@ -215,6 +217,15 @@ namespace esphome::ld2450 return targets_[i]; } + /** + * @brief Gets the state of the connected sensor + * @return True if the sensor is connected and communicating, False otherwise + */ + bool is_sensor_available() + { + return sensor_available_; + } + /** * @brief Reads and logs the sensors version number. */ @@ -315,11 +326,17 @@ namespace esphome::ld2450 /// @brief Indicated that the sensor is currently factory resetting bool is_applying_changes_ = false; + /// @brief indicates if the sensor is communicating + bool sensor_available_ = false; + /// @brief Expected length of the configuration message int configuration_message_length_ = 0; /// @brief timestamp of the last message which was sent to the sensor - long command_last_sent_ = 0; + uint32_t command_last_sent_ = 0; + + /// @brief timestamp of the last received message + uint32_t last_message_received_ = 0; /// @brief Queue of commands to execute std::vector> command_queue_; diff --git a/components/LD2450/target.h b/components/LD2450/target.h index d44adcc..d6e8ba1 100644 --- a/components/LD2450/target.h +++ b/components/LD2450/target.h @@ -125,7 +125,7 @@ namespace esphome::ld2450 * @brief Time since last last change in values. * @return timestamp in milliseconds since start */ - long get_last_change() + uint32_t get_last_change() { return last_change_; } @@ -206,10 +206,10 @@ namespace esphome::ld2450 bool fast_off_detection_ = false; /// @brief time stamp of the last debug message which was sent. - long last_debug_message_ = 0; + uint32_t last_debug_message_ = 0; /// @brief time of the last value change - long last_change_ = 0; + uint32_t last_change_ = 0; /// @brief sensor reference of the x position sensor PollingSensor *x_position_sensor_ = nullptr; diff --git a/components/LD2450/zone.cpp b/components/LD2450/zone.cpp index ab59e64..e94feb6 100644 --- a/components/LD2450/zone.cpp +++ b/components/LD2450/zone.cpp @@ -39,8 +39,21 @@ namespace esphome::ld2450 #endif } - void Zone::update(std::vector &targets) + void Zone::update(std::vector &targets, bool sensor_available) { + if (!sensor_available) + { +#ifdef USE_BINARY_SENSOR + if (occupancy_binary_sensor_ != nullptr) + occupancy_binary_sensor_->publish_state(false); +#endif +#ifdef USE_SENSOR + if (target_count_sensor_ != nullptr) + target_count_sensor_->publish_state(NAN); +#endif + return; + } + if (polygon_.size() < 3) return; diff --git a/components/LD2450/zone.h b/components/LD2450/zone.h index 50e0b1b..cff0d72 100644 --- a/components/LD2450/zone.h +++ b/components/LD2450/zone.h @@ -74,8 +74,9 @@ namespace esphome::ld2450 /** * @brief Updates sensors related to this zone. * @param targets Reference to a vector of targets which will be used for calculation + * @param available True if the sensor is currently available, false otherwise * */ - void update(std::vector &targets); + void update(std::vector &targets, bool sensor_available); /** * Logs the Zone configuration. @@ -142,6 +143,6 @@ namespace esphome::ld2450 int target_timeout_ = 5000; /// @brief Map of targets which are currently tracked inside of this polygon with their last seen timestamp - std::map tracked_targets_{}; + std::map tracked_targets_{}; }; } // namespace esphome::ld2450