11static const char *
const TAG =
"ld6002b";
13static constexpr uint8_t TF_SOF = 0x01;
14static constexpr uint32_t SETUP_DELAY_MS = 100;
17static constexpr uint16_t TYPE_CONTROL = 0x0201;
18static constexpr uint16_t TYPE_SET_AREA = 0x0202;
19static constexpr uint16_t TYPE_SET_HOLD_DELAY = 0x0203;
20static constexpr uint16_t TYPE_SET_Z_RANGE = 0x0204;
21static constexpr uint16_t TYPE_SET_LOW_POWER_SLEEP = 0x0205;
23static constexpr uint16_t TYPE_REPORT_TARGET = 0x0A04;
24static constexpr uint16_t TYPE_REPORT_POINT_CLOUD = 0x0A08;
25static constexpr uint16_t TYPE_REPORT_AREA_PRESENCE = 0x0A0A;
26static constexpr uint16_t TYPE_REPORT_INTERFERENCE_AREAS = 0x0A0B;
27static constexpr uint16_t TYPE_REPORT_DETECTION_AREAS = 0x0A0C;
28static constexpr uint16_t TYPE_REPORT_DELAY = 0x0A0D;
29static constexpr uint16_t TYPE_REPORT_SENSITIVITY = 0x0A0E;
30static constexpr uint16_t TYPE_REPORT_TRIGGER = 0x0A0F;
31static constexpr uint16_t TYPE_REPORT_Z_RANGE = 0x0A10;
32static constexpr uint16_t TYPE_REPORT_INSTALLATION = 0x0A11;
33static constexpr uint16_t TYPE_REPORT_LOW_POWER = 0x0A12;
34static constexpr uint16_t TYPE_REPORT_LOW_POWER_SLEEP = 0x0A13;
35static constexpr uint16_t TYPE_REPORT_WORK_MODE = 0x0A14;
36static constexpr uint16_t TYPE_QUERY_VERSION = 0xFFFF;
39static constexpr uint32_t CMD_AUTO_INTERFERENCE = 0x01;
40static constexpr uint32_t CMD_GET_AREAS = 0x02;
41static constexpr uint32_t CMD_CLEAR_INTERFERENCE = 0x03;
42static constexpr uint32_t CMD_RESET_DETECTION_AREA = 0x04;
43static constexpr uint32_t CMD_GET_DELAY = 0x05;
44static constexpr uint32_t CMD_POINT_CLOUD_ON = 0x06;
45static constexpr uint32_t CMD_POINT_CLOUD_OFF = 0x07;
46static constexpr uint32_t CMD_TARGET_DISPLAY_ON = 0x08;
47static constexpr uint32_t CMD_TARGET_DISPLAY_OFF = 0x09;
48static constexpr uint32_t CMD_SENSITIVITY_LOW = 0x0A;
49static constexpr uint32_t CMD_SENSITIVITY_MEDIUM = 0x0B;
50static constexpr uint32_t CMD_SENSITIVITY_HIGH = 0x0C;
51static constexpr uint32_t CMD_GET_SENSITIVITY = 0x0D;
52static constexpr uint32_t CMD_TRIGGER_SLOW = 0x0E;
53static constexpr uint32_t CMD_TRIGGER_MEDIUM = 0x0F;
54static constexpr uint32_t CMD_TRIGGER_FAST = 0x10;
55static constexpr uint32_t CMD_GET_TRIGGER = 0x11;
56static constexpr uint32_t CMD_GET_Z_RANGE = 0x12;
57static constexpr uint32_t CMD_INSTALL_TOP = 0x13;
58static constexpr uint32_t CMD_INSTALL_SIDE = 0x14;
59static constexpr uint32_t CMD_GET_INSTALLATION = 0x15;
60static constexpr uint32_t CMD_LOW_POWER_ON = 0x16;
61static constexpr uint32_t CMD_LOW_POWER_OFF = 0x17;
62static constexpr uint32_t CMD_GET_LOW_POWER = 0x18;
63static constexpr uint32_t CMD_GET_LOW_POWER_SLEEP = 0x19;
64static constexpr uint32_t CMD_RESET_UNATTENDED = 0x1A;
66static constexpr uint16_t TARGET_DATA_LEN = 20;
67static constexpr uint16_t AREA_DATA_LEN = 24;
68static constexpr uint16_t AREA_CONFIG_LEN = 28;
69static constexpr uint16_t AREA_PRESENCE_ENTRY_LEN = 4;
71static constexpr uint8_t AREA_ID_DEFAULT = 4;
73static constexpr uint8_t VERSION_QUERY_DATA[] = {0x01, 0x01, 0x00, 0x00};
75#ifdef ESPHOME_LOG_HAS_VERBOSE
76static const char *control_command_name(
uint32_t command) {
78 case CMD_AUTO_INTERFERENCE:
79 return "auto_interference";
82 case CMD_CLEAR_INTERFERENCE:
83 return "clear_interference";
84 case CMD_RESET_DETECTION_AREA:
85 return "reset_detection_area";
88 case CMD_POINT_CLOUD_ON:
89 return "point_cloud_on";
90 case CMD_POINT_CLOUD_OFF:
91 return "point_cloud_off";
92 case CMD_TARGET_DISPLAY_ON:
93 return "target_display_on";
94 case CMD_TARGET_DISPLAY_OFF:
95 return "target_display_off";
96 case CMD_SENSITIVITY_LOW:
97 return "sensitivity_low";
98 case CMD_SENSITIVITY_MEDIUM:
99 return "sensitivity_medium";
100 case CMD_SENSITIVITY_HIGH:
101 return "sensitivity_high";
102 case CMD_GET_SENSITIVITY:
103 return "get_sensitivity";
104 case CMD_TRIGGER_SLOW:
105 return "trigger_slow";
106 case CMD_TRIGGER_MEDIUM:
107 return "trigger_medium";
108 case CMD_TRIGGER_FAST:
109 return "trigger_fast";
110 case CMD_GET_TRIGGER:
111 return "get_trigger";
112 case CMD_GET_Z_RANGE:
113 return "get_z_range";
114 case CMD_INSTALL_TOP:
115 return "install_top";
116 case CMD_INSTALL_SIDE:
117 return "install_side";
118 case CMD_GET_INSTALLATION:
119 return "get_installation";
120 case CMD_LOW_POWER_ON:
121 return "low_power_on";
122 case CMD_LOW_POWER_OFF:
123 return "low_power_off";
124 case CMD_GET_LOW_POWER:
125 return "get_low_power";
126 case CMD_GET_LOW_POWER_SLEEP:
127 return "get_low_power_sleep";
128 case CMD_RESET_UNATTENDED:
129 return "reset_unattended";
135static const char *frame_type_name(uint16_t
type) {
141 case TYPE_SET_HOLD_DELAY:
142 return "set_hold_delay";
143 case TYPE_SET_Z_RANGE:
144 return "set_z_range";
145 case TYPE_SET_LOW_POWER_SLEEP:
146 return "set_low_power_sleep";
147 case TYPE_REPORT_TARGET:
148 return "report_target";
149 case TYPE_REPORT_POINT_CLOUD:
150 return "report_point_cloud";
151 case TYPE_REPORT_AREA_PRESENCE:
152 return "report_area_presence";
153 case TYPE_REPORT_INTERFERENCE_AREAS:
154 return "report_interference_areas";
155 case TYPE_REPORT_DETECTION_AREAS:
156 return "report_detection_areas";
157 case TYPE_REPORT_DELAY:
158 return "report_delay";
159 case TYPE_REPORT_SENSITIVITY:
160 return "report_sensitivity";
161 case TYPE_REPORT_TRIGGER:
162 return "report_trigger";
163 case TYPE_REPORT_Z_RANGE:
164 return "report_z_range";
165 case TYPE_REPORT_INSTALLATION:
166 return "report_installation";
167 case TYPE_REPORT_LOW_POWER:
168 return "report_low_power";
169 case TYPE_REPORT_LOW_POWER_SLEEP:
170 return "report_low_power_sleep";
171 case TYPE_REPORT_WORK_MODE:
172 return "report_work_mode";
173 case TYPE_QUERY_VERSION:
174 return "query_version";
180static bool is_expected_control_report(
uint32_t command, uint16_t
type) {
183 return type == TYPE_REPORT_INTERFERENCE_AREAS ||
type == TYPE_REPORT_DETECTION_AREAS;
185 return type == TYPE_REPORT_DELAY;
186 case CMD_GET_SENSITIVITY:
187 return type == TYPE_REPORT_SENSITIVITY;
188 case CMD_GET_TRIGGER:
189 return type == TYPE_REPORT_TRIGGER;
190 case CMD_GET_Z_RANGE:
191 return type == TYPE_REPORT_Z_RANGE;
192 case CMD_GET_INSTALLATION:
193 return type == TYPE_REPORT_INSTALLATION;
194 case CMD_GET_LOW_POWER:
195 case CMD_LOW_POWER_ON:
196 case CMD_LOW_POWER_OFF:
197 return type == TYPE_REPORT_LOW_POWER;
198 case CMD_GET_LOW_POWER_SLEEP:
199 return type == TYPE_REPORT_LOW_POWER_SLEEP;
209 return static_cast<uint32_t>(data[0]) | (
static_cast<uint32_t>(data[1]) << 8) |
210 (
static_cast<uint32_t>(data[2]) << 16) | (
static_cast<uint32_t>(data[3]) << 24);
216 std::memcpy(&value, &
raw,
sizeof(value));
223 std::memcpy(&value, &
raw,
sizeof(value));
228 data[0] = value & 0xFF;
229 data[1] = (value >> 8) & 0xFF;
230 data[2] = (value >> 16) & 0xFF;
231 data[3] = (value >> 24) & 0xFF;
240 std::memcpy(&
raw, &value,
sizeof(
raw));
246 bool point_cloud_configured =
false;
253 this->
max_data_len_ = point_cloud_configured ? DEFAULT_MAX_DATA_LEN_POINT_CLOUD : DEFAULT_MAX_DATA_LEN;
258 this->
mark_failed(LOG_STR(
"Failed to allocate frame buffer"));
267 bool want_target_stream =
false;
270 if (!want_target_stream) {
271 for (
const auto &target : this->
targets_) {
272 if (target.x !=
nullptr || target.y !=
nullptr || target.z !=
nullptr || target.dop_idx !=
nullptr ||
273 target.cluster_id !=
nullptr) {
274 want_target_stream =
true;
280#ifdef USE_BINARY_SENSOR
282 if (!want_target_stream) {
284 if (sensor !=
nullptr) {
285 want_target_stream =
true;
291#ifdef USE_TEXT_SENSOR
298 bool target_display_controlled =
false;
301 target_display_controlled =
true;
314 if (!target_display_controlled) {
319 if (want_target_stream) {
324 bool point_cloud_controlled =
false;
327 point_cloud_controlled =
true;
338 if (!point_cloud_controlled) {
341 bool want_point_cloud =
false;
373 if (want_low_power) {
385 bool want_low_power =
false;
387#ifdef USE_TEXT_SENSOR
390 if (want_low_power) {
394 bool want_area_report =
false;
397 if (area.x_min !=
nullptr || area.x_max !=
nullptr || area.y_min !=
nullptr || area.y_max !=
nullptr ||
398 area.z_min !=
nullptr || area.z_max !=
nullptr) {
399 want_area_report =
true;
403 if (!want_area_report) {
405 if (area.x_min !=
nullptr || area.x_max !=
nullptr || area.y_min !=
nullptr || area.y_max !=
nullptr ||
406 area.z_min !=
nullptr || area.z_max !=
nullptr) {
407 want_area_report =
true;
417 want_area_report =
true;
420 if (want_area_report) {
427#ifdef USE_TEXT_SENSOR
429 this->
queue_command_(TYPE_QUERY_VERSION, VERSION_QUERY_DATA,
sizeof(VERSION_QUERY_DATA));
439 " Max data length: %u",
448 for (
auto &target : this->
targets_) {
449 LOG_SENSOR(
" ",
"Target X", target.x);
450 LOG_SENSOR(
" ",
"Target Y", target.y);
451 LOG_SENSOR(
" ",
"Target Z", target.z);
452 LOG_SENSOR(
" ",
"Target Doppler Index", target.dop_idx);
453 LOG_SENSOR(
" ",
"Target Cluster ID", target.cluster_id);
456 LOG_SENSOR(
" ",
"Interference Area X Min", area.x_min);
457 LOG_SENSOR(
" ",
"Interference Area X Max", area.x_max);
458 LOG_SENSOR(
" ",
"Interference Area Y Min", area.y_min);
459 LOG_SENSOR(
" ",
"Interference Area Y Max", area.y_max);
460 LOG_SENSOR(
" ",
"Interference Area Z Min", area.z_min);
461 LOG_SENSOR(
" ",
"Interference Area Z Max", area.z_max);
464 LOG_SENSOR(
" ",
"Detection Area X Min", area.x_min);
465 LOG_SENSOR(
" ",
"Detection Area X Max", area.x_max);
466 LOG_SENSOR(
" ",
"Detection Area Y Min", area.y_min);
467 LOG_SENSOR(
" ",
"Detection Area Y Max", area.y_max);
468 LOG_SENSOR(
" ",
"Detection Area Z Min", area.z_min);
469 LOG_SENSOR(
" ",
"Detection Area Z Max", area.z_max);
472#ifdef USE_BINARY_SENSOR
474 for (uint8_t i = 0; i < MAX_TARGETS; i++) {
477 for (uint8_t i = 0; i < AREA_COUNT; i++) {
478 LOG_BINARY_SENSOR(
" ",
"Detection Area Presence", this->
area_presence_[i]);
481#ifdef USE_TEXT_SENSOR
512 uint8_t
byte = this->
read();
565 uint8_t expected =
static_cast<uint8_t
>(~this->header_xor_);
566 if (
byte != expected) {
567 ESP_LOGV(TAG,
"Header checksum mismatch");
572 ESP_LOGW(TAG,
"Frame too large: %u", this->
data_len_);
596 uint8_t expected =
static_cast<uint8_t
>(~this->data_xor_);
597 if (
byte == expected) {
600 ESP_LOGV(TAG,
"Data checksum mismatch");
616 ESP_LOGV(TAG,
"Ignoring ACK for command 0x%04X from an earlier attempt (module frame 0x%04X)",
type,
621 ESP_LOGV(TAG,
"ACK for command 0x%04X (module frame 0x%04X)",
type, this->
frame_id_);
639#ifdef ESPHOME_LOG_HAS_VERBOSE
640 const uint32_t active_control_command =
644 if (active_control_command != 0 && is_expected_control_report(active_control_command,
type)) {
645 ESP_LOGV(TAG,
"Received %s (0x%04X) while waiting for %s (0x%02" PRIX32
") ACK", frame_type_name(
type),
type,
646 control_command_name(active_control_command), active_control_command);
651 case TYPE_REPORT_TARGET:
654 case TYPE_REPORT_POINT_CLOUD:
657 case TYPE_REPORT_AREA_PRESENCE:
660 case TYPE_REPORT_INTERFERENCE_AREAS:
663 case TYPE_REPORT_DETECTION_AREAS:
666 case TYPE_REPORT_DELAY:
669 case TYPE_REPORT_SENSITIVITY:
672 case TYPE_REPORT_TRIGGER:
675 case TYPE_REPORT_Z_RANGE:
678 case TYPE_REPORT_INSTALLATION:
681 case TYPE_REPORT_LOW_POWER:
684 case TYPE_REPORT_LOW_POWER_SLEEP:
687 case TYPE_REPORT_WORK_MODE:
690 case TYPE_QUERY_VERSION:
712 uint8_t count =
static_cast<uint8_t
>(std::min<uint32_t>(reported, MAX_TARGETS));
715 std::array<int32_t, MAX_TARGETS> wire_cluster{};
716 std::array<bool, MAX_TARGETS> wire_placed{};
717 std::array<bool, MAX_TARGETS> slot_seen{};
718 std::array<uint8_t, MAX_TARGETS> slot_wire{};
719 for (uint8_t i = 0; i < count; i++) {
720 uint16_t cluster_offset = 4 + (i * TARGET_DATA_LEN) + 16;
721 wire_cluster[i] =
static_cast<int32_t
>(
read_u32_le(data + cluster_offset));
723 for (uint8_t i = 0; i < count; i++) {
724 for (uint8_t s = 0; s < MAX_TARGETS; s++) {
727 wire_placed[i] =
true;
733 for (uint8_t s = 0; s < MAX_TARGETS; s++) {
738 for (uint8_t i = 0; i < count; i++) {
739 if (wire_placed[i]) {
742 for (uint8_t s = 0; s < MAX_TARGETS; s++) {
762#ifdef USE_BINARY_SENSOR
770 for (uint8_t i = 0; i < MAX_TARGETS; i++) {
774 uint16_t offset = 4 + (slot_wire[i] * TARGET_DATA_LEN);
781 if (target.
x !=
nullptr) {
784 if (target.
y !=
nullptr) {
787 if (target.
z !=
nullptr) {
790 if (target.
dop_idx !=
nullptr) {
806#ifdef USE_BINARY_SENSOR
843 const uint16_t needed = AREA_COUNT * AREA_PRESENCE_ENTRY_LEN;
848 for (uint8_t i = 0; i < AREA_COUNT; i++) {
850 bool present =
state != 0;
852#ifdef USE_BINARY_SENSOR
859#ifdef USE_BINARY_SENSOR
869 uint16_t needed = AREA_COUNT * AREA_DATA_LEN;
873 for (uint8_t i = 0; i < AREA_COUNT; i++) {
874 uint16_t offset = i * AREA_DATA_LEN;
884 if (area.
x_min !=
nullptr)
886 if (area.
x_max !=
nullptr)
888 if (area.
y_min !=
nullptr)
890 if (area.
y_max !=
nullptr)
892 if (area.
z_min !=
nullptr)
894 if (area.
z_max !=
nullptr)
907 bool selected_interference = selected_id < AREA_COUNT;
908 uint8_t selected_index = selected_interference ? selected_id :
static_cast<uint8_t
>(selected_id - AREA_COUNT);
909 if (selected_interference == interference && selected_index == i) {
931 uint8_t value = data[0];
944 uint8_t value = data[0];
970 uint8_t value = data[0];
980 bool enabled = data[0] != 0;
1005 const bool low_power = (data[0] == 0);
1006#ifdef USE_TEXT_SENSOR
1024#ifdef USE_TEXT_SENSOR
1040#ifdef USE_TEXT_SENSOR
1055 if (number ==
nullptr)
1057 if (std::isnan(value)) {
1071 if (value < min_value || value > max_value) {
1072 ESP_LOGW(TAG,
"'%s': module reported %.1f, clamped to %.1f..%.1f", number->
get_name().
c_str(), value, min_value,
1074 value = std::clamp(value, min_value, max_value);
1083#ifdef USE_TEXT_SENSOR
1086 uint8_t project = data[0];
1087 uint8_t major = data[1];
1088 uint8_t minor = data[2];
1089 uint8_t patch = data[3];
1092 std::snprintf(buf,
sizeof(buf),
"%u.%u.%u", major, minor, patch);
1094 std::snprintf(buf,
sizeof(buf),
"p%u %u.%u.%u", project, major, minor, patch);
1102 if (
len > CMD_MAX_DATA_LEN) {
1103 ESP_LOGW(TAG,
"Command data too large: %u",
len);
1107 ESP_LOGW(TAG,
"Command queue full, dropping command 0x%04X",
type);
1114 if (
len > 0 && data !=
nullptr) {
1115 std::memcpy(cmd.
data.data(), data,
len);
1130 const uint32_t active_control_command =
1135#ifdef ESPHOME_LOG_HAS_VERBOSE
1136 if (active_control_command != 0) {
1137 ESP_LOGV(TAG,
"Retrying %s (0x%02" PRIX32
"), %u attempt(s) remaining",
1138 control_command_name(active_control_command), active_control_command, this->
retries_left_);
1141 ESP_LOGV(TAG,
"Retrying command 0x%04X, %u attempt(s) remaining", this->
active_command_.
type,
1142 this->retries_left_);
1150 if (active_control_command != 0) {
1151 ESP_LOGW(TAG,
"Command 0x%04X subcommand 0x%02" PRIX32
" timed out", this->
active_command_.
type,
1152 active_control_command);
1166 ESP_LOGW(TAG,
"Area read timed out, dropping deferred area apply");
1175 this->
stale_ack_count_ =
static_cast<uint8_t
>(std::min<uint16_t>(owed, 255));
1211 if (
len > CMD_MAX_DATA_LEN) {
1212 ESP_LOGW(TAG,
"Command data too large: %u",
len);
1225 if (len > 0 && data !=
nullptr) {
1253 uint8_t header_xor = 0;
1254 auto write_header = [&](uint8_t b) {
1259 write_header(TF_SOF);
1260 write_header((frame_id >> 8) & 0xFF);
1261 write_header(frame_id & 0xFF);
1262 write_header((
len >> 8) & 0xFF);
1263 write_header(
len & 0xFF);
1264 write_header((
type >> 8) & 0xFF);
1265 write_header(
type & 0xFF);
1267 this->
write_byte(
static_cast<uint8_t
>(~header_xor));
1269 if (
len > 0 && data !=
nullptr) {
1270 uint8_t data_xor = 0;
1271 for (uint8_t i = 0; i <
len; i++) {
1273 data_xor ^= data[i];
1275 this->
write_byte(
static_cast<uint8_t
>(~data_xor));
1298 if (std::isnan(this->
z_min_) || std::isnan(this->
z_max_)) {
1299 ESP_LOGW(TAG,
"Z range not written, other bound unknown");
1304 ESP_LOGW(TAG,
"Z range not written, min above max");
1315 ESP_LOGW(TAG,
"Area ID not selected; ignoring apply");
1318 if (this->
area_id_ >= AREA_ID_COUNT) {
1319 ESP_LOGW(TAG,
"Invalid area id: %u", this->
area_id_);
1323 const bool interference = this->
area_id_ < AREA_COUNT;
1324 const uint8_t index = interference ? this->
area_id_ :
static_cast<uint8_t
>(this->
area_id_ - AREA_COUNT);
1339 if (std::isnan(desired.
x_min) || std::isnan(desired.
x_max) || std::isnan(desired.
y_min) ||
1340 std::isnan(desired.
y_max) || std::isnan(desired.
z_min) || std::isnan(desired.
z_max)) {
1344 ESP_LOGW(TAG,
"Area read not queued; area config left unapplied");
1362 ESP_LOGI(TAG,
"Area config incomplete; requesting current areas before applying");
1402 this->
queue_command_(TYPE_SET_LOW_POWER_SLEEP, data,
sizeof(data));
1437 }
else if (index == 1) {
1439 }
else if (index == 2) {
1446 }
else if (index == 1) {
1448 }
else if (index == 2) {
1455 }
else if (index == 1) {
1460 this->
area_id_ =
static_cast<uint8_t
>(index);
1473 if (std::isnan(edits.
x_min))
1475 if (std::isnan(edits.
x_max))
1477 if (std::isnan(edits.
y_min))
1479 if (std::isnan(edits.
y_max))
1481 if (std::isnan(edits.
z_min))
1483 if (std::isnan(edits.
z_max))
1502 if (area_id >= AREA_ID_COUNT)
1504 const bool interference = area_id < AREA_COUNT;
1505 const uint8_t index = interference ? area_id :
static_cast<uint8_t
>(area_id - AREA_COUNT);
1519 ESP_LOGW(TAG,
"Area %u not written, min above max", area_id);
1522 uint8_t data[AREA_CONFIG_LEN];
1539 const bool interference = area_id < AREA_COUNT;
1540 const uint8_t index = interference ? area_id :
static_cast<uint8_t
>(area_id - AREA_COUNT);
1547 if (area_id == selected_id) {
1562 const uint8_t index =
1579 if (std::isnan(desired.
x_min) || std::isnan(desired.
x_max) || std::isnan(desired.
y_min) ||
1580 std::isnan(desired.
y_max) || std::isnan(desired.
z_min) || std::isnan(desired.
z_max)) {
1584 if (reported_interference == interference) {
1587 ESP_LOGW(TAG,
"Dropping deferred area apply, area report incomplete");
1614 value = AREA_ID_DEFAULT;
1633#ifdef USE_TEXT_SENSOR
1642 pref.value[
sizeof(pref.value) - 1] =
'\0';
1649#ifdef USE_TEXT_SENSOR
1654 std::strncpy(pref.value, value,
sizeof(pref.value) - 1);
1655 pref.value[
sizeof(pref.value) - 1] =
'\0';
1666 if (target.
x !=
nullptr) {
1669 if (target.
y !=
nullptr) {
1672 if (target.
z !=
nullptr) {
1675 if (target.
dop_idx !=
nullptr) {
1741#ifdef USE_BINARY_SENSOR
1742 for (uint8_t i = 0; i < AREA_COUNT; i++) {
1760 for (uint8_t i = 0; i < MAX_TARGETS; i++) {
1767#ifdef USE_BINARY_SENSOR
1784#ifdef USE_BINARY_SENSOR
void mark_failed()
Mark this component as failed.
bool cancel_timeout(const char *name)
Cancel a timeout function.
void set_timeout(const char *name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a const char* name.
const StringRef & get_name() const
ESPPreferenceObject make_entity_preference(uint32_t version=0)
Create a preference object for storing this entity's state/settings.
virtual void digital_write(bool value)=0
An STL allocator that uses SPI or internal RAM.
constexpr const char * c_str() const
void publish_state(bool new_state)
Publish a new state to the front-end.
text_sensor::TextSensor * work_mode_text_sensor_
select::Select * area_id_select_
bool queue_area_config_(uint8_t area_id, const AreaConfig &desired)
binary_sensor::BinarySensor * presence_binary_sensor_
number::Number * area_z_min_number_
void handle_target_report_(const uint8_t *data, uint16_t len)
text_sensor::TextSensor * ota_version_text_sensor_
std::array< uint8_t, CMD_MAX_DATA_LEN > wake_scratch_
static constexpr uint8_t CMD_QUEUE_SIZE
static constexpr const char * WAKE_BUTTON_TIMEOUT
void clear_target_state_()
number::Number * area_z_max_number_
static void write_int32_le(uint8_t *data, int32_t value)
bool last_work_mode_low_power_
void set_select_value(SelectType type, size_t index)
void save_area_id_pref_(uint8_t value)
number::Number * z_min_number_
static void write_u32_le(uint8_t *data, uint32_t value)
std::array< PendingCommand, CMD_QUEUE_SIZE > cmd_queue_
bool version_pref_initialized_
static float read_f32_le(const uint8_t *data)
uint32_t wakeup_pulse_ms_
ESPPreferenceObject version_pref_
void handle_installation_report_(const uint8_t *data, uint16_t len)
number::Number * z_max_number_
void set_switch_state(SwitchType type, bool state)
std::array< bool, MAX_TARGETS > last_cluster_id_valid_
std::array< int32_t, MAX_TARGETS > last_cluster_id_
void set_number_value(NumberType type, float value)
void handle_trigger_speed_report_(const uint8_t *data, uint16_t len)
select::Select * installation_select_
bool target_display_enabled_
std::array< AreaSensors, AREA_COUNT > detection_areas_
select::Select * trigger_speed_select_
void init_area_id_pref_()
static uint32_t read_u32_le(const uint8_t *data)
void publish_area_numbers_()
bool target_presence_any_
bool last_work_mode_valid_
void save_version_pref_(const char *value)
number::Number * area_x_max_number_
PendingCommand active_command_
sensor::Sensor * point_count_sensor_
static constexpr uint8_t CMD_MAX_RETRIES
void update_area_numbers_for_id_(uint8_t area_id)
void update_area_numbers_(const AreaConfig &area)
AreaConfig pending_area_updates_
void dump_config() override
uint32_t last_target_count_
std::array< AreaConfig, AREA_COUNT > interference_area_values_
void handle_version_report_(const uint8_t *data, uint16_t len)
number::Number * area_y_max_number_
switch_::Switch * target_display_switch_
void send_command_internal_(uint16_t type, const uint8_t *data, uint8_t len, bool track)
static uint16_t read_u16_be(const uint8_t *data)
static constexpr const char * AREA_REFRESH_TIMEOUT
void handle_area_presence_(const uint8_t *data, uint16_t len)
void publish_number_clamped_(number::Number *number, float value)
select::Select * sensitivity_select_
number::Number * hold_delay_number_
static constexpr uint32_t MODULE_AWAKE_MS
bool area_write_in_flight_
static constexpr uint32_t CMD_FIRST_ACK_TIMEOUT_MS
uint32_t discard_remaining_
void init_version_pref_()
static int32_t read_int32_le(const uint8_t *data)
void handle_area_report_(bool interference, const uint8_t *data, uint16_t len)
std::array< bool, MAX_TARGETS > slot_occupied_
void handle_low_power_report_(const uint8_t *data, uint16_t len)
std::array< AreaConfig, AREA_COUNT > detection_area_values_
static constexpr uint32_t CMD_ACK_TIMEOUT_MS
bool deferred_apply_pending_
std::array< int32_t, MAX_TARGETS > slot_cluster_
void clear_area_presence_()
std::array< binary_sensor::BinarySensor *, AREA_COUNT > area_presence_
void handle_delay_report_(const uint8_t *data, uint16_t len)
std::array< AreaSensors, AREA_COUNT > interference_areas_
void apply_area_config_()
void handle_sensitivity_report_(const uint8_t *data, uint16_t len)
bool area_id_pref_initialized_
void parse_byte_(uint8_t byte)
bool point_cloud_enabled_
std::array< TargetSensors, MAX_TARGETS > targets_
void handle_frame_(uint16_t type, const uint8_t *data, uint16_t len)
void send_command_(uint16_t type, const uint8_t *data, uint8_t len)
switch_::Switch * low_power_switch_
void restore_deferred_edits_()
sensor::Sensor * target_count_sensor_
switch_::Switch * point_cloud_switch_
std::array< bool, MAX_TARGETS > last_target_presence_
uint32_t last_point_count_
number::Number * area_y_min_number_
void publish_work_mode_(bool low_power)
void write_frame_(uint16_t type, const uint8_t *data, uint8_t len, bool track)
std::array< binary_sensor::BinarySensor *, MAX_TARGETS > target_presence_
void handle_low_power_sleep_report_(const uint8_t *data, uint16_t len)
void handle_work_mode_report_(const uint8_t *data, uint16_t len)
void press_button(ButtonType type)
number::Number * area_x_min_number_
void try_apply_pending_area_(bool reported_interference)
void process_command_queue_()
bool queue_command_(uint16_t type, const uint8_t *data, uint8_t len)
void clear_target_slot_(uint8_t index)
number::Number * low_power_sleep_number_
static constexpr uint32_t STALE_ACK_MAX_AGE_MS
ESPPreferenceObject area_id_pref_
bool send_control_command_(uint32_t command)
void handle_point_cloud_(const uint8_t *data, uint16_t len)
void handle_z_range_report_(const uint8_t *data, uint16_t len)
static void write_f32_le(uint8_t *data, float value)
void update_work_mode_fallback_()
uint32_t last_traffic_ms_
Base-class for all numbers.
void publish_state(float state)
float get_min_value() const
float get_max_value() const
void publish_state(const std::string &state)
void publish_state(float state)
Publish a new state to the front-end.
void turn_on()
Turn this switch on.
void turn_off()
Turn this switch off.
void publish_state(bool state)
Publish a state to the front-end from the back-end.
optional< bool > get_initial_state_with_restore_mode()
Returns the initial state of the switch, after applying restore mode rules.
void publish_state(const std::string &state)
void write_byte(uint8_t data)
@ GET_LOW_POWER_SLEEP_TIME
void HOT delay(uint32_t ms)
uint32_t IRAM_ATTR HOT millis()
std::array< uint8_t, CMD_MAX_DATA_LEN > data
sensor::Sensor * cluster_id