#include "esphome.h" #include 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 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 buf_; std::size_t at_ = 0; };