ESPHome  2024.5.0
commands.cpp
Go to the documentation of this file.
1 #include "commands.h"
2 
3 #include <cmath>
4 
5 #include "esphome/core/log.h"
6 
7 #include "dfrobot_sen0395.h"
8 
9 namespace esphome {
10 namespace dfrobot_sen0395 {
11 
12 static const char *const TAG = "dfrobot_sen0395.commands";
13 
15  this->parent_ = parent;
16  if (this->cmd_sent_) {
17  if (this->parent_->read_message_()) {
18  std::string message(this->parent_->read_buffer_);
19  if (message.rfind("is not recognized as a CLI command") != std::string::npos) {
20  ESP_LOGD(TAG, "Command not recognized properly by sensor");
21  if (this->retries_left_ > 0) {
22  this->retries_left_ -= 1;
23  this->cmd_sent_ = false;
24  ESP_LOGD(TAG, "Retrying...");
25  return 0;
26  } else {
27  this->parent_->find_prompt_();
28  return 1; // Command done
29  }
30  }
31  uint8_t rc = on_message(message);
32  if (rc == 2) {
33  if (this->retries_left_ > 0) {
34  this->retries_left_ -= 1;
35  this->cmd_sent_ = false;
36  ESP_LOGD(TAG, "Retrying...");
37  return 0;
38  } else {
39  this->parent_->find_prompt_();
40  return 1; // Command done
41  }
42  } else if (rc == 0) {
43  return 0;
44  } else {
45  this->parent_->find_prompt_();
46  return 1;
47  }
48  }
49  if (millis() - this->parent_->ts_last_cmd_sent_ > this->timeout_ms_) {
50  ESP_LOGD(TAG, "Command timeout");
51  if (this->retries_left_ > 0) {
52  this->retries_left_ -= 1;
53  this->cmd_sent_ = false;
54  ESP_LOGD(TAG, "Retrying...");
55  } else {
56  return 1; // Command done
57  }
58  }
59  } else if (this->parent_->send_cmd_(this->cmd_.c_str(), this->cmd_duration_ms_)) {
60  this->cmd_sent_ = true;
61  }
62  return 0; // Command not done yet
63 }
64 
66  this->parent_ = parent;
67  if (this->parent_->read_message_()) {
68  std::string message(this->parent_->read_buffer_);
69  if (message.rfind("$JYBSS,0, , , *") != std::string::npos) {
70  this->parent_->set_detected_(false);
71  this->parent_->set_active(true);
72  return 1; // Command done
73  } else if (message.rfind("$JYBSS,1, , , *") != std::string::npos) {
74  this->parent_->set_detected_(true);
75  this->parent_->set_active(true);
76  return 1; // Command done
77  }
78  }
79  if (millis() - this->parent_->ts_last_cmd_sent_ > this->timeout_ms_) {
80  return 1; // Command done, timeout
81  }
82  return 0; // Command not done yet.
83 }
84 
85 uint8_t ReadStateCommand::on_message(std::string &message) { return 1; }
86 
87 uint8_t PowerCommand::on_message(std::string &message) {
88  if (message == "sensor stopped already") {
89  this->parent_->set_active(false);
90  ESP_LOGI(TAG, "Stopped sensor (already stopped)");
91  return 1; // Command done
92  } else if (message == "sensor started already") {
93  this->parent_->set_active(true);
94  ESP_LOGI(TAG, "Started sensor (already started)");
95  return 1; // Command done
96  } else if (message == "new parameter isn't save, can't startSensor") {
97  this->parent_->set_active(false);
98  ESP_LOGE(TAG, "Can't start sensor! (Use SaveCfgCommand to save config first)");
99  return 1; // Command done
100  } else if (message == "Done") {
101  this->parent_->set_active(this->power_on_);
102  if (this->power_on_) {
103  ESP_LOGI(TAG, "Started sensor");
104  } else {
105  ESP_LOGI(TAG, "Stopped sensor");
106  }
107  return 1; // Command done
108  }
109  return 0; // Command not done yet.
110 }
111 
112 DetRangeCfgCommand::DetRangeCfgCommand(float min1, float max1, float min2, float max2, float min3, float max3,
113  float min4, float max4) {
114  // TODO: Print warning when values are rounded
115  if (min1 < 0 || max1 < 0) {
116  this->min1_ = min1 = 0;
117  this->max1_ = max1 = 0;
118  this->min2_ = min2 = this->max2_ = max2 = this->min3_ = min3 = this->max3_ = max3 = this->min4_ = min4 =
119  this->max4_ = max4 = -1;
120 
121  ESP_LOGW(TAG, "DetRangeCfgCommand invalid input parameters. Using range config 0 0.");
122 
123  this->cmd_ = "detRangeCfg -1 0 0";
124  } else if (min2 < 0 || max2 < 0) {
125  this->min1_ = min1 = round(min1 / 0.15) * 0.15;
126  this->max1_ = max1 = round(max1 / 0.15) * 0.15;
127  this->min2_ = min2 = this->max2_ = max2 = this->min3_ = min3 = this->max3_ = max3 = this->min4_ = min4 =
128  this->max4_ = max4 = -1;
129 
130  this->cmd_ = str_sprintf("detRangeCfg -1 %.0f %.0f", min1 / 0.15, max1 / 0.15);
131  } else if (min3 < 0 || max3 < 0) {
132  this->min1_ = min1 = round(min1 / 0.15) * 0.15;
133  this->max1_ = max1 = round(max1 / 0.15) * 0.15;
134  this->min2_ = min2 = round(min2 / 0.15) * 0.15;
135  this->max2_ = max2 = round(max2 / 0.15) * 0.15;
136  this->min3_ = min3 = this->max3_ = max3 = this->min4_ = min4 = this->max4_ = max4 = -1;
137 
138  this->cmd_ = str_sprintf("detRangeCfg -1 %.0f %.0f %.0f %.0f", min1 / 0.15, max1 / 0.15, min2 / 0.15, max2 / 0.15);
139  } else if (min4 < 0 || max4 < 0) {
140  this->min1_ = min1 = round(min1 / 0.15) * 0.15;
141  this->max1_ = max1 = round(max1 / 0.15) * 0.15;
142  this->min2_ = min2 = round(min2 / 0.15) * 0.15;
143  this->max2_ = max2 = round(max2 / 0.15) * 0.15;
144  this->min3_ = min3 = round(min3 / 0.15) * 0.15;
145  this->max3_ = max3 = round(max3 / 0.15) * 0.15;
146  this->min4_ = min4 = this->max4_ = max4 = -1;
147 
148  this->cmd_ = str_sprintf("detRangeCfg -1 "
149  "%.0f %.0f %.0f %.0f %.0f %.0f",
150  min1 / 0.15, max1 / 0.15, min2 / 0.15, max2 / 0.15, min3 / 0.15, max3 / 0.15);
151  } else {
152  this->min1_ = min1 = round(min1 / 0.15) * 0.15;
153  this->max1_ = max1 = round(max1 / 0.15) * 0.15;
154  this->min2_ = min2 = round(min2 / 0.15) * 0.15;
155  this->max2_ = max2 = round(max2 / 0.15) * 0.15;
156  this->min3_ = min3 = round(min3 / 0.15) * 0.15;
157  this->max3_ = max3 = round(max3 / 0.15) * 0.15;
158  this->min4_ = min4 = round(min4 / 0.15) * 0.15;
159  this->max4_ = max4 = round(max4 / 0.15) * 0.15;
160 
161  this->cmd_ = str_sprintf("detRangeCfg -1 "
162  "%.0f %.0f %.0f %.0f %.0f %.0f %.0f %.0f",
163  min1 / 0.15, max1 / 0.15, min2 / 0.15, max2 / 0.15, min3 / 0.15, max3 / 0.15, min4 / 0.15,
164  max4 / 0.15);
165  }
166 
167  this->min1_ = min1;
168  this->max1_ = max1;
169  this->min2_ = min2;
170  this->max2_ = max2;
171  this->min3_ = min3;
172  this->max3_ = max3;
173  this->min4_ = min4;
174  this->max4_ = max4;
175 };
176 
177 uint8_t DetRangeCfgCommand::on_message(std::string &message) {
178  if (message == "sensor is not stopped") {
179  ESP_LOGE(TAG, "Cannot configure range config. Sensor is not stopped!");
180  return 1; // Command done
181  } else if (message == "Done") {
182  ESP_LOGI(TAG, "Updated detection area config:");
183  ESP_LOGI(TAG, "Detection area 1 from %.02fm to %.02fm.", this->min1_, this->max1_);
184  if (this->min2_ >= 0 && this->max2_ >= 0) {
185  ESP_LOGI(TAG, "Detection area 2 from %.02fm to %.02fm.", this->min2_, this->max2_);
186  }
187  if (this->min3_ >= 0 && this->max3_ >= 0) {
188  ESP_LOGI(TAG, "Detection area 3 from %.02fm to %.02fm.", this->min3_, this->max3_);
189  }
190  if (this->min4_ >= 0 && this->max4_ >= 0) {
191  ESP_LOGI(TAG, "Detection area 4 from %.02fm to %.02fm.", this->min4_, this->max4_);
192  }
193  ESP_LOGD(TAG, "Used command: %s", this->cmd_.c_str());
194  return 1; // Command done
195  }
196  return 0; // Command not done yet.
197 }
198 
199 SetLatencyCommand::SetLatencyCommand(float delay_after_detection, float delay_after_disappear) {
200  delay_after_detection = std::round(delay_after_detection / 0.025f) * 0.025f;
201  delay_after_disappear = std::round(delay_after_disappear / 0.025f) * 0.025f;
202  this->delay_after_detection_ = clamp(delay_after_detection, 0.0f, 1638.375f);
203  this->delay_after_disappear_ = clamp(delay_after_disappear, 0.0f, 1638.375f);
204  this->cmd_ = str_sprintf("setLatency %.03f %.03f", this->delay_after_detection_, this->delay_after_disappear_);
205 };
206 
207 uint8_t SetLatencyCommand::on_message(std::string &message) {
208  if (message == "sensor is not stopped") {
209  ESP_LOGE(TAG, "Cannot configure output latency. Sensor is not stopped!");
210  return 1; // Command done
211  } else if (message == "Done") {
212  ESP_LOGI(TAG, "Updated output latency config:");
213  ESP_LOGI(TAG, "Signal that someone was detected is delayed by %.03f s.", this->delay_after_detection_);
214  ESP_LOGI(TAG, "Signal that nobody is detected anymore is delayed by %.03f s.", this->delay_after_disappear_);
215  ESP_LOGD(TAG, "Used command: %s", this->cmd_.c_str());
216  return 1; // Command done
217  }
218  return 0; // Command not done yet
219 }
220 
221 uint8_t SensorCfgStartCommand::on_message(std::string &message) {
222  if (message == "sensor is not stopped") {
223  ESP_LOGE(TAG, "Cannot configure sensor startup behavior. Sensor is not stopped!");
224  return 1; // Command done
225  } else if (message == "Done") {
226  ESP_LOGI(TAG, "Updated sensor startup behavior:");
227  if (startup_mode_) {
228  this->parent_->set_start_after_boot(true);
229  ESP_LOGI(TAG, "Sensor will start automatically after power-on.");
230  } else {
231  this->parent_->set_start_after_boot(false);
232  ESP_LOGI(TAG, "Sensor needs to be started manually after power-on.");
233  }
234  ESP_LOGD(TAG, "Used command: %s", this->cmd_.c_str());
235  return 1; // Command done
236  }
237  return 0; // Command not done yet
238 }
239 
240 uint8_t FactoryResetCommand::on_message(std::string &message) {
241  if (message == "sensor is not stopped") {
242  ESP_LOGE(TAG, "Cannot factory reset. Sensor is not stopped!");
243  return 1; // Command done
244  } else if (message == "Done") {
245  ESP_LOGI(TAG, "Sensor factory reset done.");
246  return 1; // Command done
247  }
248  return 0; // Command not done yet
249 }
250 
251 uint8_t ResetSystemCommand::on_message(std::string &message) {
252  if (message == "leapMMW:/>") {
253  ESP_LOGI(TAG, "Restarted sensor.");
254  return 1; // Command done
255  }
256  return 0; // Command not done yet
257 }
258 
259 uint8_t SaveCfgCommand::on_message(std::string &message) {
260  if (message == "no parameter has changed") {
261  ESP_LOGI(TAG, "Not saving config (no parameter changed).");
262  return 1; // Command done
263  } else if (message == "Done") {
264  ESP_LOGI(TAG, "Saved config. Saving a lot may damage the sensor.");
265  return 1; // Command done
266  }
267  return 0; // Command not done yet
268 }
269 
270 uint8_t LedModeCommand::on_message(std::string &message) {
271  if (message == "sensor is not stopped") {
272  ESP_LOGE(TAG, "Cannot set led mode. Sensor is not stopped!");
273  return 1; // Command done
274  } else if (message == "Done") {
275  ESP_LOGI(TAG, "Set led mode done.");
276  if (this->active_) {
277  this->parent_->set_led_active(true);
278  ESP_LOGI(TAG, "Sensor LED will blink.");
279  } else {
280  this->parent_->set_led_active(false);
281  ESP_LOGI(TAG, "Turned off LED.");
282  }
283  ESP_LOGD(TAG, "Used command: %s", this->cmd_.c_str());
284  return 1; // Command done
285  }
286  return 0; // Command not done yet
287 }
288 
289 uint8_t UartOutputCommand::on_message(std::string &message) {
290  if (message == "sensor is not stopped") {
291  ESP_LOGE(TAG, "Cannot set uart output mode. Sensor is not stopped!");
292  return 1; // Command done
293  } else if (message == "Done") {
294  ESP_LOGI(TAG, "Set uart mode done.");
295  if (this->active_) {
296  this->parent_->set_uart_presence_active(true);
297  ESP_LOGI(TAG, "Presence information is sent via UART and GPIO.");
298  } else {
299  this->parent_->set_uart_presence_active(false);
300  ESP_LOGI(TAG, "Presence information is only sent via GPIO.");
301  }
302  ESP_LOGD(TAG, "Used command: %s", this->cmd_.c_str());
303  return 1; // Command done
304  }
305  return 0; // Command not done yet
306 }
307 
308 uint8_t SensitivityCommand::on_message(std::string &message) {
309  if (message == "sensor is not stopped") {
310  ESP_LOGE(TAG, "Cannot set sensitivity. Sensor is not stopped!");
311  return 1; // Command done
312  } else if (message == "Done") {
313  ESP_LOGI(TAG, "Set sensitivity done. Set to value %d.", this->sensitivity_);
314  ESP_LOGD(TAG, "Used command: %s", this->cmd_.c_str());
315  return 1; // Command done
316  }
317  return 0; // Command not done yet
318 }
319 
320 } // namespace dfrobot_sen0395
321 } // namespace esphome
uint8_t execute(DfrobotSen0395Component *parent) override
Definition: commands.cpp:65
uint8_t on_message(std::string &message) override
Definition: commands.cpp:87
uint8_t on_message(std::string &message) override
Definition: commands.cpp:308
DfrobotSen0395Component * parent_
Definition: commands.h:23
uint8_t on_message(std::string &message) override
Definition: commands.cpp:251
uint8_t on_message(std::string &message) override
Definition: commands.cpp:221
uint8_t on_message(std::string &message) override
Definition: commands.cpp:85
DetRangeCfgCommand(float min1, float max1, float min2, float max2, float min3, float max3, float min4, float max4)
Definition: commands.cpp:112
uint8_t on_message(std::string &message) override
Definition: commands.cpp:240
uint8_t on_message(std::string &message) override
Definition: commands.cpp:289
constexpr const T & clamp(const T &v, const T &lo, const T &hi, Compare comp)
Definition: helpers.h:92
uint32_t IRAM_ATTR HOT millis()
Definition: core.cpp:25
virtual uint8_t execute(DfrobotSen0395Component *parent)
Definition: commands.cpp:14
uint8_t send_cmd_(const char *cmd, uint32_t duration)
std::string str_sprintf(const char *fmt,...)
Definition: helpers.cpp:312
SetLatencyCommand(float delay_after_detection, float delay_after_disappear)
Definition: commands.cpp:199
char read_buffer_[MMWAVE_READ_BUFFER_LENGTH]
uint8_t on_message(std::string &message) override
Definition: commands.cpp:270
uint8_t on_message(std::string &message) override
Definition: commands.cpp:259
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
virtual uint8_t on_message(std::string &message)=0
uint8_t on_message(std::string &message) override
Definition: commands.cpp:207
uint8_t on_message(std::string &message) override
Definition: commands.cpp:177