ESPHome 2026.10.0
Loading...
Searching...
No Matches
systa_bus.cpp
Go to the documentation of this file.
1#include "systa_bus.h"
2#include "esphome/core/log.h"
3
4#include <algorithm>
5#include <array>
6
7namespace esphome::systa_bus {
8
9static const char *const TAG = "systa_bus";
10
11void SystaBus::dump_config() { ESP_LOGCONFIG(TAG, "SystaBus:"); }
12
13static bool checksum(std::span<const uint8_t> data) {
14 uint8_t csum = 0;
15 for (uint8_t i : data)
16 csum += i;
17 return csum == 0;
18}
19
21 uint8_t c;
22 while (this->available() && this->read_byte(&c))
23 this->handle_byte_(c);
24}
25
26void SystaBus::handle_byte_(uint8_t c) {
27 if (this->buffer_.empty()) {
28 if (c == START_BYTE)
29 this->buffer_.push_back(c);
30 return;
31 }
32 this->buffer_.push_back(c);
33 if (this->buffer_.size() == 2) {
34 // The length byte is only trusted for known message types; anything else restarts the search
35 uint16_t message_type = get_message_type(this->buffer_);
36 if (message_type != MESSAGE_TYPE_AQUA_SENSOR_DATA) {
37 ESP_LOGV(TAG, "Unknown message type 0x%04x", message_type);
38 this->buffer_.clear();
39 // A stray start byte followed by a real frame: keep this byte as the new start
40 if (c == START_BYTE)
41 this->buffer_.push_back(c);
42 }
43 return;
44 }
45 if (this->buffer_.size() < this->buffer_[1] + FRAME_OVERHEAD)
46 return;
47 if (!checksum(this->buffer_)) {
48 ESP_LOGW(TAG, "Checksum failed");
49 this->resync_();
50 return;
51 }
52#ifdef SYSTA_BUS_LISTENER_COUNT
53 for (auto *listener : this->listeners_)
54 listener->handle_message(this->buffer_);
55#endif
56 this->buffer_.clear();
57}
58
59// A frame that lost a byte swallows the start of the next one, so the failed bytes are fed back through the
60// parser from the second byte on. They are fewer than a full frame, so this cannot fail the checksum again.
62 std::array<uint8_t, MAX_MESSAGE_SIZE> failed;
63 const size_t count = this->buffer_.size();
64 std::copy(this->buffer_.begin(), this->buffer_.end(), failed.begin());
65 this->buffer_.clear();
66 for (size_t i = 1; i < count; i++)
67 this->handle_byte_(failed[i]);
68}
69
70} // namespace esphome::systa_bus
uint8_t checksum
Definition bl0906.h:3
size_t size() const
Definition helpers.h:360
void push_back(const T &value)
Definition helpers.h:330
bool empty() const
Definition helpers.h:362
void dump_config() override
Definition systa_bus.cpp:11
void handle_byte_(uint8_t c)
Definition systa_bus.cpp:26
StaticVector< uint8_t, MAX_MESSAGE_SIZE > buffer_
Definition systa_bus.h:47
StaticVector< SystaBusListener *, SYSTA_BUS_LISTENER_COUNT > listeners_
Definition systa_bus.h:45
bool read_byte(uint8_t *data)
Definition uart.h:35
unsigned count
Definition gif.cpp:51
const char *const TAG
Definition spi.cpp:7
uint16_t get_message_type(std::span< const uint8_t > message)
Definition systa_bus.h:23