1
0
mirror of https://github.com/esphome/esphome.git synced 2026-02-08 08:41:59 +00:00

Merge branch 'get_peername_stack_save_ram' into integration

This commit is contained in:
J. Nick Koston
2026-01-04 13:07:32 -10:00
25 changed files with 306 additions and 124 deletions

View File

@@ -22,7 +22,6 @@ from esphome.core import CORE, CoroPriority, TimePeriod, coroutine_with_priority
import esphome.final_validate as fv
DEPENDENCIES = ["esp32"]
AUTO_LOAD = ["socket"]
CODEOWNERS = ["@jesserockz", "@Rapsssito", "@bdraco"]
DOMAIN = "esp32_ble"

View File

@@ -154,15 +154,17 @@ void MQTTClientComponent::on_log(uint8_t level, const char *tag, const char *mes
void MQTTClientComponent::dump_config() {
char ip_buf[network::IP_ADDRESS_BUFFER_SIZE];
// clang-format off
ESP_LOGCONFIG(TAG,
"MQTT:\n"
" Server Address: %s:%u (%s)\n"
" Username: " LOG_SECRET("'%s'") "\n"
" Client ID: " LOG_SECRET("'%s'") "\n"
" Clean Session: %s",
" Client ID: " LOG_SECRET("'%s'") "\n"
" Clean Session: %s",
this->credentials_.address.c_str(), this->credentials_.port, this->ip_.str_to(ip_buf),
this->credentials_.username.c_str(), this->credentials_.client_id.c_str(),
YESNO(this->credentials_.clean_session));
// clang-format on
if (this->is_discovery_ip_enabled()) {
ESP_LOGCONFIG(TAG, " Discovery IP enabled");
}

View File

@@ -47,6 +47,8 @@ def require_wake_loop_threadsafe() -> None:
This enables the shared UDP loopback socket mechanism (~208 bytes RAM).
The socket is shared across all components that use this feature.
This call is a no-op if networking is not enabled in the configuration.
IMPORTANT: This is for background thread context only, NOT ISR context.
Socket operations are not safe to call from ISR handlers.
@@ -56,8 +58,11 @@ def require_wake_loop_threadsafe() -> None:
async def to_code(config):
socket.require_wake_loop_threadsafe()
"""
# Only set up once (idempotent - multiple components can call this)
if not CORE.data.get(KEY_WAKE_LOOP_THREADSAFE_REQUIRED, False):
if CORE.has_networking and not CORE.data.get(
KEY_WAKE_LOOP_THREADSAFE_REQUIRED, False
):
CORE.data[KEY_WAKE_LOOP_THREADSAFE_REQUIRED] = True
cg.add_define("USE_WAKE_LOOP_THREADSAFE")
# Consume 1 socket for the shared wake notification socket

View File

@@ -172,21 +172,25 @@ struct SunAtTime {
void debug() const {
// debug output like in example 25.a, p. 165
ESP_LOGV(TAG, "jde: %f", jde);
ESP_LOGV(TAG, "T: %f", t);
ESP_LOGV(TAG, "L_0: %f", mean_longitude());
ESP_LOGV(TAG, "M: %f", mean_anomaly());
ESP_LOGV(TAG, "e: %f", eccentricity());
ESP_LOGV(TAG, "C: %f", equation_of_center());
ESP_LOGV(TAG, "Odot: %f", true_longitude());
ESP_LOGV(TAG, "Omega: %f", omega());
ESP_LOGV(TAG, "lambda: %f", apparent_longitude());
ESP_LOGV(TAG, "epsilon_0: %f", mean_obliquity());
ESP_LOGV(TAG, "epsilon: %f", true_obliquity());
ESP_LOGV(TAG, "v: %f", true_anomaly());
auto eq = equatorial_coordinate();
ESP_LOGV(TAG, "right_ascension: %f", eq.right_ascension);
ESP_LOGV(TAG, "declination: %f", eq.declination);
ESP_LOGV(TAG,
"jde: %f\n"
"T: %f\n"
"L_0: %f\n"
"M: %f\n"
"e: %f\n"
"C: %f\n"
"Odot: %f\n"
"Omega: %f\n"
"lambda: %f\n"
"epsilon_0: %f\n"
"epsilon: %f\n"
"v: %f\n"
"right_ascension: %f\n"
"declination: %f",
jde, t, mean_longitude(), mean_anomaly(), eccentricity(), equation_of_center(), true_longitude(), omega(),
apparent_longitude(), mean_obliquity(), true_obliquity(), true_anomaly(), eq.right_ascension,
eq.declination);
}
};

View File

@@ -22,8 +22,10 @@ void SX1509FloatOutputChannel::setup() {
}
void SX1509FloatOutputChannel::dump_config() {
ESP_LOGCONFIG(TAG, "SX1509 PWM:");
ESP_LOGCONFIG(TAG, " sx1509 pin: %d", this->pin_);
ESP_LOGCONFIG(TAG,
"SX1509 PWM:\n"
" sx1509 pin: %d",
this->pin_);
LOG_FLOAT_OUTPUT(this);
}

View File

@@ -21,12 +21,14 @@ void TLC5947::setup() {
this->pwm_amounts_.resize(this->num_chips_ * N_CHANNELS_PER_CHIP, 0);
}
void TLC5947::dump_config() {
ESP_LOGCONFIG(TAG, "TLC5947:");
ESP_LOGCONFIG(TAG,
"TLC5947:\n"
" Number of chips: %u",
this->num_chips_);
LOG_PIN(" Data Pin: ", this->data_pin_);
LOG_PIN(" Clock Pin: ", this->clock_pin_);
LOG_PIN(" LAT Pin: ", this->lat_pin_);
LOG_PIN(" OE Pin: ", this->outenable_pin_);
ESP_LOGCONFIG(TAG, " Number of chips: %u", this->num_chips_);
}
void TLC5947::loop() {

View File

@@ -73,12 +73,15 @@ void TMP1075Sensor::set_fault_count(const int faults) {
}
void TMP1075Sensor::log_config_() {
ESP_LOGV(TAG, " oneshot : %d", config_.fields.oneshot);
ESP_LOGV(TAG, " rate : %d", config_.fields.rate);
ESP_LOGV(TAG, " faults : %d", config_.fields.faults);
ESP_LOGV(TAG, " polarity : %d", config_.fields.polarity);
ESP_LOGV(TAG, " alert_mode: %d", config_.fields.alert_mode);
ESP_LOGV(TAG, " shutdown : %d", config_.fields.shutdown);
ESP_LOGV(TAG,
" oneshot : %d\n"
" rate : %d\n"
" faults : %d\n"
" polarity : %d\n"
" alert_mode: %d\n"
" shutdown : %d",
config_.fields.oneshot, config_.fields.rate, config_.fields.faults, config_.fields.polarity,
config_.fields.alert_mode, config_.fields.shutdown);
}
void TMP1075Sensor::write_config() {

View File

@@ -14,8 +14,10 @@ void TuyaBinarySensor::setup() {
}
void TuyaBinarySensor::dump_config() {
ESP_LOGCONFIG(TAG, "Tuya Binary Sensor:");
ESP_LOGCONFIG(TAG, " Binary Sensor has datapoint ID %u", this->sensor_id_);
ESP_LOGCONFIG(TAG,
"Tuya Binary Sensor:\n"
" Binary Sensor has datapoint ID %u",
this->sensor_id_);
}
} // namespace tuya

View File

@@ -33,8 +33,10 @@ void TuyaTextSensor::setup() {
}
void TuyaTextSensor::dump_config() {
ESP_LOGCONFIG(TAG, "Tuya Text Sensor:");
ESP_LOGCONFIG(TAG, " Text Sensor has datapoint ID %u", this->sensor_id_);
ESP_LOGCONFIG(TAG,
"Tuya Text Sensor:\n"
" Text Sensor has datapoint ID %u",
this->sensor_id_);
}
} // namespace tuya

View File

@@ -102,16 +102,16 @@ void UFireECComponent::write_data_(uint8_t reg, float data) {
}
void UFireECComponent::dump_config() {
ESP_LOGCONFIG(TAG, "uFire-EC");
ESP_LOGCONFIG(TAG,
"uFire-EC:\n"
" Temperature Compensation: %f\n"
" Temperature Coefficient: %f",
this->temperature_compensation_, this->temperature_coefficient_);
LOG_I2C_DEVICE(this)
LOG_UPDATE_INTERVAL(this);
LOG_SENSOR(" ", "EC Sensor", this->ec_sensor_);
LOG_SENSOR(" ", "Temperature Sensor", this->temperature_sensor_);
LOG_SENSOR(" ", "Temperature Sensor external", this->temperature_sensor_external_);
ESP_LOGCONFIG(TAG,
" Temperature Compensation: %f\n"
" Temperature Coefficient: %f",
this->temperature_compensation_, this->temperature_coefficient_);
}
} // namespace ufire_ec

View File

@@ -34,12 +34,14 @@ void ULN2003::loop() {
this->write_step_(this->current_uln_pos_);
}
void ULN2003::dump_config() {
ESP_LOGCONFIG(TAG, "ULN2003:");
ESP_LOGCONFIG(TAG,
"ULN2003:\n"
" Sleep when done: %s",
YESNO(this->sleep_when_done_));
LOG_PIN(" Pin A: ", this->pin_a_);
LOG_PIN(" Pin B: ", this->pin_b_);
LOG_PIN(" Pin C: ", this->pin_c_);
LOG_PIN(" Pin D: ", this->pin_d_);
ESP_LOGCONFIG(TAG, " Sleep when done: %s", YESNO(this->sleep_when_done_));
const char *step_mode_s;
switch (this->step_mode_) {
case ULN2003_STEP_MODE_FULL_STEP:

View File

@@ -39,37 +39,46 @@ static void print_ep_desc(const usb_ep_desc_t *ep_desc) {
break;
}
ESP_LOGV(TAG, "\t\t*** Endpoint descriptor ***");
ESP_LOGV(TAG, "\t\tbLength %d", ep_desc->bLength);
ESP_LOGV(TAG, "\t\tbDescriptorType %d", ep_desc->bDescriptorType);
ESP_LOGV(TAG, "\t\tbEndpointAddress 0x%x\tEP %d %s", ep_desc->bEndpointAddress, USB_EP_DESC_GET_EP_NUM(ep_desc),
USB_EP_DESC_GET_EP_DIR(ep_desc) ? "IN" : "OUT");
ESP_LOGV(TAG, "\t\tbmAttributes 0x%x\t%s", ep_desc->bmAttributes, ep_type_str);
ESP_LOGV(TAG, "\t\twMaxPacketSize %d", ep_desc->wMaxPacketSize);
ESP_LOGV(TAG, "\t\tbInterval %d", ep_desc->bInterval);
ESP_LOGV(TAG,
"\t\t*** Endpoint descriptor ***\n"
"\t\tbLength %d\n"
"\t\tbDescriptorType %d\n"
"\t\tbEndpointAddress 0x%x\tEP %d %s\n"
"\t\tbmAttributes 0x%x\t%s\n"
"\t\twMaxPacketSize %d\n"
"\t\tbInterval %d",
ep_desc->bLength, ep_desc->bDescriptorType, ep_desc->bEndpointAddress, USB_EP_DESC_GET_EP_NUM(ep_desc),
USB_EP_DESC_GET_EP_DIR(ep_desc) ? "IN" : "OUT", ep_desc->bmAttributes, ep_type_str, ep_desc->wMaxPacketSize,
ep_desc->bInterval);
}
static void usbh_print_intf_desc(const usb_intf_desc_t *intf_desc) {
ESP_LOGV(TAG, "\t*** Interface descriptor ***");
ESP_LOGV(TAG, "\tbLength %d", intf_desc->bLength);
ESP_LOGV(TAG, "\tbDescriptorType %d", intf_desc->bDescriptorType);
ESP_LOGV(TAG, "\tbInterfaceNumber %d", intf_desc->bInterfaceNumber);
ESP_LOGV(TAG, "\tbAlternateSetting %d", intf_desc->bAlternateSetting);
ESP_LOGV(TAG, "\tbNumEndpoints %d", intf_desc->bNumEndpoints);
ESP_LOGV(TAG, "\tbInterfaceClass 0x%x", intf_desc->bInterfaceProtocol);
ESP_LOGV(TAG, "\tiInterface %d", intf_desc->iInterface);
ESP_LOGV(TAG,
"\t*** Interface descriptor ***\n"
"\tbLength %d\n"
"\tbDescriptorType %d\n"
"\tbInterfaceNumber %d\n"
"\tbAlternateSetting %d\n"
"\tbNumEndpoints %d\n"
"\tbInterfaceClass 0x%x\n"
"\tiInterface %d",
intf_desc->bLength, intf_desc->bDescriptorType, intf_desc->bInterfaceNumber, intf_desc->bAlternateSetting,
intf_desc->bNumEndpoints, intf_desc->bInterfaceProtocol, intf_desc->iInterface);
}
static void usbh_print_cfg_desc(const usb_config_desc_t *cfg_desc) {
ESP_LOGV(TAG, "*** Configuration descriptor ***");
ESP_LOGV(TAG, "bLength %d", cfg_desc->bLength);
ESP_LOGV(TAG, "bDescriptorType %d", cfg_desc->bDescriptorType);
ESP_LOGV(TAG, "wTotalLength %d", cfg_desc->wTotalLength);
ESP_LOGV(TAG, "bNumInterfaces %d", cfg_desc->bNumInterfaces);
ESP_LOGV(TAG, "bConfigurationValue %d", cfg_desc->bConfigurationValue);
ESP_LOGV(TAG, "iConfiguration %d", cfg_desc->iConfiguration);
ESP_LOGV(TAG, "bmAttributes 0x%x", cfg_desc->bmAttributes);
ESP_LOGV(TAG, "bMaxPower %dmA", cfg_desc->bMaxPower * 2);
ESP_LOGV(TAG,
"*** Configuration descriptor ***\n"
"bLength %d\n"
"bDescriptorType %d\n"
"wTotalLength %d\n"
"bNumInterfaces %d\n"
"bConfigurationValue %d\n"
"iConfiguration %d\n"
"bmAttributes 0x%x\n"
"bMaxPower %dmA",
cfg_desc->bLength, cfg_desc->bDescriptorType, cfg_desc->wTotalLength, cfg_desc->bNumInterfaces,
cfg_desc->bConfigurationValue, cfg_desc->iConfiguration, cfg_desc->bmAttributes, cfg_desc->bMaxPower * 2);
}
static void usb_client_print_device_descriptor(const usb_device_desc_t *devc_desc) {
@@ -77,21 +86,27 @@ static void usb_client_print_device_descriptor(const usb_device_desc_t *devc_des
return;
}
ESP_LOGV(TAG, "*** Device descriptor ***");
ESP_LOGV(TAG, "bLength %d", devc_desc->bLength);
ESP_LOGV(TAG, "bDescriptorType %d", devc_desc->bDescriptorType);
ESP_LOGV(TAG, "bcdUSB %d.%d0", ((devc_desc->bcdUSB >> 8) & 0xF), ((devc_desc->bcdUSB >> 4) & 0xF));
ESP_LOGV(TAG, "bDeviceClass 0x%x", devc_desc->bDeviceClass);
ESP_LOGV(TAG, "bDeviceSubClass 0x%x", devc_desc->bDeviceSubClass);
ESP_LOGV(TAG, "bDeviceProtocol 0x%x", devc_desc->bDeviceProtocol);
ESP_LOGV(TAG, "bMaxPacketSize0 %d", devc_desc->bMaxPacketSize0);
ESP_LOGV(TAG, "idVendor 0x%x", devc_desc->idVendor);
ESP_LOGV(TAG, "idProduct 0x%x", devc_desc->idProduct);
ESP_LOGV(TAG, "bcdDevice %d.%d0", ((devc_desc->bcdDevice >> 8) & 0xF), ((devc_desc->bcdDevice >> 4) & 0xF));
ESP_LOGV(TAG, "iManufacturer %d", devc_desc->iManufacturer);
ESP_LOGV(TAG, "iProduct %d", devc_desc->iProduct);
ESP_LOGV(TAG, "iSerialNumber %d", devc_desc->iSerialNumber);
ESP_LOGV(TAG, "bNumConfigurations %d", devc_desc->bNumConfigurations);
ESP_LOGV(TAG,
"*** Device descriptor ***\n"
"bLength %d\n"
"bDescriptorType %d\n"
"bcdUSB %d.%d0\n"
"bDeviceClass 0x%x\n"
"bDeviceSubClass 0x%x\n"
"bDeviceProtocol 0x%x\n"
"bMaxPacketSize0 %d\n"
"idVendor 0x%x\n"
"idProduct 0x%x\n"
"bcdDevice %d.%d0\n"
"iManufacturer %d\n"
"iProduct %d\n"
"iSerialNumber %d\n"
"bNumConfigurations %d",
devc_desc->bLength, devc_desc->bDescriptorType, ((devc_desc->bcdUSB >> 8) & 0xF),
((devc_desc->bcdUSB >> 4) & 0xF), devc_desc->bDeviceClass, devc_desc->bDeviceSubClass,
devc_desc->bDeviceProtocol, devc_desc->bMaxPacketSize0, devc_desc->idVendor, devc_desc->idProduct,
((devc_desc->bcdDevice >> 8) & 0xF), ((devc_desc->bcdDevice >> 4) & 0xF), devc_desc->iManufacturer,
devc_desc->iProduct, devc_desc->iSerialNumber, devc_desc->bNumConfigurations);
}
static void usb_client_print_config_descriptor(const usb_config_desc_t *cfg_desc,

View File

@@ -58,8 +58,10 @@ std::vector<CdcEps> USBUartTypeCP210X::parse_descriptors(usb_device_handle_t dev
ESP_LOGE(TAG, "get_active_config_descriptor failed");
return {};
}
ESP_LOGD(TAG, "bDeviceClass: %u, bDeviceSubClass: %u", device_desc->bDeviceClass, device_desc->bDeviceSubClass);
ESP_LOGD(TAG, "bNumInterfaces: %u", config_desc->bNumInterfaces);
ESP_LOGD(TAG,
"bDeviceClass: %u, bDeviceSubClass: %u\n"
"bNumInterfaces: %u",
device_desc->bDeviceClass, device_desc->bDeviceSubClass, config_desc->bNumInterfaces);
if (device_desc->bDeviceClass != 0) {
ESP_LOGE(TAG, "bDeviceClass != 0");
return {};

View File

@@ -27,8 +27,10 @@ void VL53L0XSensor::dump_config() {
if (this->enable_pin_ != nullptr) {
LOG_PIN(" Enable Pin: ", this->enable_pin_);
}
ESP_LOGCONFIG(TAG, " Timeout: %u%s", this->timeout_us_, this->timeout_us_ > 0 ? "us" : " (no timeout)");
ESP_LOGCONFIG(TAG, " Timing Budget %uus ", this->measurement_timing_budget_us_);
ESP_LOGCONFIG(TAG,
" Timeout: %u%s\n"
" Timing Budget %uus ",
this->timeout_us_, this->timeout_us_ > 0 ? "us" : " (no timeout)", this->measurement_timing_budget_us_);
}
void VL53L0XSensor::setup() {

View File

@@ -430,9 +430,12 @@ void VoiceAssistant::client_subscription(api::APIConnection *client, bool subscr
}
if (this->api_client_ != nullptr) {
ESP_LOGE(TAG, "Multiple API Clients attempting to connect to Voice Assistant");
ESP_LOGE(TAG, "Current client: %s (%s)", this->api_client_->get_name(), this->api_client_->get_peername());
ESP_LOGE(TAG, "New client: %s (%s)", client->get_name(), client->get_peername());
ESP_LOGE(TAG,
"Multiple API Clients attempting to connect to Voice Assistant\n"
"Current client: %s (%s)\n"
"New client: %s (%s)",
this->api_client_->get_name(), this->api_client_->get_peername(), client->get_name(),
client->get_peername());
return;
}
@@ -864,9 +867,11 @@ void VoiceAssistant::on_timer_event(const api::VoiceAssistantTimerEventResponse
.is_active = msg.is_active,
};
this->timers_[timer.id] = timer;
ESP_LOGD(TAG, "Timer Event");
ESP_LOGD(TAG, " Type: %" PRId32, msg.event_type);
ESP_LOGD(TAG, " %s", timer.to_string().c_str());
ESP_LOGD(TAG,
"Timer Event\n"
" Type: %" PRId32 "\n"
" %s",
msg.event_type, timer.to_string().c_str());
switch (msg.event_type) {
case api::enums::VOICE_ASSISTANT_TIMER_STARTED:

View File

@@ -1825,8 +1825,10 @@ void WaveshareEPaper2P9InV2R2::write_lut_(const uint8_t *lut, const uint8_t size
void WaveshareEPaper2P9InV2R2::dump_config() {
LOG_DISPLAY("", "Waveshare E-Paper", this);
ESP_LOGCONFIG(TAG, " Model: 2.9inV2R2");
ESP_LOGCONFIG(TAG, " Full Update Every: %" PRIu32, this->full_update_every_);
ESP_LOGCONFIG(TAG,
" Model: 2.9inV2R2\n"
" Full Update Every: %" PRIu32,
this->full_update_every_);
LOG_PIN(" Reset Pin: ", this->reset_pin_);
LOG_PIN(" DC Pin: ", this->dc_pin_);
LOG_PIN(" Busy Pin: ", this->busy_pin_);
@@ -2528,8 +2530,10 @@ int GDEY042T81::get_height_internal() { return 300; }
uint32_t GDEY042T81::idle_timeout_() { return 5000; }
void GDEY042T81::dump_config() {
LOG_DISPLAY("", "GoodDisplay E-Paper", this);
ESP_LOGCONFIG(TAG, " Model: 4.2in B/W GDEY042T81");
ESP_LOGCONFIG(TAG, " Full Update Every: %" PRIu32, this->full_update_every_);
ESP_LOGCONFIG(TAG,
" Model: 4.2in B/W GDEY042T81\n"
" Full Update Every: %" PRIu32,
this->full_update_every_);
LOG_PIN(" Reset Pin: ", this->reset_pin_);
LOG_PIN(" DC Pin: ", this->dc_pin_);
LOG_PIN(" Busy Pin: ", this->busy_pin_);
@@ -3159,8 +3163,10 @@ int GDEY0583T81::get_height_internal() { return 480; }
uint32_t GDEY0583T81::idle_timeout_() { return 5000; }
void GDEY0583T81::dump_config() {
LOG_DISPLAY("", "GoodDisplay E-Paper", this);
ESP_LOGCONFIG(TAG, " Model: 5.83in B/W GDEY0583T81");
ESP_LOGCONFIG(TAG, " Full Update Every: %" PRIu32, this->full_update_every_);
ESP_LOGCONFIG(TAG,
" Model: 5.83in B/W GDEY0583T81\n"
" Full Update Every: %" PRIu32,
this->full_update_every_);
LOG_PIN(" Reset Pin: ", this->reset_pin_);
LOG_PIN(" DC Pin: ", this->dc_pin_);
LOG_PIN(" Busy Pin: ", this->busy_pin_);
@@ -4340,8 +4346,10 @@ int WaveshareEPaper7P5InV2P::get_height_internal() { return 480; }
uint32_t WaveshareEPaper7P5InV2P::idle_timeout_() { return 10000; }
void WaveshareEPaper7P5InV2P::dump_config() {
LOG_DISPLAY("", "Waveshare E-Paper", this);
ESP_LOGCONFIG(TAG, " Model: 7.50inv2p");
ESP_LOGCONFIG(TAG, " Full Update Every: %" PRIu32, this->full_update_every_);
ESP_LOGCONFIG(TAG,
" Model: 7.50inv2p\n"
" Full Update Every: %" PRIu32,
this->full_update_every_);
LOG_PIN(" Reset Pin: ", this->reset_pin_);
LOG_PIN(" DC Pin: ", this->dc_pin_);
LOG_PIN(" Busy Pin: ", this->busy_pin_);

View File

@@ -131,15 +131,21 @@ void Wireguard::update() {
}
void Wireguard::dump_config() {
ESP_LOGCONFIG(TAG, "WireGuard:");
ESP_LOGCONFIG(TAG, " Address: %s", this->address_.c_str());
ESP_LOGCONFIG(TAG, " Netmask: %s", this->netmask_.c_str());
ESP_LOGCONFIG(TAG, " Private Key: " LOG_SECRET("%s"), mask_key(this->private_key_).c_str());
ESP_LOGCONFIG(TAG, " Peer Endpoint: " LOG_SECRET("%s"), this->peer_endpoint_.c_str());
ESP_LOGCONFIG(TAG, " Peer Port: " LOG_SECRET("%d"), this->peer_port_);
ESP_LOGCONFIG(TAG, " Peer Public Key: " LOG_SECRET("%s"), this->peer_public_key_.c_str());
ESP_LOGCONFIG(TAG, " Peer Pre-shared Key: " LOG_SECRET("%s"),
(!this->preshared_key_.empty() ? mask_key(this->preshared_key_).c_str() : "NOT IN USE"));
// clang-format off
ESP_LOGCONFIG(
TAG,
"WireGuard:\n"
" Address: %s\n"
" Netmask: %s\n"
" Private Key: " LOG_SECRET("%s") "\n"
" Peer Endpoint: " LOG_SECRET("%s") "\n"
" Peer Port: " LOG_SECRET("%d") "\n"
" Peer Public Key: " LOG_SECRET("%s") "\n"
" Peer Pre-shared Key: " LOG_SECRET("%s"),
this->address_.c_str(), this->netmask_.c_str(), mask_key(this->private_key_).c_str(),
this->peer_endpoint_.c_str(), this->peer_port_, this->peer_public_key_.c_str(),
(!this->preshared_key_.empty() ? mask_key(this->preshared_key_).c_str() : "NOT IN USE"));
// clang-format on
ESP_LOGCONFIG(TAG, " Peer Allowed IPs:");
for (auto &allowed_ip : this->allowed_ips_) {
ESP_LOGCONFIG(TAG, " - %s/%s", std::get<0>(allowed_ip).c_str(), std::get<1>(allowed_ip).c_str());

View File

@@ -68,12 +68,15 @@ Wl134Component::Rfid134Error Wl134Component::read_packet_() {
reading.reserved1 = this->hex_lsb_ascii_to_uint64_(&(packet[RFID134_PACKET_RESERVED1]),
RFID134_PACKET_CHECKSUM - RFID134_PACKET_RESERVED1);
ESP_LOGV(TAG, "Tag id: %012lld", reading.id);
ESP_LOGV(TAG, "Country: %03d", reading.country);
ESP_LOGV(TAG, "isData: %s", reading.isData ? "true" : "false");
ESP_LOGV(TAG, "isAnimal: %s", reading.isAnimal ? "true" : "false");
ESP_LOGV(TAG, "Reserved0: %d", reading.reserved0);
ESP_LOGV(TAG, "Reserved1: %" PRId32, reading.reserved1);
ESP_LOGV(TAG,
"Tag id: %012lld\n"
"Country: %03d\n"
"isData: %s\n"
"isAnimal: %s\n"
"Reserved0: %d\n"
"Reserved1: %" PRId32,
reading.id, reading.country, reading.isData ? "true" : "false", reading.isAnimal ? "true" : "false",
reading.reserved0, reading.reserved1);
char buf[20];
sprintf(buf, "%03d%012lld", reading.country, reading.id);

View File

@@ -62,14 +62,14 @@ void X9cOutput::write_state(float state) {
}
void X9cOutput::dump_config() {
ESP_LOGCONFIG(TAG, "X9C Potentiometer Output:");
LOG_PIN(" Chip Select Pin: ", this->cs_pin_);
LOG_PIN(" Increment Pin: ", this->inc_pin_);
LOG_PIN(" Up/Down Pin: ", this->ud_pin_);
ESP_LOGCONFIG(TAG,
"X9C Potentiometer Output:\n"
" Initial Value: %f\n"
" Step Delay: %d",
this->initial_value_, this->step_delay_);
LOG_PIN(" Chip Select Pin: ", this->cs_pin_);
LOG_PIN(" Increment Pin: ", this->inc_pin_);
LOG_PIN(" Up/Down Pin: ", this->ud_pin_);
LOG_FLOAT_OUTPUT(this);
}

View File

@@ -72,8 +72,10 @@ void XGZP68XXComponent::update() {
temperature_raw = encode_uint16(data[3], data[4]);
// Convert the pressure data to hPa
ESP_LOGV(TAG, "Got raw pressure=%" PRIu32 ", raw temperature=%u", pressure_raw, temperature_raw);
ESP_LOGV(TAG, "K value is %u", this->k_value_);
ESP_LOGV(TAG,
"Got raw pressure=%" PRIu32 ", raw temperature=%u\n"
"K value is %u",
pressure_raw, temperature_raw, this->k_value_);
// Sign extend the pressure
float pressure_in_pa = (float) (((int32_t) pressure_raw << 8) >> 8);

View File

@@ -13,8 +13,10 @@ static constexpr size_t XMWSDJ04MMC_BINDKEY_SIZE = 16;
void XiaomiXMWSDJ04MMC::dump_config() {
char bindkey_hex[format_hex_pretty_size(XMWSDJ04MMC_BINDKEY_SIZE)];
ESP_LOGCONFIG(TAG, "Xiaomi XMWSDJ04MMC");
ESP_LOGCONFIG(TAG, " Bindkey: %s", format_hex_pretty_to(bindkey_hex, this->bindkey_, XMWSDJ04MMC_BINDKEY_SIZE, '.'));
ESP_LOGCONFIG(TAG,
"Xiaomi XMWSDJ04MMC\n"
" Bindkey: %s",
format_hex_pretty_to(bindkey_hex, this->bindkey_, XMWSDJ04MMC_BINDKEY_SIZE, '.'));
LOG_SENSOR(" ", "Temperature", this->temperature_);
LOG_SENSOR(" ", "Humidity", this->humidity_);
LOG_SENSOR(" ", "Battery Level", this->battery_level_);

View File

@@ -59,10 +59,8 @@ void XPT2046Component::update_touches() {
}
void XPT2046Component::dump_config() {
ESP_LOGCONFIG(TAG, "XPT2046:");
LOG_PIN(" IRQ Pin: ", this->irq_pin_);
ESP_LOGCONFIG(TAG,
"XPT2046:\n"
" X min: %d\n"
" X max: %d\n"
" Y min: %d\n"
@@ -73,7 +71,7 @@ void XPT2046Component::dump_config() {
" threshold: %d",
this->x_raw_min_, this->x_raw_max_, this->y_raw_min_, this->y_raw_max_, YESNO(this->swap_x_y_),
YESNO(this->invert_x_), YESNO(this->invert_y_), this->threshold_);
LOG_PIN(" IRQ Pin: ", this->irq_pin_);
LOG_UPDATE_INTERVAL(this);
}

View File

@@ -721,6 +721,25 @@ class EsphomeCore:
def config_filename(self) -> str:
return self.config_path.name
def has_at_least_one_component(self, *components: str) -> bool:
"""
Are any of the given components configured?
:param components: component names
:return: true if so
"""
if self.config is None:
raise ValueError("Config has not been loaded yet")
return any(component in self.config for component in components)
@property
def has_networking(self) -> bool:
"""
Is a network component configured?
:return: true if so
"""
return self.has_at_least_one_component("wifi", "ethernet", "openthread")
def relative_config_path(self, *path: str | Path) -> Path:
path_ = Path(*path).expanduser()
return self.config_dir / path_

View File

@@ -4,6 +4,7 @@ from esphome.core import CORE
def test_require_wake_loop_threadsafe__first_call() -> None:
"""Test that first call sets up define and consumes socket."""
CORE.config = {"wifi": True}
socket.require_wake_loop_threadsafe()
# Verify CORE.data was updated
@@ -17,6 +18,7 @@ def test_require_wake_loop_threadsafe__idempotent() -> None:
"""Test that subsequent calls are idempotent."""
# Set up initial state as if already called
CORE.data[socket.KEY_WAKE_LOOP_THREADSAFE_REQUIRED] = True
CORE.config = {"ethernet": True}
# Call again - should not raise or fail
socket.require_wake_loop_threadsafe()
@@ -31,6 +33,7 @@ def test_require_wake_loop_threadsafe__idempotent() -> None:
def test_require_wake_loop_threadsafe__multiple_calls() -> None:
"""Test that multiple calls only set up once."""
# Call three times
CORE.config = {"openthread": True}
socket.require_wake_loop_threadsafe()
socket.require_wake_loop_threadsafe()
socket.require_wake_loop_threadsafe()
@@ -40,3 +43,35 @@ def test_require_wake_loop_threadsafe__multiple_calls() -> None:
# Verify the define was added (only once, but we can just check it exists)
assert any(d.name == "USE_WAKE_LOOP_THREADSAFE" for d in CORE.defines)
def test_require_wake_loop_threadsafe__no_networking() -> None:
"""Test that wake loop is NOT configured when no networking is configured."""
# Set up config without any networking components
CORE.config = {"esphome": {"name": "test"}, "logger": {}}
# Call require_wake_loop_threadsafe
socket.require_wake_loop_threadsafe()
# Verify CORE.data flag was NOT set (since has_networking returns False)
assert socket.KEY_WAKE_LOOP_THREADSAFE_REQUIRED not in CORE.data
# Verify the define was NOT added
assert not any(d.name == "USE_WAKE_LOOP_THREADSAFE" for d in CORE.defines)
def test_require_wake_loop_threadsafe__no_networking_does_not_consume_socket() -> None:
"""Test that no socket is consumed when no networking is configured."""
# Set up config without any networking components
CORE.config = {"logger": {}}
# Track initial socket consumer state
initial_consumers = CORE.data.get(socket.KEY_SOCKET_CONSUMERS, {})
# Call require_wake_loop_threadsafe
socket.require_wake_loop_threadsafe()
# Verify no socket was consumed
consumers = CORE.data.get(socket.KEY_SOCKET_CONSUMERS, {})
assert "socket.wake_loop_threadsafe" not in consumers
assert consumers == initial_consumers

View File

@@ -718,3 +718,65 @@ class TestEsphomeCore:
# Even though "web_server" is in loaded_integrations due to the platform,
# web_port must return None because the full web_server component is not configured
assert target.web_port is None
def test_has_at_least_one_component__none_configured(self, target):
"""Test has_at_least_one_component returns False when none of the components are configured."""
target.config = {const.CONF_ESPHOME: {"name": "test"}, "logger": {}}
assert target.has_at_least_one_component("wifi", "ethernet") is False
def test_has_at_least_one_component__one_configured(self, target):
"""Test has_at_least_one_component returns True when one component is configured."""
target.config = {const.CONF_WIFI: {}, "logger": {}}
assert target.has_at_least_one_component("wifi", "ethernet") is True
def test_has_at_least_one_component__multiple_configured(self, target):
"""Test has_at_least_one_component returns True when multiple components are configured."""
target.config = {
const.CONF_WIFI: {},
const.CONF_ETHERNET: {},
"logger": {},
}
assert (
target.has_at_least_one_component("wifi", "ethernet", "bluetooth") is True
)
def test_has_at_least_one_component__single_component(self, target):
"""Test has_at_least_one_component works with a single component."""
target.config = {const.CONF_MQTT: {}}
assert target.has_at_least_one_component("mqtt") is True
assert target.has_at_least_one_component("wifi") is False
def test_has_at_least_one_component__config_not_loaded(self, target):
"""Test has_at_least_one_component raises ValueError when config is not loaded."""
target.config = None
with pytest.raises(ValueError, match="Config has not been loaded yet"):
target.has_at_least_one_component("wifi")
def test_has_networking__with_wifi(self, target):
"""Test has_networking returns True when wifi is configured."""
target.config = {const.CONF_WIFI: {}}
assert target.has_networking is True
def test_has_networking__with_ethernet(self, target):
"""Test has_networking returns True when ethernet is configured."""
target.config = {const.CONF_ETHERNET: {}}
assert target.has_networking is True
def test_has_networking__with_openthread(self, target):
"""Test has_networking returns True when openthread is configured."""
target.config = {const.CONF_OPENTHREAD: {}}
assert target.has_networking is True
def test_has_networking__without_networking(self, target):
"""Test has_networking returns False when no networking component is configured."""
target.config = {const.CONF_ESPHOME: {"name": "test"}, "logger": {}}
assert target.has_networking is False