mirror of
https://github.com/esphome/esphome.git
synced 2026-01-19 17:46:23 -07:00
Compare commits
6 Commits
filter-pla
...
copilot/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c4f265796c | ||
|
|
2c16d6eb9a | ||
|
|
f32ecb73db | ||
|
|
484087f780 | ||
|
|
d91eed1411 | ||
|
|
47714a1745 |
@@ -37,7 +37,6 @@ from esphome.const import (
|
||||
__version__,
|
||||
)
|
||||
from esphome.core import CORE, HexInt, TimePeriod
|
||||
from esphome.coroutine import CoroPriority, coroutine_with_priority
|
||||
import esphome.final_validate as fv
|
||||
from esphome.helpers import copy_file_if_changed, write_file_if_changed
|
||||
from esphome.types import ConfigType
|
||||
@@ -263,32 +262,15 @@ def add_idf_component(
|
||||
"deprecated and will be removed in ESPHome 2026.1. If you are seeing this, report "
|
||||
"an issue to the external_component author and ask them to update it."
|
||||
)
|
||||
components_registry = CORE.data[KEY_ESP32][KEY_COMPONENTS]
|
||||
if components:
|
||||
for comp in components:
|
||||
existing = components_registry.get(comp)
|
||||
if existing and existing.get(KEY_REF) != ref:
|
||||
_LOGGER.warning(
|
||||
"IDF component %s version conflict %s replaced by %s",
|
||||
comp,
|
||||
existing.get(KEY_REF),
|
||||
ref,
|
||||
)
|
||||
components_registry[comp] = {
|
||||
CORE.data[KEY_ESP32][KEY_COMPONENTS][comp] = {
|
||||
KEY_REPO: repo,
|
||||
KEY_REF: ref,
|
||||
KEY_PATH: f"{path}/{comp}" if path else comp,
|
||||
}
|
||||
else:
|
||||
existing = components_registry.get(name)
|
||||
if existing and existing.get(KEY_REF) != ref:
|
||||
_LOGGER.warning(
|
||||
"IDF component %s version conflict %s replaced by %s",
|
||||
name,
|
||||
existing.get(KEY_REF),
|
||||
ref,
|
||||
)
|
||||
components_registry[name] = {
|
||||
CORE.data[KEY_ESP32][KEY_COMPONENTS][name] = {
|
||||
KEY_REPO: repo,
|
||||
KEY_REF: ref,
|
||||
KEY_PATH: path,
|
||||
@@ -610,14 +592,6 @@ def require_vfs_dir() -> None:
|
||||
CORE.data[KEY_VFS_DIR_REQUIRED] = True
|
||||
|
||||
|
||||
def _parse_idf_component(value: str) -> ConfigType:
|
||||
"""Parse IDF component shorthand syntax like 'owner/component^version'"""
|
||||
if "^" not in value:
|
||||
raise cv.Invalid(f"Invalid IDF component shorthand '{value}'")
|
||||
name, ref = value.split("^", 1)
|
||||
return {CONF_NAME: name, CONF_REF: ref}
|
||||
|
||||
|
||||
def _validate_idf_component(config: ConfigType) -> ConfigType:
|
||||
"""Validate IDF component config and warn about deprecated options."""
|
||||
if CONF_REFRESH in config:
|
||||
@@ -685,19 +659,14 @@ FRAMEWORK_SCHEMA = cv.Schema(
|
||||
),
|
||||
cv.Optional(CONF_COMPONENTS, default=[]): cv.ensure_list(
|
||||
cv.All(
|
||||
cv.Any(
|
||||
cv.All(cv.string_strict, _parse_idf_component),
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_NAME): cv.string_strict,
|
||||
cv.Optional(CONF_SOURCE): cv.git_ref,
|
||||
cv.Optional(CONF_REF): cv.string,
|
||||
cv.Optional(CONF_PATH): cv.string,
|
||||
cv.Optional(CONF_REFRESH): cv.All(
|
||||
cv.string, cv.source_refresh
|
||||
),
|
||||
}
|
||||
),
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_NAME): cv.string_strict,
|
||||
cv.Optional(CONF_SOURCE): cv.git_ref,
|
||||
cv.Optional(CONF_REF): cv.string,
|
||||
cv.Optional(CONF_PATH): cv.string,
|
||||
cv.Optional(CONF_REFRESH): cv.All(cv.string, cv.source_refresh),
|
||||
}
|
||||
),
|
||||
_validate_idf_component,
|
||||
)
|
||||
@@ -882,18 +851,6 @@ def _configure_lwip_max_sockets(conf: dict) -> None:
|
||||
add_idf_sdkconfig_option("CONFIG_LWIP_MAX_SOCKETS", max_sockets)
|
||||
|
||||
|
||||
@coroutine_with_priority(CoroPriority.FINAL)
|
||||
async def _add_yaml_idf_components(components: list[ConfigType]):
|
||||
"""Add IDF components from YAML config with final priority to override code-added components."""
|
||||
for component in components:
|
||||
add_idf_component(
|
||||
name=component[CONF_NAME],
|
||||
repo=component.get(CONF_SOURCE),
|
||||
ref=component.get(CONF_REF),
|
||||
path=component.get(CONF_PATH),
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
cg.add_platformio_option("board", config[CONF_BOARD])
|
||||
cg.add_platformio_option("board_upload.flash_size", config[CONF_FLASH_SIZE])
|
||||
@@ -1140,10 +1097,13 @@ async def to_code(config):
|
||||
for name, value in conf[CONF_SDKCONFIG_OPTIONS].items():
|
||||
add_idf_sdkconfig_option(name, RawSdkconfigValue(value))
|
||||
|
||||
# Components from YAML are added in a separate coroutine with FINAL priority
|
||||
# Schedule it to run after all other components
|
||||
if conf[CONF_COMPONENTS]:
|
||||
CORE.add_job(_add_yaml_idf_components, conf[CONF_COMPONENTS])
|
||||
for component in conf[CONF_COMPONENTS]:
|
||||
add_idf_component(
|
||||
name=component[CONF_NAME],
|
||||
repo=component.get(CONF_SOURCE),
|
||||
ref=component.get(CONF_REF),
|
||||
path=component.get(CONF_PATH),
|
||||
)
|
||||
|
||||
|
||||
APP_PARTITION_SIZES = {
|
||||
|
||||
@@ -64,15 +64,21 @@ void MR24HPC1Component::dump_config() {
|
||||
void MR24HPC1Component::setup() {
|
||||
this->check_uart_settings(115200);
|
||||
|
||||
#ifdef USE_NUMBER
|
||||
if (this->custom_mode_number_ != nullptr) {
|
||||
this->custom_mode_number_->publish_state(0); // Zero out the custom mode
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_SENSOR
|
||||
if (this->custom_mode_num_sensor_ != nullptr) {
|
||||
this->custom_mode_num_sensor_->publish_state(0);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
if (this->custom_mode_end_text_sensor_ != nullptr) {
|
||||
this->custom_mode_end_text_sensor_->publish_state("Not in custom mode");
|
||||
}
|
||||
#endif
|
||||
this->set_custom_end_mode();
|
||||
this->poll_time_base_func_check_ = true;
|
||||
this->check_dev_inf_sign_ = true;
|
||||
@@ -352,6 +358,7 @@ void MR24HPC1Component::r24_split_data_frame_(uint8_t value) {
|
||||
}
|
||||
|
||||
// Parses data frames related to product information
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
void MR24HPC1Component::r24_frame_parse_product_information_(uint8_t *data) {
|
||||
uint16_t product_len = encode_uint16(data[FRAME_COMMAND_WORD_INDEX + 1], data[FRAME_COMMAND_WORD_INDEX + 2]);
|
||||
if (data[FRAME_COMMAND_WORD_INDEX] == COMMAND_PRODUCT_MODE) {
|
||||
@@ -389,20 +396,29 @@ void MR24HPC1Component::r24_frame_parse_product_information_(uint8_t *data) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Parsing the underlying open parameters
|
||||
void MR24HPC1Component::r24_frame_parse_open_underlying_information_(uint8_t *data) {
|
||||
if (data[FRAME_COMMAND_WORD_INDEX] == 0x00) {
|
||||
uint8_t cmd = data[FRAME_COMMAND_WORD_INDEX];
|
||||
|
||||
if (cmd == 0x00) {
|
||||
#ifdef USE_SWITCH
|
||||
if (this->underlying_open_function_switch_ != nullptr) {
|
||||
this->underlying_open_function_switch_->publish_state(
|
||||
data[FRAME_DATA_INDEX]); // Underlying Open Parameter Switch Status Updates
|
||||
}
|
||||
#endif
|
||||
if (data[FRAME_DATA_INDEX]) {
|
||||
this->s_output_info_switch_flag_ = OUTPUT_SWITCH_ON;
|
||||
} else {
|
||||
this->s_output_info_switch_flag_ = OUTPUT_SWTICH_OFF;
|
||||
}
|
||||
} else if (data[FRAME_COMMAND_WORD_INDEX] == 0x01) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd == 0x01) {
|
||||
#ifdef USE_SENSOR
|
||||
if (this->custom_spatial_static_value_sensor_ != nullptr) {
|
||||
this->custom_spatial_static_value_sensor_->publish_state(data[FRAME_DATA_INDEX]);
|
||||
}
|
||||
@@ -418,72 +434,125 @@ void MR24HPC1Component::r24_frame_parse_open_underlying_information_(uint8_t *da
|
||||
if (this->custom_motion_speed_sensor_ != nullptr) {
|
||||
this->custom_motion_speed_sensor_->publish_state((data[FRAME_DATA_INDEX + 4] - 10) * 0.5f);
|
||||
}
|
||||
} else if ((data[FRAME_COMMAND_WORD_INDEX] == 0x06) || (data[FRAME_COMMAND_WORD_INDEX] == 0x86)) {
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd == 0x06 || cmd == 0x86) {
|
||||
// none:0x00 close_to:0x01 far_away:0x02
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
if ((this->keep_away_text_sensor_ != nullptr) && (data[FRAME_DATA_INDEX] < 3)) {
|
||||
this->keep_away_text_sensor_->publish_state(S_KEEP_AWAY_STR[data[FRAME_DATA_INDEX]]);
|
||||
}
|
||||
} else if ((this->movement_signs_sensor_ != nullptr) &&
|
||||
((data[FRAME_COMMAND_WORD_INDEX] == 0x07) || (data[FRAME_COMMAND_WORD_INDEX] == 0x87))) {
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef USE_SENSOR
|
||||
if ((cmd == 0x07 || cmd == 0x87) && this->movement_signs_sensor_ != nullptr) {
|
||||
this->movement_signs_sensor_->publish_state(data[FRAME_DATA_INDEX]);
|
||||
} else if ((this->existence_threshold_number_ != nullptr) &&
|
||||
((data[FRAME_COMMAND_WORD_INDEX] == 0x08) || (data[FRAME_COMMAND_WORD_INDEX] == 0x88))) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_NUMBER
|
||||
if ((cmd == 0x08 || cmd == 0x88) && this->existence_threshold_number_ != nullptr) {
|
||||
this->existence_threshold_number_->publish_state(data[FRAME_DATA_INDEX]);
|
||||
} else if ((this->motion_threshold_number_ != nullptr) &&
|
||||
((data[FRAME_COMMAND_WORD_INDEX] == 0x09) || (data[FRAME_COMMAND_WORD_INDEX] == 0x89))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((cmd == 0x09 || cmd == 0x89) && this->motion_threshold_number_ != nullptr) {
|
||||
this->motion_threshold_number_->publish_state(data[FRAME_DATA_INDEX]);
|
||||
} else if ((this->existence_boundary_select_ != nullptr) &&
|
||||
((data[FRAME_COMMAND_WORD_INDEX] == 0x0a) || (data[FRAME_COMMAND_WORD_INDEX] == 0x8a))) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SELECT
|
||||
if ((cmd == 0x0a || cmd == 0x8a) && this->existence_boundary_select_ != nullptr) {
|
||||
if (this->existence_boundary_select_->has_index(data[FRAME_DATA_INDEX] - 1)) {
|
||||
this->existence_boundary_select_->publish_state(data[FRAME_DATA_INDEX] - 1);
|
||||
}
|
||||
} else if ((this->motion_boundary_select_ != nullptr) &&
|
||||
((data[FRAME_COMMAND_WORD_INDEX] == 0x0b) || (data[FRAME_COMMAND_WORD_INDEX] == 0x8b))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((cmd == 0x0b || cmd == 0x8b) && this->motion_boundary_select_ != nullptr) {
|
||||
if (this->motion_boundary_select_->has_index(data[FRAME_DATA_INDEX] - 1)) {
|
||||
this->motion_boundary_select_->publish_state(data[FRAME_DATA_INDEX] - 1);
|
||||
}
|
||||
} else if ((this->motion_trigger_number_ != nullptr) &&
|
||||
((data[FRAME_COMMAND_WORD_INDEX] == 0x0c) || (data[FRAME_COMMAND_WORD_INDEX] == 0x8c))) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_NUMBER
|
||||
if ((cmd == 0x0c || cmd == 0x8c) && this->motion_trigger_number_ != nullptr) {
|
||||
uint32_t motion_trigger_time = encode_uint32(data[FRAME_DATA_INDEX], data[FRAME_DATA_INDEX + 1],
|
||||
data[FRAME_DATA_INDEX + 2], data[FRAME_DATA_INDEX + 3]);
|
||||
this->motion_trigger_number_->publish_state(motion_trigger_time);
|
||||
} else if ((this->motion_to_rest_number_ != nullptr) &&
|
||||
((data[FRAME_COMMAND_WORD_INDEX] == 0x0d) || (data[FRAME_COMMAND_WORD_INDEX] == 0x8d))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((cmd == 0x0d || cmd == 0x8d) && this->motion_to_rest_number_ != nullptr) {
|
||||
uint32_t move_to_rest_time = encode_uint32(data[FRAME_DATA_INDEX], data[FRAME_DATA_INDEX + 1],
|
||||
data[FRAME_DATA_INDEX + 2], data[FRAME_DATA_INDEX + 3]);
|
||||
this->motion_to_rest_number_->publish_state(move_to_rest_time);
|
||||
} else if ((this->custom_unman_time_number_ != nullptr) &&
|
||||
((data[FRAME_COMMAND_WORD_INDEX] == 0x0e) || (data[FRAME_COMMAND_WORD_INDEX] == 0x8e))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((cmd == 0x0e || cmd == 0x8e) && this->custom_unman_time_number_ != nullptr) {
|
||||
uint32_t enter_unmanned_time = encode_uint32(data[FRAME_DATA_INDEX], data[FRAME_DATA_INDEX + 1],
|
||||
data[FRAME_DATA_INDEX + 2], data[FRAME_DATA_INDEX + 3]);
|
||||
float custom_unmanned_time = enter_unmanned_time / 1000.0;
|
||||
this->custom_unman_time_number_->publish_state(custom_unmanned_time);
|
||||
} else if (data[FRAME_COMMAND_WORD_INDEX] == 0x80) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cmd == 0x80) {
|
||||
if (data[FRAME_DATA_INDEX]) {
|
||||
this->s_output_info_switch_flag_ = OUTPUT_SWITCH_ON;
|
||||
} else {
|
||||
this->s_output_info_switch_flag_ = OUTPUT_SWTICH_OFF;
|
||||
}
|
||||
#ifdef USE_SWITCH
|
||||
if (this->underlying_open_function_switch_ != nullptr) {
|
||||
this->underlying_open_function_switch_->publish_state(data[FRAME_DATA_INDEX]);
|
||||
}
|
||||
} else if ((this->custom_spatial_static_value_sensor_ != nullptr) && (data[FRAME_COMMAND_WORD_INDEX] == 0x81)) {
|
||||
this->custom_spatial_static_value_sensor_->publish_state(data[FRAME_DATA_INDEX]);
|
||||
} else if ((this->custom_spatial_motion_value_sensor_ != nullptr) && (data[FRAME_COMMAND_WORD_INDEX] == 0x82)) {
|
||||
this->custom_spatial_motion_value_sensor_->publish_state(data[FRAME_DATA_INDEX]);
|
||||
} else if ((this->custom_presence_of_detection_sensor_ != nullptr) && (data[FRAME_COMMAND_WORD_INDEX] == 0x83)) {
|
||||
this->custom_presence_of_detection_sensor_->publish_state(
|
||||
S_PRESENCE_OF_DETECTION_RANGE_STR[data[FRAME_DATA_INDEX]]);
|
||||
} else if ((this->custom_motion_distance_sensor_ != nullptr) && (data[FRAME_COMMAND_WORD_INDEX] == 0x84)) {
|
||||
this->custom_motion_distance_sensor_->publish_state(data[FRAME_DATA_INDEX] * 0.5f);
|
||||
} else if ((this->custom_motion_speed_sensor_ != nullptr) && (data[FRAME_COMMAND_WORD_INDEX] == 0x85)) {
|
||||
this->custom_motion_speed_sensor_->publish_state((data[FRAME_DATA_INDEX] - 10) * 0.5f);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef USE_SENSOR
|
||||
if (cmd == 0x81 && this->custom_spatial_static_value_sensor_ != nullptr) {
|
||||
this->custom_spatial_static_value_sensor_->publish_state(data[FRAME_DATA_INDEX]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd == 0x82 && this->custom_spatial_motion_value_sensor_ != nullptr) {
|
||||
this->custom_spatial_motion_value_sensor_->publish_state(data[FRAME_DATA_INDEX]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd == 0x83 && this->custom_presence_of_detection_sensor_ != nullptr) {
|
||||
this->custom_presence_of_detection_sensor_->publish_state(S_PRESENCE_OF_DETECTION_RANGE_STR[data[FRAME_DATA_INDEX]]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd == 0x84 && this->custom_motion_distance_sensor_ != nullptr) {
|
||||
this->custom_motion_distance_sensor_->publish_state(data[FRAME_DATA_INDEX] * 0.5f);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd == 0x85 && this->custom_motion_speed_sensor_ != nullptr) {
|
||||
this->custom_motion_speed_sensor_->publish_state((data[FRAME_DATA_INDEX] - 10) * 0.5f);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MR24HPC1Component::r24_parse_data_frame_(uint8_t *data, uint8_t len) {
|
||||
switch (data[FRAME_CONTROL_WORD_INDEX]) {
|
||||
case 0x01: {
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
if ((this->heartbeat_state_text_sensor_ != nullptr) && (data[FRAME_COMMAND_WORD_INDEX] == 0x01)) {
|
||||
this->heartbeat_state_text_sensor_->publish_state("Equipment Normal");
|
||||
} else if (data[FRAME_COMMAND_WORD_INDEX] == 0x02) {
|
||||
@@ -491,9 +560,16 @@ void MR24HPC1Component::r24_parse_data_frame_(uint8_t *data, uint8_t len) {
|
||||
} else if (this->heartbeat_state_text_sensor_ != nullptr) {
|
||||
this->heartbeat_state_text_sensor_->publish_state("Equipment Abnormal");
|
||||
}
|
||||
#else
|
||||
if (data[FRAME_COMMAND_WORD_INDEX] == 0x02) {
|
||||
ESP_LOGD(TAG, "Reply: query restart packet");
|
||||
}
|
||||
#endif
|
||||
} break;
|
||||
case 0x02: {
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
this->r24_frame_parse_product_information_(data);
|
||||
#endif
|
||||
} break;
|
||||
case 0x05: {
|
||||
this->r24_frame_parse_work_status_(data);
|
||||
@@ -511,87 +587,152 @@ void MR24HPC1Component::r24_parse_data_frame_(uint8_t *data, uint8_t len) {
|
||||
}
|
||||
|
||||
void MR24HPC1Component::r24_frame_parse_work_status_(uint8_t *data) {
|
||||
if (data[FRAME_COMMAND_WORD_INDEX] == 0x01) {
|
||||
uint8_t cmd = data[FRAME_COMMAND_WORD_INDEX];
|
||||
|
||||
if (cmd == 0x01) {
|
||||
ESP_LOGD(TAG, "Reply: get radar init status 0x%02X", data[FRAME_DATA_INDEX]);
|
||||
} else if (data[FRAME_COMMAND_WORD_INDEX] == 0x07) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd == 0x07) {
|
||||
#ifdef USE_SELECT
|
||||
if ((this->scene_mode_select_ != nullptr) && (this->scene_mode_select_->has_index(data[FRAME_DATA_INDEX]))) {
|
||||
this->scene_mode_select_->publish_state(data[FRAME_DATA_INDEX]);
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Select has index offset %d Error", data[FRAME_DATA_INDEX]);
|
||||
}
|
||||
} else if ((this->sensitivity_number_ != nullptr) &&
|
||||
((data[FRAME_COMMAND_WORD_INDEX] == 0x08) || (data[FRAME_COMMAND_WORD_INDEX] == 0x88))) {
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef USE_NUMBER
|
||||
if ((cmd == 0x08 || cmd == 0x88) && this->sensitivity_number_ != nullptr) {
|
||||
// 1-3
|
||||
this->sensitivity_number_->publish_state(data[FRAME_DATA_INDEX]);
|
||||
} else if (data[FRAME_COMMAND_WORD_INDEX] == 0x09) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cmd == 0x09) {
|
||||
// 1-4
|
||||
#ifdef USE_SENSOR
|
||||
if (this->custom_mode_num_sensor_ != nullptr) {
|
||||
this->custom_mode_num_sensor_->publish_state(data[FRAME_DATA_INDEX]);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_NUMBER
|
||||
if (this->custom_mode_number_ != nullptr) {
|
||||
this->custom_mode_number_->publish_state(0);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
if (this->custom_mode_end_text_sensor_ != nullptr) {
|
||||
this->custom_mode_end_text_sensor_->publish_state("Setup in progress");
|
||||
}
|
||||
} else if (data[FRAME_COMMAND_WORD_INDEX] == 0x81) {
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd == 0x81) {
|
||||
ESP_LOGD(TAG, "Reply: get radar init status 0x%02X", data[FRAME_DATA_INDEX]);
|
||||
} else if (data[FRAME_COMMAND_WORD_INDEX] == 0x87) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd == 0x87) {
|
||||
#ifdef USE_SELECT
|
||||
if ((this->scene_mode_select_ != nullptr) && (this->scene_mode_select_->has_index(data[FRAME_DATA_INDEX]))) {
|
||||
this->scene_mode_select_->publish_state(data[FRAME_DATA_INDEX]);
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Select has index offset %d Error", data[FRAME_DATA_INDEX]);
|
||||
}
|
||||
} else if ((this->custom_mode_end_text_sensor_ != nullptr) && (data[FRAME_COMMAND_WORD_INDEX] == 0x0A)) {
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
if (cmd == 0x0A && this->custom_mode_end_text_sensor_ != nullptr) {
|
||||
this->custom_mode_end_text_sensor_->publish_state("Set Success!");
|
||||
} else if (data[FRAME_COMMAND_WORD_INDEX] == 0x89) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cmd == 0x89) {
|
||||
if (data[FRAME_DATA_INDEX] == 0) {
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
if (this->custom_mode_end_text_sensor_ != nullptr) {
|
||||
this->custom_mode_end_text_sensor_->publish_state("Not in custom mode");
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_NUMBER
|
||||
if (this->custom_mode_number_ != nullptr) {
|
||||
this->custom_mode_number_->publish_state(0);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_SENSOR
|
||||
if (this->custom_mode_num_sensor_ != nullptr) {
|
||||
this->custom_mode_num_sensor_->publish_state(data[FRAME_DATA_INDEX]);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
#ifdef USE_SENSOR
|
||||
if (this->custom_mode_num_sensor_ != nullptr) {
|
||||
this->custom_mode_num_sensor_->publish_state(data[FRAME_DATA_INDEX]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
ESP_LOGD(TAG, "[%s] No found COMMAND_WORD(%02X) in Frame", __FUNCTION__, data[FRAME_COMMAND_WORD_INDEX]);
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "[%s] No found COMMAND_WORD(%02X) in Frame", __FUNCTION__, cmd);
|
||||
}
|
||||
|
||||
void MR24HPC1Component::r24_frame_parse_human_information_(uint8_t *data) {
|
||||
if ((this->has_target_binary_sensor_ != nullptr) &&
|
||||
((data[FRAME_COMMAND_WORD_INDEX] == 0x01) || (data[FRAME_COMMAND_WORD_INDEX] == 0x81))) {
|
||||
uint8_t cmd = data[FRAME_COMMAND_WORD_INDEX];
|
||||
|
||||
#ifdef USE_BINARY_SENSOR
|
||||
if ((cmd == 0x01 || cmd == 0x81) && this->has_target_binary_sensor_ != nullptr) {
|
||||
this->has_target_binary_sensor_->publish_state(S_SOMEONE_EXISTS_STR[data[FRAME_DATA_INDEX]]);
|
||||
} else if ((this->motion_status_text_sensor_ != nullptr) &&
|
||||
((data[FRAME_COMMAND_WORD_INDEX] == 0x02) || (data[FRAME_COMMAND_WORD_INDEX] == 0x82))) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
if ((cmd == 0x02 || cmd == 0x82) && this->motion_status_text_sensor_ != nullptr) {
|
||||
if (data[FRAME_DATA_INDEX] < 3) {
|
||||
this->motion_status_text_sensor_->publish_state(S_MOTION_STATUS_STR[data[FRAME_DATA_INDEX]]);
|
||||
}
|
||||
} else if ((this->movement_signs_sensor_ != nullptr) &&
|
||||
((data[FRAME_COMMAND_WORD_INDEX] == 0x03) || (data[FRAME_COMMAND_WORD_INDEX] == 0x83))) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SENSOR
|
||||
if ((cmd == 0x03 || cmd == 0x83) && this->movement_signs_sensor_ != nullptr) {
|
||||
this->movement_signs_sensor_->publish_state(data[FRAME_DATA_INDEX]);
|
||||
} else if ((this->unman_time_select_ != nullptr) &&
|
||||
((data[FRAME_COMMAND_WORD_INDEX] == 0x0A) || (data[FRAME_COMMAND_WORD_INDEX] == 0x8A))) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SELECT
|
||||
if ((cmd == 0x0A || cmd == 0x8A) && this->unman_time_select_ != nullptr) {
|
||||
// none:0x00 1s:0x01 30s:0x02 1min:0x03 2min:0x04 5min:0x05 10min:0x06 30min:0x07 1hour:0x08
|
||||
if (data[FRAME_DATA_INDEX] < 9) {
|
||||
this->unman_time_select_->publish_state(data[FRAME_DATA_INDEX]);
|
||||
}
|
||||
} else if ((this->keep_away_text_sensor_ != nullptr) &&
|
||||
((data[FRAME_COMMAND_WORD_INDEX] == 0x0B) || (data[FRAME_COMMAND_WORD_INDEX] == 0x8B))) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
if ((cmd == 0x0B || cmd == 0x8B) && this->keep_away_text_sensor_ != nullptr) {
|
||||
// none:0x00 close_to:0x01 far_away:0x02
|
||||
if (data[FRAME_DATA_INDEX] < 3) {
|
||||
this->keep_away_text_sensor_->publish_state(S_KEEP_AWAY_STR[data[FRAME_DATA_INDEX]]);
|
||||
}
|
||||
} else {
|
||||
ESP_LOGD(TAG, "[%s] No found COMMAND_WORD(%02X) in Frame", __FUNCTION__, data[FRAME_COMMAND_WORD_INDEX]);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
ESP_LOGD(TAG, "[%s] No found COMMAND_WORD(%02X) in Frame", __FUNCTION__, cmd);
|
||||
}
|
||||
|
||||
// Sending data frames
|
||||
@@ -695,12 +836,15 @@ void MR24HPC1Component::set_underlying_open_function(bool enable) {
|
||||
} else {
|
||||
this->send_query_(UNDERLYING_SWITCH_OFF, sizeof(UNDERLYING_SWITCH_OFF));
|
||||
}
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
if (this->keep_away_text_sensor_ != nullptr) {
|
||||
this->keep_away_text_sensor_->publish_state("");
|
||||
}
|
||||
if (this->motion_status_text_sensor_ != nullptr) {
|
||||
this->motion_status_text_sensor_->publish_state("");
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_SENSOR
|
||||
if (this->custom_spatial_static_value_sensor_ != nullptr) {
|
||||
this->custom_spatial_static_value_sensor_->publish_state(NAN);
|
||||
}
|
||||
@@ -716,6 +860,7 @@ void MR24HPC1Component::set_underlying_open_function(bool enable) {
|
||||
if (this->custom_motion_speed_sensor_ != nullptr) {
|
||||
this->custom_motion_speed_sensor_->publish_state(NAN);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MR24HPC1Component::set_scene_mode(uint8_t value) {
|
||||
@@ -723,12 +868,16 @@ void MR24HPC1Component::set_scene_mode(uint8_t value) {
|
||||
uint8_t send_data[10] = {0x53, 0x59, 0x05, 0x07, 0x00, 0x01, value, 0x00, 0x54, 0x43};
|
||||
send_data[7] = get_frame_crc_sum(send_data, send_data_len);
|
||||
this->send_query_(send_data, send_data_len);
|
||||
#ifdef USE_NUMBER
|
||||
if (this->custom_mode_number_ != nullptr) {
|
||||
this->custom_mode_number_->publish_state(0);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_SENSOR
|
||||
if (this->custom_mode_num_sensor_ != nullptr) {
|
||||
this->custom_mode_num_sensor_->publish_state(0);
|
||||
}
|
||||
#endif
|
||||
this->get_scene_mode();
|
||||
this->get_sensitivity();
|
||||
this->get_custom_mode();
|
||||
@@ -768,9 +917,11 @@ void MR24HPC1Component::set_unman_time(uint8_t value) {
|
||||
void MR24HPC1Component::set_custom_mode(uint8_t mode) {
|
||||
if (mode == 0) {
|
||||
this->set_custom_end_mode(); // Equivalent to end setting
|
||||
#ifdef USE_NUMBER
|
||||
if (this->custom_mode_number_ != nullptr) {
|
||||
this->custom_mode_number_->publish_state(0);
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
uint8_t send_data_len = 10;
|
||||
@@ -793,9 +944,11 @@ void MR24HPC1Component::set_custom_end_mode() {
|
||||
uint8_t send_data_len = 10;
|
||||
uint8_t send_data[10] = {0x53, 0x59, 0x05, 0x0a, 0x00, 0x01, 0x0F, 0xCB, 0x54, 0x43};
|
||||
this->send_query_(send_data, send_data_len);
|
||||
#ifdef USE_NUMBER
|
||||
if (this->custom_mode_number_ != nullptr) {
|
||||
this->custom_mode_number_->publish_state(0); // Clear setpoints
|
||||
}
|
||||
#endif
|
||||
this->get_existence_boundary();
|
||||
this->get_motion_boundary();
|
||||
this->get_existence_threshold();
|
||||
@@ -809,8 +962,10 @@ void MR24HPC1Component::set_custom_end_mode() {
|
||||
}
|
||||
|
||||
void MR24HPC1Component::set_existence_boundary(uint8_t value) {
|
||||
#ifdef USE_SENSOR
|
||||
if ((this->custom_mode_num_sensor_ != nullptr) && (this->custom_mode_num_sensor_->state == 0))
|
||||
return; // You'll have to check that you're in custom mode to set it up
|
||||
#endif
|
||||
uint8_t send_data_len = 10;
|
||||
uint8_t send_data[10] = {0x53, 0x59, 0x08, 0x0A, 0x00, 0x01, (uint8_t) (value + 1), 0x00, 0x54, 0x43};
|
||||
send_data[7] = get_frame_crc_sum(send_data, send_data_len);
|
||||
@@ -819,8 +974,10 @@ void MR24HPC1Component::set_existence_boundary(uint8_t value) {
|
||||
}
|
||||
|
||||
void MR24HPC1Component::set_motion_boundary(uint8_t value) {
|
||||
#ifdef USE_SENSOR
|
||||
if ((this->custom_mode_num_sensor_ != nullptr) && (this->custom_mode_num_sensor_->state == 0))
|
||||
return; // You'll have to check that you're in custom mode to set it up
|
||||
#endif
|
||||
uint8_t send_data_len = 10;
|
||||
uint8_t send_data[10] = {0x53, 0x59, 0x08, 0x0B, 0x00, 0x01, (uint8_t) (value + 1), 0x00, 0x54, 0x43};
|
||||
send_data[7] = get_frame_crc_sum(send_data, send_data_len);
|
||||
@@ -829,8 +986,10 @@ void MR24HPC1Component::set_motion_boundary(uint8_t value) {
|
||||
}
|
||||
|
||||
void MR24HPC1Component::set_existence_threshold(uint8_t value) {
|
||||
#ifdef USE_SENSOR
|
||||
if ((this->custom_mode_num_sensor_ != nullptr) && (this->custom_mode_num_sensor_->state == 0))
|
||||
return; // You'll have to check that you're in custom mode to set it up
|
||||
#endif
|
||||
uint8_t send_data_len = 10;
|
||||
uint8_t send_data[10] = {0x53, 0x59, 0x08, 0x08, 0x00, 0x01, value, 0x00, 0x54, 0x43};
|
||||
send_data[7] = get_frame_crc_sum(send_data, send_data_len);
|
||||
@@ -839,8 +998,10 @@ void MR24HPC1Component::set_existence_threshold(uint8_t value) {
|
||||
}
|
||||
|
||||
void MR24HPC1Component::set_motion_threshold(uint8_t value) {
|
||||
#ifdef USE_SENSOR
|
||||
if ((this->custom_mode_num_sensor_ != nullptr) && (this->custom_mode_num_sensor_->state == 0))
|
||||
return; // You'll have to check that you're in custom mode to set it up
|
||||
#endif
|
||||
uint8_t send_data_len = 10;
|
||||
uint8_t send_data[10] = {0x53, 0x59, 0x08, 0x09, 0x00, 0x01, value, 0x00, 0x54, 0x43};
|
||||
send_data[7] = get_frame_crc_sum(send_data, send_data_len);
|
||||
@@ -849,8 +1010,10 @@ void MR24HPC1Component::set_motion_threshold(uint8_t value) {
|
||||
}
|
||||
|
||||
void MR24HPC1Component::set_motion_trigger_time(uint8_t value) {
|
||||
#ifdef USE_SENSOR
|
||||
if ((this->custom_mode_num_sensor_ != nullptr) && (this->custom_mode_num_sensor_->state == 0))
|
||||
return; // You'll have to check that you're in custom mode to set it up
|
||||
#endif
|
||||
uint8_t send_data_len = 13;
|
||||
uint8_t send_data[13] = {0x53, 0x59, 0x08, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, value, 0x00, 0x54, 0x43};
|
||||
send_data[10] = get_frame_crc_sum(send_data, send_data_len);
|
||||
@@ -859,8 +1022,10 @@ void MR24HPC1Component::set_motion_trigger_time(uint8_t value) {
|
||||
}
|
||||
|
||||
void MR24HPC1Component::set_motion_to_rest_time(uint16_t value) {
|
||||
#ifdef USE_SENSOR
|
||||
if ((this->custom_mode_num_sensor_ != nullptr) && (this->custom_mode_num_sensor_->state == 0))
|
||||
return; // You'll have to check that you're in custom mode to set it up
|
||||
#endif
|
||||
uint8_t h8_num = (value >> 8) & 0xff;
|
||||
uint8_t l8_num = value & 0xff;
|
||||
uint8_t send_data_len = 13;
|
||||
@@ -871,8 +1036,10 @@ void MR24HPC1Component::set_motion_to_rest_time(uint16_t value) {
|
||||
}
|
||||
|
||||
void MR24HPC1Component::set_custom_unman_time(uint16_t value) {
|
||||
#ifdef USE_SENSOR
|
||||
if ((this->custom_mode_num_sensor_ != nullptr) && (this->custom_mode_num_sensor_->state == 0))
|
||||
return; // You'll have to check that you're in custom mode to set it up
|
||||
#endif
|
||||
uint32_t value_ms = value * 1000;
|
||||
uint8_t h24_num = (value_ms >> 24) & 0xff;
|
||||
uint8_t h16_num = (value_ms >> 16) & 0xff;
|
||||
|
||||
@@ -160,7 +160,9 @@ class MR24HPC1Component : public Component,
|
||||
void r24_parse_data_frame_(uint8_t *data, uint8_t len);
|
||||
void r24_frame_parse_open_underlying_information_(uint8_t *data);
|
||||
void r24_frame_parse_work_status_(uint8_t *data);
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
void r24_frame_parse_product_information_(uint8_t *data);
|
||||
#endif
|
||||
void r24_frame_parse_human_information_(uint8_t *data);
|
||||
void send_query_(const uint8_t *query, size_t string_length);
|
||||
|
||||
|
||||
@@ -107,32 +107,9 @@ FILTER_PLATFORMIO_LINES = [
|
||||
r"Warning: DEPRECATED: 'esptool.py' is deprecated. Please use 'esptool' instead. The '.py' suffix will be removed in a future major release.",
|
||||
r"Warning: esp-idf-size exited with code 2",
|
||||
r"esp_idf_size: error: unrecognized arguments: --ng",
|
||||
r"Package configuration completed successfully",
|
||||
]
|
||||
|
||||
|
||||
class PlatformioLogFilter(logging.Filter):
|
||||
"""Filter to suppress noisy platformio log messages."""
|
||||
|
||||
_PATTERN = re.compile(
|
||||
r"|".join(r"(?:" + pattern + r")" for pattern in FILTER_PLATFORMIO_LINES)
|
||||
)
|
||||
|
||||
def filter(self, record: logging.LogRecord) -> bool:
|
||||
# Only filter messages from platformio-related loggers
|
||||
if "platformio" not in record.name.lower():
|
||||
return True
|
||||
return self._PATTERN.match(record.getMessage()) is None
|
||||
|
||||
|
||||
def patch_platformio_logging() -> None:
|
||||
"""Add filter to root logger handlers to suppress noisy platformio messages."""
|
||||
root_logger = logging.getLogger()
|
||||
for handler in root_logger.handlers:
|
||||
if not any(isinstance(f, PlatformioLogFilter) for f in handler.filters):
|
||||
handler.addFilter(PlatformioLogFilter())
|
||||
|
||||
|
||||
def run_platformio_cli(*args, **kwargs) -> str | int:
|
||||
os.environ["PLATFORMIO_FORCE_COLOR"] = "true"
|
||||
os.environ["PLATFORMIO_BUILD_DIR"] = str(CORE.relative_pioenvs_path().absolute())
|
||||
@@ -153,8 +130,6 @@ def run_platformio_cli(*args, **kwargs) -> str | int:
|
||||
|
||||
patch_structhash()
|
||||
patch_file_downloader()
|
||||
if not CORE.verbose:
|
||||
patch_platformio_logging()
|
||||
return run_external_command(platformio.__main__.main, *cmd, **kwargs)
|
||||
|
||||
|
||||
|
||||
@@ -4,10 +4,6 @@ esp32:
|
||||
cpu_frequency: 400MHz
|
||||
framework:
|
||||
type: esp-idf
|
||||
components:
|
||||
- espressif/mdns^1.8.2
|
||||
- name: espressif/esp_hosted
|
||||
ref: 2.6.6
|
||||
advanced:
|
||||
enable_idf_experimental_features: yes
|
||||
|
||||
|
||||
4
tests/components/seeed_mr24hpc1/test.esp8266-ard.yaml
Normal file
4
tests/components/seeed_mr24hpc1/test.esp8266-ard.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
packages:
|
||||
uart: !include ../../test_build_components/common/uart/esp8266-ard.yaml
|
||||
|
||||
<<: !include common.yaml
|
||||
@@ -1,7 +1,6 @@
|
||||
"""Tests for platformio_api.py path functions."""
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
@@ -671,152 +670,3 @@ def test_process_stacktrace_bad_alloc(
|
||||
assert "Memory allocation of 512 bytes failed at 40201234" in caplog.text
|
||||
mock_decode_pc.assert_called_once_with(config, "40201234")
|
||||
assert state is False
|
||||
|
||||
|
||||
def test_platformio_log_filter_allows_non_platformio_messages() -> None:
|
||||
"""Test that non-platformio logger messages are allowed through."""
|
||||
log_filter = platformio_api.PlatformioLogFilter()
|
||||
record = logging.LogRecord(
|
||||
name="esphome.core",
|
||||
level=logging.INFO,
|
||||
pathname="",
|
||||
lineno=0,
|
||||
msg="Some esphome message",
|
||||
args=(),
|
||||
exc_info=None,
|
||||
)
|
||||
assert log_filter.filter(record) is True
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"msg",
|
||||
[
|
||||
pytest.param(
|
||||
"Verbose mode can be enabled via `-v, --verbose` option", id="verbose_mode"
|
||||
),
|
||||
pytest.param("Found 5 compatible libraries", id="found_5_libs"),
|
||||
pytest.param("Found 123 compatible libraries", id="found_123_libs"),
|
||||
pytest.param("Building in release mode", id="release_mode"),
|
||||
pytest.param("Building in debug mode", id="debug_mode"),
|
||||
pytest.param("Merged 2 ELF section", id="merged_elf"),
|
||||
pytest.param("esptool.py v4.7.0", id="esptool_py"),
|
||||
pytest.param("esptool v4.8.1", id="esptool"),
|
||||
pytest.param("PLATFORM: espressif32 @ 6.4.0", id="platform"),
|
||||
pytest.param("Using cache: /path/to/cache", id="cache"),
|
||||
pytest.param("Package configuration completed successfully", id="pkg_config"),
|
||||
pytest.param("Scanning dependencies...", id="scanning_deps"),
|
||||
pytest.param("Installing dependencies", id="installing_deps"),
|
||||
pytest.param(
|
||||
"Library Manager: Already installed, built-in library", id="lib_manager"
|
||||
),
|
||||
pytest.param(
|
||||
"Memory Usage -> https://bit.ly/pio-memory-usage", id="memory_usage"
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_platformio_log_filter_blocks_noisy_messages(msg: str) -> None:
|
||||
"""Test that noisy platformio messages are filtered out."""
|
||||
log_filter = platformio_api.PlatformioLogFilter()
|
||||
record = logging.LogRecord(
|
||||
name="platformio.builder",
|
||||
level=logging.INFO,
|
||||
pathname="",
|
||||
lineno=0,
|
||||
msg=msg,
|
||||
args=(),
|
||||
exc_info=None,
|
||||
)
|
||||
assert log_filter.filter(record) is False
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"msg",
|
||||
[
|
||||
pytest.param("Compiling .pio/build/test/src/main.cpp.o", id="compiling"),
|
||||
pytest.param("Linking .pio/build/test/firmware.elf", id="linking"),
|
||||
pytest.param("Error: something went wrong", id="error"),
|
||||
pytest.param("warning: unused variable", id="warning"),
|
||||
],
|
||||
)
|
||||
def test_platformio_log_filter_allows_other_platformio_messages(msg: str) -> None:
|
||||
"""Test that non-noisy platformio messages are allowed through."""
|
||||
log_filter = platformio_api.PlatformioLogFilter()
|
||||
record = logging.LogRecord(
|
||||
name="platformio.builder",
|
||||
level=logging.INFO,
|
||||
pathname="",
|
||||
lineno=0,
|
||||
msg=msg,
|
||||
args=(),
|
||||
exc_info=None,
|
||||
)
|
||||
assert log_filter.filter(record) is True
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"logger_name",
|
||||
[
|
||||
pytest.param("PLATFORMIO.builder", id="upper"),
|
||||
pytest.param("PlatformIO.core", id="mixed"),
|
||||
pytest.param("platformio.run", id="lower"),
|
||||
],
|
||||
)
|
||||
def test_platformio_log_filter_case_insensitive_logger_name(logger_name: str) -> None:
|
||||
"""Test that platformio logger name matching is case insensitive."""
|
||||
log_filter = platformio_api.PlatformioLogFilter()
|
||||
record = logging.LogRecord(
|
||||
name=logger_name,
|
||||
level=logging.INFO,
|
||||
pathname="",
|
||||
lineno=0,
|
||||
msg="Found 5 compatible libraries",
|
||||
args=(),
|
||||
exc_info=None,
|
||||
)
|
||||
assert log_filter.filter(record) is False
|
||||
|
||||
|
||||
def test_patch_platformio_logging_adds_filter() -> None:
|
||||
"""Test that patch_platformio_logging adds filter to all handlers."""
|
||||
test_handler = logging.StreamHandler()
|
||||
root_logger = logging.getLogger()
|
||||
original_handlers = root_logger.handlers.copy()
|
||||
|
||||
try:
|
||||
root_logger.addHandler(test_handler)
|
||||
|
||||
assert not any(
|
||||
isinstance(f, platformio_api.PlatformioLogFilter)
|
||||
for f in test_handler.filters
|
||||
)
|
||||
|
||||
platformio_api.patch_platformio_logging()
|
||||
|
||||
assert any(
|
||||
isinstance(f, platformio_api.PlatformioLogFilter)
|
||||
for f in test_handler.filters
|
||||
)
|
||||
finally:
|
||||
root_logger.handlers = original_handlers
|
||||
|
||||
|
||||
def test_patch_platformio_logging_no_duplicate_filters() -> None:
|
||||
"""Test that patch_platformio_logging doesn't add duplicate filters."""
|
||||
test_handler = logging.StreamHandler()
|
||||
root_logger = logging.getLogger()
|
||||
original_handlers = root_logger.handlers.copy()
|
||||
|
||||
try:
|
||||
root_logger.addHandler(test_handler)
|
||||
|
||||
platformio_api.patch_platformio_logging()
|
||||
platformio_api.patch_platformio_logging()
|
||||
|
||||
filter_count = sum(
|
||||
1
|
||||
for f in test_handler.filters
|
||||
if isinstance(f, platformio_api.PlatformioLogFilter)
|
||||
)
|
||||
assert filter_count == 1
|
||||
finally:
|
||||
root_logger.handlers = original_handlers
|
||||
|
||||
Reference in New Issue
Block a user