The UART Bus component provides a write action but no read actions. Typically the UART read is implemented in a custom component that also does the processing. The UART debug sequence can be exploited to act like a call back function whenever there is received data to process. So basically instead of creating a small custom component a large lambda call can be used in the UART debug yaml. Here was an example that implements processing in the UART debug for the text formatting you provided. I tested it on an esp32 devboard with a jumper to loop back the UART tx pin output back into the rx pin. The buttons entities in HA can be used to test the logic.
I am not aware of this approach used anywhere else but that was my goal, find a way to help people read UART data without a custom component. It seems to be well suited for implementing simple UART devices where the code in the lambda would be 90% of the custom component code.
Key points are:
dummy_receiver: true to make sure the debug logging gets triggered
the rx data is returned in std::vector<uint8_t> bytes
delimiter and timeout tweaked so rx data is presented in consistent format
doesn’t have a setup() if you need to perform some initialization (esphome.on_boot could be work around)
is constrained to cases where the rx data packets can be handled by the uart debug after mapping
only gets called when data arrives
I think reliability and performance should be similar between both approaches. The uart-logging-hack is only called when there is data to process but the framework is still checking and buffering the data in the background.
For some reason I think it is not being ‘captured’ by the if statement and the ‘batVol’ sensors don’t update when a message is received (I have adjusted names of variables from your example)
I also incorporated the test buttons and loop back wire. The test button creates the response at the Rx but again the sensorBatVol never updates.
Things to note:
There are only 2 arguments. the Sensor number and the Battery voltage
I only seen to have a /n in my message (even though I added a /r as well on the Tx of the message sending ESP32.
Also - have I amended this line correctly?
if (sscanf(str.c_str(), "%d:%f", &sensorID, &sensorBatVol) == 2 ) {
Take a look at this post for some more general examples. Assuming you want the first two values in HA as numeric sensors, modify the section with sscanf to extract the first two values. Example was changed to use comma as delimiter between the values. The ==2 make sure sscanf reads two values.
//Sample uart text protocol
if (sscanf(str.c_str(), "%d,%d", &val1, &val2) == 2 ) {
id(sensor1).publish_state(val1);
id(sensor2).publish_state(val2);
}
The log_string debug output treats the received byte vales as the ASCII index for each character. For the log_int, it prints the byte values received formatted as integers.