janet/etc/uart2mqtt.h

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;
};