Merge remote-tracking branch 'upstream/dev' into isr-wake-enable-loop-soon

This commit is contained in:
J. Nick Koston
2026-02-28 14:29:15 -10:00
16 changed files with 153 additions and 141 deletions
+21 -16
View File
@@ -550,22 +550,8 @@ def binary_sensor_schema(
return _BINARY_SENSOR_SCHEMA.extend(schema)
async def setup_binary_sensor_core_(var, config):
await setup_entity(var, config, "binary_sensor")
if (device_class := config.get(CONF_DEVICE_CLASS)) is not None:
cg.add(var.set_device_class(device_class))
trigger = config.get(CONF_TRIGGER_ON_INITIAL_STATE, False) or config.get(
CONF_PUBLISH_INITIAL_STATE, False
)
cg.add(var.set_trigger_on_initial_state(trigger))
if inverted := config.get(CONF_INVERTED):
cg.add(var.set_inverted(inverted))
if filters_config := config.get(CONF_FILTERS):
cg.add_define("USE_BINARY_SENSOR_FILTER")
filters = await cg.build_registry_list(FILTER_REGISTRY, filters_config)
cg.add(var.add_filters(filters))
@coroutine_with_priority(CoroPriority.AUTOMATION)
async def _build_binary_sensor_automations(var, config):
for conf in config.get(CONF_ON_PRESS, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [], conf)
@@ -617,6 +603,25 @@ async def setup_binary_sensor_core_(var, config):
conf,
)
async def setup_binary_sensor_core_(var, config):
await setup_entity(var, config, "binary_sensor")
if (device_class := config.get(CONF_DEVICE_CLASS)) is not None:
cg.add(var.set_device_class(device_class))
trigger = config.get(CONF_TRIGGER_ON_INITIAL_STATE, False) or config.get(
CONF_PUBLISH_INITIAL_STATE, False
)
cg.add(var.set_trigger_on_initial_state(trigger))
if inverted := config.get(CONF_INVERTED):
cg.add(var.set_inverted(inverted))
if filters_config := config.get(CONF_FILTERS):
cg.add_define("USE_BINARY_SENSOR_FILTER")
filters = await cg.build_registry_list(FILTER_REGISTRY, filters_config)
cg.add(var.add_filters(filters))
CORE.add_job(_build_binary_sensor_automations, var, config)
if mqtt_id := config.get(CONF_MQTT_ID):
mqtt_ = cg.new_Pvariable(mqtt_id, var)
await mqtt.register_mqtt_component(mqtt_, config)
+8 -13
View File
@@ -173,8 +173,6 @@ static constexpr uint8_t DATA_FRAME_FOOTER[HEADER_FOOTER_SIZE] = {0xF8, 0xF7, 0x
// MAC address the module uses when Bluetooth is disabled
static constexpr uint8_t NO_MAC[] = {0x08, 0x05, 0x04, 0x03, 0x02, 0x01};
static inline int two_byte_to_int(char firstbyte, char secondbyte) { return (int16_t) (secondbyte << 8) + firstbyte; }
static inline bool validate_header_footer(const uint8_t *header_footer, const uint8_t *buffer) {
return std::memcmp(header_footer, buffer, HEADER_FOOTER_SIZE) == 0;
}
@@ -361,17 +359,14 @@ void LD2410Component::handle_periodic_data_() {
Detect distance: 16~17th bytes
*/
#ifdef USE_SENSOR
SAFE_PUBLISH_SENSOR(
this->moving_target_distance_sensor_,
ld2410::two_byte_to_int(this->buffer_data_[MOVING_TARGET_LOW], this->buffer_data_[MOVING_TARGET_HIGH]))
SAFE_PUBLISH_SENSOR(this->moving_target_distance_sensor_,
encode_uint16(this->buffer_data_[MOVING_TARGET_HIGH], this->buffer_data_[MOVING_TARGET_LOW]))
SAFE_PUBLISH_SENSOR(this->moving_target_energy_sensor_, this->buffer_data_[MOVING_ENERGY])
SAFE_PUBLISH_SENSOR(
this->still_target_distance_sensor_,
ld2410::two_byte_to_int(this->buffer_data_[STILL_TARGET_LOW], this->buffer_data_[STILL_TARGET_HIGH]));
SAFE_PUBLISH_SENSOR(this->still_target_distance_sensor_,
encode_uint16(this->buffer_data_[STILL_TARGET_HIGH], this->buffer_data_[STILL_TARGET_LOW]));
SAFE_PUBLISH_SENSOR(this->still_target_energy_sensor_, this->buffer_data_[STILL_ENERGY]);
SAFE_PUBLISH_SENSOR(
this->detection_distance_sensor_,
ld2410::two_byte_to_int(this->buffer_data_[DETECT_DISTANCE_LOW], this->buffer_data_[DETECT_DISTANCE_HIGH]));
SAFE_PUBLISH_SENSOR(this->detection_distance_sensor_,
encode_uint16(this->buffer_data_[DETECT_DISTANCE_HIGH], this->buffer_data_[DETECT_DISTANCE_LOW]));
if (engineering_mode) {
/*
@@ -578,8 +573,8 @@ bool LD2410Component::handle_ack_data_() {
/*
None Duration: 33~34th bytes
*/
updates.push_back(set_number_value(this->timeout_number_,
ld2410::two_byte_to_int(this->buffer_data_[32], this->buffer_data_[33])));
updates.push_back(
set_number_value(this->timeout_number_, encode_uint16(this->buffer_data_[33], this->buffer_data_[32])));
for (auto &update : updates) {
update();
}
+9 -14
View File
@@ -192,8 +192,6 @@ static constexpr uint8_t DATA_FRAME_FOOTER[HEADER_FOOTER_SIZE] = {0xF8, 0xF7, 0x
// MAC address the module uses when Bluetooth is disabled
static constexpr uint8_t NO_MAC[] = {0x08, 0x05, 0x04, 0x03, 0x02, 0x01};
static inline int two_byte_to_int(char firstbyte, char secondbyte) { return (int16_t) (secondbyte << 8) + firstbyte; }
static inline bool validate_header_footer(const uint8_t *header_footer, const uint8_t *buffer) {
return std::memcmp(header_footer, buffer, HEADER_FOOTER_SIZE) == 0;
}
@@ -398,22 +396,19 @@ void LD2412Component::handle_periodic_data_() {
Detect distance: 16~17th bytes
*/
#ifdef USE_SENSOR
SAFE_PUBLISH_SENSOR(
this->moving_target_distance_sensor_,
ld2412::two_byte_to_int(this->buffer_data_[MOVING_TARGET_LOW], this->buffer_data_[MOVING_TARGET_HIGH]))
SAFE_PUBLISH_SENSOR(this->moving_target_distance_sensor_,
encode_uint16(this->buffer_data_[MOVING_TARGET_HIGH], this->buffer_data_[MOVING_TARGET_LOW]))
SAFE_PUBLISH_SENSOR(this->moving_target_energy_sensor_, this->buffer_data_[MOVING_ENERGY])
SAFE_PUBLISH_SENSOR(
this->still_target_distance_sensor_,
ld2412::two_byte_to_int(this->buffer_data_[STILL_TARGET_LOW], this->buffer_data_[STILL_TARGET_HIGH]))
SAFE_PUBLISH_SENSOR(this->still_target_distance_sensor_,
encode_uint16(this->buffer_data_[STILL_TARGET_HIGH], this->buffer_data_[STILL_TARGET_LOW]))
SAFE_PUBLISH_SENSOR(this->still_target_energy_sensor_, this->buffer_data_[STILL_ENERGY])
if (this->detection_distance_sensor_ != nullptr) {
int new_detect_distance = 0;
if (target_state != 0x00 && (target_state & MOVE_BITMASK)) {
new_detect_distance =
ld2412::two_byte_to_int(this->buffer_data_[MOVING_TARGET_LOW], this->buffer_data_[MOVING_TARGET_HIGH]);
encode_uint16(this->buffer_data_[MOVING_TARGET_HIGH], this->buffer_data_[MOVING_TARGET_LOW]);
} else if (target_state != 0x00) {
new_detect_distance =
ld2412::two_byte_to_int(this->buffer_data_[STILL_TARGET_LOW], this->buffer_data_[STILL_TARGET_HIGH]);
new_detect_distance = encode_uint16(this->buffer_data_[STILL_TARGET_HIGH], this->buffer_data_[STILL_TARGET_LOW]);
}
this->detection_distance_sensor_->publish_state_if_not_dup(new_detect_distance);
}
@@ -637,9 +632,9 @@ bool LD2412Component::handle_ack_data_() {
/*
None Duration: 11~12th bytes
*/
updates.push_back(set_number_value(this->timeout_number_,
ld2412::two_byte_to_int(this->buffer_data_[12], this->buffer_data_[13])));
ESP_LOGV(TAG, "timeout_number_: %u", ld2412::two_byte_to_int(this->buffer_data_[12], this->buffer_data_[13]));
updates.push_back(
set_number_value(this->timeout_number_, encode_uint16(this->buffer_data_[13], this->buffer_data_[12])));
ESP_LOGV(TAG, "timeout_number_: %u", encode_uint16(this->buffer_data_[13], this->buffer_data_[12]));
/*
Output pin configuration: 13th bytes
*/
+19 -28
View File
@@ -168,15 +168,6 @@ static inline int16_t hex_to_signed_int(const uint8_t *buffer, uint8_t offset) {
return dec_val;
}
static inline float calculate_angle(float base, float hypotenuse) {
if (base < 0.0f || hypotenuse <= 0.0f) {
return 0.0f;
}
float angle_radians = acosf(base / hypotenuse);
float angle_degrees = angle_radians * (180.0f / std::numbers::pi_v<float>);
return angle_degrees;
}
static inline bool validate_header_footer(const uint8_t *header_footer, const uint8_t *buffer) {
return std::memcmp(header_footer, buffer, HEADER_FOOTER_SIZE) == 0;
}
@@ -292,16 +283,19 @@ void LD2450Component::loop() {
}
}
// Count targets in zone
uint8_t LD2450Component::count_targets_in_zone_(const Zone &zone, bool is_moving) {
uint8_t count = 0;
for (auto &index : this->target_info_) {
if (index.x > zone.x1 && index.x < zone.x2 && index.y > zone.y1 && index.y < zone.y2 &&
index.is_moving == is_moving) {
count++;
// Count targets in zone (single pass for both still and moving)
void LD2450Component::count_targets_in_zone_(const Zone &zone, uint8_t &still, uint8_t &moving) {
still = 0;
moving = 0;
for (auto &target : this->target_info_) {
if (target.x > zone.x1 && target.x < zone.x2 && target.y > zone.y1 && target.y < zone.y2) {
if (target.is_moving) {
moving++;
} else {
still++;
}
}
}
return count;
}
// Service reset_radar_zone
@@ -510,11 +504,8 @@ void LD2450Component::handle_periodic_data_() {
}
#ifdef USE_SENSOR
SAFE_PUBLISH_SENSOR(this->move_distance_sensors_[index], td);
// ANGLE
angle = ld2450::calculate_angle(static_cast<float>(ty), static_cast<float>(td));
if (tx > 0) {
angle = angle * -1;
}
// ANGLE - atan2f computes angle from Y axis directly, no sqrt/division needed
angle = atan2f(static_cast<float>(-tx), static_cast<float>(ty)) * (180.0f / std::numbers::pi_v<float>);
SAFE_PUBLISH_SENSOR(this->move_angle_sensors_[index], angle);
#endif
#ifdef USE_TEXT_SENSOR
@@ -528,10 +519,11 @@ void LD2450Component::handle_periodic_data_() {
} else {
direction = DIRECTION_STATIONARY;
}
text_sensor::TextSensor *tsd = this->direction_text_sensors_[index];
const auto *dir_str = find_str(ld2450::DIRECTION_BY_UINT, direction);
if (tsd != nullptr && (!tsd->has_state() || tsd->get_state() != dir_str)) {
tsd->publish_state(dir_str);
if (this->direction_dedup_[index].next(direction)) {
text_sensor::TextSensor *tsd = this->direction_text_sensors_[index];
if (tsd != nullptr) {
tsd->publish_state(find_str(ld2450::DIRECTION_BY_UINT, direction));
}
}
#endif
@@ -551,8 +543,7 @@ void LD2450Component::handle_periodic_data_() {
uint8_t zone_moving_targets = 0;
uint8_t zone_all_targets = 0;
for (index = 0; index < MAX_ZONES; index++) {
zone_still_targets = this->count_targets_in_zone_(this->zone_config_[index], false);
zone_moving_targets = this->count_targets_in_zone_(this->zone_config_[index], true);
this->count_targets_in_zone_(this->zone_config_[index], zone_still_targets, zone_moving_targets);
zone_all_targets = zone_still_targets + zone_moving_targets;
// Publish Still Target Count in Zones
+3 -2
View File
@@ -163,7 +163,7 @@ class LD2450Component : public Component, public uart::UARTDevice {
void save_to_flash_(float value);
float restore_from_flash_();
bool get_timeout_status_(uint32_t check_millis);
uint8_t count_targets_in_zone_(const Zone &zone, bool is_moving);
void count_targets_in_zone_(const Zone &zone, uint8_t &still, uint8_t &moving);
uint32_t presence_millis_ = 0;
uint32_t still_presence_millis_ = 0;
@@ -194,7 +194,8 @@ class LD2450Component : public Component, public uart::UARTDevice {
std::array<SensorWithDedup<uint8_t> *, MAX_ZONES> zone_moving_target_count_sensors_{};
#endif
#ifdef USE_TEXT_SENSOR
std::array<text_sensor::TextSensor *, 3> direction_text_sensors_{};
std::array<text_sensor::TextSensor *, MAX_TARGETS> direction_text_sensors_{};
std::array<Deduplicator<uint8_t>, MAX_TARGETS> direction_dedup_{};
#endif
LazyCallbackManager<void()> data_callback_;
+18 -13
View File
@@ -240,6 +240,23 @@ def number_schema(
return _NUMBER_SCHEMA.extend(schema)
@coroutine_with_priority(CoroPriority.AUTOMATION)
async def _build_number_automations(var, config):
for conf in config.get(CONF_ON_VALUE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(float, "x")], conf)
for conf in config.get(CONF_ON_VALUE_RANGE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await cg.register_component(trigger, conf)
if CONF_ABOVE in conf:
template_ = await cg.templatable(conf[CONF_ABOVE], [(float, "x")], float)
cg.add(trigger.set_min(template_))
if CONF_BELOW in conf:
template_ = await cg.templatable(conf[CONF_BELOW], [(float, "x")], float)
cg.add(trigger.set_max(template_))
await automation.build_automation(trigger, [(float, "x")], conf)
async def setup_number_core_(
var, config, *, min_value: float, max_value: float, step: float
):
@@ -254,19 +271,7 @@ async def setup_number_core_(
if config[CONF_MODE] != NumberMode.NUMBER_MODE_AUTO:
cg.add(var.traits.set_mode(config[CONF_MODE]))
for conf in config.get(CONF_ON_VALUE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(float, "x")], conf)
for conf in config.get(CONF_ON_VALUE_RANGE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await cg.register_component(trigger, conf)
if CONF_ABOVE in conf:
template_ = await cg.templatable(conf[CONF_ABOVE], [(float, "x")], float)
cg.add(trigger.set_min(template_))
if CONF_BELOW in conf:
template_ = await cg.templatable(conf[CONF_BELOW], [(float, "x")], float)
cg.add(trigger.set_max(template_))
await automation.build_automation(trigger, [(float, "x")], conf)
CORE.add_job(_build_number_automations, var, config)
if (unit_of_measurement := config.get(CONF_UNIT_OF_MEASUREMENT)) is not None:
cg.add(var.traits.set_unit_of_measurement(unit_of_measurement))
+21 -16
View File
@@ -888,6 +888,26 @@ async def build_filters(config):
return await cg.build_registry_list(FILTER_REGISTRY, config)
@coroutine_with_priority(CoroPriority.AUTOMATION)
async def _build_sensor_automations(var, config):
for conf in config.get(CONF_ON_VALUE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(float, "x")], conf)
for conf in config.get(CONF_ON_RAW_VALUE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(float, "x")], conf)
for conf in config.get(CONF_ON_VALUE_RANGE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await cg.register_component(trigger, conf)
if (above := conf.get(CONF_ABOVE)) is not None:
template_ = await cg.templatable(above, [(float, "x")], float)
cg.add(trigger.set_min(template_))
if (below := conf.get(CONF_BELOW)) is not None:
template_ = await cg.templatable(below, [(float, "x")], float)
cg.add(trigger.set_max(template_))
await automation.build_automation(trigger, [(float, "x")], conf)
async def setup_sensor_core_(var, config):
await setup_entity(var, config, "sensor")
@@ -907,22 +927,7 @@ async def setup_sensor_core_(var, config):
filters = await build_filters(config[CONF_FILTERS])
cg.add(var.set_filters(filters))
for conf in config.get(CONF_ON_VALUE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(float, "x")], conf)
for conf in config.get(CONF_ON_RAW_VALUE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(float, "x")], conf)
for conf in config.get(CONF_ON_VALUE_RANGE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await cg.register_component(trigger, conf)
if (above := conf.get(CONF_ABOVE)) is not None:
template_ = await cg.templatable(above, [(float, "x")], float)
cg.add(trigger.set_min(template_))
if (below := conf.get(CONF_BELOW)) is not None:
template_ = await cg.templatable(below, [(float, "x")], float)
cg.add(trigger.set_max(template_))
await automation.build_automation(trigger, [(float, "x")], conf)
CORE.add_job(_build_sensor_automations, var, config)
if (mqtt_id := config.get(CONF_MQTT_ID)) is not None:
mqtt_ = cg.new_Pvariable(mqtt_id, var)
+11 -5
View File
@@ -141,11 +141,8 @@ def switch_schema(
return _SWITCH_SCHEMA.extend(schema)
async def setup_switch_core_(var, config):
await setup_entity(var, config, "switch")
if (inverted := config.get(CONF_INVERTED)) is not None:
cg.add(var.set_inverted(inverted))
@coroutine_with_priority(CoroPriority.AUTOMATION)
async def _build_switch_automations(var, config):
for conf in config.get(CONF_ON_STATE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(bool, "x")], conf)
@@ -156,6 +153,15 @@ async def setup_switch_core_(var, config):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [], conf)
async def setup_switch_core_(var, config):
await setup_entity(var, config, "switch")
if (inverted := config.get(CONF_INVERTED)) is not None:
cg.add(var.set_inverted(inverted))
CORE.add_job(_build_switch_automations, var, config)
if (mqtt_id := config.get(CONF_MQTT_ID)) is not None:
mqtt_ = cg.new_Pvariable(mqtt_id, var)
await mqtt.register_mqtt_component(mqtt_, config)
+12 -7
View File
@@ -197,6 +197,17 @@ async def build_filters(config):
return await cg.build_registry_list(FILTER_REGISTRY, config)
@coroutine_with_priority(CoroPriority.AUTOMATION)
async def _build_text_sensor_automations(var, config):
for conf in config.get(CONF_ON_VALUE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(cg.std_string, "x")], conf)
for conf in config.get(CONF_ON_RAW_VALUE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(cg.std_string, "x")], conf)
async def setup_text_sensor_core_(var, config):
await setup_entity(var, config, "text_sensor")
@@ -208,13 +219,7 @@ async def setup_text_sensor_core_(var, config):
filters = await build_filters(config[CONF_FILTERS])
cg.add(var.set_filters(filters))
for conf in config.get(CONF_ON_VALUE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(cg.std_string, "x")], conf)
for conf in config.get(CONF_ON_RAW_VALUE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(cg.std_string, "x")], conf)
CORE.add_job(_build_text_sensor_automations, var, config)
if (mqtt_id := config.get(CONF_MQTT_ID)) is not None:
mqtt_ = cg.new_Pvariable(mqtt_id, var)
+3 -3
View File
@@ -12,6 +12,7 @@ from esphome.const import (
CONF_BAUD_RATE,
CONF_BYTES,
CONF_DATA,
CONF_DATA_BITS,
CONF_DEBUG,
CONF_DELIMITER,
CONF_DIRECTION,
@@ -21,10 +22,12 @@ from esphome.const import (
CONF_ID,
CONF_LAMBDA,
CONF_NUMBER,
CONF_PARITY,
CONF_PORT,
CONF_RX_BUFFER_SIZE,
CONF_RX_PIN,
CONF_SEQUENCE,
CONF_STOP_BITS,
CONF_TIMEOUT,
CONF_TRIGGER_ID,
CONF_TX_PIN,
@@ -215,9 +218,6 @@ UART_PARITY_OPTIONS = {
"ODD": UARTParityOptions.UART_CONFIG_PARITY_ODD,
}
CONF_STOP_BITS = "stop_bits"
CONF_DATA_BITS = "data_bits"
CONF_PARITY = "parity"
CONF_RX_FULL_THRESHOLD = "rx_full_threshold"
CONF_RX_TIMEOUT = "rx_timeout"
+4 -6
View File
@@ -1,20 +1,18 @@
import esphome.codegen as cg
from esphome.components import socket
from esphome.components.uart import (
CONF_DATA_BITS,
CONF_PARITY,
CONF_STOP_BITS,
UARTComponent,
)
from esphome.components.uart import UARTComponent
from esphome.components.usb_host import register_usb_client, usb_device_schema
import esphome.config_validation as cv
from esphome.const import (
CONF_BAUD_RATE,
CONF_BUFFER_SIZE,
CONF_CHANNELS,
CONF_DATA_BITS,
CONF_DEBUG,
CONF_DUMMY_RECEIVER,
CONF_ID,
CONF_PARITY,
CONF_STOP_BITS,
)
from esphome.cpp_types import Component
+3 -3
View File
@@ -4,21 +4,21 @@ import esphome.config_validation as cv
from esphome.const import (
CONF_BAUD_RATE,
CONF_CHANNEL,
CONF_DATA_BITS,
CONF_ID,
CONF_INPUT,
CONF_INVERTED,
CONF_MODE,
CONF_NUMBER,
CONF_OUTPUT,
CONF_PARITY,
CONF_STOP_BITS,
)
CODEOWNERS = ["@DrCoolZic"]
AUTO_LOAD = ["uart"]
MULTI_CONF = True
CONF_DATA_BITS = "data_bits"
CONF_STOP_BITS = "stop_bits"
CONF_PARITY = "parity"
CONF_CRYSTAL = "crystal"
CONF_UART = "uart"
CONF_TEST_MODE = "test_mode"
+3
View File
@@ -280,6 +280,7 @@ CONF_CUSTOM_PRESETS = "custom_presets"
CONF_CYCLE = "cycle"
CONF_DALLAS_ID = "dallas_id"
CONF_DATA = "data"
CONF_DATA_BITS = "data_bits"
CONF_DATA_PIN = "data_pin"
CONF_DATA_PINS = "data_pins"
CONF_DATA_RATE = "data_rate"
@@ -759,6 +760,7 @@ CONF_PAGE_ID = "page_id"
CONF_PAGES = "pages"
CONF_PANASONIC = "panasonic"
CONF_PARAMETERS = "parameters"
CONF_PARITY = "parity"
CONF_PASSWORD = "password"
CONF_PATH = "path"
CONF_PATTERN = "pattern"
@@ -961,6 +963,7 @@ CONF_STEP_PIN = "step_pin"
CONF_STILL_THRESHOLD = "still_threshold"
CONF_STOP = "stop"
CONF_STOP_ACTION = "stop_action"
CONF_STOP_BITS = "stop_bits"
CONF_STORE_BASELINE = "store_baseline"
CONF_SUBNET = "subnet"
CONF_SUBSCRIBE_QOS = "subscribe_qos"
+11 -14
View File
@@ -390,31 +390,30 @@ bool Component::is_idle() const { return (this->component_state_ & COMPONENT_STA
bool Component::can_proceed() { return true; }
bool Component::status_has_warning() const { return this->component_state_ & STATUS_LED_WARNING; }
bool Component::status_has_error() const { return this->component_state_ & STATUS_LED_ERROR; }
bool Component::set_status_flag_(uint8_t flag) {
if ((this->component_state_ & flag) != 0)
return false;
this->component_state_ |= flag;
App.app_state_ |= flag;
return true;
}
void Component::status_set_warning(const char *message) {
// Don't spam the log. This risks missing different warning messages though.
if ((this->component_state_ & STATUS_LED_WARNING) != 0)
if (!this->set_status_flag_(STATUS_LED_WARNING))
return;
this->component_state_ |= STATUS_LED_WARNING;
App.app_state_ |= STATUS_LED_WARNING;
ESP_LOGW(TAG, "%s set Warning flag: %s", LOG_STR_ARG(this->get_component_log_str()),
message ? message : LOG_STR_LITERAL("unspecified"));
}
void Component::status_set_warning(const LogString *message) {
// Don't spam the log. This risks missing different warning messages though.
if ((this->component_state_ & STATUS_LED_WARNING) != 0)
if (!this->set_status_flag_(STATUS_LED_WARNING))
return;
this->component_state_ |= STATUS_LED_WARNING;
App.app_state_ |= STATUS_LED_WARNING;
ESP_LOGW(TAG, "%s set Warning flag: %s", LOG_STR_ARG(this->get_component_log_str()),
message ? LOG_STR_ARG(message) : LOG_STR_LITERAL("unspecified"));
}
void Component::status_set_error() { this->status_set_error((const LogString *) nullptr); }
void Component::status_set_error(const char *message) {
if ((this->component_state_ & STATUS_LED_ERROR) != 0)
if (!this->set_status_flag_(STATUS_LED_ERROR))
return;
this->component_state_ |= STATUS_LED_ERROR;
App.app_state_ |= STATUS_LED_ERROR;
ESP_LOGE(TAG, "%s set Error flag: %s", LOG_STR_ARG(this->get_component_log_str()),
message ? message : LOG_STR_LITERAL("unspecified"));
if (message != nullptr) {
@@ -422,10 +421,8 @@ void Component::status_set_error(const char *message) {
}
}
void Component::status_set_error(const LogString *message) {
if ((this->component_state_ & STATUS_LED_ERROR) != 0)
if (!this->set_status_flag_(STATUS_LED_ERROR))
return;
this->component_state_ |= STATUS_LED_ERROR;
App.app_state_ |= STATUS_LED_ERROR;
ESP_LOGE(TAG, "%s set Error flag: %s", LOG_STR_ARG(this->get_component_log_str()),
message ? LOG_STR_ARG(message) : LOG_STR_LITERAL("unspecified"));
if (message != nullptr) {
+6
View File
@@ -299,6 +299,12 @@ class Component {
this->component_state_ |= state;
}
/// Helper to set a status LED flag on both this component and the app.
/// Returns true if the flag was newly set, false if it was already set.
/// Note: Callers often use the return value to decide whether to log a warning/error,
/// so once a flag is set, subsequent (potentially different) messages may be suppressed.
bool set_status_flag_(uint8_t flag);
/** Set an interval function with a unique name. Empty name means no cancelling possible.
*
* This will call f every interval ms. Can be cancelled via CancelInterval().
+1 -1
View File
@@ -959,7 +959,7 @@ def main():
continue
run_checks(LINT_CONTENT_CHECKS, fname, fname, content)
run_checks(LINT_POST_CHECKS, "POST")
run_checks(LINT_POST_CHECKS, Path("POST"))
for f, errs in sorted(errors.items()):
bold = functools.partial(styled, colorama.Style.BRIGHT)