mirror of
https://github.com/esphome/esphome.git
synced 2026-02-21 08:55:36 -07:00
Merge remote-tracking branch 'upstream/dev' into get_peername_stack_save_ram
# Conflicts: # esphome/components/voice_assistant/voice_assistant.cpp
This commit is contained in:
@@ -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"
|
||||
|
||||
|
||||
@@ -95,11 +95,13 @@ void GCJA5Component::parse_data_() {
|
||||
if (!this->first_status_log_) {
|
||||
this->first_status_log_ = true;
|
||||
|
||||
ESP_LOGI(TAG, "GCJA5 Status");
|
||||
ESP_LOGI(TAG, "Overall Status : %i", (status >> 6) & 0x03);
|
||||
ESP_LOGI(TAG, "PD Status : %i", (status >> 4) & 0x03);
|
||||
ESP_LOGI(TAG, "LD Status : %i", (status >> 2) & 0x03);
|
||||
ESP_LOGI(TAG, "Fan Status : %i", (status >> 0) & 0x03);
|
||||
ESP_LOGI(TAG,
|
||||
"GCJA5 Status\n"
|
||||
"Overall Status : %i\n"
|
||||
"PD Status : %i\n"
|
||||
"LD Status : %i\n"
|
||||
"Fan Status : %i",
|
||||
(status >> 6) & 0x03, (status >> 4) & 0x03, (status >> 2) & 0x03, (status >> 0) & 0x03);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,8 +27,10 @@ void GLR01I2CComponent::setup() {
|
||||
}
|
||||
|
||||
void GLR01I2CComponent::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "GL-R01 I2C:");
|
||||
ESP_LOGCONFIG(TAG, " Firmware Version: 0x%04X", this->version_);
|
||||
ESP_LOGCONFIG(TAG,
|
||||
"GL-R01 I2C:\n"
|
||||
" Firmware Version: 0x%04X",
|
||||
this->version_);
|
||||
LOG_I2C_DEVICE(this);
|
||||
LOG_SENSOR(" ", "Distance", this);
|
||||
}
|
||||
|
||||
@@ -89,11 +89,12 @@ void HC8Component::calibrate(uint16_t baseline) {
|
||||
float HC8Component::get_setup_priority() const { return setup_priority::DATA; }
|
||||
|
||||
void HC8Component::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "HC8:");
|
||||
ESP_LOGCONFIG(TAG,
|
||||
"HC8:\n"
|
||||
" Warmup time: %" PRIu32 " s",
|
||||
this->warmup_seconds_);
|
||||
LOG_SENSOR(" ", "CO2", this->co2_sensor_);
|
||||
this->check_uart_settings(9600);
|
||||
|
||||
ESP_LOGCONFIG(TAG, " Warmup time: %" PRIu32 " s", this->warmup_seconds_);
|
||||
}
|
||||
|
||||
} // namespace esphome::hc8
|
||||
|
||||
@@ -33,15 +33,15 @@ void HLW8012Component::setup() {
|
||||
}
|
||||
}
|
||||
void HLW8012Component::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "HLW8012:");
|
||||
LOG_PIN(" SEL Pin: ", this->sel_pin_);
|
||||
LOG_PIN(" CF Pin: ", this->cf_pin_);
|
||||
LOG_PIN(" CF1 Pin: ", this->cf1_pin_);
|
||||
ESP_LOGCONFIG(TAG,
|
||||
"HLW8012:\n"
|
||||
" Change measurement mode every %" PRIu32 "\n"
|
||||
" Current resistor: %.1f mΩ\n"
|
||||
" Voltage Divider: %.1f",
|
||||
this->change_mode_every_, this->current_resistor_ * 1000.0f, this->voltage_divider_);
|
||||
LOG_PIN(" SEL Pin: ", this->sel_pin_);
|
||||
LOG_PIN(" CF Pin: ", this->cf_pin_);
|
||||
LOG_PIN(" CF1 Pin: ", this->cf1_pin_);
|
||||
LOG_UPDATE_INTERVAL(this);
|
||||
LOG_SENSOR(" ", "Voltage", this->voltage_sensor_);
|
||||
LOG_SENSOR(" ", "Current", this->current_sensor_);
|
||||
|
||||
@@ -35,8 +35,10 @@ uint8_t HONEYWELLABPSensor::readsensor_() {
|
||||
pressure_count_ = ((uint16_t) (buf_[0]) << 8 & 0x3F00) | ((uint16_t) (buf_[1]) & 0xFF);
|
||||
// 11 - bit temperature is all of byte 2 (lowest 8 bits) and the first three bits of byte 3
|
||||
temperature_count_ = (((uint16_t) (buf_[2]) << 3) & 0x7F8) | (((uint16_t) (buf_[3]) >> 5) & 0x7);
|
||||
ESP_LOGV(TAG, "Sensor pressure_count_ %d", pressure_count_);
|
||||
ESP_LOGV(TAG, "Sensor temperature_count_ %d", temperature_count_);
|
||||
ESP_LOGV(TAG,
|
||||
"Sensor pressure_count_ %d\n"
|
||||
"Sensor temperature_count_ %d",
|
||||
pressure_count_, temperature_count_);
|
||||
}
|
||||
return status_;
|
||||
}
|
||||
|
||||
@@ -61,13 +61,13 @@ void INA260Component::setup() {
|
||||
}
|
||||
|
||||
void INA260Component::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "INA260:");
|
||||
ESP_LOGCONFIG(TAG,
|
||||
"INA260:\n"
|
||||
" Manufacture ID: 0x%x\n"
|
||||
" Device ID: 0x%x",
|
||||
this->manufacture_id_, this->device_id_);
|
||||
LOG_I2C_DEVICE(this);
|
||||
LOG_UPDATE_INTERVAL(this);
|
||||
|
||||
ESP_LOGCONFIG(TAG, " Manufacture ID: 0x%x", this->manufacture_id_);
|
||||
ESP_LOGCONFIG(TAG, " Device ID: 0x%x", this->device_id_);
|
||||
|
||||
LOG_SENSOR(" ", "Bus Voltage", this->bus_voltage_sensor_);
|
||||
LOG_SENSOR(" ", "Current", this->current_sensor_);
|
||||
LOG_SENSOR(" ", "Power", this->power_sensor_);
|
||||
|
||||
@@ -364,8 +364,10 @@ bool INA2XX::configure_shunt_() {
|
||||
ESP_LOGW(TAG, "Shunt value too high");
|
||||
}
|
||||
this->shunt_cal_ &= 0x7FFF;
|
||||
ESP_LOGV(TAG, "Given Rshunt=%f Ohm and Max_current=%.3f", this->shunt_resistance_ohm_, this->max_current_a_);
|
||||
ESP_LOGV(TAG, "New CURRENT_LSB=%f, SHUNT_CAL=%u", this->current_lsb_, this->shunt_cal_);
|
||||
ESP_LOGV(TAG,
|
||||
"Given Rshunt=%f Ohm and Max_current=%.3f\n"
|
||||
"New CURRENT_LSB=%f, SHUNT_CAL=%u",
|
||||
this->shunt_resistance_ohm_, this->max_current_a_, this->current_lsb_, this->shunt_cal_);
|
||||
return this->write_unsigned_16_(RegisterMap::REG_SHUNT_CAL, this->shunt_cal_);
|
||||
}
|
||||
|
||||
|
||||
@@ -146,19 +146,14 @@ void Lc709203f::update() {
|
||||
}
|
||||
|
||||
void Lc709203f::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "LC709203F:");
|
||||
LOG_I2C_DEVICE(this);
|
||||
|
||||
LOG_UPDATE_INTERVAL(this);
|
||||
ESP_LOGCONFIG(TAG,
|
||||
"LC709203F:\n"
|
||||
" Pack Size: %d mAH\n"
|
||||
" Pack APA: 0x%02X",
|
||||
this->pack_size_, this->apa_);
|
||||
|
||||
// This is only true if the pack_voltage_ is either 0x0000 or 0x0001. The config validator
|
||||
// should have already verified this.
|
||||
ESP_LOGCONFIG(TAG, " Pack Rated Voltage: 3.%sV", this->pack_voltage_ == 0x0000 ? "8" : "7");
|
||||
|
||||
" Pack APA: 0x%02X\n"
|
||||
" Pack Rated Voltage: 3.%sV",
|
||||
this->pack_size_, this->apa_, this->pack_voltage_ == 0x0000 ? "8" : "7");
|
||||
LOG_I2C_DEVICE(this);
|
||||
LOG_UPDATE_INTERVAL(this);
|
||||
LOG_SENSOR(" ", "Voltage", this->voltage_sensor_);
|
||||
LOG_SENSOR(" ", "Battery Remaining", this->battery_remaining_sensor_);
|
||||
|
||||
|
||||
@@ -130,8 +130,10 @@ void LEDCOutput::setup() {
|
||||
}
|
||||
int hpoint = ledc_angle_to_htop(this->phase_angle_, this->bit_depth_);
|
||||
|
||||
ESP_LOGV(TAG, "Configured frequency %f with a bit depth of %u bits", this->frequency_, this->bit_depth_);
|
||||
ESP_LOGV(TAG, "Angle of %.1f° results in hpoint %u", this->phase_angle_, hpoint);
|
||||
ESP_LOGV(TAG,
|
||||
"Configured frequency %f with a bit depth of %u bits\n"
|
||||
"Angle of %.1f° results in hpoint %u",
|
||||
this->frequency_, this->bit_depth_, this->phase_angle_, hpoint);
|
||||
|
||||
ledc_channel_config_t chan_conf{};
|
||||
chan_conf.gpio_num = this->pin_->get_pin();
|
||||
@@ -147,25 +149,30 @@ void LEDCOutput::setup() {
|
||||
}
|
||||
|
||||
void LEDCOutput::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "Output:");
|
||||
LOG_PIN(" Pin ", this->pin_);
|
||||
ESP_LOGCONFIG(TAG,
|
||||
"Output:\n"
|
||||
" Channel: %u\n"
|
||||
" PWM Frequency: %.1f Hz\n"
|
||||
" Phase angle: %.1f°\n"
|
||||
" Bit depth: %u",
|
||||
this->channel_, this->frequency_, this->phase_angle_, this->bit_depth_);
|
||||
ESP_LOGV(TAG, " Max frequency for bit depth: %f", ledc_max_frequency_for_bit_depth(this->bit_depth_));
|
||||
ESP_LOGV(TAG, " Min frequency for bit depth: %f",
|
||||
ledc_min_frequency_for_bit_depth(this->bit_depth_, (this->frequency_ < 100)));
|
||||
ESP_LOGV(TAG, " Max frequency for bit depth-1: %f", ledc_max_frequency_for_bit_depth(this->bit_depth_ - 1));
|
||||
ESP_LOGV(TAG, " Min frequency for bit depth-1: %f",
|
||||
ledc_min_frequency_for_bit_depth(this->bit_depth_ - 1, (this->frequency_ < 100)));
|
||||
ESP_LOGV(TAG, " Max frequency for bit depth+1: %f", ledc_max_frequency_for_bit_depth(this->bit_depth_ + 1));
|
||||
ESP_LOGV(TAG, " Min frequency for bit depth+1: %f",
|
||||
ledc_min_frequency_for_bit_depth(this->bit_depth_ + 1, (this->frequency_ < 100)));
|
||||
ESP_LOGV(TAG, " Max res bits: %d", MAX_RES_BITS);
|
||||
ESP_LOGV(TAG, " Clock frequency: %f", CLOCK_FREQUENCY);
|
||||
LOG_PIN(" Pin ", this->pin_);
|
||||
ESP_LOGV(TAG,
|
||||
" Max frequency for bit depth: %f\n"
|
||||
" Min frequency for bit depth: %f\n"
|
||||
" Max frequency for bit depth-1: %f\n"
|
||||
" Min frequency for bit depth-1: %f\n"
|
||||
" Max frequency for bit depth+1: %f\n"
|
||||
" Min frequency for bit depth+1: %f\n"
|
||||
" Max res bits: %d\n"
|
||||
" Clock frequency: %f",
|
||||
ledc_max_frequency_for_bit_depth(this->bit_depth_),
|
||||
ledc_min_frequency_for_bit_depth(this->bit_depth_, (this->frequency_ < 100)),
|
||||
ledc_max_frequency_for_bit_depth(this->bit_depth_ - 1),
|
||||
ledc_min_frequency_for_bit_depth(this->bit_depth_ - 1, (this->frequency_ < 100)),
|
||||
ledc_max_frequency_for_bit_depth(this->bit_depth_ + 1),
|
||||
ledc_min_frequency_for_bit_depth(this->bit_depth_ + 1, (this->frequency_ < 100)), MAX_RES_BITS,
|
||||
CLOCK_FREQUENCY);
|
||||
}
|
||||
|
||||
void LEDCOutput::update_frequency(float frequency) {
|
||||
|
||||
@@ -31,9 +31,11 @@ void LibreTinyPWM::setup() {
|
||||
}
|
||||
|
||||
void LibreTinyPWM::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "PWM Output:");
|
||||
ESP_LOGCONFIG(TAG,
|
||||
"PWM Output:\n"
|
||||
" Frequency: %.1f Hz",
|
||||
this->frequency_);
|
||||
LOG_PIN(" Pin ", this->pin_);
|
||||
ESP_LOGCONFIG(TAG, " Frequency: %.1f Hz", this->frequency_);
|
||||
}
|
||||
|
||||
void LibreTinyPWM::update_frequency(float frequency) {
|
||||
|
||||
@@ -26,9 +26,11 @@ void M5Stack8AngleComponent::setup() {
|
||||
}
|
||||
|
||||
void M5Stack8AngleComponent::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "M5STACK_8ANGLE:");
|
||||
ESP_LOGCONFIG(TAG,
|
||||
"M5STACK_8ANGLE:\n"
|
||||
" Firmware version: %d",
|
||||
this->fw_version_);
|
||||
LOG_I2C_DEVICE(this);
|
||||
ESP_LOGCONFIG(TAG, " Firmware version: %d ", this->fw_version_);
|
||||
}
|
||||
|
||||
float M5Stack8AngleComponent::read_knob_pos(uint8_t channel, AnalogBits bits) {
|
||||
|
||||
@@ -11,9 +11,11 @@ float MCP3204::get_setup_priority() const { return setup_priority::HARDWARE; }
|
||||
void MCP3204::setup() { this->spi_setup(); }
|
||||
|
||||
void MCP3204::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "MCP3204:");
|
||||
ESP_LOGCONFIG(TAG,
|
||||
"MCP3204:\n"
|
||||
" Reference Voltage: %.2fV",
|
||||
this->reference_voltage_);
|
||||
LOG_PIN(" CS Pin:", this->cs_);
|
||||
ESP_LOGCONFIG(TAG, " Reference Voltage: %.2fV", this->reference_voltage_);
|
||||
}
|
||||
|
||||
float MCP3204::read_data(uint8_t pin, bool differential) {
|
||||
|
||||
@@ -11,8 +11,10 @@ float MCP3204Sensor::get_setup_priority() const { return setup_priority::DATA; }
|
||||
|
||||
void MCP3204Sensor::dump_config() {
|
||||
LOG_SENSOR("", "MCP3204 Sensor", this);
|
||||
ESP_LOGCONFIG(TAG, " Pin: %u", this->pin_);
|
||||
ESP_LOGCONFIG(TAG, " Differential Mode: %s", YESNO(this->differential_mode_));
|
||||
ESP_LOGCONFIG(TAG,
|
||||
" Pin: %u\n"
|
||||
" Differential Mode: %s",
|
||||
this->pin_, YESNO(this->differential_mode_));
|
||||
LOG_UPDATE_INTERVAL(this);
|
||||
}
|
||||
float MCP3204Sensor::sample() { return this->parent_->read_data(this->pin_, this->differential_mode_); }
|
||||
|
||||
@@ -63,12 +63,12 @@ void MCP9600Component::setup() {
|
||||
}
|
||||
|
||||
void MCP9600Component::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "MCP9600:");
|
||||
ESP_LOGCONFIG(TAG,
|
||||
"MCP9600:\n"
|
||||
" Device ID: 0x%x",
|
||||
this->device_id_);
|
||||
LOG_I2C_DEVICE(this);
|
||||
LOG_UPDATE_INTERVAL(this);
|
||||
|
||||
ESP_LOGCONFIG(TAG, " Device ID: 0x%x", this->device_id_);
|
||||
|
||||
LOG_SENSOR(" ", "Hot Junction Temperature", this->hot_junction_sensor_);
|
||||
LOG_SENSOR(" ", "Cold Junction Temperature", this->cold_junction_sensor_);
|
||||
|
||||
|
||||
@@ -196,12 +196,12 @@ bool Modbus::parse_modbus_byte_(uint8_t byte) {
|
||||
}
|
||||
|
||||
void Modbus::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "Modbus:");
|
||||
LOG_PIN(" Flow Control Pin: ", this->flow_control_pin_);
|
||||
ESP_LOGCONFIG(TAG,
|
||||
"Modbus:\n"
|
||||
" Send Wait Time: %d ms\n"
|
||||
" CRC Disabled: %s",
|
||||
this->send_wait_time_, YESNO(this->disable_crc_));
|
||||
LOG_PIN(" Flow Control Pin: ", this->flow_control_pin_);
|
||||
}
|
||||
float Modbus::get_setup_priority() const {
|
||||
// After UART bus
|
||||
|
||||
@@ -17,10 +17,12 @@ static const uint16_t MANUFACTURER_ID = 0x000D;
|
||||
static constexpr size_t MOPEKA_MAX_LOG_BYTES = 32;
|
||||
|
||||
void MopekaStdCheck::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "Mopeka Std Check");
|
||||
ESP_LOGCONFIG(TAG, " Propane Butane mix: %.0f%%", this->propane_butane_mix_ * 100);
|
||||
ESP_LOGCONFIG(TAG, " Tank distance empty: %" PRIi32 "mm", this->empty_mm_);
|
||||
ESP_LOGCONFIG(TAG, " Tank distance full: %" PRIi32 "mm", this->full_mm_);
|
||||
ESP_LOGCONFIG(TAG,
|
||||
"Mopeka Std Check\n"
|
||||
" Propane Butane mix: %.0f%%\n"
|
||||
" Tank distance empty: %" PRIi32 "mm\n"
|
||||
" Tank distance full: %" PRIi32 "mm",
|
||||
this->propane_butane_mix_ * 100, this->empty_mm_, this->full_mm_);
|
||||
LOG_SENSOR(" ", "Level", this->level_);
|
||||
LOG_SENSOR(" ", "Temperature", this->temperature_);
|
||||
LOG_SENSOR(" ", "Battery Level", this->battery_level_);
|
||||
|
||||
@@ -166,10 +166,12 @@ void MQTTBackendESP32::mqtt_event_handler_(const Event &event) {
|
||||
case MQTT_EVENT_ERROR:
|
||||
ESP_LOGE(TAG, "MQTT_EVENT_ERROR");
|
||||
if (event.error_handle.error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
|
||||
ESP_LOGE(TAG, "Last error code reported from esp-tls: 0x%x", event.error_handle.esp_tls_last_esp_err);
|
||||
ESP_LOGE(TAG, "Last tls stack error number: 0x%x", event.error_handle.esp_tls_stack_err);
|
||||
ESP_LOGE(TAG, "Last captured errno : %d (%s)", event.error_handle.esp_transport_sock_errno,
|
||||
strerror(event.error_handle.esp_transport_sock_errno));
|
||||
ESP_LOGE(TAG,
|
||||
"Last error code reported from esp-tls: 0x%x\n"
|
||||
"Last tls stack error number: 0x%x\n"
|
||||
"Last captured errno : %d (%s)",
|
||||
event.error_handle.esp_tls_last_esp_err, event.error_handle.esp_tls_stack_err,
|
||||
event.error_handle.esp_transport_sock_errno, strerror(event.error_handle.esp_transport_sock_errno));
|
||||
} else if (event.error_handle.error_type == MQTT_ERROR_TYPE_CONNECTION_REFUSED) {
|
||||
ESP_LOGE(TAG, "Connection refused error: 0x%x", event.error_handle.connect_return_code);
|
||||
} else {
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -58,14 +58,14 @@ void MY9231OutputComponent::setup() {
|
||||
}
|
||||
}
|
||||
void MY9231OutputComponent::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "MY9231:");
|
||||
LOG_PIN(" DI Pin: ", this->pin_di_);
|
||||
LOG_PIN(" DCKI Pin: ", this->pin_dcki_);
|
||||
ESP_LOGCONFIG(TAG,
|
||||
"MY9231:\n"
|
||||
" Total number of channels: %u\n"
|
||||
" Number of chips: %u\n"
|
||||
" Bit depth: %u",
|
||||
this->num_channels_, this->num_chips_, this->bit_depth_);
|
||||
LOG_PIN(" DI Pin: ", this->pin_di_);
|
||||
LOG_PIN(" DCKI Pin: ", this->pin_dcki_);
|
||||
}
|
||||
void MY9231OutputComponent::loop() {
|
||||
if (!this->update_)
|
||||
|
||||
@@ -395,10 +395,8 @@ void OpenthermHub::dump_config() {
|
||||
this->write_initial_messages_(initial_messages);
|
||||
this->write_repeating_messages_(repeating_messages);
|
||||
|
||||
ESP_LOGCONFIG(TAG, "OpenTherm:");
|
||||
LOG_PIN(" In: ", this->in_pin_);
|
||||
LOG_PIN(" Out: ", this->out_pin_);
|
||||
ESP_LOGCONFIG(TAG,
|
||||
"OpenTherm:\n"
|
||||
" Sync mode: %s\n"
|
||||
" Sensors: %s\n"
|
||||
" Binary sensors: %s\n"
|
||||
@@ -409,6 +407,8 @@ void OpenthermHub::dump_config() {
|
||||
YESNO(this->sync_mode_), SHOW(OPENTHERM_SENSOR_LIST(ID, )), SHOW(OPENTHERM_BINARY_SENSOR_LIST(ID, )),
|
||||
SHOW(OPENTHERM_SWITCH_LIST(ID, )), SHOW(OPENTHERM_INPUT_SENSOR_LIST(ID, )),
|
||||
SHOW(OPENTHERM_OUTPUT_LIST(ID, )), SHOW(OPENTHERM_NUMBER_LIST(ID, )));
|
||||
LOG_PIN(" In: ", this->in_pin_);
|
||||
LOG_PIN(" Out: ", this->out_pin_);
|
||||
ESP_LOGCONFIG(TAG, " Initial requests:");
|
||||
for (auto type : initial_messages) {
|
||||
ESP_LOGCONFIG(TAG, " - %d (%s)", type, this->opentherm_->message_id_to_str(type));
|
||||
|
||||
@@ -126,9 +126,12 @@ void OpenThreadComponent::ot_main() {
|
||||
ESP_LOGE(TAG, "Failed to set OpenThread linkmode.");
|
||||
}
|
||||
link_mode_config = otThreadGetLinkMode(esp_openthread_get_instance());
|
||||
ESP_LOGD(TAG, "Link Mode Device Type: %s", link_mode_config.mDeviceType ? "true" : "false");
|
||||
ESP_LOGD(TAG, "Link Mode Network Data: %s", link_mode_config.mNetworkData ? "true" : "false");
|
||||
ESP_LOGD(TAG, "Link Mode RX On When Idle: %s", link_mode_config.mRxOnWhenIdle ? "true" : "false");
|
||||
ESP_LOGD(TAG,
|
||||
"Link Mode Device Type: %s\n"
|
||||
"Link Mode Network Data: %s\n"
|
||||
"Link Mode RX On When Idle: %s",
|
||||
link_mode_config.mDeviceType ? "true" : "false", link_mode_config.mNetworkData ? "true" : "false",
|
||||
link_mode_config.mRxOnWhenIdle ? "true" : "false");
|
||||
|
||||
// Run the main loop
|
||||
#if CONFIG_OPENTHREAD_CLI
|
||||
@@ -144,8 +147,8 @@ void OpenThreadComponent::ot_main() {
|
||||
// Make sure the length is 0 so we fallback to the configuration
|
||||
dataset.mLength = 0;
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Found OpenThread-managed dataset, ignoring esphome configuration");
|
||||
ESP_LOGI(TAG, "(set force_dataset: true to override)");
|
||||
ESP_LOGI(TAG, "Found OpenThread-managed dataset, ignoring esphome configuration\n"
|
||||
"(set force_dataset: true to override)");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {};
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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_);
|
||||
|
||||
@@ -245,6 +245,10 @@ enum WifiMinAuthMode : uint8_t {
|
||||
struct IDFWiFiEvent;
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIBRETINY
|
||||
struct LTWiFiEvent;
|
||||
#endif
|
||||
|
||||
/** Listener interface for WiFi IP state changes.
|
||||
*
|
||||
* Components can implement this interface to receive IP address updates
|
||||
@@ -583,6 +587,7 @@ class WiFiComponent : public Component {
|
||||
|
||||
#ifdef USE_LIBRETINY
|
||||
void wifi_event_callback_(arduino_event_id_t event, arduino_event_info_t info);
|
||||
void wifi_process_event_(LTWiFiEvent *event);
|
||||
void wifi_scan_done_callback_();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -3,12 +3,16 @@
|
||||
#ifdef USE_WIFI
|
||||
#ifdef USE_LIBRETINY
|
||||
|
||||
#include <cinttypes>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/dns.h"
|
||||
|
||||
#include <FreeRTOS.h>
|
||||
#include <queue.h>
|
||||
|
||||
#include "esphome/core/application.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
@@ -19,7 +23,68 @@ namespace esphome::wifi {
|
||||
|
||||
static const char *const TAG = "wifi_lt";
|
||||
|
||||
static bool s_sta_connecting = false; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
// Thread-safe event handling for LibreTiny WiFi
|
||||
//
|
||||
// LibreTiny's WiFi.onEvent() callback runs in the WiFi driver's thread context,
|
||||
// not the main ESPHome loop. Without synchronization, modifying shared state
|
||||
// (like connection status flags) from the callback causes race conditions:
|
||||
// - The main loop may never see state changes (values cached in registers)
|
||||
// - State changes may be visible in inconsistent order
|
||||
// - LibreTiny targets (BK7231, RTL8720) lack atomic instructions (no LDREX/STREX)
|
||||
//
|
||||
// Solution: Queue events in the callback and process them in the main loop.
|
||||
// This is the same approach used by ESP32 IDF's wifi_process_event_().
|
||||
// All state modifications happen in the main loop context, eliminating races.
|
||||
|
||||
static constexpr size_t EVENT_QUEUE_SIZE = 16; // Max pending WiFi events before overflow
|
||||
static QueueHandle_t s_event_queue = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
static volatile uint32_t s_event_queue_overflow_count =
|
||||
0; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
|
||||
// Event structure for queued WiFi events - contains a copy of event data
|
||||
// to avoid lifetime issues with the original event data from the callback
|
||||
struct LTWiFiEvent {
|
||||
arduino_event_id_t event_id;
|
||||
union {
|
||||
struct {
|
||||
uint8_t ssid[33];
|
||||
uint8_t ssid_len;
|
||||
uint8_t bssid[6];
|
||||
uint8_t channel;
|
||||
uint8_t authmode;
|
||||
} sta_connected;
|
||||
struct {
|
||||
uint8_t ssid[33];
|
||||
uint8_t ssid_len;
|
||||
uint8_t bssid[6];
|
||||
uint8_t reason;
|
||||
} sta_disconnected;
|
||||
struct {
|
||||
uint8_t old_mode;
|
||||
uint8_t new_mode;
|
||||
} sta_authmode_change;
|
||||
struct {
|
||||
uint32_t status;
|
||||
uint8_t number;
|
||||
uint8_t scan_id;
|
||||
} scan_done;
|
||||
struct {
|
||||
uint8_t mac[6];
|
||||
int rssi;
|
||||
} ap_probe_req;
|
||||
} data;
|
||||
};
|
||||
|
||||
// Connection state machine - only modified from main loop after queue processing
|
||||
enum class LTWiFiSTAState : uint8_t {
|
||||
IDLE, // Not connecting
|
||||
CONNECTING, // Connection in progress
|
||||
CONNECTED, // Successfully connected with IP
|
||||
ERROR_NOT_FOUND, // AP not found (probe failed)
|
||||
ERROR_FAILED, // Connection failed (auth, timeout, etc.)
|
||||
};
|
||||
|
||||
static LTWiFiSTAState s_sta_state = LTWiFiSTAState::IDLE; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
|
||||
bool WiFiComponent::wifi_mode_(optional<bool> sta, optional<bool> ap) {
|
||||
uint8_t current_mode = WiFi.getMode();
|
||||
@@ -136,7 +201,8 @@ bool WiFiComponent::wifi_sta_connect_(const WiFiAP &ap) {
|
||||
|
||||
this->wifi_apply_hostname_();
|
||||
|
||||
s_sta_connecting = true;
|
||||
// Reset state machine before connecting
|
||||
s_sta_state = LTWiFiSTAState::CONNECTING;
|
||||
|
||||
WiFiStatus status = WiFi.begin(ap.get_ssid().c_str(), ap.get_password().empty() ? NULL : ap.get_password().c_str(),
|
||||
ap.get_channel(), // 0 = auto
|
||||
@@ -271,16 +337,101 @@ const char *get_disconnect_reason_str(uint8_t reason) {
|
||||
using esphome_wifi_event_id_t = arduino_event_id_t;
|
||||
using esphome_wifi_event_info_t = arduino_event_info_t;
|
||||
|
||||
// Event callback - runs in WiFi driver thread context
|
||||
// Only queues events for processing in main loop, no logging or state changes here
|
||||
void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_wifi_event_info_t info) {
|
||||
if (s_event_queue == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Allocate on heap and fill directly to avoid extra memcpy
|
||||
auto *to_send = new LTWiFiEvent{}; // NOLINT(cppcoreguidelines-owning-memory)
|
||||
to_send->event_id = event;
|
||||
|
||||
// Copy event-specific data
|
||||
switch (event) {
|
||||
case ESPHOME_EVENT_ID_WIFI_STA_CONNECTED: {
|
||||
auto &it = info.wifi_sta_connected;
|
||||
to_send->data.sta_connected.ssid_len = it.ssid_len;
|
||||
memcpy(to_send->data.sta_connected.ssid, it.ssid,
|
||||
std::min(static_cast<size_t>(it.ssid_len), sizeof(to_send->data.sta_connected.ssid) - 1));
|
||||
memcpy(to_send->data.sta_connected.bssid, it.bssid, 6);
|
||||
to_send->data.sta_connected.channel = it.channel;
|
||||
to_send->data.sta_connected.authmode = it.authmode;
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_STA_DISCONNECTED: {
|
||||
auto &it = info.wifi_sta_disconnected;
|
||||
to_send->data.sta_disconnected.ssid_len = it.ssid_len;
|
||||
memcpy(to_send->data.sta_disconnected.ssid, it.ssid,
|
||||
std::min(static_cast<size_t>(it.ssid_len), sizeof(to_send->data.sta_disconnected.ssid) - 1));
|
||||
memcpy(to_send->data.sta_disconnected.bssid, it.bssid, 6);
|
||||
to_send->data.sta_disconnected.reason = it.reason;
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_STA_AUTHMODE_CHANGE: {
|
||||
auto &it = info.wifi_sta_authmode_change;
|
||||
to_send->data.sta_authmode_change.old_mode = it.old_mode;
|
||||
to_send->data.sta_authmode_change.new_mode = it.new_mode;
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_SCAN_DONE: {
|
||||
auto &it = info.wifi_scan_done;
|
||||
to_send->data.scan_done.status = it.status;
|
||||
to_send->data.scan_done.number = it.number;
|
||||
to_send->data.scan_done.scan_id = it.scan_id;
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_AP_PROBEREQRECVED: {
|
||||
auto &it = info.wifi_ap_probereqrecved;
|
||||
memcpy(to_send->data.ap_probe_req.mac, it.mac, 6);
|
||||
to_send->data.ap_probe_req.rssi = it.rssi;
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_AP_STACONNECTED: {
|
||||
auto &it = info.wifi_sta_connected;
|
||||
memcpy(to_send->data.sta_connected.bssid, it.bssid, 6);
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_AP_STADISCONNECTED: {
|
||||
auto &it = info.wifi_sta_disconnected;
|
||||
memcpy(to_send->data.sta_disconnected.bssid, it.bssid, 6);
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_READY:
|
||||
case ESPHOME_EVENT_ID_WIFI_STA_START:
|
||||
case ESPHOME_EVENT_ID_WIFI_STA_STOP:
|
||||
case ESPHOME_EVENT_ID_WIFI_STA_GOT_IP:
|
||||
case ESPHOME_EVENT_ID_WIFI_STA_GOT_IP6:
|
||||
case ESPHOME_EVENT_ID_WIFI_STA_LOST_IP:
|
||||
case ESPHOME_EVENT_ID_WIFI_AP_START:
|
||||
case ESPHOME_EVENT_ID_WIFI_AP_STOP:
|
||||
case ESPHOME_EVENT_ID_WIFI_AP_STAIPASSIGNED:
|
||||
// No additional data needed
|
||||
break;
|
||||
default:
|
||||
// Unknown event, don't queue
|
||||
delete to_send; // NOLINT(cppcoreguidelines-owning-memory)
|
||||
return;
|
||||
}
|
||||
|
||||
// Queue event (don't block if queue is full)
|
||||
if (xQueueSend(s_event_queue, &to_send, 0) != pdPASS) {
|
||||
delete to_send; // NOLINT(cppcoreguidelines-owning-memory)
|
||||
s_event_queue_overflow_count++;
|
||||
}
|
||||
}
|
||||
|
||||
// Process a single event from the queue - runs in main loop context
|
||||
void WiFiComponent::wifi_process_event_(LTWiFiEvent *event) {
|
||||
switch (event->event_id) {
|
||||
case ESPHOME_EVENT_ID_WIFI_READY: {
|
||||
ESP_LOGV(TAG, "Ready");
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_SCAN_DONE: {
|
||||
auto it = info.wifi_scan_done;
|
||||
ESP_LOGV(TAG, "Scan done: status=%u number=%u scan_id=%u", it.status, it.number, it.scan_id);
|
||||
|
||||
auto &it = event->data.scan_done;
|
||||
ESP_LOGV(TAG, "Scan done: status=%" PRIu32 " number=%u scan_id=%u", it.status, it.number, it.scan_id);
|
||||
this->wifi_scan_done_callback_();
|
||||
break;
|
||||
}
|
||||
@@ -291,14 +442,18 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_STA_STOP: {
|
||||
ESP_LOGV(TAG, "STA stop");
|
||||
s_sta_connecting = false;
|
||||
s_sta_state = LTWiFiSTAState::IDLE;
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_STA_CONNECTED: {
|
||||
auto it = info.wifi_sta_connected;
|
||||
auto &it = event->data.sta_connected;
|
||||
char bssid_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE];
|
||||
format_mac_addr_upper(it.bssid, bssid_buf);
|
||||
ESP_LOGV(TAG, "Connected ssid='%.*s' bssid=" LOG_SECRET("%s") " channel=%u, authmode=%s", it.ssid_len,
|
||||
(const char *) it.ssid, format_mac_address_pretty(it.bssid).c_str(), it.channel,
|
||||
get_auth_mode_str(it.authmode));
|
||||
(const char *) it.ssid, bssid_buf, it.channel, get_auth_mode_str(it.authmode));
|
||||
// Note: We don't set CONNECTED state here yet - wait for GOT_IP
|
||||
// This matches ESP32 IDF behavior where s_sta_connected is set but
|
||||
// wifi_sta_connect_status_() also checks got_ipv4_address_
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
for (auto *listener : this->connect_state_listeners_) {
|
||||
listener->on_wifi_connect_state(StringRef(it.ssid, it.ssid_len), it.bssid);
|
||||
@@ -306,6 +461,7 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
|
||||
// For static IP configurations, GOT_IP event may not fire, so notify IP listeners here
|
||||
#ifdef USE_WIFI_MANUAL_IP
|
||||
if (const WiFiAP *config = this->get_selected_sta_(); config && config->get_manual_ip().has_value()) {
|
||||
s_sta_state = LTWiFiSTAState::CONNECTED;
|
||||
for (auto *listener : this->ip_state_listeners_) {
|
||||
listener->on_ip_state(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1));
|
||||
}
|
||||
@@ -315,19 +471,18 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_STA_DISCONNECTED: {
|
||||
auto it = info.wifi_sta_disconnected;
|
||||
auto &it = event->data.sta_disconnected;
|
||||
|
||||
// LibreTiny can send spurious disconnect events with empty ssid/bssid during connection.
|
||||
// These are typically "Association Leave" events that don't indicate actual failures:
|
||||
// [W][wifi_lt]: Disconnected ssid='' bssid=00:00:00:00:00:00 reason='Association Leave'
|
||||
// [W][wifi_lt]: Disconnected ssid='' bssid=00:00:00:00:00:00 reason='Association Leave'
|
||||
// [V][wifi_lt]: Connected ssid='WIFI' bssid=... channel=3, authmode=WPA2 PSK
|
||||
// Without this check, the spurious events set s_sta_connecting=false, causing
|
||||
// wifi_sta_connect_status_() to return IDLE. The main loop then sees
|
||||
// "Unknown connection status 0" (wifi_component.cpp check_connecting_finished)
|
||||
// and calls retry_connect(), aborting a connection that may succeed moments later.
|
||||
// Real connection failures will have ssid/bssid populated, or we'll hit the connection timeout.
|
||||
if (it.ssid_len == 0 && s_sta_connecting) {
|
||||
// Without this check, the spurious events would transition state to ERROR_FAILED,
|
||||
// causing wifi_sta_connect_status_() to return an error. The main loop would then
|
||||
// call retry_connect(), aborting a connection that may succeed moments later.
|
||||
// Only ignore benign reasons - real failures like NO_AP_FOUND should still be processed.
|
||||
if (it.ssid_len == 0 && s_sta_state == LTWiFiSTAState::CONNECTING && it.reason != WIFI_REASON_NO_AP_FOUND) {
|
||||
ESP_LOGV(TAG, "Ignoring disconnect event with empty ssid while connecting (reason=%s)",
|
||||
get_disconnect_reason_str(it.reason));
|
||||
break;
|
||||
@@ -336,11 +491,13 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
|
||||
if (it.reason == WIFI_REASON_NO_AP_FOUND) {
|
||||
ESP_LOGW(TAG, "Disconnected ssid='%.*s' reason='Probe Request Unsuccessful'", it.ssid_len,
|
||||
(const char *) it.ssid);
|
||||
s_sta_state = LTWiFiSTAState::ERROR_NOT_FOUND;
|
||||
} else {
|
||||
char bssid_s[18];
|
||||
char bssid_s[MAC_ADDRESS_PRETTY_BUFFER_SIZE];
|
||||
format_mac_addr_upper(it.bssid, bssid_s);
|
||||
ESP_LOGW(TAG, "Disconnected ssid='%.*s' bssid=" LOG_SECRET("%s") " reason='%s'", it.ssid_len,
|
||||
(const char *) it.ssid, bssid_s, get_disconnect_reason_str(it.reason));
|
||||
s_sta_state = LTWiFiSTAState::ERROR_FAILED;
|
||||
}
|
||||
|
||||
uint8_t reason = it.reason;
|
||||
@@ -351,7 +508,6 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
|
||||
this->error_from_callback_ = true;
|
||||
}
|
||||
|
||||
s_sta_connecting = false;
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
static constexpr uint8_t EMPTY_BSSID[6] = {};
|
||||
for (auto *listener : this->connect_state_listeners_) {
|
||||
@@ -361,24 +517,22 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_STA_AUTHMODE_CHANGE: {
|
||||
auto it = info.wifi_sta_authmode_change;
|
||||
auto &it = event->data.sta_authmode_change;
|
||||
ESP_LOGV(TAG, "Authmode Change old=%s new=%s", get_auth_mode_str(it.old_mode), get_auth_mode_str(it.new_mode));
|
||||
// Mitigate CVE-2020-12638
|
||||
// https://lbsfilm.at/blog/wpa2-authenticationmode-downgrade-in-espressif-microprocessors
|
||||
if (it.old_mode != WIFI_AUTH_OPEN && it.new_mode == WIFI_AUTH_OPEN) {
|
||||
ESP_LOGW(TAG, "Potential Authmode downgrade detected, disconnecting");
|
||||
// we can't call retry_connect() from this context, so disconnect immediately
|
||||
// and notify main thread with error_from_callback_
|
||||
WiFi.disconnect();
|
||||
this->error_from_callback_ = true;
|
||||
s_sta_state = LTWiFiSTAState::ERROR_FAILED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_STA_GOT_IP: {
|
||||
// auto it = info.got_ip.ip_info;
|
||||
ESP_LOGV(TAG, "static_ip=%s gateway=%s", format_ip4_addr(WiFi.localIP()).c_str(),
|
||||
format_ip4_addr(WiFi.gatewayIP()).c_str());
|
||||
s_sta_connecting = false;
|
||||
s_sta_state = LTWiFiSTAState::CONNECTED;
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
for (auto *listener : this->ip_state_listeners_) {
|
||||
listener->on_ip_state(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1));
|
||||
@@ -387,7 +541,6 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_STA_GOT_IP6: {
|
||||
// auto it = info.got_ip.ip_info;
|
||||
ESP_LOGV(TAG, "Got IPv6");
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
for (auto *listener : this->ip_state_listeners_) {
|
||||
@@ -398,6 +551,7 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_STA_LOST_IP: {
|
||||
ESP_LOGV(TAG, "Lost IP");
|
||||
// Don't change state to IDLE - let the disconnect event handle that
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_AP_START: {
|
||||
@@ -409,15 +563,21 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_AP_STACONNECTED: {
|
||||
auto it = info.wifi_sta_connected;
|
||||
auto &mac = it.bssid;
|
||||
ESP_LOGV(TAG, "AP client connected MAC=%s", format_mac_address_pretty(mac).c_str());
|
||||
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
|
||||
auto &it = event->data.sta_connected;
|
||||
char mac_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE];
|
||||
format_mac_addr_upper(it.bssid, mac_buf);
|
||||
ESP_LOGV(TAG, "AP client connected MAC=%s", mac_buf);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_AP_STADISCONNECTED: {
|
||||
auto it = info.wifi_sta_disconnected;
|
||||
auto &mac = it.bssid;
|
||||
ESP_LOGV(TAG, "AP client disconnected MAC=%s", format_mac_address_pretty(mac).c_str());
|
||||
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
|
||||
auto &it = event->data.sta_disconnected;
|
||||
char mac_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE];
|
||||
format_mac_addr_upper(it.bssid, mac_buf);
|
||||
ESP_LOGV(TAG, "AP client disconnected MAC=%s", mac_buf);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_AP_STAIPASSIGNED: {
|
||||
@@ -425,8 +585,12 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
|
||||
break;
|
||||
}
|
||||
case ESPHOME_EVENT_ID_WIFI_AP_PROBEREQRECVED: {
|
||||
auto it = info.wifi_ap_probereqrecved;
|
||||
ESP_LOGVV(TAG, "AP receive Probe Request MAC=%s RSSI=%d", format_mac_address_pretty(it.mac).c_str(), it.rssi);
|
||||
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE
|
||||
auto &it = event->data.ap_probe_req;
|
||||
char mac_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE];
|
||||
format_mac_addr_upper(it.mac, mac_buf);
|
||||
ESP_LOGVV(TAG, "AP receive Probe Request MAC=%s RSSI=%d", mac_buf, it.rssi);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -434,23 +598,35 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
|
||||
}
|
||||
}
|
||||
void WiFiComponent::wifi_pre_setup_() {
|
||||
// Create event queue for thread-safe event handling
|
||||
// Events are pushed from WiFi callback thread and processed in main loop
|
||||
s_event_queue = xQueueCreate(EVENT_QUEUE_SIZE, sizeof(LTWiFiEvent *));
|
||||
if (s_event_queue == nullptr) {
|
||||
ESP_LOGE(TAG, "Failed to create event queue");
|
||||
return;
|
||||
}
|
||||
|
||||
auto f = std::bind(&WiFiComponent::wifi_event_callback_, this, std::placeholders::_1, std::placeholders::_2);
|
||||
WiFi.onEvent(f);
|
||||
// Make sure WiFi is in clean state before anything starts
|
||||
this->wifi_mode_(false, false);
|
||||
}
|
||||
WiFiSTAConnectStatus WiFiComponent::wifi_sta_connect_status_() {
|
||||
auto status = WiFi.status();
|
||||
if (status == WL_CONNECTED) {
|
||||
return WiFiSTAConnectStatus::CONNECTED;
|
||||
} else if (status == WL_CONNECT_FAILED || status == WL_CONNECTION_LOST) {
|
||||
return WiFiSTAConnectStatus::ERROR_CONNECT_FAILED;
|
||||
} else if (status == WL_NO_SSID_AVAIL) {
|
||||
return WiFiSTAConnectStatus::ERROR_NETWORK_NOT_FOUND;
|
||||
} else if (s_sta_connecting) {
|
||||
return WiFiSTAConnectStatus::CONNECTING;
|
||||
// Use state machine instead of querying WiFi.status() directly
|
||||
// State is updated in main loop from queued events, ensuring thread safety
|
||||
switch (s_sta_state) {
|
||||
case LTWiFiSTAState::CONNECTED:
|
||||
return WiFiSTAConnectStatus::CONNECTED;
|
||||
case LTWiFiSTAState::ERROR_NOT_FOUND:
|
||||
return WiFiSTAConnectStatus::ERROR_NETWORK_NOT_FOUND;
|
||||
case LTWiFiSTAState::ERROR_FAILED:
|
||||
return WiFiSTAConnectStatus::ERROR_CONNECT_FAILED;
|
||||
case LTWiFiSTAState::CONNECTING:
|
||||
return WiFiSTAConnectStatus::CONNECTING;
|
||||
case LTWiFiSTAState::IDLE:
|
||||
default:
|
||||
return WiFiSTAConnectStatus::IDLE;
|
||||
}
|
||||
return WiFiSTAConnectStatus::IDLE;
|
||||
}
|
||||
bool WiFiComponent::wifi_scan_start_(bool passive) {
|
||||
// enable STA
|
||||
@@ -534,9 +710,9 @@ network::IPAddress WiFiComponent::wifi_soft_ap_ip() { return {WiFi.softAPIP()};
|
||||
#endif // USE_WIFI_AP
|
||||
|
||||
bool WiFiComponent::wifi_disconnect_() {
|
||||
// Clear connecting flag first so disconnect events aren't ignored
|
||||
// Reset state first so disconnect events aren't ignored
|
||||
// and wifi_sta_connect_status_() returns IDLE instead of CONNECTING
|
||||
s_sta_connecting = false;
|
||||
s_sta_state = LTWiFiSTAState::IDLE;
|
||||
return WiFi.disconnect();
|
||||
}
|
||||
|
||||
@@ -563,7 +739,29 @@ int32_t WiFiComponent::get_wifi_channel() { return WiFi.channel(); }
|
||||
network::IPAddress WiFiComponent::wifi_subnet_mask_() { return {WiFi.subnetMask()}; }
|
||||
network::IPAddress WiFiComponent::wifi_gateway_ip_() { return {WiFi.gatewayIP()}; }
|
||||
network::IPAddress WiFiComponent::wifi_dns_ip_(int num) { return {WiFi.dnsIP(num)}; }
|
||||
void WiFiComponent::wifi_loop_() {}
|
||||
void WiFiComponent::wifi_loop_() {
|
||||
// Process all pending events from the queue
|
||||
if (s_event_queue == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for dropped events due to queue overflow
|
||||
if (s_event_queue_overflow_count > 0) {
|
||||
ESP_LOGW(TAG, "Event queue overflow, %" PRIu32 " events dropped", s_event_queue_overflow_count);
|
||||
s_event_queue_overflow_count = 0;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
LTWiFiEvent *event;
|
||||
if (xQueueReceive(s_event_queue, &event, 0) != pdTRUE) {
|
||||
// No more events
|
||||
break;
|
||||
}
|
||||
|
||||
wifi_process_event_(event);
|
||||
delete event; // NOLINT(cppcoreguidelines-owning-memory)
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace esphome::wifi
|
||||
#endif // USE_LIBRETINY
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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_);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user