[uart][usb_uart] Add debug_prefix option to distinguish multiple defined uarts in log (#14525)

This commit is contained in:
Oliver Kleinecke
2026-03-08 00:16:12 +01:00
committed by GitHub
parent 3f700bac1c
commit f2dfb5e1dc
12 changed files with 138 additions and 48 deletions
+11 -2
View File
@@ -203,8 +203,10 @@ UART_DIRECTIONS = {
# round numbers.
AFTER_DEFAULTS = {CONF_BYTES: 150, CONF_TIMEOUT: "100ms"}
CONF_DEBUG_PREFIX = "debug_prefix"
# By default, log in hex format when no specific sequence is provided.
DEFAULT_DEBUG_OUTPUT = "UARTDebug::log_hex(direction, bytes, ':');"
DEFAULT_DEBUG_OUTPUT = "UARTDebug::log_hex(direction, bytes, ':', debug_prefix);"
DEFAULT_SEQUENCE = [{CONF_LAMBDA: make_data_base(DEFAULT_DEBUG_OUTPUT)}]
@@ -242,6 +244,7 @@ DEBUG_SCHEMA = cv.Schema(
): automation.validate_automation(),
cv.Optional(CONF_DUMMY_RECEIVER, default=False): cv.boolean,
cv.GenerateID(CONF_DUMMY_RECEIVER_ID): cv.declare_id(UARTDummyReceiver),
cv.Optional(CONF_DEBUG_PREFIX, default=""): cv.string,
}
)
@@ -283,7 +286,11 @@ async def debug_to_code(config, parent):
for action in config[CONF_SEQUENCE]:
await automation.build_automation(
trigger,
[(UARTDirection, "direction"), (cg.std_vector.template(cg.uint8), "bytes")],
[
(UARTDirection, "direction"),
(cg.std_vector.template(cg.uint8), "bytes"),
(cg.StringRef, "debug_prefix"),
],
action,
)
cg.add(trigger.set_direction(config[CONF_DIRECTION]))
@@ -299,6 +306,8 @@ async def debug_to_code(config, parent):
if config[CONF_DUMMY_RECEIVER]:
dummy = cg.new_Pvariable(config[CONF_DUMMY_RECEIVER_ID], parent)
await cg.register_component(dummy, {})
if debug_prefix := config[CONF_DEBUG_PREFIX]:
cg.add(trigger.set_debug_prefix(debug_prefix))
cg.add_define("USE_UART_DEBUGGER")
+9 -9
View File
@@ -74,7 +74,7 @@ bool UARTDebugger::has_buffered_bytes_() { return !this->bytes_.empty(); }
void UARTDebugger::fire_trigger_() {
this->is_triggering_ = true;
trigger(this->last_direction_, this->bytes_);
trigger(this->last_direction_, this->bytes_, this->debug_prefix_);
this->bytes_.clear();
this->is_triggering_ = false;
}
@@ -94,7 +94,7 @@ void UARTDummyReceiver::loop() {
// TCP connection(s). Without these delays, debug log lines could go
// missing when UART devices block the main loop for too long.
void UARTDebug::log_hex(UARTDirection direction, std::vector<uint8_t> bytes, uint8_t separator) {
void UARTDebug::log_hex(UARTDirection direction, std::vector<uint8_t> bytes, uint8_t separator, StringRef prefix) {
std::string res;
if (direction == UART_DIRECTION_RX) {
res += "<<< ";
@@ -110,11 +110,11 @@ void UARTDebug::log_hex(UARTDirection direction, std::vector<uint8_t> bytes, uin
buf_append_printf(buf, sizeof(buf), 0, "%02X", bytes[i]);
res += buf;
}
ESP_LOGD(TAG, "%s", res.c_str());
ESP_LOGD(TAG, "%s%s", prefix.c_str(), res.c_str());
delay(10);
}
void UARTDebug::log_string(UARTDirection direction, std::vector<uint8_t> bytes) {
void UARTDebug::log_string(UARTDirection direction, std::vector<uint8_t> bytes, StringRef prefix) {
std::string res;
if (direction == UART_DIRECTION_RX) {
res += "<<< \"";
@@ -154,11 +154,11 @@ void UARTDebug::log_string(UARTDirection direction, std::vector<uint8_t> bytes)
}
}
res += '"';
ESP_LOGD(TAG, "%s", res.c_str());
ESP_LOGD(TAG, "%s%s", prefix.c_str(), res.c_str());
delay(10);
}
void UARTDebug::log_int(UARTDirection direction, std::vector<uint8_t> bytes, uint8_t separator) {
void UARTDebug::log_int(UARTDirection direction, std::vector<uint8_t> bytes, uint8_t separator, StringRef prefix) {
std::string res;
size_t len = bytes.size();
if (direction == UART_DIRECTION_RX) {
@@ -174,11 +174,11 @@ void UARTDebug::log_int(UARTDirection direction, std::vector<uint8_t> bytes, uin
buf_append_printf(buf, sizeof(buf), 0, "%u", bytes[i]);
res += buf;
}
ESP_LOGD(TAG, "%s", res.c_str());
ESP_LOGD(TAG, "%s%s", prefix.c_str(), res.c_str());
delay(10);
}
void UARTDebug::log_binary(UARTDirection direction, std::vector<uint8_t> bytes, uint8_t separator) {
void UARTDebug::log_binary(UARTDirection direction, std::vector<uint8_t> bytes, uint8_t separator, StringRef prefix) {
std::string res;
size_t len = bytes.size();
if (direction == UART_DIRECTION_RX) {
@@ -194,7 +194,7 @@ void UARTDebug::log_binary(UARTDirection direction, std::vector<uint8_t> bytes,
buf_append_printf(buf, sizeof(buf), 0, "0b" BYTE_TO_BINARY_PATTERN " (0x%02X)", BYTE_TO_BINARY(bytes[i]), bytes[i]);
res += buf;
}
ESP_LOGD(TAG, "%s", res.c_str());
ESP_LOGD(TAG, "%s%s", prefix.c_str(), res.c_str());
delay(10);
}
+12 -5
View File
@@ -5,6 +5,7 @@
#include <vector>
#include "esphome/core/component.h"
#include "esphome/core/automation.h"
#include "esphome/core/string_ref.h"
#include "uart.h"
#include "uart_component.h"
@@ -17,7 +18,7 @@ namespace esphome::uart {
/// 'appropriate time' means exactly, is determined by a number of
/// configurable constraints. E.g. when a given number of bytes is gathered
/// and/or when no more data has been seen for a given time interval.
class UARTDebugger : public Component, public Trigger<UARTDirection, std::vector<uint8_t>> {
class UARTDebugger : public Component, public Trigger<UARTDirection, std::vector<uint8_t>, StringRef> {
public:
explicit UARTDebugger(UARTComponent *parent);
void loop() override;
@@ -41,6 +42,8 @@ class UARTDebugger : public Component, public Trigger<UARTDirection, std::vector
/// logging will be triggered.
void add_delimiter_byte(uint8_t byte) { this->after_delimiter_.push_back(byte); }
void set_debug_prefix(const char *prefix) { this->debug_prefix_ = StringRef(prefix); }
protected:
UARTDirection for_direction_;
UARTDirection last_direction_{};
@@ -51,6 +54,7 @@ class UARTDebugger : public Component, public Trigger<UARTDirection, std::vector
std::vector<uint8_t> after_delimiter_{};
size_t after_delimiter_pos_{};
bool is_triggering_{false};
StringRef debug_prefix_{};
bool is_my_direction_(UARTDirection direction);
bool is_recursive_();
@@ -81,18 +85,21 @@ class UARTDebug {
public:
/// Log the bytes as hex values, separated by the provided separator
/// character.
static void log_hex(UARTDirection direction, std::vector<uint8_t> bytes, uint8_t separator);
static void log_hex(UARTDirection direction, std::vector<uint8_t> bytes, uint8_t separator,
StringRef prefix = StringRef());
/// Log the bytes as string values, escaping unprintable characters.
static void log_string(UARTDirection direction, std::vector<uint8_t> bytes);
static void log_string(UARTDirection direction, std::vector<uint8_t> bytes, StringRef prefix = StringRef());
/// Log the bytes as integer values, separated by the provided separator
/// character.
static void log_int(UARTDirection direction, std::vector<uint8_t> bytes, uint8_t separator);
static void log_int(UARTDirection direction, std::vector<uint8_t> bytes, uint8_t separator,
StringRef prefix = StringRef());
/// Log the bytes as '<binary> (<hex>)' values, separated by the provided
/// separator.
static void log_binary(UARTDirection direction, std::vector<uint8_t> bytes, uint8_t separator);
static void log_binary(UARTDirection direction, std::vector<uint8_t> bytes, uint8_t separator,
StringRef prefix = StringRef());
};
} // namespace esphome::uart
+4 -1
View File
@@ -1,7 +1,7 @@
import esphome.codegen as cg
from esphome.components import socket
from esphome.components.const import CONF_DATA_BITS, CONF_PARITY, CONF_STOP_BITS
from esphome.components.uart import UARTComponent
from esphome.components.uart import CONF_DEBUG_PREFIX, UARTComponent
from esphome.components.usb_host import register_usb_client, usb_device_schema
import esphome.config_validation as cv
from esphome.const import (
@@ -90,6 +90,7 @@ def channel_schema(channels, baud_rate_required):
),
cv.Optional(CONF_DUMMY_RECEIVER, default=False): cv.boolean,
cv.Optional(CONF_DEBUG, default=False): cv.boolean,
cv.Optional(CONF_DEBUG_PREFIX, default=""): cv.string,
}
)
),
@@ -129,6 +130,8 @@ async def to_code(config):
cg.add(chvar.set_baud_rate(channel[CONF_BAUD_RATE]))
cg.add(chvar.set_dummy_receiver(channel[CONF_DUMMY_RECEIVER]))
cg.add(chvar.set_debug(channel[CONF_DEBUG]))
if channel[CONF_DEBUG_PREFIX]:
cg.add(chvar.set_debug_prefix(channel[CONF_DEBUG_PREFIX]))
cg.add(var.add_channel(chvar))
if channel[CONF_DEBUG]:
cg.add_define("USE_UART_DEBUGGER")
+2 -2
View File
@@ -142,7 +142,7 @@ void USBUartChannel::write_array(const uint8_t *data, size_t len) {
size_t n = std::min(len - off, BATCH);
memcpy(buf, ">>> ", 4);
format_hex_pretty_to(buf + 4, sizeof(buf) - 4, data + off, n, ',');
ESP_LOGD(TAG, "%s", buf);
ESP_LOGD(TAG, "%s%s", this->debug_prefix_.c_str(), buf);
}
}
#endif
@@ -219,7 +219,7 @@ void USBUartComponent::loop() {
char buf[4 + format_hex_pretty_size(UsbDataChunk::MAX_CHUNK_SIZE)]; // "<<< " + hex
memcpy(buf, "<<< ", 4);
format_hex_pretty_to(buf + 4, sizeof(buf) - 4, chunk->data, chunk->length, ',');
ESP_LOGD(TAG, "%s", buf);
ESP_LOGD(TAG, "%s%s", channel->debug_prefix_.c_str(), buf);
}
#endif
+3
View File
@@ -3,6 +3,7 @@
#if defined(USE_ESP32_VARIANT_ESP32P4) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
#include "esphome/core/component.h"
#include "esphome/core/helpers.h"
#include "esphome/core/string_ref.h"
#include "esphome/components/uart/uart_component.h"
#include "esphome/components/usb_host/usb_host.h"
#include "esphome/core/lock_free_queue.h"
@@ -114,6 +115,7 @@ class USBUartChannel : public uart::UARTComponent, public Parented<USBUartCompon
void set_parity(UARTParityOptions parity) { this->parity_ = parity; }
void set_debug(bool debug) { this->debug_ = debug; }
void set_dummy_receiver(bool dummy_receiver) { this->dummy_receiver_ = dummy_receiver; }
void set_debug_prefix(const char *prefix) { this->debug_prefix_ = StringRef(prefix); }
/// Register a callback invoked immediately after data is pushed to the input ring buffer.
/// Called from USBUartComponent::loop() in the main loop context.
@@ -138,6 +140,7 @@ class USBUartChannel : public uart::UARTComponent, public Parented<USBUartCompon
const uint8_t index_;
bool debug_{};
bool dummy_receiver_{};
StringRef debug_prefix_{};
};
class USBUartComponent : public usb_host::USBClient {
+13 -3
View File
@@ -1,11 +1,15 @@
esphome:
on_boot:
then:
- uart.write: 'Hello World'
- uart.write: [0x00, 0x20, 0x42]
- uart.write:
id: uart_id
data: 'Hello World'
- uart.write:
id: uart_id
data: [0x00, 0x20, 0x42]
uart:
- id: uart_uart
- id: uart_id
tx_pin: 4
rx_pin: 5
flow_control_pin: 6
@@ -16,3 +20,9 @@ uart:
rx_timeout: 1
parity: EVEN
stop_bits: 2
- id: uart_debug
tx_pin: 18
rx_pin: 19
baud_rate: 115200
debug:
debug_prefix: "[UART1] "
+45 -15
View File
@@ -1,13 +1,19 @@
esphome:
on_boot:
then:
- uart.write: 'Hello World'
- uart.write: [0x00, 0x20, 0x42]
- uart.write: !lambda |-
return {0xAA, 0xBB, 0xCC};
- uart.write:
id: uart_id
data: 'Hello World'
- uart.write:
id: uart_id
data: [0x00, 0x20, 0x42]
- uart.write:
id: uart_id
data: !lambda |-
return {0xAA, 0xBB, 0xCC};
uart:
- id: uart_uart
- id: uart_id
tx_pin: 17
rx_pin: 16
flow_control_pin: 4
@@ -18,32 +24,54 @@ uart:
rx_timeout: 1
parity: EVEN
stop_bits: 2
- id: uart_debug
tx_pin: 21
rx_pin: 22
baud_rate: 115200
debug:
debug_prefix: "[UART1] "
- id: uart_debug_custom
tx_pin: 25
rx_pin: 26
baud_rate: 9600
debug:
debug_prefix: "[UART2] "
after:
delimiter: "\n"
sequence:
- lambda: UARTDebug::log_string(direction, bytes, debug_prefix);
- id: uart_debug_no_prefix
tx_pin: 32
rx_pin: 33
baud_rate: 9600
debug:
packet_transport:
- platform: uart
uart_id: uart_id
switch:
# Test uart switch with single state (array)
- platform: uart
name: "UART Switch Single Array"
uart_id: uart_uart
uart_id: uart_id
data: [0x01, 0x02, 0x03]
# Test uart switch with single state (string)
- platform: uart
name: "UART Switch Single String"
uart_id: uart_uart
uart_id: uart_id
data: "ON"
# Test uart switch with turn_on/turn_off (arrays)
- platform: uart
name: "UART Switch Dual Array"
uart_id: uart_uart
uart_id: uart_id
data:
turn_on: [0xA0, 0xA1, 0xA2]
turn_off: [0xB0, 0xB1, 0xB2]
# Test uart switch with turn_on/turn_off (strings)
- platform: uart
name: "UART Switch Dual String"
uart_id: uart_uart
uart_id: uart_id
data:
turn_on: "TURN_ON"
turn_off: "TURN_OFF"
@@ -61,24 +89,26 @@ button:
# Test uart button with array data
- platform: uart
name: "UART Button Array"
uart_id: uart_uart
uart_id: uart_id
data: [0xFF, 0xEE, 0xDD]
# Test uart button with string data
- platform: uart
name: "UART Button String"
uart_id: uart_uart
uart_id: uart_id
data: "BUTTON_PRESS"
# Test uart button with lambda (function pointer)
- platform: template
name: "UART Lambda Test"
on_press:
- uart.write: !lambda |-
std::string cmd = "VALUE=" + str_sprintf("%.0f", id(test_number).state) + "\r\n";
return std::vector<uint8_t>(cmd.begin(), cmd.end());
- uart.write:
id: uart_id
data: !lambda |-
std::string cmd = "VALUE=" + str_sprintf("%.0f", id(test_number).state) + "\r\n";
return std::vector<uint8_t>(cmd.begin(), cmd.end());
event:
- platform: uart
uart_id: uart_uart
uart_id: uart_id
name: "UART Event"
event_types:
- "string_event_A": "*A#"
+17 -7
View File
@@ -1,11 +1,15 @@
esphome:
on_boot:
then:
- uart.write: 'Hello World'
- uart.write: [0x00, 0x20, 0x42]
- uart.write:
id: uart_id
data: 'Hello World'
- uart.write:
id: uart_id
data: [0x00, 0x20, 0x42]
uart:
- id: uart_uart
- id: uart_id
tx_pin: 4
rx_pin: 5
baud_rate: 9600
@@ -13,15 +17,21 @@ uart:
rx_buffer_size: 512
parity: EVEN
stop_bits: 2
- id: uart_debug
tx_pin: 14
rx_pin: 12
baud_rate: 115200
debug:
debug_prefix: "[UART1] "
switch:
- platform: uart
name: "UART Switch Array"
uart_id: uart_uart
uart_id: uart_id
data: [0x01, 0x02, 0x03]
- platform: uart
name: "UART Switch Dual"
uart_id: uart_uart
uart_id: uart_id
data:
turn_on: [0xA0, 0xA1]
turn_off: [0xB0, 0xB1]
@@ -29,12 +39,12 @@ switch:
button:
- platform: uart
name: "UART Button"
uart_id: uart_uart
uart_id: uart_id
data: [0xFF, 0xEE]
event:
- platform: uart
uart_id: uart_uart
uart_id: uart_id
name: "UART Event"
event_types:
- "string_event_A": "*A#"
+1 -1
View File
@@ -5,7 +5,7 @@ esphome:
- uart.write: [0x00, 0x20, 0x42]
uart:
- id: uart_uart
- id: uart_id
port: "/dev/ttyS0"
baud_rate: 9600
data_bits: 8
+13 -3
View File
@@ -1,11 +1,15 @@
esphome:
on_boot:
then:
- uart.write: 'Hello World'
- uart.write: [0x00, 0x20, 0x42]
- uart.write:
id: uart_id
data: 'Hello World'
- uart.write:
id: uart_id
data: [0x00, 0x20, 0x42]
uart:
- id: uart_uart
- id: uart_id
tx_pin: 4
rx_pin: 5
baud_rate: 9600
@@ -13,3 +17,9 @@ uart:
rx_buffer_size: 512
parity: EVEN
stop_bits: 2
- id: uart_debug
tx_pin: 8
rx_pin: 9
baud_rate: 115200
debug:
debug_prefix: "[UART1] "
+8
View File
@@ -34,3 +34,11 @@ usb_uart:
- id: channel_4_1
debug: true
dummy_receiver: true
debug_prefix: "[ESP_JTAG] "
- id: uart_5
type: cp210x
channels:
- id: channel_5_1
baud_rate: 9600
debug: true
debug_prefix: "[CP210X] "