mirror of
https://github.com/esphome/esphome.git
synced 2026-05-10 05:37:55 +08:00
[uart][usb_uart] Add debug_prefix option to distinguish multiple defined uarts in log (#14525)
This commit is contained in:
@@ -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")
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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,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 {
|
||||
|
||||
@@ -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] "
|
||||
|
||||
@@ -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#"
|
||||
|
||||
@@ -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#"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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] "
|
||||
|
||||
@@ -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] "
|
||||
|
||||
Reference in New Issue
Block a user