74 lines
1.5 KiB
C++
74 lines
1.5 KiB
C++
#include "esphome.h"
|
|
|
|
#include <vector>
|
|
|
|
using esphome::Component;
|
|
using esphome::PollingComponent;
|
|
using esphome::text_sensor::TextSensor;
|
|
using esphome::uart::UARTComponent;
|
|
using esphome::uart::UARTDevice;
|
|
|
|
class UART2MQTT : public PollingComponent,
|
|
public UARTDevice,
|
|
public TextSensor
|
|
{
|
|
public:
|
|
UART2MQTT(UARTComponent *parent)
|
|
: PollingComponent(200), UARTDevice(parent), TextSensor()
|
|
{
|
|
}
|
|
|
|
void update() override
|
|
{
|
|
std::size_t ready = available();
|
|
if (ready > 0) {
|
|
auto take = std::min(ready, buf_.size() - at_);
|
|
ESP_LOGI("uart2mqtt", "taking %d", take);
|
|
read_array(buf_.begin() + at_, take);
|
|
at_ += take;
|
|
}
|
|
if (at_ > 0 && (ready == 0 || at_ >= buf_.size())) {
|
|
ESP_LOGI("uart2mqtt", "flush %d", at_);
|
|
|
|
std::string hex;
|
|
for (auto i = 0; i < at_; i++) {
|
|
char byte[3];
|
|
sprintf(byte, "%02X", buf_[i]);
|
|
hex += byte;
|
|
}
|
|
publish_state(hex);
|
|
at_ = 0;
|
|
}
|
|
}
|
|
|
|
static uint8_t nibble(char ch)
|
|
{
|
|
if (ch >= '0' && ch <= '9') {
|
|
return ch - '0';
|
|
} else if (ch >= 'a' && ch <= 'F') {
|
|
return 10 + ch - 'a';
|
|
} else {
|
|
return 10 + ch - 'A';
|
|
}
|
|
}
|
|
void tx(std::string msg)
|
|
{
|
|
ESP_LOGI("uart2mqtt", "::tx %s", msg.c_str());
|
|
if (msg.length() % 2 != 0) {
|
|
ESP_LOGE("uart2mqtt", "Dropping odd length message");
|
|
return;
|
|
}
|
|
|
|
std::vector<uint8_t> raw(msg.length() / 2, 0);
|
|
for (auto i = 0; i < raw.size(); i++) {
|
|
raw[i] = (nibble(msg[i * 2]) << 4) |
|
|
nibble(msg[i * 2 + 1]);
|
|
}
|
|
write_array(raw);
|
|
}
|
|
|
|
private:
|
|
std::array<uint8_t, 256> buf_;
|
|
std::size_t at_ = 0;
|
|
};
|