From 8b2d76e8cebca0055b08319076f5cc8d94f25383 Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Sun, 14 Jan 2024 16:05:47 -0800 Subject: [PATCH] convert cse7766 to non-polling (#6095) Co-authored-by: Samuel Sieb --- esphome/components/cse7766/cse7766.cpp | 52 +++++--------------- esphome/components/cse7766/cse7766.h | 11 +---- esphome/components/cse7766/sensor.py | 66 ++++++++++++-------------- 3 files changed, 44 insertions(+), 85 deletions(-) diff --git a/esphome/components/cse7766/cse7766.cpp b/esphome/components/cse7766/cse7766.cpp index 60132fd98f..9c5016c503 100644 --- a/esphome/components/cse7766/cse7766.cpp +++ b/esphome/components/cse7766/cse7766.cpp @@ -113,8 +113,9 @@ void CSE7766Component::parse_data_() { bool have_voltage = adj & 0x40; if (have_voltage) { // voltage cycle of serial port outputted is a complete cycle; - this->voltage_acc_ += voltage_calib / float(voltage_cycle); - this->voltage_counts_ += 1; + float voltage = voltage_calib / float(voltage_cycle); + if (this->voltage_sensor_ != nullptr) + this->voltage_sensor_->publish_state(voltage); } bool have_power = adj & 0x10; @@ -126,8 +127,8 @@ void CSE7766Component::parse_data_() { if (!power_cycle_exceeds_range) { power = power_calib / float(power_cycle); } - this->power_acc_ += power; - this->power_counts_ += 1; + if (this->power_sensor_ != nullptr) + this->power_sensor_->publish_state(power); uint32_t difference; if (this->cf_pulses_last_ == 0) { @@ -141,7 +142,10 @@ void CSE7766Component::parse_data_() { } this->cf_pulses_last_ = cf_pulses; this->energy_total_ += difference * float(power_calib) / 1000000.0f / 3600.0f; - this->energy_total_counts_ += 1; + if (this->energy_sensor_ != nullptr) + this->energy_sensor_->publish_state(this->energy_total_); + } else if ((this->energy_sensor_ != nullptr) && !this->energy_sensor_->has_state()) { + this->energy_sensor_->publish_state(0); } if (adj & 0x20) { @@ -150,42 +154,13 @@ void CSE7766Component::parse_data_() { if (have_voltage && !have_power) { // Testing has shown that when we have voltage and current but not power, that means the power is 0. // We report a power of 0, which in turn means we should report a current of 0. - this->power_counts_ += 1; + if (this->power_sensor_ != nullptr) + this->power_sensor_->publish_state(0); } else if (power != 0.0f) { current = current_calib / float(current_cycle); } - this->current_acc_ += current; - this->current_counts_ += 1; - } -} -void CSE7766Component::update() { - const auto publish_state = [](const char *name, sensor::Sensor *sensor, float &acc, uint32_t &counts) { - if (counts != 0) { - const auto avg = acc / counts; - - ESP_LOGV(TAG, "Got %s_acc=%.2f %s_counts=%" PRIu32 " %s=%.1f", name, acc, name, counts, name, avg); - - if (sensor != nullptr) { - sensor->publish_state(avg); - } - - acc = 0.0f; - counts = 0; - } - }; - - publish_state("voltage", this->voltage_sensor_, this->voltage_acc_, this->voltage_counts_); - publish_state("current", this->current_sensor_, this->current_acc_, this->current_counts_); - publish_state("power", this->power_sensor_, this->power_acc_, this->power_counts_); - - if (this->energy_total_counts_ != 0) { - ESP_LOGV(TAG, "Got energy_total=%.2f energy_total_counts=%" PRIu32, this->energy_total_, - this->energy_total_counts_); - - if (this->energy_sensor_ != nullptr) { - this->energy_sensor_->publish_state(this->energy_total_); - } - this->energy_total_counts_ = 0; + if (this->current_sensor_ != nullptr) + this->current_sensor_->publish_state(current); } } @@ -196,7 +171,6 @@ uint32_t CSE7766Component::get_24_bit_uint_(uint8_t start_index) { void CSE7766Component::dump_config() { ESP_LOGCONFIG(TAG, "CSE7766:"); - LOG_UPDATE_INTERVAL(this); LOG_SENSOR(" ", "Voltage", this->voltage_sensor_); LOG_SENSOR(" ", "Current", this->current_sensor_); LOG_SENSOR(" ", "Power", this->power_sensor_); diff --git a/esphome/components/cse7766/cse7766.h b/esphome/components/cse7766/cse7766.h index 2f30eec09f..3ab8d609bd 100644 --- a/esphome/components/cse7766/cse7766.h +++ b/esphome/components/cse7766/cse7766.h @@ -7,7 +7,7 @@ namespace esphome { namespace cse7766 { -class CSE7766Component : public PollingComponent, public uart::UARTDevice { +class CSE7766Component : public Component, public uart::UARTDevice { public: void set_voltage_sensor(sensor::Sensor *voltage_sensor) { voltage_sensor_ = voltage_sensor; } void set_current_sensor(sensor::Sensor *current_sensor) { current_sensor_ = current_sensor; } @@ -16,7 +16,6 @@ class CSE7766Component : public PollingComponent, public uart::UARTDevice { void loop() override; float get_setup_priority() const override; - void update() override; void dump_config() override; protected: @@ -31,16 +30,8 @@ class CSE7766Component : public PollingComponent, public uart::UARTDevice { sensor::Sensor *current_sensor_{nullptr}; sensor::Sensor *power_sensor_{nullptr}; sensor::Sensor *energy_sensor_{nullptr}; - float voltage_acc_{0.0f}; - float current_acc_{0.0f}; - float power_acc_{0.0f}; float energy_total_{0.0f}; uint32_t cf_pulses_last_{0}; - uint32_t voltage_counts_{0}; - uint32_t current_counts_{0}; - uint32_t power_counts_{0}; - // Setting this to 1 means it will always publish 0 once at startup - uint32_t energy_total_counts_{1}; }; } // namespace cse7766 diff --git a/esphome/components/cse7766/sensor.py b/esphome/components/cse7766/sensor.py index d98b351287..f2750bb4f2 100644 --- a/esphome/components/cse7766/sensor.py +++ b/esphome/components/cse7766/sensor.py @@ -22,43 +22,37 @@ from esphome.const import ( DEPENDENCIES = ["uart"] cse7766_ns = cg.esphome_ns.namespace("cse7766") -CSE7766Component = cse7766_ns.class_( - "CSE7766Component", cg.PollingComponent, uart.UARTDevice -) +CSE7766Component = cse7766_ns.class_("CSE7766Component", cg.Component, uart.UARTDevice) -CONFIG_SCHEMA = ( - cv.Schema( - { - cv.GenerateID(): cv.declare_id(CSE7766Component), - cv.Optional(CONF_VOLTAGE): sensor.sensor_schema( - unit_of_measurement=UNIT_VOLT, - accuracy_decimals=1, - device_class=DEVICE_CLASS_VOLTAGE, - state_class=STATE_CLASS_MEASUREMENT, - ), - cv.Optional(CONF_CURRENT): sensor.sensor_schema( - unit_of_measurement=UNIT_AMPERE, - accuracy_decimals=2, - device_class=DEVICE_CLASS_CURRENT, - state_class=STATE_CLASS_MEASUREMENT, - ), - cv.Optional(CONF_POWER): sensor.sensor_schema( - unit_of_measurement=UNIT_WATT, - accuracy_decimals=1, - device_class=DEVICE_CLASS_POWER, - state_class=STATE_CLASS_MEASUREMENT, - ), - cv.Optional(CONF_ENERGY): sensor.sensor_schema( - unit_of_measurement=UNIT_WATT_HOURS, - accuracy_decimals=3, - device_class=DEVICE_CLASS_ENERGY, - state_class=STATE_CLASS_TOTAL_INCREASING, - ), - } - ) - .extend(cv.polling_component_schema("60s")) - .extend(uart.UART_DEVICE_SCHEMA) -) +CONFIG_SCHEMA = cv.Schema( + { + cv.GenerateID(): cv.declare_id(CSE7766Component), + cv.Optional(CONF_VOLTAGE): sensor.sensor_schema( + unit_of_measurement=UNIT_VOLT, + accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLTAGE, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_CURRENT): sensor.sensor_schema( + unit_of_measurement=UNIT_AMPERE, + accuracy_decimals=2, + device_class=DEVICE_CLASS_CURRENT, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_POWER): sensor.sensor_schema( + unit_of_measurement=UNIT_WATT, + accuracy_decimals=1, + device_class=DEVICE_CLASS_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_ENERGY): sensor.sensor_schema( + unit_of_measurement=UNIT_WATT_HOURS, + accuracy_decimals=3, + device_class=DEVICE_CLASS_ENERGY, + state_class=STATE_CLASS_TOTAL_INCREASING, + ), + } +).extend(uart.UART_DEVICE_SCHEMA) FINAL_VALIDATE_SCHEMA = uart.final_validate_device_schema( "cse7766", baud_rate=4800, require_rx=True )