ESPHome 2025.5.0
Loading...
Searching...
No Matches
vbus.cpp
Go to the documentation of this file.
1#include "vbus.h"
3#include "esphome/core/log.h"
4#include <cinttypes>
5
6namespace esphome {
7namespace vbus {
8
9static const char *const TAG = "vbus";
10
12 ESP_LOGCONFIG(TAG, "VBus:");
14}
15
16static void septet_spread(uint8_t *data, int start, int count, uint8_t septet) {
17 for (int i = 0; i < count; i++, septet >>= 1) {
18 if (septet & 1)
19 data[start + i] |= 0x80;
20 }
21}
22
23static bool checksum(const uint8_t *data, int start, int count) {
24 uint8_t csum = 0x7f;
25 for (int i = 0; i < count; i++)
26 csum = (csum - data[start + i]) & 0x7f;
27 return csum == 0;
28}
29
30void VBus::loop() {
31 if (!available())
32 return;
33
34 while (available()) {
35 uint8_t c;
36 read_byte(&c);
37
38 if (c == 0xaa) {
39 this->state_ = 1;
40 this->buffer_.clear();
41 continue;
42 }
43 if (c & 0x80) {
44 this->state_ = 0;
45 continue;
46 }
47 if (this->state_ == 0)
48 continue;
49
50 if (this->state_ == 1) {
51 this->buffer_.push_back(c);
52 if (this->buffer_.size() == 7) {
53 this->protocol_ = this->buffer_[4];
54 this->source_ = (this->buffer_[3] << 8) + this->buffer_[2];
55 this->dest_ = (this->buffer_[1] << 8) + this->buffer_[0];
56 this->command_ = (this->buffer_[6] << 8) + this->buffer_[5];
57 }
58 if ((this->protocol_ == 0x20) && (this->buffer_.size() == 15)) {
59 this->state_ = 0;
60 if (!checksum(this->buffer_.data(), 0, 15)) {
61 ESP_LOGE(TAG, "P2 checksum failed");
62 continue;
63 }
64 septet_spread(this->buffer_.data(), 7, 6, this->buffer_[13]);
65 uint16_t id = (this->buffer_[8] << 8) + this->buffer_[7];
66 uint32_t value =
67 (this->buffer_[12] << 24) + (this->buffer_[11] << 16) + (this->buffer_[10] << 8) + this->buffer_[9];
68 ESP_LOGV(TAG, "P1 C%04x %04x->%04x: %04x %04" PRIx32 " (%" PRIu32 ")", this->command_, this->source_,
69 this->dest_, id, value, value);
70 } else if ((this->protocol_ == 0x10) && (this->buffer_.size() == 9)) {
71 if (!checksum(this->buffer_.data(), 0, 9)) {
72 ESP_LOGE(TAG, "P1 checksum failed");
73 this->state_ = 0;
74 continue;
75 }
76 this->frames_ = this->buffer_[7];
77 if (this->frames_) {
78 this->state_ = 2;
79 this->cframe_ = 0;
80 this->fbcount_ = 0;
81 this->buffer_.clear();
82 } else {
83 this->state_ = 0;
84 ESP_LOGD(TAG, "P1 empty message");
85 }
86 }
87 continue;
88 }
89
90 if (this->state_ == 2) {
91 this->fbytes_[this->fbcount_++] = c;
92 if (this->fbcount_ < 6)
93 continue;
94 this->fbcount_ = 0;
95 if (!checksum(this->fbytes_, 0, 6)) {
96 ESP_LOGE(TAG, "frame checksum failed");
97 continue;
98 }
99 septet_spread(this->fbytes_, 0, 4, this->fbytes_[4]);
100 for (int i = 0; i < 4; i++)
101 this->buffer_.push_back(this->fbytes_[i]);
102 if (++this->cframe_ < this->frames_)
103 continue;
104 ESP_LOGV(TAG, "P2 C%04x %04x->%04x: %s", this->command_, this->source_, this->dest_,
105 format_hex(this->buffer_).c_str());
106 for (auto &listener : this->listeners_)
107 listener->on_message(this->command_, this->source_, this->dest_, this->buffer_);
108 this->state_ = 0;
109 continue;
110 }
111 }
112}
113
114void VBusListener::on_message(uint16_t command, uint16_t source, uint16_t dest, std::vector<uint8_t> &message) {
115 if ((this->command_ != 0xffff) && (this->command_ != command))
116 return;
117 if ((this->source_ != 0xffff) && (this->source_ != source))
118 return;
119 if ((this->dest_ != 0xffff) && (this->dest_ != dest))
120 return;
121 this->handle_message(message);
122}
123
124} // namespace vbus
125} // namespace esphome
uint8_t checksum
Definition bl0906.h:3
void check_uart_settings(uint32_t baud_rate, uint8_t stop_bits=1, UARTParityOptions parity=UART_CONFIG_PARITY_NONE, uint8_t data_bits=8)
Check that the configuration of the UART bus matches the provided values and otherwise print a warnin...
Definition uart.cpp:13
bool read_byte(uint8_t *data)
Definition uart.h:29
uint8_t frames_
Definition vbus.h:44
uint16_t dest_
Definition vbus.h:42
uint8_t cframe_
Definition vbus.h:45
uint8_t fbytes_[6]
Definition vbus.h:46
uint16_t command_
Definition vbus.h:43
std::vector< VBusListener * > listeners_
Definition vbus.h:48
std::vector< uint8_t > buffer_
Definition vbus.h:39
void dump_config() override
Definition vbus.cpp:11
uint16_t source_
Definition vbus.h:41
void loop() override
Definition vbus.cpp:30
uint8_t protocol_
Definition vbus.h:40
void on_message(uint16_t command, uint16_t source, uint16_t dest, std::vector< uint8_t > &message)
Definition vbus.cpp:114
virtual void handle_message(std::vector< uint8_t > &message)=0
const char *const TAG
Definition spi.cpp:8
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::string format_hex(const uint8_t *data, size_t length)
Format the byte array data of length len in lowercased hex.
Definition helpers.cpp:360