Esp32, hex to automation Nightmare

Hello everyone,

I’m encountering an issue with my ESPHome setup, where I’m trying to use a custom UART component to read hex values from a UART sensor and trigger Home Assistant actions based on those values. However, I’m getting the following error:

Arduino

Failed config
sensor.uart_read_line: [source /config/esphome/offline-voice.yaml:51]
Platform not found: 'sensor.uart_read_line'.

It seems like the sensor.uart_read_line platform isn’t recognized by ESPHome, and I can’t use it as expected. I’ve tried including it in my YAML configuration, but it doesn’t work, as ESPHome throws the error: “No module named ‘esphome.components.uart_read_line’.”

Here’s a summary of what I’m trying to achieve:

  • I’m using an ESP32 with a UART sensor to receive two-byte hex values.
  • I want to process the UART data and trigger specific actions in Home Assistant based on the hex values received (e.g., AA 01 triggers a light, AB 01 triggers another action, etc.).
  • I have a custom UartReadLineSensor class that handles reading the UART data and formatting it into a hex string.
  • However, I’m struggling to integrate this into my ESPHome configuration properly.

I’d really appreciate your help in resolving this. If there’s an alternative way to set this up using ESPHome, or if I’m missing something in my configuration, could you kindly point me in the right direction?

yaml Code:

esphome:
  name: offline-voice
  platform: ESP32
  board: esp32dev
  includes:
    - uart_read_line_sensor.h

api:
  encryption:
    key: "x.x.x.x"

ota:
  password: "x.x.x.x"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: x.x.x.x
    gateway: x.x.x.x
    subnet: x.x.x.x

logger:
  level: VERBOSE
  baud_rate: 0

uart:
  id: uart1
  tx_pin: GPIO17
  rx_pin: GPIO16
  baud_rate: 9600

text_sensor:
  - platform: template
    name: "Hexadecimal String"
    id: hex_string
    update_interval: 1s
    lambda: |-
      return id(uart_sensor).state;

sensor:
  - platform: uart_read_line
    id: uart_sensor
    uart_id: uart1
    name: "UART Hex Sensor"
    on_value:
      then:
        - homeassistant.service:
            service: switch.turn_on
            data:
              entity_id: >
                {% if value == 'AA 01' %}
                  switch.sonoff_10016734d4
                {% elif value == 'AB 01' %}
                  button.1001d51b30_2
                {% endif %}

# Define a custom component for UART line reading
custom_component:
  - lambda: |-
      class UartReadLineSensor : public PollingComponent {
        public:
          UartReadLineSensor(UARTComponent *parent) : PollingComponent(1000), uart(parent) {}


          void setup() override {
            ESP_LOGD("uart_sensor", "UART Read Line Sensor Initialized");
          }

          void update() override {
            if (uart->available()) {
              String uart_line = uart->read_line();
              ESP_LOGD("uart_sensor", "Received line: %s", uart_line.c_str());

              // Actions based on received hex values
              if (uart_line == "AA 01") {
                App.make_service_call("homeassistant.service", {
                  {"service", "switch.turn_on"},
                  {"data", {{"entity_id", "switch.sonoff_10016734d4"}}}
                });
              } else if (uart_line == "AB 01") {
                App.make_service_call("homeassistant.service", {
                  {"service", "button.press"},
                  {"data", {{"entity_id", "button.1001d51b30_2"}}}
                });
              }
            }
          }

        private:
          UARTComponent *uart;
      };

Here is the uart_read_line_sensor.h

#include "esphome.h"

class UartReadLineSensor : public Component, public UARTDevice, public TextSensor {
 public:
  UartReadLineSensor(UARTComponent *parent) : UARTDevice(parent) {}

  void setup() override {
    // Nothing to do here for setup
  }

  void loop() override {
    static uint8_t buffer[2]; // Buffer to store two bytes
    static int index = 0;

    while (available()) {
      buffer[index++] = read(); // Read one byte into the buffer

      if (index == 2) { // Once we have two bytes, process them
        char hex[6]; // Buffer to hold the 4-digit hex string (plus null terminator)
        sprintf(hex, "%02X %02X", buffer[0], buffer[1]); // Convert the two bytes to a 4-digit hex string
        publish_state(hex); // Send the 4-digit hex string to Home Assistant
        index = 0; // Reset the buffer index for the next pair
      }
    }
  }
};