Merge remote-tracking branch 'upstream/sensor_value_list_static_array' into integration

This commit is contained in:
J. Nick Koston
2026-03-27 15:18:08 -10:00
13 changed files with 133 additions and 177 deletions
@@ -2,11 +2,9 @@ import esphome.codegen as cg
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_ANGLE,
CONF_GAIN,
CONF_ID,
CONF_MAGNITUDE,
CONF_POSITION,
CONF_STATUS,
ENTITY_CATEGORY_DIAGNOSTIC,
ICON_MAGNET,
@@ -21,7 +19,6 @@ DEPENDENCIES = ["as5600"]
AS5600Sensor = as5600_ns.class_("AS5600Sensor", sensor.Sensor, cg.PollingComponent)
CONF_RAW_ANGLE = "raw_angle"
CONF_RAW_POSITION = "raw_position"
CONF_SLOW_FILTER = "slow_filter"
CONF_FAST_FILTER = "fast_filter"
@@ -89,18 +86,6 @@ async def to_code(config):
if out_of_range_mode_config := config.get(CONF_OUT_OF_RANGE_MODE):
cg.add(var.set_out_of_range_mode(out_of_range_mode_config))
if angle_config := config.get(CONF_ANGLE):
sens = await sensor.new_sensor(angle_config)
cg.add(var.set_angle_sensor(sens))
if raw_angle_config := config.get(CONF_RAW_ANGLE):
sens = await sensor.new_sensor(raw_angle_config)
cg.add(var.set_raw_angle_sensor(sens))
if position_config := config.get(CONF_POSITION):
sens = await sensor.new_sensor(position_config)
cg.add(var.set_position_sensor(sens))
if raw_position_config := config.get(CONF_RAW_POSITION):
sens = await sensor.new_sensor(raw_position_config)
cg.add(var.set_raw_position_sensor(sens))
@@ -25,27 +25,10 @@ static const uint8_t REGISTER_MAGNITUDE = 0x1B; // 16 bytes / R
void AS5600Sensor::dump_config() {
LOG_SENSOR("", "AS5600 Sensor", this);
ESP_LOGCONFIG(TAG, " Out of Range Mode: %u", this->out_of_range_mode_);
if (this->angle_sensor_ != nullptr) {
LOG_SENSOR(" ", "Angle Sensor", this->angle_sensor_);
}
if (this->raw_angle_sensor_ != nullptr) {
LOG_SENSOR(" ", "Raw Angle Sensor", this->raw_angle_sensor_);
}
if (this->position_sensor_ != nullptr) {
LOG_SENSOR(" ", "Position Sensor", this->position_sensor_);
}
if (this->raw_position_sensor_ != nullptr) {
LOG_SENSOR(" ", "Raw Position Sensor", this->raw_position_sensor_);
}
if (this->gain_sensor_ != nullptr) {
LOG_SENSOR(" ", "Gain Sensor", this->gain_sensor_);
}
if (this->magnitude_sensor_ != nullptr) {
LOG_SENSOR(" ", "Magnitude Sensor", this->magnitude_sensor_);
}
if (this->status_sensor_ != nullptr) {
LOG_SENSOR(" ", "Status Sensor", this->status_sensor_);
}
LOG_SENSOR(" ", "Raw Position Sensor", this->raw_position_sensor_);
LOG_SENSOR(" ", "Gain Sensor", this->gain_sensor_);
LOG_SENSOR(" ", "Magnitude Sensor", this->magnitude_sensor_);
LOG_SENSOR(" ", "Status Sensor", this->status_sensor_);
LOG_UPDATE_INTERVAL(this);
}
@@ -15,9 +15,6 @@ class AS5600Sensor : public PollingComponent, public Parented<AS5600Component>,
void update() override;
void dump_config() override;
void set_angle_sensor(sensor::Sensor *angle_sensor) { this->angle_sensor_ = angle_sensor; }
void set_raw_angle_sensor(sensor::Sensor *raw_angle_sensor) { this->raw_angle_sensor_ = raw_angle_sensor; }
void set_position_sensor(sensor::Sensor *position_sensor) { this->position_sensor_ = position_sensor; }
void set_raw_position_sensor(sensor::Sensor *raw_position_sensor) {
this->raw_position_sensor_ = raw_position_sensor;
}
@@ -28,9 +25,6 @@ class AS5600Sensor : public PollingComponent, public Parented<AS5600Component>,
OutRangeMode get_out_of_range_mode() { return this->out_of_range_mode_; }
protected:
sensor::Sensor *angle_sensor_{nullptr};
sensor::Sensor *raw_angle_sensor_{nullptr};
sensor::Sensor *position_sensor_{nullptr};
sensor::Sensor *raw_position_sensor_{nullptr};
sensor::Sensor *gain_sensor_{nullptr};
sensor::Sensor *magnitude_sensor_{nullptr};
+1 -1
View File
@@ -124,7 +124,7 @@ def set_reference_values(config):
config.setdefault(CONF_VOLTAGE_REFERENCE, DEFAULT_BL0940_LEGACY_UREF)
config.setdefault(CONF_CURRENT_REFERENCE, DEFAULT_BL0940_LEGACY_IREF)
config.setdefault(CONF_POWER_REFERENCE, DEFAULT_BL0940_LEGACY_PREF)
config.setdefault(CONF_ENERGY_REFERENCE, DEFAULT_BL0940_LEGACY_PREF)
config.setdefault(CONF_ENERGY_REFERENCE, DEFAULT_BL0940_LEGACY_EREF)
else:
vref = config.get(CONF_VOLTAGE_REFERENCE, DEFAULT_BL0940_VREF)
r_one = config.get(CONF_RESISTOR_ONE, DEFAULT_BL0940_R1)
@@ -362,7 +362,7 @@ async def register_modbus_device(var, config):
def function_code_to_register(function_code):
FUNCTION_CODE_TYPE_MAP = {
"read_coils": ModbusRegisterType.COIL,
"read_discrete_inputs": ModbusRegisterType.DISCRETE,
"read_discrete_inputs": ModbusRegisterType.DISCRETE_INPUT,
"read_holding_registers": ModbusRegisterType.HOLDING,
"read_input_registers": ModbusRegisterType.READ,
"write_single_coil": ModbusRegisterType.COIL,
+9 -4
View File
@@ -241,7 +241,7 @@ bool Nextion::send_command(const char *command) {
return false;
if (this->send_command_(command)) {
this->add_no_result_to_queue_("send_command");
this->add_no_result_to_queue_("command");
return true;
}
return false;
@@ -262,7 +262,7 @@ bool Nextion::send_command_printf(const char *format, ...) {
}
if (this->send_command_(buffer)) {
this->add_no_result_to_queue_("send_command_printf");
this->add_no_result_to_queue_("command_printf");
return true;
}
return false;
@@ -853,8 +853,13 @@ void Nextion::process_nextion_commands_() {
this->is_sleeping_ = false;
}
ESP_LOGD(TAG, "Remove old queue '%s':'%s'", component->get_queue_type_string().c_str(),
component->get_variable_name().c_str());
if ((*it)->pending_command.empty()) {
ESP_LOGD(TAG, "Remove old queue '%s':'%s'", component->get_queue_type_string().c_str(),
component->get_variable_name().c_str());
} else {
ESP_LOGD(TAG, "Remove old queue '%s':'%s' cmd:'%s'", component->get_queue_type_string().c_str(),
component->get_variable_name().c_str(), (*it)->pending_command.c_str());
}
if (component->get_queue_type() == NextionQueueType::NO_RESULT) {
if (component->get_variable_name() == "sleep_wake") {
+53 -62
View File
@@ -12,7 +12,7 @@ void Nextion::soft_reset() { this->send_command_("rest"); }
void Nextion::set_wake_up_page(uint8_t wake_up_page) {
this->wake_up_page_ = wake_up_page;
this->add_no_result_to_queue_with_set_internal_("wake_up_page", "wup", wake_up_page, true);
this->add_no_result_to_queue_with_set_internal_("wup", "wup", wake_up_page, true);
}
void Nextion::set_touch_sleep_timeout(const uint16_t touch_sleep_timeout) {
@@ -23,7 +23,7 @@ void Nextion::set_touch_sleep_timeout(const uint16_t touch_sleep_timeout) {
this->touch_sleep_timeout_ = touch_sleep_timeout;
}
this->add_no_result_to_queue_with_set_internal_("touch_sleep_timeout", "thsp", this->touch_sleep_timeout_, true);
this->add_no_result_to_queue_with_set_internal_("thsp", "thsp", this->touch_sleep_timeout_, true);
}
void Nextion::sleep(bool sleep) {
@@ -58,115 +58,107 @@ bool Nextion::set_protocol_reparse_mode(bool active_mode) {
// Set Colors - Background
void Nextion::set_component_background_color(const char *component, uint16_t color) {
this->add_no_result_to_queue_with_printf_("set_component_background_color", "%s.bco=%" PRIu16, component, color);
this->add_no_result_to_queue_with_printf_(".bco", "%s.bco=%" PRIu16, component, color);
}
void Nextion::set_component_background_color(const char *component, const char *color) {
this->add_no_result_to_queue_with_printf_("set_component_background_color", "%s.bco=%s", component, color);
this->add_no_result_to_queue_with_printf_(".bco", "%s.bco=%s", component, color);
}
void Nextion::set_component_background_color(const char *component, Color color) {
this->add_no_result_to_queue_with_printf_("set_component_background_color", "%s.bco=%d", component,
display::ColorUtil::color_to_565(color));
this->add_no_result_to_queue_with_printf_(".bco", "%s.bco=%d", component, display::ColorUtil::color_to_565(color));
}
// Set Colors - Background (pressed)
void Nextion::set_component_pressed_background_color(const char *component, uint16_t color) {
this->add_no_result_to_queue_with_printf_("set_component_pressed_background_color", "%s.bco2=%" PRIu16, component,
color);
this->add_no_result_to_queue_with_printf_(".bco2", "%s.bco2=%" PRIu16, component, color);
}
void Nextion::set_component_pressed_background_color(const char *component, const char *color) {
this->add_no_result_to_queue_with_printf_("set_component_pressed_background_color", "%s.bco2=%s", component, color);
this->add_no_result_to_queue_with_printf_(".bco2", "%s.bco2=%s", component, color);
}
void Nextion::set_component_pressed_background_color(const char *component, Color color) {
this->add_no_result_to_queue_with_printf_("set_component_pressed_background_color", "%s.bco2=%d", component,
display::ColorUtil::color_to_565(color));
this->add_no_result_to_queue_with_printf_(".bco2", "%s.bco2=%d", component, display::ColorUtil::color_to_565(color));
}
// Set Colors - Foreground
void Nextion::set_component_foreground_color(const char *component, uint16_t color) {
this->add_no_result_to_queue_with_printf_("set_component_foreground_color", "%s.pco=%" PRIu16, component, color);
this->add_no_result_to_queue_with_printf_(".pco", "%s.pco=%" PRIu16, component, color);
}
void Nextion::set_component_foreground_color(const char *component, const char *color) {
this->add_no_result_to_queue_with_printf_("set_component_foreground_color", "%s.pco=%s", component, color);
this->add_no_result_to_queue_with_printf_(".pco", "%s.pco=%s", component, color);
}
void Nextion::set_component_foreground_color(const char *component, Color color) {
this->add_no_result_to_queue_with_printf_("set_component_foreground_color", "%s.pco=%d", component,
display::ColorUtil::color_to_565(color));
this->add_no_result_to_queue_with_printf_(".pco", "%s.pco=%d", component, display::ColorUtil::color_to_565(color));
}
// Set Colors - Foreground (pressed)
void Nextion::set_component_pressed_foreground_color(const char *component, uint16_t color) {
this->add_no_result_to_queue_with_printf_("set_component_pressed_foreground_color", "%s.pco2=%" PRIu16, component,
color);
this->add_no_result_to_queue_with_printf_(".pco2", "%s.pco2=%" PRIu16, component, color);
}
void Nextion::set_component_pressed_foreground_color(const char *component, const char *color) {
this->add_no_result_to_queue_with_printf_("set_component_pressed_foreground_color", "%s.pco2=%s", component, color);
this->add_no_result_to_queue_with_printf_(".pco2", "%s.pco2=%s", component, color);
}
void Nextion::set_component_pressed_foreground_color(const char *component, Color color) {
this->add_no_result_to_queue_with_printf_("set_component_pressed_foreground_color", "%s.pco2=%d", component,
display::ColorUtil::color_to_565(color));
this->add_no_result_to_queue_with_printf_(".pco2", "%s.pco2=%d", component, display::ColorUtil::color_to_565(color));
}
// Set Colors - Font
void Nextion::set_component_font_color(const char *component, uint16_t color) {
this->add_no_result_to_queue_with_printf_("set_component_font_color", "%s.pco=%" PRIu16, component, color);
this->add_no_result_to_queue_with_printf_(".pco", "%s.pco=%" PRIu16, component, color);
}
void Nextion::set_component_font_color(const char *component, const char *color) {
this->add_no_result_to_queue_with_printf_("set_component_font_color", "%s.pco=%s", component, color);
this->add_no_result_to_queue_with_printf_(".pco", "%s.pco=%s", component, color);
}
void Nextion::set_component_font_color(const char *component, Color color) {
this->add_no_result_to_queue_with_printf_("set_component_font_color", "%s.pco=%d", component,
display::ColorUtil::color_to_565(color));
this->add_no_result_to_queue_with_printf_(".pco", "%s.pco=%d", component, display::ColorUtil::color_to_565(color));
}
// Set Colors - Font (pressed)
void Nextion::set_component_pressed_font_color(const char *component, uint16_t color) {
this->add_no_result_to_queue_with_printf_("set_component_pressed_font_color", "%s.pco2=%" PRIu16, component, color);
this->add_no_result_to_queue_with_printf_(".pco2", "%s.pco2=%" PRIu16, component, color);
}
void Nextion::set_component_pressed_font_color(const char *component, const char *color) {
this->add_no_result_to_queue_with_printf_("set_component_pressed_font_color", "%s.pco2=%s", component, color);
this->add_no_result_to_queue_with_printf_(".pco2", "%s.pco2=%s", component, color);
}
void Nextion::set_component_pressed_font_color(const char *component, Color color) {
this->add_no_result_to_queue_with_printf_("set_component_pressed_font_color", "%s.pco2=%d", component,
display::ColorUtil::color_to_565(color));
this->add_no_result_to_queue_with_printf_(".pco2", "%s.pco2=%d", component, display::ColorUtil::color_to_565(color));
}
// Set picture
void Nextion::set_component_pic(const char *component, uint16_t pic_id) {
this->add_no_result_to_queue_with_printf_("set_component_pic", "%s.pic=%" PRIu16, component, pic_id);
this->add_no_result_to_queue_with_printf_(".pic", "%s.pic=%" PRIu16, component, pic_id);
}
void Nextion::set_component_picc(const char *component, uint16_t pic_id) {
this->add_no_result_to_queue_with_printf_("set_component_picc", "%s.picc=%" PRIu16, component, pic_id);
this->add_no_result_to_queue_with_printf_(".picc", "%s.picc=%" PRIu16, component, pic_id);
}
// Set video
void Nextion::set_component_vid(const char *component, uint8_t vid_id) {
this->add_no_result_to_queue_with_printf_("set_component_vid", "%s.vid=%" PRIu8, component, vid_id);
this->add_no_result_to_queue_with_printf_(".vid", "%s.vid=%" PRIu8, component, vid_id);
}
void Nextion::set_component_drag(const char *component, bool drag) {
this->add_no_result_to_queue_with_printf_("set_component_drag", "%s.drag=%i", component, drag ? 1 : 0);
this->add_no_result_to_queue_with_printf_(".drag", "%s.drag=%i", component, drag ? 1 : 0);
}
void Nextion::set_component_aph(const char *component, uint8_t aph) {
this->add_no_result_to_queue_with_printf_("set_component_aph", "%s.aph=%" PRIu8, component, aph);
this->add_no_result_to_queue_with_printf_(".aph", "%s.aph=%" PRIu8, component, aph);
}
void Nextion::set_component_position(const char *component, uint32_t x, uint32_t y) {
this->add_no_result_to_queue_with_printf_("set_component_position_x", "%s.x=%" PRIu32, component, x);
this->add_no_result_to_queue_with_printf_("set_component_position_y", "%s.y=%" PRIu32, component, y);
this->add_no_result_to_queue_with_printf_(".x", "%s.x=%" PRIu32, component, x);
this->add_no_result_to_queue_with_printf_(".y", "%s.y=%" PRIu32, component, y);
}
void Nextion::set_component_text_printf(const char *component, const char *format, ...) {
@@ -180,29 +172,29 @@ void Nextion::set_component_text_printf(const char *component, const char *forma
}
// General Nextion
void Nextion::goto_page(const char *page) { this->add_no_result_to_queue_with_printf_("goto_page", "page %s", page); }
void Nextion::goto_page(uint8_t page) { this->add_no_result_to_queue_with_printf_("goto_page", "page %i", page); }
void Nextion::goto_page(const char *page) { this->add_no_result_to_queue_with_printf_("page", "page %s", page); }
void Nextion::goto_page(uint8_t page) { this->add_no_result_to_queue_with_printf_("page", "page %i", page); }
void Nextion::set_backlight_brightness(float brightness) {
if (brightness < 0 || brightness > 1.0) {
ESP_LOGD(TAG, "Brightness out of bounds (0-1.0)");
return;
}
this->add_no_result_to_queue_with_printf_("backlight_brightness", "dim=%d", static_cast<int>(brightness * 100));
this->add_no_result_to_queue_with_printf_("dim", "dim=%d", static_cast<int>(brightness * 100));
}
void Nextion::set_auto_wake_on_touch(bool auto_wake_on_touch) {
this->connection_state_.auto_wake_on_touch_ = auto_wake_on_touch;
this->add_no_result_to_queue_with_set("auto_wake_on_touch", "thup", auto_wake_on_touch ? 1 : 0);
this->add_no_result_to_queue_with_set("thup", "thup", auto_wake_on_touch ? 1 : 0);
}
// General Component
void Nextion::set_component_font(const char *component, uint8_t font_id) {
this->add_no_result_to_queue_with_printf_("set_component_font", "%s.font=%" PRIu8, component, font_id);
this->add_no_result_to_queue_with_printf_(".font", "%s.font=%" PRIu8, component, font_id);
}
void Nextion::set_component_visibility(const char *component, bool show) {
this->add_no_result_to_queue_with_printf_("set_component_visibility", "vis %s,%d", component, show ? 1 : 0);
this->add_no_result_to_queue_with_printf_("vis", "vis %s,%d", component, show ? 1 : 0);
}
void Nextion::hide_component(const char *component) { this->set_component_visibility(component, false); }
@@ -210,56 +202,55 @@ void Nextion::hide_component(const char *component) { this->set_component_visibi
void Nextion::show_component(const char *component) { this->set_component_visibility(component, true); }
void Nextion::enable_component_touch(const char *component) {
this->add_no_result_to_queue_with_printf_("enable_component_touch", "tsw %s,1", component);
this->add_no_result_to_queue_with_printf_("tsw", "tsw %s,1", component);
}
void Nextion::disable_component_touch(const char *component) {
this->add_no_result_to_queue_with_printf_("disable_component_touch", "tsw %s,0", component);
this->add_no_result_to_queue_with_printf_("tsw", "tsw %s,0", component);
}
void Nextion::set_component_text(const char *component, const char *text) {
this->add_no_result_to_queue_with_printf_("set_component_text", "%s.txt=\"%s\"", component, text);
this->add_no_result_to_queue_with_printf_(".txt", "%s.txt=\"%s\"", component, text);
}
void Nextion::set_component_value(const char *component, int32_t value) {
this->add_no_result_to_queue_with_printf_("set_component_value", "%s.val=%" PRId32, component, value);
this->add_no_result_to_queue_with_printf_(".val", "%s.val=%" PRId32, component, value);
}
void Nextion::add_waveform_data(uint8_t component_id, uint8_t channel_number, uint8_t value) {
this->add_no_result_to_queue_with_printf_("add_waveform_data", "add %" PRIu8 ",%" PRIu8 ",%" PRIu8, component_id,
channel_number, value);
this->add_no_result_to_queue_with_printf_("add", "add %" PRIu8 ",%" PRIu8 ",%" PRIu8, component_id, channel_number,
value);
}
void Nextion::open_waveform_channel(uint8_t component_id, uint8_t channel_number, uint8_t value) {
this->add_no_result_to_queue_with_printf_("open_waveform_channel", "addt %" PRIu8 ",%" PRIu8 ",%" PRIu8, component_id,
channel_number, value);
this->add_no_result_to_queue_with_printf_("addt", "addt %" PRIu8 ",%" PRIu8 ",%" PRIu8, component_id, channel_number,
value);
}
void Nextion::set_component_coordinates(const char *component, uint16_t x, uint16_t y) {
this->add_no_result_to_queue_with_printf_("set_component_coordinates command 1", "%s.xcen=%" PRIu16, component, x);
this->add_no_result_to_queue_with_printf_("set_component_coordinates command 2", "%s.ycen=%" PRIu16, component, y);
this->add_no_result_to_queue_with_printf_(".xcen", "%s.xcen=%" PRIu16, component, x);
this->add_no_result_to_queue_with_printf_(".ycen", "%s.ycen=%" PRIu16, component, y);
}
// Drawing
void Nextion::display_picture(uint16_t picture_id, uint16_t x_start, uint16_t y_start) {
this->add_no_result_to_queue_with_printf_("display_picture", "pic %" PRIu16 ", %" PRIu16 ", %" PRIu16, x_start,
y_start, picture_id);
this->add_no_result_to_queue_with_printf_("pic", "pic %" PRIu16 ", %" PRIu16 ", %" PRIu16, x_start, y_start,
picture_id);
}
void Nextion::fill_area(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint16_t color) {
this->add_no_result_to_queue_with_printf_(
"fill_area", "fill %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16, x1, y1, width, height, color);
}
void Nextion::fill_area(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, const char *color) {
this->add_no_result_to_queue_with_printf_("fill_area", "fill %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%s", x1,
this->add_no_result_to_queue_with_printf_("fill", "fill %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16, x1,
y1, width, height, color);
}
void Nextion::fill_area(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, const char *color) {
this->add_no_result_to_queue_with_printf_("fill", "fill %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%s", x1, y1,
width, height, color);
}
void Nextion::fill_area(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, Color color) {
this->add_no_result_to_queue_with_printf_("fill_area",
"fill %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16, x1, y1,
width, height, display::ColorUtil::color_to_565(color));
this->add_no_result_to_queue_with_printf_("fill", "fill %" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16, x1,
y1, width, height, display::ColorUtil::color_to_565(color));
}
void Nextion::line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) {
+4 -2
View File
@@ -381,7 +381,7 @@ async def filter_out_filter_to_code(config, filter_id):
if not isinstance(config, list):
config = [config]
template_ = [await cg.templatable(x, [], float) for x in config]
return cg.new_Pvariable(filter_id, template_)
return cg.new_Pvariable(filter_id, cg.TemplateArguments(len(template_)), template_)
QUANTILE_SCHEMA = cv.All(
@@ -650,7 +650,9 @@ async def throttle_with_priority_filter_to_code(config, filter_id):
if not isinstance(config[CONF_VALUE], list):
config[CONF_VALUE] = [config[CONF_VALUE]]
template_ = [await cg.templatable(x, [], float) for x in config[CONF_VALUE]]
return cg.new_Pvariable(filter_id, config[CONF_TIMEOUT], template_)
return cg.new_Pvariable(
filter_id, cg.TemplateArguments(len(template_)), config[CONF_TIMEOUT], template_
)
HEARTBEAT_SCHEMA = cv.Schema(
+6 -32
View File
@@ -222,16 +222,16 @@ MultiplyFilter::MultiplyFilter(TemplatableValue<float> multiplier) : multiplier_
optional<float> MultiplyFilter::new_value(float value) { return value * this->multiplier_.value(); }
// ValueListFilter (base class)
ValueListFilter::ValueListFilter(std::initializer_list<TemplatableValue<float>> values) : values_(values) {}
uint32_t get_loop_component_start_time() { return App.get_loop_component_start_time(); }
bool ValueListFilter::value_matches_any_(float sensor_value) {
int8_t accuracy = this->parent_->get_accuracy_decimals();
// ValueListFilter helper (non-template, shared by all ValueListFilter<N> instantiations)
bool value_list_matches_any(Sensor *parent, float sensor_value, const TemplatableValue<float> *values, size_t count) {
int8_t accuracy = parent->get_accuracy_decimals();
float accuracy_mult = pow10_int(accuracy);
float rounded_sensor = roundf(accuracy_mult * sensor_value);
for (auto &filter_value : this->values_) {
float fv = filter_value.value();
for (size_t i = 0; i < count; i++) {
float fv = values[i].value();
// Handle NaN comparison
if (std::isnan(fv)) {
@@ -248,16 +248,6 @@ bool ValueListFilter::value_matches_any_(float sensor_value) {
return false;
}
// FilterOutValueFilter
FilterOutValueFilter::FilterOutValueFilter(std::initializer_list<TemplatableValue<float>> values_to_filter_out)
: ValueListFilter(values_to_filter_out) {}
optional<float> FilterOutValueFilter::new_value(float value) {
if (this->value_matches_any_(value))
return {}; // Filter out
return value; // Pass through
}
// ThrottleFilter
ThrottleFilter::ThrottleFilter(uint32_t min_time_between_inputs) : min_time_between_inputs_(min_time_between_inputs) {}
optional<float> ThrottleFilter::new_value(float value) {
@@ -269,22 +259,6 @@ optional<float> ThrottleFilter::new_value(float value) {
return {};
}
// ThrottleWithPriorityFilter
ThrottleWithPriorityFilter::ThrottleWithPriorityFilter(
uint32_t min_time_between_inputs, std::initializer_list<TemplatableValue<float>> prioritized_values)
: ValueListFilter(prioritized_values), min_time_between_inputs_(min_time_between_inputs) {}
optional<float> ThrottleWithPriorityFilter::new_value(float value) {
const uint32_t now = App.get_loop_component_start_time();
// Allow value through if: no previous input, time expired, or is prioritized
if (this->last_input_ == 0 || now - this->last_input_ >= min_time_between_inputs_ ||
this->value_matches_any_(value)) {
this->last_input_ = now;
return value;
}
return {};
}
// DeltaFilter
DeltaFilter::DeltaFilter(float min_a0, float min_a1, float max_a0, float max_a1)
: min_a0_(min_a0), min_a1_(min_a1), max_a0_(max_a0), max_a1_(max_a1) {}
+46 -14
View File
@@ -3,6 +3,7 @@
#include "esphome/core/defines.h"
#ifdef USE_SENSOR_FILTER
#include <array>
#include <utility>
#include <vector>
#include "esphome/core/automation.h"
@@ -328,28 +329,50 @@ class MultiplyFilter : public Filter {
TemplatableValue<float> multiplier_;
};
/** Base class for filters that compare sensor values against a list of configured values.
/// Non-template helper for value matching (implementation in filter.cpp)
bool value_list_matches_any(Sensor *parent, float sensor_value, const TemplatableValue<float> *values, size_t count);
/// Non-template helper to get cached loop start time (avoids circular include of application.h)
uint32_t get_loop_component_start_time();
/** Base class for filters that compare sensor values against a fixed list of configured values.
*
* This base class provides common functionality for filters that need to check if a sensor
* value matches any value in a configured list, with proper handling of NaN values and
* accuracy-based rounding for comparisons.
* Templated on N (the number of values) so the list is stored inline in a std::array,
* avoiding heap allocation and the overhead of FixedVector.
*
* @tparam N Number of values in the filter list, set by code generation to match
* the exact number of values configured in YAML.
*/
class ValueListFilter : public Filter {
template<size_t N> class ValueListFilter : public Filter {
protected:
explicit ValueListFilter(std::initializer_list<TemplatableValue<float>> values);
explicit ValueListFilter(std::initializer_list<TemplatableValue<float>> values) {
size_t i = 0;
for (const auto &v : values) {
if (i >= N)
break;
this->values_[i++] = v;
}
}
/// Check if sensor value matches any configured value (with accuracy rounding)
bool value_matches_any_(float sensor_value);
bool value_matches_any_(float sensor_value) {
return value_list_matches_any(this->parent_, sensor_value, this->values_.data(), N);
}
FixedVector<TemplatableValue<float>> values_;
std::array<TemplatableValue<float>, N> values_{};
};
/// A simple filter that only forwards the filter chain if it doesn't receive `value_to_filter_out`.
class FilterOutValueFilter : public ValueListFilter {
template<size_t N> class FilterOutValueFilter : public ValueListFilter<N> {
public:
explicit FilterOutValueFilter(std::initializer_list<TemplatableValue<float>> values_to_filter_out);
explicit FilterOutValueFilter(std::initializer_list<TemplatableValue<float>> values_to_filter_out)
: ValueListFilter<N>(values_to_filter_out) {}
optional<float> new_value(float value) override;
optional<float> new_value(float value) override {
if (this->value_matches_any_(value))
return {}; // Filter out
return value; // Pass through
}
};
class ThrottleFilter : public Filter {
@@ -364,12 +387,21 @@ class ThrottleFilter : public Filter {
};
/// Same as 'throttle' but will immediately publish values contained in `value_to_prioritize`.
class ThrottleWithPriorityFilter : public ValueListFilter {
template<size_t N> class ThrottleWithPriorityFilter : public ValueListFilter<N> {
public:
explicit ThrottleWithPriorityFilter(uint32_t min_time_between_inputs,
std::initializer_list<TemplatableValue<float>> prioritized_values);
std::initializer_list<TemplatableValue<float>> prioritized_values)
: ValueListFilter<N>(prioritized_values), min_time_between_inputs_(min_time_between_inputs) {}
optional<float> new_value(float value) override;
optional<float> new_value(float value) override {
const uint32_t now = get_loop_component_start_time();
if (this->last_input_ == 0 || now - this->last_input_ >= this->min_time_between_inputs_ ||
this->value_matches_any_(value)) {
this->last_input_ = now;
return value;
}
return {};
}
protected:
uint32_t last_input_{0};
-5
View File
@@ -15,7 +15,6 @@ from esphome.const import (
CONF_STORE_BASELINE,
CONF_TEMPERATURE_SOURCE,
CONF_VOC,
CONF_VOC_BASELINE,
DEVICE_CLASS_AQI,
ICON_RADIATOR,
STATE_CLASS_MEASUREMENT,
@@ -83,7 +82,6 @@ CONFIG_SCHEMA = cv.All(
state_class=STATE_CLASS_MEASUREMENT,
).extend(NOX_SENSOR),
cv.Optional(CONF_STORE_BASELINE, default=True): cv.boolean,
cv.Optional(CONF_VOC_BASELINE): cv.hex_uint16_t,
cv.Optional(CONF_COMPENSATION): cv.Schema(
{
cv.Required(CONF_HUMIDITY_SOURCE): cv.use_id(sensor.Sensor),
@@ -112,9 +110,6 @@ async def to_code(config):
cg.add(var.set_store_baseline(config[CONF_STORE_BASELINE]))
if CONF_VOC_BASELINE in config:
cg.add(var.set_voc_baseline(CONF_VOC_BASELINE))
if CONF_VOC in config:
sens = await sensor.new_sensor(config[CONF_VOC])
cg.add(var.set_voc_sensor(sens))
+7 -10
View File
@@ -4,8 +4,7 @@
#include "tmp117.h"
#include "esphome/core/log.h"
namespace esphome {
namespace tmp117 {
namespace esphome::tmp117 {
static const char *const TAG = "tmp117";
@@ -18,11 +17,10 @@ void TMP117Component::update() {
if ((uint16_t) data != 0x8000) {
float temperature = data * 0.0078125f;
ESP_LOGD(TAG, "Got temperature=%.2f°C", temperature);
this->publish_state(temperature);
this->status_clear_warning();
} else {
ESP_LOGD(TAG, "TMP117 not ready");
ESP_LOGD(TAG, "Not ready");
}
}
void TMP117Component::setup() {
@@ -38,7 +36,7 @@ void TMP117Component::setup() {
}
}
void TMP117Component::dump_config() {
ESP_LOGD(TAG, "TMP117:");
ESP_LOGCONFIG(TAG, "TMP117:");
LOG_I2C_DEVICE(this);
if (this->is_failed()) {
ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
@@ -48,7 +46,7 @@ void TMP117Component::dump_config() {
bool TMP117Component::read_data_(int16_t *data) {
if (!this->read_byte_16(0, (uint16_t *) data)) {
ESP_LOGW(TAG, "Updating TMP117 failed!");
ESP_LOGW(TAG, "Updating failed");
return false;
}
return true;
@@ -56,7 +54,7 @@ bool TMP117Component::read_data_(int16_t *data) {
bool TMP117Component::read_config_(uint16_t *config) {
if (!this->read_byte_16(1, (uint16_t *) config)) {
ESP_LOGW(TAG, "Reading TMP117 config failed!");
ESP_LOGW(TAG, "Reading config failed");
return false;
}
return true;
@@ -64,11 +62,10 @@ bool TMP117Component::read_config_(uint16_t *config) {
bool TMP117Component::write_config_(uint16_t config) {
if (!this->write_byte_16(1, config)) {
ESP_LOGE(TAG, "Writing TMP117 config failed!");
ESP_LOGE(TAG, "Writing config failed");
return false;
}
return true;
}
} // namespace tmp117
} // namespace esphome
} // namespace esphome::tmp117
+2 -4
View File
@@ -4,8 +4,7 @@
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/i2c/i2c.h"
namespace esphome {
namespace tmp117 {
namespace esphome::tmp117 {
class TMP117Component : public PollingComponent, public i2c::I2CDevice, public sensor::Sensor {
public:
@@ -22,5 +21,4 @@ class TMP117Component : public PollingComponent, public i2c::I2CDevice, public s
uint16_t config_;
};
} // namespace tmp117
} // namespace esphome
} // namespace esphome::tmp117