Custom UART Sensor ?!

How would I add a custom sensor, which gets it’s data from UART?

there is a “custom UART Text Sensor” (Lambda Magic — ESPHome), but no regular custom UART sensor!

How can I do that? - it should be really simple - UART delivers one numeric value every 5sec and I want a sensor that shows this …

The Text sensor works flawlessly, but I can’t use lambda: return id(uart).state ; to use that value to calculate with in other template sensors :confused:

This works great:

text_sensor:

  • platform: custom
    lambda: |-
    auto my_custom_sensor = new UartReadLineSensor(id(uart_bus));
    App.register_component(my_custom_sensor);
    return {my_custom_sensor};
    text_sensors:
    • name: “UART CPM Sensor”
      internal: true
      id: “uart”

but I can’t use it (for example) here:

sensor:

  • platform: template
    name: “${device_name} CPM”
    unit_of_measurement: CPM
    accuracy_decimals: 0
    lambda: return id(uart).state ;

Also: in HA it looks like this … and not like a normal sensor
image

EDIT:
the error ESPhome shows when trying to upload:

Does the “unit_of_measurement:” value need to be quoted?

Nope - that did not make any difference. I believe it has to do with the “text sensor” - the number the sensor receives is not a number, but text ?! :woman_shrugging:

Also, I forgot, this is the error ESPhome shows when trying to upload:

Did you try to covert your string representing the number into a floating point value with something like ESPHome: esphome Namespace Reference ?

I feel super stupid right now, because I have absolutely no idea where and how I would implement this

Not an expert of esphome, but try to implement your lambda return like:

lambda: return parse_number(id(uart).state) ;

1 Like

almost!!!

It has to be

> lambda: return parse_number<float>(id(uart).state) ;

:smiley:

My solution for custom uart, just yaml file edit.

Sensor type is Honeywell CRIR Series CO2 sensor
Sensor data:
send to sensor: [0xFE, 0x04, 0x00, 0x07, 0x00, 0x01, 0x94, 0x04]
get from sensor: “\xFE\x04\x02\ x02\xEF \xED\xC8”

02EF (byte 3 and 4) is 16bit ppm value of 751

sensor:
  - platform: template
    name: "CO2"
    id: uart_co2
    unit_of_measurement: ppm

interval:
  - interval: 10s
    then:
      # send uart query
      - uart.write:  [0xFE, 0x04, 0x00, 0x07, 0x00, 0x01, 0x94, 0x04]

uart:
  id: uart_bus
  tx_pin: 12
  rx_pin: 13
  baud_rate: 9600
  debug:
    direction: "RX"
    dummy_receiver: True
    sequence:
      - lambda: |-
          UARTDebug::log_string(direction, bytes);  
          // Read 16bit data from uart byte 3 and 4
          id(uart_co2).publish_state(uint16_t((bytes[3] << 8) | bytes[4] ));
          // use this if you have 8bit
          id(uart_co2).publish_state( bytes[3] );