ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
ezo_pmp.cpp
Go to the documentation of this file.
1#include "ezo_pmp.h"
2#include "esphome/core/log.h"
3#include "esphome/core/hal.h"
4
5namespace esphome::ezo_pmp {
6
7ESPHOME_LOG_TAG(TAG, "ezo-pmp");
8
9static const uint16_t EZO_PMP_COMMAND_NONE = 0;
10static const uint16_t EZO_PMP_COMMAND_TYPE_READ = 1;
11
12static const uint16_t EZO_PMP_COMMAND_FIND = 2;
13static const uint16_t EZO_PMP_COMMAND_DOSE_CONTINUOUSLY = 4;
14static const uint16_t EZO_PMP_COMMAND_DOSE_VOLUME = 8;
15static const uint16_t EZO_PMP_COMMAND_DOSE_VOLUME_OVER_TIME = 16;
16static const uint16_t EZO_PMP_COMMAND_DOSE_WITH_CONSTANT_FLOW_RATE = 32;
17static const uint16_t EZO_PMP_COMMAND_SET_CALIBRATION_VOLUME = 64;
18static const uint16_t EZO_PMP_COMMAND_CLEAR_TOTAL_VOLUME_DOSED = 128;
19static const uint16_t EZO_PMP_COMMAND_CLEAR_CALIBRATION = 256;
20static const uint16_t EZO_PMP_COMMAND_PAUSE_DOSING = 512;
21static const uint16_t EZO_PMP_COMMAND_STOP_DOSING = 1024;
22static const uint16_t EZO_PMP_COMMAND_CHANGE_I2C_ADDRESS = 2048;
23static const uint16_t EZO_PMP_COMMAND_EXEC_ARBITRARY_COMMAND_ADDRESS = 4096;
24
25static const uint16_t EZO_PMP_COMMAND_READ_DOSING = 3;
26static const uint16_t EZO_PMP_COMMAND_READ_SINGLE_REPORT = 5;
27static const uint16_t EZO_PMP_COMMAND_READ_MAX_FLOW_RATE = 9;
28static const uint16_t EZO_PMP_COMMAND_READ_PAUSE_STATUS = 17;
29static const uint16_t EZO_PMP_COMMAND_READ_TOTAL_VOLUME_DOSED = 33;
30static const uint16_t EZO_PMP_COMMAND_READ_ABSOLUTE_TOTAL_VOLUME_DOSED = 65;
31static const uint16_t EZO_PMP_COMMAND_READ_CALIBRATION_STATUS = 129;
32static const uint16_t EZO_PMP_COMMAND_READ_PUMP_VOLTAGE = 257;
33
34static const std::string DOSING_MODE_NONE = "None";
35static const std::string DOSING_MODE_VOLUME = "Volume";
36static const std::string DOSING_MODE_VOLUME_OVER_TIME = "Volume/Time";
37static const std::string DOSING_MODE_CONSTANT_FLOW_RATE = "Constant Flow Rate";
38static const std::string DOSING_MODE_CONTINUOUS = "Continuous";
39
41 LOG_I2C_DEVICE(this);
42 LOG_UPDATE_INTERVAL(this);
43}
44
46 if (this->is_waiting_) {
47 return;
48 }
49
50 if (this->is_first_read_) {
51#ifdef USE_TEXT_SENSOR
52 this->queue_command_(EZO_PMP_COMMAND_READ_CALIBRATION_STATUS, 0, 0, (bool) this->calibration_status_);
53#endif
54#ifdef USE_SENSOR
55 this->queue_command_(EZO_PMP_COMMAND_READ_MAX_FLOW_RATE, 0, 0, (bool) this->max_flow_rate_);
56 this->queue_command_(EZO_PMP_COMMAND_READ_SINGLE_REPORT, 0, 0, (bool) this->current_volume_dosed_);
57 this->queue_command_(EZO_PMP_COMMAND_READ_TOTAL_VOLUME_DOSED, 0, 0, (bool) this->total_volume_dosed_);
58 this->queue_command_(EZO_PMP_COMMAND_READ_ABSOLUTE_TOTAL_VOLUME_DOSED, 0, 0,
59 (bool) this->absolute_total_volume_dosed_);
60#endif
61 this->queue_command_(EZO_PMP_COMMAND_READ_PAUSE_STATUS, 0, 0, true);
62 this->is_first_read_ = false;
63 }
64
65 if (!this->is_waiting_ && this->peek_next_command_() == EZO_PMP_COMMAND_NONE) {
66 this->queue_command_(EZO_PMP_COMMAND_READ_DOSING, 0, 0, true);
67
68#ifdef USE_SENSOR
69 if (this->is_dosing_flag_) {
70 this->queue_command_(EZO_PMP_COMMAND_READ_SINGLE_REPORT, 0, 0, (bool) this->current_volume_dosed_);
71 this->queue_command_(EZO_PMP_COMMAND_READ_TOTAL_VOLUME_DOSED, 0, 0, (bool) this->total_volume_dosed_);
72 this->queue_command_(EZO_PMP_COMMAND_READ_ABSOLUTE_TOTAL_VOLUME_DOSED, 0, 0,
73 (bool) this->absolute_total_volume_dosed_);
74 }
75
76 this->queue_command_(EZO_PMP_COMMAND_READ_PUMP_VOLTAGE, 0, 0, (bool) this->pump_voltage_);
77#endif
78 } else {
79 ESP_LOGV(TAG, "Not Scheduling new Command during update()");
80 }
81}
82
84 // If we are not waiting for anything and there is no command to be sent, return
85 if (!this->is_waiting_ && this->peek_next_command_() == EZO_PMP_COMMAND_NONE) {
86 return;
87 }
88
89 // If we are not waiting for anything and there IS a command to be sent, do it.
90 if (!this->is_waiting_ && this->peek_next_command_() != EZO_PMP_COMMAND_NONE) {
91 this->send_next_command_();
92 }
93
94 // If we are waiting for something but it isn't ready yet, then return
95 if (this->is_waiting_ && millis() - this->start_time_ < this->wait_time_) {
96 return;
97 }
98
99 // We are waiting for something and it should be ready.
100 this->read_command_result_();
101}
102
104 this->current_command_ = EZO_PMP_COMMAND_NONE;
105 this->is_waiting_ = false;
106}
107
109 uint8_t response_buffer[21] = {'\0'};
110
111 response_buffer[0] = 0;
112 if (!this->read_bytes_raw(response_buffer, 20)) {
113 ESP_LOGE(TAG, "read error");
115 return;
116 }
117
118 switch (response_buffer[0]) {
119 case 254:
120 return; // keep waiting
121 case 1:
122 break;
123 case 2:
124 ESP_LOGE(TAG, "device returned a syntax error");
126 return;
127 case 255:
128 ESP_LOGE(TAG, "device returned no data");
130 return;
131 default:
132 ESP_LOGE(TAG, "device returned an unknown response: %d", response_buffer[0]);
134 return;
135 }
136
137 char first_parameter_buffer[10] = {'\0'};
138 char second_parameter_buffer[10] = {'\0'};
139 char third_parameter_buffer[10] = {'\0'};
140
141 first_parameter_buffer[0] = '\0';
142 second_parameter_buffer[0] = '\0';
143 third_parameter_buffer[0] = '\0';
144
145 int current_parameter = 1;
146
147 size_t position_in_parameter_buffer = 0;
148 // some sensors return multiple comma-separated values, terminate string after first one
149 for (size_t i = 1; i < sizeof(response_buffer) - 1; i++) {
150 char current_char = response_buffer[i];
151
152 if (current_char == '\0') {
153 ESP_LOGV(TAG,
154 "Read Response from device: %s\n"
155 " First Component: %s\n"
156 " Second Component: %s\n"
157 " Third Component: %s",
158 (char *) response_buffer, (char *) first_parameter_buffer, (char *) second_parameter_buffer,
159 (char *) third_parameter_buffer);
160
161 break;
162 }
163
164 if (current_char == ',') {
165 current_parameter++;
166 position_in_parameter_buffer = 0;
167 continue;
168 }
169
170 if (position_in_parameter_buffer < sizeof(first_parameter_buffer) - 1) {
171 switch (current_parameter) {
172 case 1:
173 first_parameter_buffer[position_in_parameter_buffer] = current_char;
174 first_parameter_buffer[position_in_parameter_buffer + 1] = '\0';
175 break;
176 case 2:
177 second_parameter_buffer[position_in_parameter_buffer] = current_char;
178 second_parameter_buffer[position_in_parameter_buffer + 1] = '\0';
179 break;
180 case 3:
181 third_parameter_buffer[position_in_parameter_buffer] = current_char;
182 third_parameter_buffer[position_in_parameter_buffer + 1] = '\0';
183 break;
184 default:
185 break;
186 }
187 position_in_parameter_buffer++;
188 }
189 }
190
191 auto parsed_first_parameter = parse_number<float>(first_parameter_buffer);
192 auto parsed_second_parameter = parse_number<float>(second_parameter_buffer);
193 auto parsed_third_parameter = parse_number<float>(third_parameter_buffer);
194
195 switch (this->current_command_) {
196 // Read Commands
197 case EZO_PMP_COMMAND_READ_DOSING: // Page 54
198 if (parsed_third_parameter.has_value())
199 this->is_dosing_flag_ = parsed_third_parameter.value_or(0) == 1;
200
201#ifdef USE_BINARY_SENSOR
202 if (this->is_dosing_)
204#endif
205
206#ifdef USE_SENSOR
207 if (parsed_second_parameter.has_value() && this->last_volume_requested_) {
208 this->last_volume_requested_->publish_state(parsed_second_parameter.value_or(0));
209 }
210#endif
211
212#ifdef USE_TEXT_SENSOR
213 if (!this->is_dosing_flag_ && !this->is_paused_flag_) {
214 // If pump is not paused and not dispensing
215 if (this->dosing_mode_ && this->dosing_mode_->state != DOSING_MODE_NONE)
216 this->dosing_mode_->publish_state(DOSING_MODE_NONE);
217 }
218#endif
219
220 break;
221
222 case EZO_PMP_COMMAND_READ_SINGLE_REPORT: // Single Report (page 53)
223#ifdef USE_SENSOR
224 if (parsed_first_parameter.has_value() && (bool) this->current_volume_dosed_) {
225 this->current_volume_dosed_->publish_state(parsed_first_parameter.value_or(0));
226 }
227#endif
228 break;
229
230 case EZO_PMP_COMMAND_READ_MAX_FLOW_RATE: // Constant Flow Rate (page 57)
231#ifdef USE_SENSOR
232 if (parsed_second_parameter.has_value() && this->max_flow_rate_)
233 this->max_flow_rate_->publish_state(parsed_second_parameter.value_or(0));
234#endif
235 break;
236
237 case EZO_PMP_COMMAND_READ_PAUSE_STATUS: // Pause (page 61)
238 if (parsed_second_parameter.has_value())
239 this->is_paused_flag_ = parsed_second_parameter.value_or(0) == 1;
240
241#ifdef USE_BINARY_SENSOR
242 if (this->is_paused_)
244#endif
245 break;
246
247 case EZO_PMP_COMMAND_READ_TOTAL_VOLUME_DOSED: // Total Volume Dispensed (page 64)
248#ifdef USE_SENSOR
249 if (parsed_second_parameter.has_value() && this->total_volume_dosed_)
250 this->total_volume_dosed_->publish_state(parsed_second_parameter.value_or(0));
251#endif
252 break;
253
254 case EZO_PMP_COMMAND_READ_ABSOLUTE_TOTAL_VOLUME_DOSED: // Total Volume Dispensed (page 64)
255#ifdef USE_SENSOR
256 if (parsed_second_parameter.has_value() && this->absolute_total_volume_dosed_)
257 this->absolute_total_volume_dosed_->publish_state(parsed_second_parameter.value_or(0));
258#endif
259 break;
260
261 case EZO_PMP_COMMAND_READ_CALIBRATION_STATUS: // Calibration (page 65)
262#ifdef USE_TEXT_SENSOR
263 if (parsed_second_parameter.has_value() && this->calibration_status_) {
264 if (parsed_second_parameter.value_or(0) == 1) {
265 this->calibration_status_->publish_state("Fixed Volume");
266 } else if (parsed_second_parameter.value_or(0) == 2) {
267 this->calibration_status_->publish_state("Volume/Time");
268 } else if (parsed_second_parameter.value_or(0) == 3) {
269 this->calibration_status_->publish_state("Fixed Volume & Volume/Time");
270 } else {
271 this->calibration_status_->publish_state("Uncalibrated");
272 }
273 }
274#endif
275 break;
276
277 case EZO_PMP_COMMAND_READ_PUMP_VOLTAGE: // Pump Voltage (page 67)
278#ifdef USE_SENSOR
279 if (parsed_second_parameter.has_value() && this->pump_voltage_)
280 this->pump_voltage_->publish_state(parsed_second_parameter.value_or(0));
281#endif
282 break;
283
284 // Non-Read Commands
285
286 case EZO_PMP_COMMAND_DOSE_VOLUME: // Volume Dispensing (page 55)
287#ifdef USE_TEXT_SENSOR
288 if (this->dosing_mode_ && this->dosing_mode_->state != DOSING_MODE_VOLUME)
289 this->dosing_mode_->publish_state(DOSING_MODE_VOLUME);
290#endif
291 break;
292
293 case EZO_PMP_COMMAND_DOSE_VOLUME_OVER_TIME: // Dose over time (page 56)
294#ifdef USE_TEXT_SENSOR
295 if (this->dosing_mode_ && this->dosing_mode_->state != DOSING_MODE_VOLUME_OVER_TIME)
296 this->dosing_mode_->publish_state(DOSING_MODE_VOLUME_OVER_TIME);
297#endif
298 break;
299
300 case EZO_PMP_COMMAND_DOSE_WITH_CONSTANT_FLOW_RATE: // Constant Flow Rate (page 57)
301#ifdef USE_TEXT_SENSOR
302 if (this->dosing_mode_ && this->dosing_mode_->state != DOSING_MODE_CONSTANT_FLOW_RATE)
303 this->dosing_mode_->publish_state(DOSING_MODE_CONSTANT_FLOW_RATE);
304#endif
305 break;
306
307 case EZO_PMP_COMMAND_DOSE_CONTINUOUSLY: // Continuous Dispensing (page 54)
308#ifdef USE_TEXT_SENSOR
309 if (this->dosing_mode_ && this->dosing_mode_->state != DOSING_MODE_CONTINUOUS)
310 this->dosing_mode_->publish_state(DOSING_MODE_CONTINUOUS);
311#endif
312 break;
313
314 case EZO_PMP_COMMAND_STOP_DOSING: // Stop (page 62)
315 this->is_paused_flag_ = false;
316#ifdef USE_BINARY_SENSOR
317 if (this->is_paused_)
319#endif
320#ifdef USE_TEXT_SENSOR
321 if (this->dosing_mode_ && this->dosing_mode_->state != DOSING_MODE_NONE)
322 this->dosing_mode_->publish_state(DOSING_MODE_NONE);
323#endif
324 break;
325
326 case EZO_PMP_COMMAND_EXEC_ARBITRARY_COMMAND_ADDRESS:
327 ESP_LOGI(TAG, "Arbitrary Command Response: %s", (char *) response_buffer);
328 break;
329
330 case EZO_PMP_COMMAND_CLEAR_CALIBRATION: // Clear Calibration (page 65)
331 case EZO_PMP_COMMAND_PAUSE_DOSING: // Pause (page 61)
332 case EZO_PMP_COMMAND_SET_CALIBRATION_VOLUME: // Set Calibration Volume (page 65)
333 case EZO_PMP_COMMAND_CLEAR_TOTAL_VOLUME_DOSED: // Clear Total Volume Dosed (page 64)
334 case EZO_PMP_COMMAND_FIND: // Find (page 52)
335 // Nothing to do here
336 break;
337
338 case EZO_PMP_COMMAND_TYPE_READ:
339 case EZO_PMP_COMMAND_NONE:
340 default:
341 ESP_LOGE(TAG, "Unsupported command received: %d", this->current_command_);
342 return;
343 }
344
346}
347
349 int wait_time_for_command = 400; // milliseconds
350 uint8_t command_buffer[21];
351 int command_buffer_length = 0;
352
353 this->pop_next_command_(); // this->next_command will be updated.
354
355 switch (this->next_command_) {
356 // Read Commands
357 case EZO_PMP_COMMAND_READ_DOSING: // Page 54
358 command_buffer_length = snprintf((char *) command_buffer, sizeof(command_buffer), "D,?");
359 break;
360
361 case EZO_PMP_COMMAND_READ_SINGLE_REPORT: // Single Report (page 53)
362 command_buffer_length = snprintf((char *) command_buffer, sizeof(command_buffer), "R");
363 break;
364
365 case EZO_PMP_COMMAND_READ_MAX_FLOW_RATE:
366 command_buffer_length = snprintf((char *) command_buffer, sizeof(command_buffer), "DC,?");
367 break;
368
369 case EZO_PMP_COMMAND_READ_PAUSE_STATUS:
370 command_buffer_length = snprintf((char *) command_buffer, sizeof(command_buffer), "P,?");
371 break;
372
373 case EZO_PMP_COMMAND_READ_TOTAL_VOLUME_DOSED:
374 command_buffer_length = snprintf((char *) command_buffer, sizeof(command_buffer), "TV,?");
375 break;
376
377 case EZO_PMP_COMMAND_READ_ABSOLUTE_TOTAL_VOLUME_DOSED:
378 command_buffer_length = snprintf((char *) command_buffer, sizeof(command_buffer), "ATV,?");
379 break;
380
381 case EZO_PMP_COMMAND_READ_CALIBRATION_STATUS:
382 command_buffer_length = snprintf((char *) command_buffer, sizeof(command_buffer), "Cal,?");
383 break;
384
385 case EZO_PMP_COMMAND_READ_PUMP_VOLTAGE:
386 command_buffer_length = snprintf((char *) command_buffer, sizeof(command_buffer), "PV,?");
387 break;
388
389 // Non-Read Commands
390
391 case EZO_PMP_COMMAND_FIND: // Find (page 52)
392 command_buffer_length = snprintf((char *) command_buffer, sizeof(command_buffer), "Find");
393 wait_time_for_command = 60000; // This command will block all updates for a minute
394 break;
395
396 case EZO_PMP_COMMAND_DOSE_CONTINUOUSLY: // Continuous Dispensing (page 54)
397 command_buffer_length = snprintf((char *) command_buffer, sizeof(command_buffer), "D,*");
398 break;
399
400 case EZO_PMP_COMMAND_CLEAR_TOTAL_VOLUME_DOSED: // Clear Total Volume Dosed (page 64)
401 command_buffer_length = snprintf((char *) command_buffer, sizeof(command_buffer), "Clear");
402 break;
403
404 case EZO_PMP_COMMAND_CLEAR_CALIBRATION: // Clear Calibration (page 65)
405 command_buffer_length = snprintf((char *) command_buffer, sizeof(command_buffer), "Cal,clear");
406 break;
407
408 case EZO_PMP_COMMAND_PAUSE_DOSING: // Pause (page 61)
409 command_buffer_length = snprintf((char *) command_buffer, sizeof(command_buffer), "P");
410 break;
411
412 case EZO_PMP_COMMAND_STOP_DOSING: // Stop (page 62)
413 command_buffer_length = snprintf((char *) command_buffer, sizeof(command_buffer), "X");
414 break;
415
416 // Non-Read commands with parameters
417
418 case EZO_PMP_COMMAND_DOSE_VOLUME: // Volume Dispensing (page 55)
419 command_buffer_length =
420 snprintf((char *) command_buffer, sizeof(command_buffer), "D,%0.1f", this->next_command_volume_);
421 break;
422
423 case EZO_PMP_COMMAND_DOSE_VOLUME_OVER_TIME: // Dose over time (page 56)
424 command_buffer_length = snprintf((char *) command_buffer, sizeof(command_buffer), "D,%0.1f,%i",
426 break;
427
428 case EZO_PMP_COMMAND_DOSE_WITH_CONSTANT_FLOW_RATE: // Constant Flow Rate (page 57)
429 command_buffer_length = snprintf((char *) command_buffer, sizeof(command_buffer), "DC,%0.1f,%i",
431 break;
432
433 case EZO_PMP_COMMAND_SET_CALIBRATION_VOLUME: // Set Calibration Volume (page 65)
434 command_buffer_length =
435 snprintf((char *) command_buffer, sizeof(command_buffer), "Cal,%0.2f", this->next_command_volume_);
436 break;
437
438 case EZO_PMP_COMMAND_CHANGE_I2C_ADDRESS: // Change I2C Address (page 73)
439 command_buffer_length =
440 snprintf((char *) command_buffer, sizeof(command_buffer), "I2C,%i", this->next_command_duration_);
441 break;
442
443 case EZO_PMP_COMMAND_EXEC_ARBITRARY_COMMAND_ADDRESS: // Run an arbitrary command
444 command_buffer_length =
445 snprintf((char *) command_buffer, sizeof(command_buffer), "%s", this->arbitrary_command_.c_str());
446 ESP_LOGI(TAG, "Sending arbitrary command: %s", (char *) command_buffer);
447 break;
448
449 case EZO_PMP_COMMAND_TYPE_READ:
450 case EZO_PMP_COMMAND_NONE:
451 default:
452 ESP_LOGE(TAG, "Unsupported command received: %d", this->next_command_);
453 return;
454 }
455
456 // Send command
457 ESP_LOGV(TAG, "Sending command to device: %s", (char *) command_buffer);
458 this->write(command_buffer, command_buffer_length);
459
460 this->current_command_ = this->next_command_;
461 this->next_command_ = EZO_PMP_COMMAND_NONE;
462 this->is_waiting_ = true;
463 this->start_time_ = millis();
464 this->wait_time_ = wait_time_for_command;
465}
466
468 if (this->next_command_queue_length_ <= 0) {
469 ESP_LOGE(TAG, "Tried to dequeue command from empty queue");
470 this->next_command_ = EZO_PMP_COMMAND_NONE;
471 this->next_command_volume_ = 0;
472 this->next_command_duration_ = 0;
473 return;
474 }
475
476 // Read from Head
480
481 // Move positions
483 if (next_command_queue_head_ >= 10) {
485 }
486
488}
489
491 if (this->next_command_queue_length_ <= 0) {
492 return EZO_PMP_COMMAND_NONE;
493 }
494
496}
497
498void EzoPMP::queue_command_(uint16_t command, double volume, int duration, bool should_schedule) {
499 if (!should_schedule) {
500 return;
501 }
502
503 if (this->next_command_queue_length_ >= 10) {
504 ESP_LOGE(TAG, "Tried to queue command '%d' but queue is full", command);
505 return;
506 }
507
508 this->next_command_queue_[this->next_command_queue_last_] = command;
511
512 ESP_LOGV(TAG, "Queue command '%d' in position '%d'", command, next_command_queue_last_);
513
514 // Move positions
516 if (next_command_queue_last_ >= 10) {
518 }
519
521}
522
523// Actions
524
525void EzoPMP::find() { this->queue_command_(EZO_PMP_COMMAND_FIND, 0, 0, true); }
526
528 this->queue_command_(EZO_PMP_COMMAND_DOSE_CONTINUOUSLY, 0, 0, true);
529 this->queue_command_(EZO_PMP_COMMAND_READ_DOSING, 0, 0, true);
530#ifdef USE_SENSOR
531 this->queue_command_(EZO_PMP_COMMAND_READ_SINGLE_REPORT, 0, 0, (bool) this->current_volume_dosed_);
532#endif
533}
534
535void EzoPMP::dose_volume(double volume) {
536 this->queue_command_(EZO_PMP_COMMAND_DOSE_VOLUME, volume, 0, true);
537 this->queue_command_(EZO_PMP_COMMAND_READ_DOSING, 0, 0, true);
538#ifdef USE_SENSOR
539 this->queue_command_(EZO_PMP_COMMAND_READ_SINGLE_REPORT, 0, 0, (bool) this->current_volume_dosed_);
540#endif
541}
542
543void EzoPMP::dose_volume_over_time(double volume, int duration) {
544 this->queue_command_(EZO_PMP_COMMAND_DOSE_VOLUME_OVER_TIME, volume, duration, true);
545 this->queue_command_(EZO_PMP_COMMAND_READ_DOSING, 0, 0, true);
546#ifdef USE_SENSOR
547 this->queue_command_(EZO_PMP_COMMAND_READ_SINGLE_REPORT, 0, 0, (bool) this->current_volume_dosed_);
548#endif
549}
550
552 this->queue_command_(EZO_PMP_COMMAND_DOSE_WITH_CONSTANT_FLOW_RATE, volume, duration, true);
553 this->queue_command_(EZO_PMP_COMMAND_READ_DOSING, 0, 0, true);
554#ifdef USE_SENSOR
555 this->queue_command_(EZO_PMP_COMMAND_READ_SINGLE_REPORT, 0, 0, (bool) this->current_volume_dosed_);
556#endif
557}
558
560 this->queue_command_(EZO_PMP_COMMAND_SET_CALIBRATION_VOLUME, volume, 0, true);
561 this->queue_command_(EZO_PMP_COMMAND_READ_CALIBRATION_STATUS, 0, 0, true);
562 this->queue_command_(EZO_PMP_COMMAND_READ_MAX_FLOW_RATE, 0, 0, true);
563}
564
566 this->queue_command_(EZO_PMP_COMMAND_CLEAR_TOTAL_VOLUME_DOSED, 0, 0, true);
567 this->queue_command_(EZO_PMP_COMMAND_READ_SINGLE_REPORT, 0, 0, true);
568 this->queue_command_(EZO_PMP_COMMAND_READ_TOTAL_VOLUME_DOSED, 0, 0, true);
569 this->queue_command_(EZO_PMP_COMMAND_READ_ABSOLUTE_TOTAL_VOLUME_DOSED, 0, 0, true);
570}
571
573 this->queue_command_(EZO_PMP_COMMAND_CLEAR_CALIBRATION, 0, 0, true);
574 this->queue_command_(EZO_PMP_COMMAND_READ_CALIBRATION_STATUS, 0, 0, true);
575 this->queue_command_(EZO_PMP_COMMAND_READ_MAX_FLOW_RATE, 0, 0, true);
576}
577
579 this->queue_command_(EZO_PMP_COMMAND_PAUSE_DOSING, 0, 0, true);
580 this->queue_command_(EZO_PMP_COMMAND_READ_PAUSE_STATUS, 0, 0, true);
581}
582
583void EzoPMP::stop_dosing() { this->queue_command_(EZO_PMP_COMMAND_STOP_DOSING, 0, 0, true); }
584
586 this->queue_command_(EZO_PMP_COMMAND_CHANGE_I2C_ADDRESS, 0, address, true);
587}
588
589void EzoPMP::exec_arbitrary_command(const std::basic_string<char> &command) {
590 this->arbitrary_command_ = command;
591 this->queue_command_(EZO_PMP_COMMAND_EXEC_ARBITRARY_COMMAND_ADDRESS, 0, 0, true);
592}
593
594} // namespace esphome::ezo_pmp
uint8_t address
Definition bl0906.h:4
void publish_state(bool new_state)
Publish a new state to the front-end.
sensor::Sensor * total_volume_dosed_
Definition ezo_pmp.h:97
void exec_arbitrary_command(const std::basic_string< char > &command)
Definition ezo_pmp.cpp:589
void dose_volume(double volume)
Definition ezo_pmp.cpp:535
uint16_t current_command_
Definition ezo_pmp.h:82
binary_sensor::BinarySensor * is_paused_
Definition ezo_pmp.h:106
int next_command_duration_queue_[10]
Definition ezo_pmp.h:77
sensor::Sensor * max_flow_rate_
Definition ezo_pmp.h:100
uint16_t next_command_queue_[10]
Definition ezo_pmp.h:75
std::string arbitrary_command_
Definition ezo_pmp.h:86
void dump_config() override
Definition ezo_pmp.cpp:40
double next_command_volume_queue_[10]
Definition ezo_pmp.h:76
void set_calibration_volume(double volume)
Definition ezo_pmp.cpp:559
void change_i2c_address(int address)
Definition ezo_pmp.cpp:585
void queue_command_(uint16_t command, double volume, int duration, bool should_schedule)
Definition ezo_pmp.cpp:498
void loop() override
Definition ezo_pmp.cpp:83
binary_sensor::BinarySensor * is_dosing_
Definition ezo_pmp.h:105
sensor::Sensor * last_volume_requested_
Definition ezo_pmp.h:101
void dose_volume_over_time(double volume, int duration)
Definition ezo_pmp.cpp:543
uint16_t peek_next_command_()
Definition ezo_pmp.cpp:490
sensor::Sensor * absolute_total_volume_dosed_
Definition ezo_pmp.h:98
text_sensor::TextSensor * dosing_mode_
Definition ezo_pmp.h:110
sensor::Sensor * pump_voltage_
Definition ezo_pmp.h:99
sensor::Sensor * current_volume_dosed_
Definition ezo_pmp.h:96
void dose_with_constant_flow_rate(double volume, int duration)
Definition ezo_pmp.cpp:551
void update() override
Definition ezo_pmp.cpp:45
text_sensor::TextSensor * calibration_status_
Definition ezo_pmp.h:111
ErrorCode write(const uint8_t *data, size_t len) const
writes an array of bytes to a device using an I2CBus
Definition i2c.h:195
optional< std::array< uint8_t, N > > read_bytes_raw()
Definition i2c.h:262
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:65
void publish_state(const std::string &state)
Definition text_sensor.h:42
uint8_t duration
Definition msa3xx.h:0
ESPHOME_LOG_TAG(TAG, "ezo-pmp")
optional< T > parse_number(const char *str)
Parse an unsigned decimal number from a null-terminated string.
Definition helpers.h:1352
uint32_t IRAM_ATTR HOT millis()
Definition hal.cpp:25