add fields

This commit is contained in:
kbx81
2026-02-12 20:30:48 -06:00
parent 41f344c0e2
commit f7d03ab381
10 changed files with 134 additions and 11 deletions

View File

@@ -204,6 +204,17 @@ message DeviceInfo {
uint32 area_id = 3;
}
enum SerialProxyPortType {
SERIAL_PROXY_PORT_TYPE_TTL = 0;
SERIAL_PROXY_PORT_TYPE_RS232 = 1;
SERIAL_PROXY_PORT_TYPE_RS485 = 2;
}
message SerialProxyInfo {
string name = 1; // Human-readable port name
SerialProxyPortType port_type = 2; // Port type (RS232, RS485)
}
message DeviceInfoResponse {
option (id) = 10;
option (source) = SOURCE_SERVER;
@@ -267,8 +278,8 @@ message DeviceInfoResponse {
uint32 zwave_proxy_feature_flags = 23 [(field_ifdef) = "USE_ZWAVE_PROXY"];
uint32 zwave_home_id = 24 [(field_ifdef) = "USE_ZWAVE_PROXY"];
// Number of serial proxy instances available on the device
uint32 serial_proxy_count = 25 [(field_ifdef) = "USE_SERIAL_PROXY"];
// Serial proxy instance metadata
repeated SerialProxyInfo serial_proxies = 25 [(field_ifdef) = "USE_SERIAL_PROXY", (fixed_array_size_define) = "SERIAL_PROXY_COUNT"];
}
message ListEntitiesRequest {

View File

@@ -1695,7 +1695,14 @@ bool APIConnection::send_device_info_response_() {
resp.zwave_home_id = zwave_proxy::global_zwave_proxy->get_home_id();
#endif
#ifdef USE_SERIAL_PROXY
resp.serial_proxy_count = App.get_serial_proxies().size();
size_t serial_proxy_index = 0;
for (auto const &proxy : App.get_serial_proxies()) {
if (serial_proxy_index >= SERIAL_PROXY_COUNT)
break;
auto &info = resp.serial_proxies[serial_proxy_index++];
info.name = StringRef(proxy->get_name());
info.port_type = proxy->get_port_type();
}
#endif
#ifdef USE_API_NOISE
resp.api_encryption_supported = true;

View File

@@ -65,6 +65,16 @@ void DeviceInfo::calculate_size(ProtoSize &size) const {
size.add_uint32(1, this->area_id);
}
#endif
#ifdef USE_SERIAL_PROXY
void SerialProxyInfo::encode(ProtoWriteBuffer buffer) const {
buffer.encode_string(1, this->name);
buffer.encode_uint32(2, static_cast<uint32_t>(this->port_type));
}
void SerialProxyInfo::calculate_size(ProtoSize &size) const {
size.add_length(1, this->name.size());
size.add_uint32(1, static_cast<uint32_t>(this->port_type));
}
#endif
void DeviceInfoResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_string(2, this->name);
buffer.encode_string(3, this->mac_address);
@@ -120,7 +130,9 @@ void DeviceInfoResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_uint32(24, this->zwave_home_id);
#endif
#ifdef USE_SERIAL_PROXY
buffer.encode_uint32(25, this->serial_proxy_count);
for (const auto &it : this->serial_proxies) {
buffer.encode_message(25, it);
}
#endif
}
void DeviceInfoResponse::calculate_size(ProtoSize &size) const {
@@ -178,7 +190,9 @@ void DeviceInfoResponse::calculate_size(ProtoSize &size) const {
size.add_uint32(2, this->zwave_home_id);
#endif
#ifdef USE_SERIAL_PROXY
size.add_uint32(2, this->serial_proxy_count);
for (const auto &it : this->serial_proxies) {
size.add_message_object_force(2, it);
}
#endif
}
#ifdef USE_BINARY_SENSOR

View File

@@ -12,6 +12,11 @@ namespace esphome::api {
namespace enums {
enum SerialProxyPortType : uint32_t {
SERIAL_PROXY_PORT_TYPE_TTL = 0,
SERIAL_PROXY_PORT_TYPE_RS232 = 1,
SERIAL_PROXY_PORT_TYPE_RS485 = 2,
};
enum EntityCategory : uint32_t {
ENTITY_CATEGORY_NONE = 0,
ENTITY_CATEGORY_CONFIG = 1,
@@ -481,10 +486,24 @@ class DeviceInfo final : public ProtoMessage {
protected:
};
#endif
#ifdef USE_SERIAL_PROXY
class SerialProxyInfo final : public ProtoMessage {
public:
StringRef name{};
enums::SerialProxyPortType port_type{};
void encode(ProtoWriteBuffer buffer) const override;
void calculate_size(ProtoSize &size) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP
const char *dump_to(DumpBuffer &out) const override;
#endif
protected:
};
#endif
class DeviceInfoResponse final : public ProtoMessage {
public:
static constexpr uint8_t MESSAGE_TYPE = 10;
static constexpr uint16_t ESTIMATED_SIZE = 260;
static constexpr uint16_t ESTIMATED_SIZE = 309;
#ifdef HAS_PROTO_MESSAGE_DUMP
const char *message_name() const override { return "device_info_response"; }
#endif
@@ -538,7 +557,7 @@ class DeviceInfoResponse final : public ProtoMessage {
uint32_t zwave_home_id{0};
#endif
#ifdef USE_SERIAL_PROXY
uint32_t serial_proxy_count{0};
std::array<SerialProxyInfo, SERIAL_PROXY_COUNT> serial_proxies{};
#endif
void encode(ProtoWriteBuffer buffer) const override;
void calculate_size(ProtoSize &size) const override;

View File

@@ -100,6 +100,18 @@ static void dump_bytes_field(DumpBuffer &out, const char *field_name, const uint
out.append(hex_buf).append("\n");
}
template<> const char *proto_enum_to_string<enums::SerialProxyPortType>(enums::SerialProxyPortType value) {
switch (value) {
case enums::SERIAL_PROXY_PORT_TYPE_TTL:
return "SERIAL_PROXY_PORT_TYPE_TTL";
case enums::SERIAL_PROXY_PORT_TYPE_RS232:
return "SERIAL_PROXY_PORT_TYPE_RS232";
case enums::SERIAL_PROXY_PORT_TYPE_RS485:
return "SERIAL_PROXY_PORT_TYPE_RS485";
default:
return "UNKNOWN";
}
}
template<> const char *proto_enum_to_string<enums::EntityCategory>(enums::EntityCategory value) {
switch (value) {
case enums::ENTITY_CATEGORY_NONE:
@@ -807,6 +819,14 @@ const char *DeviceInfo::dump_to(DumpBuffer &out) const {
return out.c_str();
}
#endif
#ifdef USE_SERIAL_PROXY
const char *SerialProxyInfo::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, "SerialProxyInfo");
dump_field(out, "name", this->name);
dump_field(out, "port_type", static_cast<enums::SerialProxyPortType>(this->port_type));
return out.c_str();
}
#endif
const char *DeviceInfoResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, "DeviceInfoResponse");
dump_field(out, "name", this->name);
@@ -869,7 +889,11 @@ const char *DeviceInfoResponse::dump_to(DumpBuffer &out) const {
dump_field(out, "zwave_home_id", this->zwave_home_id);
#endif
#ifdef USE_SERIAL_PROXY
dump_field(out, "serial_proxy_count", this->serial_proxy_count);
for (const auto &it : this->serial_proxies) {
out.append(" serial_proxies: ");
it.dump_to(out);
out.append("\n");
}
#endif
return out.c_str();
}

View File

@@ -16,7 +16,7 @@ from esphome import pins
import esphome.codegen as cg
from esphome.components import uart
import esphome.config_validation as cv
from esphome.const import CONF_ID
from esphome.const import CONF_ID, CONF_NAME
CODEOWNERS = ["@kbx81"]
DEPENDENCIES = ["api", "uart"]
@@ -26,14 +26,27 @@ MULTI_CONF = True
serial_proxy_ns = cg.esphome_ns.namespace("serial_proxy")
SerialProxy = serial_proxy_ns.class_("SerialProxy", cg.Component, uart.UARTDevice)
CONF_RTS_PIN = "rts_pin"
api_enums_ns = cg.esphome_ns.namespace("api").namespace("enums")
SerialProxyPortType = api_enums_ns.enum("SerialProxyPortType")
SERIAL_PROXY_PORT_TYPES = {
"TTL": SerialProxyPortType.SERIAL_PROXY_PORT_TYPE_TTL,
"RS232": SerialProxyPortType.SERIAL_PROXY_PORT_TYPE_RS232,
"RS485": SerialProxyPortType.SERIAL_PROXY_PORT_TYPE_RS485,
}
CONF_DTR_PIN = "dtr_pin"
CONF_PORT_TYPE = "port_type"
CONF_RTS_PIN = "rts_pin"
_serial_proxy_count = []
CONFIG_SCHEMA = (
cv.Schema(
{
cv.GenerateID(): cv.declare_id(SerialProxy),
cv.Required(CONF_NAME): cv.string_strict,
cv.Required(CONF_PORT_TYPE): cv.enum(SERIAL_PROXY_PORT_TYPES, upper=True),
cv.Optional(CONF_RTS_PIN): pins.gpio_output_pin_schema,
cv.Optional(CONF_DTR_PIN): pins.gpio_output_pin_schema,
}
@@ -48,7 +61,12 @@ async def to_code(config):
await cg.register_component(var, config)
await uart.register_uart_device(var, config)
cg.add(cg.App.register_serial_proxy(var))
cg.add(var.set_name(config[CONF_NAME]))
cg.add(var.set_port_type(config[CONF_PORT_TYPE]))
cg.add_define("USE_SERIAL_PROXY")
# Track instance count — last define wins, so the final value is the total count
_serial_proxy_count.append(var)
cg.add_define("SERIAL_PROXY_COUNT", len(_serial_proxy_count))
if CONF_RTS_PIN in config:
rts_pin = await cg.gpio_pin_expression(config[CONF_RTS_PIN])

View File

@@ -47,9 +47,15 @@ void SerialProxy::loop() {
void SerialProxy::dump_config() {
ESP_LOGCONFIG(TAG,
"Serial Proxy [%u]:\n"
" Name: %s\n"
" Port Type: %s\n"
" RTS Pin: %s\n"
" DTR Pin: %s",
this->instance_index_, this->rts_pin_ != nullptr ? "configured" : "not configured",
this->instance_index_, this->name_.c_str(),
this->port_type_ == api::enums::SERIAL_PROXY_PORT_TYPE_RS485 ? "RS485"
: this->port_type_ == api::enums::SERIAL_PROXY_PORT_TYPE_RS232 ? "RS232"
: "TTL",
this->rts_pin_ != nullptr ? "configured" : "not configured",
this->dtr_pin_ != nullptr ? "configured" : "not configured");
}

View File

@@ -8,10 +8,13 @@
#ifdef USE_SERIAL_PROXY
#include "esphome/components/api/api_pb2.h"
#include "esphome/core/component.h"
#include "esphome/core/hal.h"
#include "esphome/components/uart/uart.h"
#include <string>
namespace esphome::serial_proxy {
/// Maximum bytes to read from UART in a single loop iteration
@@ -30,6 +33,18 @@ class SerialProxy : public uart::UARTDevice, public Component {
/// Set the instance index (called by Application::register_serial_proxy)
void set_instance_index(uint32_t index) { this->instance_index_ = index; }
/// Set the human-readable port name (from YAML configuration)
void set_name(const std::string &name) { this->name_ = name; }
/// Get the human-readable port name
const std::string &get_name() const { return this->name_; }
/// Set the port type (from YAML configuration)
void set_port_type(api::enums::SerialProxyPortType port_type) { this->port_type_ = port_type; }
/// Get the port type
api::enums::SerialProxyPortType get_port_type() const { return this->port_type_; }
/// Configure UART parameters and apply them
/// @param baudrate Baud rate in bits per second
/// @param flow_control True to enable hardware flow control
@@ -66,6 +81,12 @@ class SerialProxy : public uart::UARTDevice, public Component {
/// Instance index for identifying this proxy in API messages
uint32_t instance_index_{0};
/// Human-readable port name
std::string name_;
/// Port type
api::enums::SerialProxyPortType port_type_{api::enums::SERIAL_PROXY_PORT_TYPE_TTL};
/// Optional GPIO pins for modem control
GPIOPin *rts_pin_{nullptr};
GPIOPin *dtr_pin_{nullptr};

View File

@@ -99,6 +99,7 @@
#define MDNS_SERVICE_COUNT 3
#define USE_MDNS_DYNAMIC_TXT
#define MDNS_DYNAMIC_TXT_COUNT 2
#define SERIAL_PROXY_COUNT 2
#define SNTP_SERVER_COUNT 3
#define USE_MEDIA_PLAYER
#define USE_NEXTION_TFT_UPLOAD

View File

@@ -6,3 +6,5 @@ api:
serial_proxy:
- id: serial_proxy_1
name: Test Serial Port
port_type: RS232