ESPHome 2026.11.0-dev
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
9ESPHOME_LOG_TAG(TAG, "systa_bus");
10
11void SystaBus::dump_config() { ESP_LOGCONFIG(TAG, "SystaBus:"); }
12
13static bool checksum(std::span<const uint8_t> data) { return sum_bytes(data.data(), data.size()) == 0; }
14
16 uint8_t c;
17 while (this->available() && this->read_byte(&c))
18 this->handle_byte_(c);
19}
20
21void SystaBus::handle_byte_(uint8_t c) {
22 if (this->buffer_.empty()) {
23 if (c == START_BYTE)
24 this->buffer_.push_back(c);
25 return;
26 }
27 this->buffer_.push_back(c);
28 if (this->buffer_.size() == 2) {
29 // The length byte is only trusted for known message types; anything else restarts the search
30 uint16_t message_type = get_message_type(this->buffer_);
31 if (message_type != MESSAGE_TYPE_AQUA_SENSOR_DATA) {
32 ESP_LOGV(TAG, "Unknown message type 0x%04x", message_type);
33 this->buffer_.clear();
34 // A stray start byte followed by a real frame: keep this byte as the new start
35 if (c == START_BYTE)
36 this->buffer_.push_back(c);
37 }
38 return;
39 }
40 if (this->buffer_.size() < this->buffer_[1] + FRAME_OVERHEAD)
41 return;
42 if (!checksum(this->buffer_)) {
43 ESP_LOGW(TAG, "Checksum failed");
44 this->resync_();
45 return;
46 }
47#ifdef SYSTA_BUS_LISTENER_COUNT
48 for (auto *listener : this->listeners_)
49 listener->handle_message(this->buffer_);
50#endif
51 this->buffer_.clear();
52}
53
54// A frame that lost a byte swallows the start of the next one, so the failed bytes are fed back through the
55// parser from the second byte on. They are fewer than a full frame, so this cannot fail the checksum again.
57 std::array<uint8_t, MAX_MESSAGE_SIZE> failed;
58 const size_t count = this->buffer_.size();
59 std::copy(this->buffer_.begin(), this->buffer_.end(), failed.begin());
60 this->buffer_.clear();
61 for (size_t i = 1; i < count; i++)
62 this->handle_byte_(failed[i]);
63}
64
65} // namespace esphome::systa_bus
uint8_t checksum
Definition bl0906.h:3
size_t size() const
Definition helpers.h:355
void push_back(const T &value)
Definition helpers.h:325
bool empty() const
Definition helpers.h:357
void dump_config() override
Definition systa_bus.cpp:11
void handle_byte_(uint8_t c)
Definition systa_bus.cpp:21
StaticVector< uint8_t, MAX_MESSAGE_SIZE > buffer_
Definition systa_bus.h:48
StaticVector< SystaBusListener *, SYSTA_BUS_LISTENER_COUNT > listeners_
Definition systa_bus.h:46
bool read_byte(uint8_t *data)
Definition uart.h:36
unsigned count
Definition gif.cpp:51
uint16_t get_message_type(std::span< const uint8_t > message)
Definition systa_bus.h:24
ESPHOME_LOG_TAG(TAG, "systa_bus.sensor")
constexpr uint8_t sum_bytes(const uint8_t *data, size_t len, uint8_t sum=0)
Add up the bytes of data with size len, truncated to 8 bits: the checksum many serial and IR protocol...
Definition helpers.h:886