From defe8ac97b580fede9584f50c8ee6feacb05d4b2 Mon Sep 17 00:00:00 2001 From: Angel Nunez Mencias Date: Tue, 7 Nov 2023 01:17:29 +0100 Subject: [PATCH] Add spi support for ade7953 (#5439) Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- CODEOWNERS | 3 + esphome/components/ade7953/__init__.py | 1 + esphome/components/ade7953/ade7953.cpp | 53 ----- esphome/components/ade7953/ade7953.h | 97 --------- esphome/components/ade7953/sensor.py | 91 +------- esphome/components/ade7953_base/__init__.py | 196 ++++++++++++++++++ .../components/ade7953_base/ade7953_base.cpp | 129 ++++++++++++ .../components/ade7953_base/ade7953_base.h | 121 +++++++++++ esphome/components/ade7953_i2c/__init__.py | 1 + .../components/ade7953_i2c/ade7953_i2c.cpp | 80 +++++++ esphome/components/ade7953_i2c/ade7953_i2c.h | 28 +++ esphome/components/ade7953_i2c/sensor.py | 27 +++ esphome/components/ade7953_spi/__init__.py | 1 + .../components/ade7953_spi/ade7953_spi.cpp | 81 ++++++++ esphome/components/ade7953_spi/ade7953_spi.h | 32 +++ esphome/components/ade7953_spi/sensor.py | 27 +++ tests/test11.5.yaml | 63 ++++++ tests/test3.1.yaml | 44 +++- 18 files changed, 834 insertions(+), 241 deletions(-) delete mode 100644 esphome/components/ade7953/ade7953.cpp delete mode 100644 esphome/components/ade7953/ade7953.h create mode 100644 esphome/components/ade7953_base/__init__.py create mode 100644 esphome/components/ade7953_base/ade7953_base.cpp create mode 100644 esphome/components/ade7953_base/ade7953_base.h create mode 100644 esphome/components/ade7953_i2c/__init__.py create mode 100644 esphome/components/ade7953_i2c/ade7953_i2c.cpp create mode 100644 esphome/components/ade7953_i2c/ade7953_i2c.h create mode 100644 esphome/components/ade7953_i2c/sensor.py create mode 100644 esphome/components/ade7953_spi/__init__.py create mode 100644 esphome/components/ade7953_spi/ade7953_spi.cpp create mode 100644 esphome/components/ade7953_spi/ade7953_spi.h create mode 100644 esphome/components/ade7953_spi/sensor.py diff --git a/CODEOWNERS b/CODEOWNERS index 067b886320..2dcef6c514 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -17,6 +17,9 @@ esphome/components/ac_dimmer/* @glmnet esphome/components/adc/* @esphome/core esphome/components/adc128s102/* @DeerMaximum esphome/components/addressable_light/* @justfalter +esphome/components/ade7953/* @angelnu +esphome/components/ade7953_i2c/* @angelnu +esphome/components/ade7953_spi/* @angelnu esphome/components/airthings_ble/* @jeromelaban esphome/components/airthings_wave_base/* @jeromelaban @kpfleming @ncareau esphome/components/airthings_wave_mini/* @ncareau diff --git a/esphome/components/ade7953/__init__.py b/esphome/components/ade7953/__init__.py index e69de29bb2..d3078a0b67 100644 --- a/esphome/components/ade7953/__init__.py +++ b/esphome/components/ade7953/__init__.py @@ -0,0 +1 @@ +CODEOWNERS = ["@angelnu"] diff --git a/esphome/components/ade7953/ade7953.cpp b/esphome/components/ade7953/ade7953.cpp deleted file mode 100644 index 2c61fc6a44..0000000000 --- a/esphome/components/ade7953/ade7953.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "ade7953.h" -#include "esphome/core/log.h" - -namespace esphome { -namespace ade7953 { - -static const char *const TAG = "ade7953"; - -void ADE7953::dump_config() { - ESP_LOGCONFIG(TAG, "ADE7953:"); - LOG_PIN(" IRQ Pin: ", irq_pin_); - LOG_I2C_DEVICE(this); - LOG_UPDATE_INTERVAL(this); - LOG_SENSOR(" ", "Voltage Sensor", this->voltage_sensor_); - LOG_SENSOR(" ", "Current A Sensor", this->current_a_sensor_); - LOG_SENSOR(" ", "Current B Sensor", this->current_b_sensor_); - LOG_SENSOR(" ", "Active Power A Sensor", this->active_power_a_sensor_); - LOG_SENSOR(" ", "Active Power B Sensor", this->active_power_b_sensor_); -} - -#define ADE_PUBLISH_(name, val, factor) \ - if (err == i2c::ERROR_OK && this->name##_sensor_) { \ - float value = (val) / (factor); \ - this->name##_sensor_->publish_state(value); \ - } -#define ADE_PUBLISH(name, val, factor) ADE_PUBLISH_(name, val, factor) - -void ADE7953::update() { - if (!this->is_setup_) - return; - - uint32_t val; - i2c::ErrorCode err = ade_read_32_(0x0312, &val); - ADE_PUBLISH(active_power_a, (int32_t) val, 154.0f); - err = ade_read_32_(0x0313, &val); - ADE_PUBLISH(active_power_b, (int32_t) val, 154.0f); - err = ade_read_32_(0x031A, &val); - ADE_PUBLISH(current_a, (uint32_t) val, 100000.0f); - err = ade_read_32_(0x031B, &val); - ADE_PUBLISH(current_b, (uint32_t) val, 100000.0f); - err = ade_read_32_(0x031C, &val); - ADE_PUBLISH(voltage, (uint32_t) val, 26000.0f); - - // auto apparent_power_a = this->ade_read_(0x0310); - // auto apparent_power_b = this->ade_read_(0x0311); - // auto reactive_power_a = this->ade_read_(0x0314); - // auto reactive_power_b = this->ade_read_(0x0315); - // auto power_factor_a = this->ade_read_(0x010A); - // auto power_factor_b = this->ade_read_(0x010B); -} - -} // namespace ade7953 -} // namespace esphome diff --git a/esphome/components/ade7953/ade7953.h b/esphome/components/ade7953/ade7953.h deleted file mode 100644 index c0c1cc4db8..0000000000 --- a/esphome/components/ade7953/ade7953.h +++ /dev/null @@ -1,97 +0,0 @@ -#pragma once - -#include "esphome/core/component.h" -#include "esphome/core/hal.h" -#include "esphome/components/i2c/i2c.h" -#include "esphome/components/sensor/sensor.h" - -#include - -namespace esphome { -namespace ade7953 { - -class ADE7953 : public i2c::I2CDevice, public PollingComponent { - public: - void set_irq_pin(InternalGPIOPin *irq_pin) { irq_pin_ = irq_pin; } - void set_voltage_sensor(sensor::Sensor *voltage_sensor) { voltage_sensor_ = voltage_sensor; } - void set_current_a_sensor(sensor::Sensor *current_a_sensor) { current_a_sensor_ = current_a_sensor; } - void set_current_b_sensor(sensor::Sensor *current_b_sensor) { current_b_sensor_ = current_b_sensor; } - void set_active_power_a_sensor(sensor::Sensor *active_power_a_sensor) { - active_power_a_sensor_ = active_power_a_sensor; - } - void set_active_power_b_sensor(sensor::Sensor *active_power_b_sensor) { - active_power_b_sensor_ = active_power_b_sensor; - } - - void setup() override { - if (this->irq_pin_ != nullptr) { - this->irq_pin_->setup(); - } - this->set_timeout(100, [this]() { - this->ade_write_8_(0x0010, 0x04); - this->ade_write_8_(0x00FE, 0xAD); - this->ade_write_16_(0x0120, 0x0030); - this->is_setup_ = true; - }); - } - - void dump_config() override; - - void update() override; - - protected: - i2c::ErrorCode ade_write_8_(uint16_t reg, uint8_t value) { - std::vector data; - data.push_back(reg >> 8); - data.push_back(reg >> 0); - data.push_back(value); - return write(data.data(), data.size()); - } - i2c::ErrorCode ade_write_16_(uint16_t reg, uint16_t value) { - std::vector data; - data.push_back(reg >> 8); - data.push_back(reg >> 0); - data.push_back(value >> 8); - data.push_back(value >> 0); - return write(data.data(), data.size()); - } - i2c::ErrorCode ade_write_32_(uint16_t reg, uint32_t value) { - std::vector data; - data.push_back(reg >> 8); - data.push_back(reg >> 0); - data.push_back(value >> 24); - data.push_back(value >> 16); - data.push_back(value >> 8); - data.push_back(value >> 0); - return write(data.data(), data.size()); - } - i2c::ErrorCode ade_read_32_(uint16_t reg, uint32_t *value) { - uint8_t reg_data[2]; - reg_data[0] = reg >> 8; - reg_data[1] = reg >> 0; - i2c::ErrorCode err = write(reg_data, 2); - if (err != i2c::ERROR_OK) - return err; - uint8_t recv[4]; - err = read(recv, 4); - if (err != i2c::ERROR_OK) - return err; - *value = 0; - *value |= ((uint32_t) recv[0]) << 24; - *value |= ((uint32_t) recv[1]) << 16; - *value |= ((uint32_t) recv[2]) << 8; - *value |= ((uint32_t) recv[3]); - return i2c::ERROR_OK; - } - - InternalGPIOPin *irq_pin_{nullptr}; - bool is_setup_{false}; - sensor::Sensor *voltage_sensor_{nullptr}; - sensor::Sensor *current_a_sensor_{nullptr}; - sensor::Sensor *current_b_sensor_{nullptr}; - sensor::Sensor *active_power_a_sensor_{nullptr}; - sensor::Sensor *active_power_b_sensor_{nullptr}; -}; - -} // namespace ade7953 -} // namespace esphome diff --git a/esphome/components/ade7953/sensor.py b/esphome/components/ade7953/sensor.py index 8a43baf475..0caa2ef454 100644 --- a/esphome/components/ade7953/sensor.py +++ b/esphome/components/ade7953/sensor.py @@ -1,90 +1,5 @@ -import esphome.codegen as cg import esphome.config_validation as cv -from esphome.components import sensor, i2c -from esphome import pins -from esphome.const import ( - CONF_ID, - CONF_IRQ_PIN, - CONF_VOLTAGE, - DEVICE_CLASS_CURRENT, - DEVICE_CLASS_POWER, - DEVICE_CLASS_VOLTAGE, - STATE_CLASS_MEASUREMENT, - UNIT_AMPERE, - UNIT_VOLT, - UNIT_WATT, + +CONFIG_SCHEMA = CONFIG_SCHEMA = cv.invalid( + "The ade7953 sensor component has been renamed to ade7953_i2c." ) - -DEPENDENCIES = ["i2c"] - -ade7953_ns = cg.esphome_ns.namespace("ade7953") -ADE7953 = ade7953_ns.class_("ADE7953", cg.PollingComponent, i2c.I2CDevice) - -CONF_CURRENT_A = "current_a" -CONF_CURRENT_B = "current_b" -CONF_ACTIVE_POWER_A = "active_power_a" -CONF_ACTIVE_POWER_B = "active_power_b" - -CONFIG_SCHEMA = ( - cv.Schema( - { - cv.GenerateID(): cv.declare_id(ADE7953), - cv.Optional(CONF_IRQ_PIN): pins.internal_gpio_input_pin_schema, - 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_A): sensor.sensor_schema( - unit_of_measurement=UNIT_AMPERE, - accuracy_decimals=2, - device_class=DEVICE_CLASS_CURRENT, - state_class=STATE_CLASS_MEASUREMENT, - ), - cv.Optional(CONF_CURRENT_B): sensor.sensor_schema( - unit_of_measurement=UNIT_AMPERE, - accuracy_decimals=2, - device_class=DEVICE_CLASS_CURRENT, - state_class=STATE_CLASS_MEASUREMENT, - ), - cv.Optional(CONF_ACTIVE_POWER_A): sensor.sensor_schema( - unit_of_measurement=UNIT_WATT, - accuracy_decimals=1, - device_class=DEVICE_CLASS_POWER, - state_class=STATE_CLASS_MEASUREMENT, - ), - cv.Optional(CONF_ACTIVE_POWER_B): sensor.sensor_schema( - unit_of_measurement=UNIT_WATT, - accuracy_decimals=1, - device_class=DEVICE_CLASS_POWER, - state_class=STATE_CLASS_MEASUREMENT, - ), - } - ) - .extend(cv.polling_component_schema("60s")) - .extend(i2c.i2c_device_schema(0x38)) -) - - -async def to_code(config): - var = cg.new_Pvariable(config[CONF_ID]) - await cg.register_component(var, config) - await i2c.register_i2c_device(var, config) - - if irq_pin_config := config.get(CONF_IRQ_PIN): - irq_pin = await cg.gpio_pin_expression(irq_pin_config) - cg.add(var.set_irq_pin(irq_pin)) - - for key in [ - CONF_VOLTAGE, - CONF_CURRENT_A, - CONF_CURRENT_B, - CONF_ACTIVE_POWER_A, - CONF_ACTIVE_POWER_B, - ]: - if key not in config: - continue - conf = config[key] - sens = await sensor.new_sensor(conf) - cg.add(getattr(var, f"set_{key}_sensor")(sens)) diff --git a/esphome/components/ade7953_base/__init__.py b/esphome/components/ade7953_base/__init__.py new file mode 100644 index 0000000000..d4c18f8ffd --- /dev/null +++ b/esphome/components/ade7953_base/__init__.py @@ -0,0 +1,196 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import sensor +from esphome import pins +from esphome.const import ( + CONF_IRQ_PIN, + CONF_VOLTAGE, + CONF_FREQUENCY, + DEVICE_CLASS_CURRENT, + DEVICE_CLASS_APPARENT_POWER, + DEVICE_CLASS_POWER, + DEVICE_CLASS_REACTIVE_POWER, + DEVICE_CLASS_POWER_FACTOR, + DEVICE_CLASS_VOLTAGE, + DEVICE_CLASS_FREQUENCY, + STATE_CLASS_MEASUREMENT, + UNIT_VOLT, + UNIT_HERTZ, + UNIT_AMPERE, + UNIT_VOLT_AMPS, + UNIT_WATT, + UNIT_VOLT_AMPS_REACTIVE, + UNIT_PERCENT, +) + +CONF_CURRENT_A = "current_a" +CONF_CURRENT_B = "current_b" +CONF_ACTIVE_POWER_A = "active_power_a" +CONF_ACTIVE_POWER_B = "active_power_b" +CONF_APPARENT_POWER_A = "apparent_power_a" +CONF_APPARENT_POWER_B = "apparent_power_b" +CONF_REACTIVE_POWER_A = "reactive_power_a" +CONF_REACTIVE_POWER_B = "reactive_power_b" +CONF_POWER_FACTOR_A = "power_factor_a" +CONF_POWER_FACTOR_B = "power_factor_b" +CONF_VOLTAGE_PGA_GAIN = "voltage_pga_gain" +CONF_CURRENT_PGA_GAIN_A = "current_pga_gain_a" +CONF_CURRENT_PGA_GAIN_B = "current_pga_gain_b" +CONF_VOLTAGE_GAIN = "voltage_gain" +CONF_CURRENT_GAIN_A = "current_gain_a" +CONF_CURRENT_GAIN_B = "current_gain_b" +CONF_ACTIVE_POWER_GAIN_A = "active_power_gain_a" +CONF_ACTIVE_POWER_GAIN_B = "active_power_gain_b" +PGA_GAINS = { + "1x": 0b000, + "2x": 0b001, + "4x": 0b010, + "8x": 0b011, + "16x": 0b100, + "22x": 0b101, +} + +ade7953_base_ns = cg.esphome_ns.namespace("ade7953_base") +ADE7953 = ade7953_base_ns.class_("ADE7953", cg.PollingComponent) + +ADE7953_CONFIG_SCHEMA = cv.Schema( + { + cv.Optional(CONF_IRQ_PIN): pins.internal_gpio_input_pin_schema, + 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_FREQUENCY): sensor.sensor_schema( + unit_of_measurement=UNIT_HERTZ, + accuracy_decimals=2, + device_class=DEVICE_CLASS_FREQUENCY, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_CURRENT_A): sensor.sensor_schema( + unit_of_measurement=UNIT_AMPERE, + accuracy_decimals=2, + device_class=DEVICE_CLASS_CURRENT, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_CURRENT_B): sensor.sensor_schema( + unit_of_measurement=UNIT_AMPERE, + accuracy_decimals=2, + device_class=DEVICE_CLASS_CURRENT, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_ACTIVE_POWER_A): sensor.sensor_schema( + unit_of_measurement=UNIT_WATT, + accuracy_decimals=1, + device_class=DEVICE_CLASS_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_ACTIVE_POWER_B): sensor.sensor_schema( + unit_of_measurement=UNIT_WATT, + accuracy_decimals=1, + device_class=DEVICE_CLASS_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_APPARENT_POWER_A): sensor.sensor_schema( + unit_of_measurement=UNIT_VOLT_AMPS, + accuracy_decimals=1, + device_class=DEVICE_CLASS_APPARENT_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_APPARENT_POWER_B): sensor.sensor_schema( + unit_of_measurement=UNIT_VOLT_AMPS, + accuracy_decimals=1, + device_class=DEVICE_CLASS_APPARENT_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_REACTIVE_POWER_A): sensor.sensor_schema( + unit_of_measurement=UNIT_VOLT_AMPS_REACTIVE, + accuracy_decimals=1, + device_class=DEVICE_CLASS_REACTIVE_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_REACTIVE_POWER_B): sensor.sensor_schema( + unit_of_measurement=UNIT_VOLT_AMPS_REACTIVE, + accuracy_decimals=1, + device_class=DEVICE_CLASS_REACTIVE_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_POWER_FACTOR_A): sensor.sensor_schema( + unit_of_measurement=UNIT_PERCENT, + accuracy_decimals=2, + device_class=DEVICE_CLASS_POWER_FACTOR, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_POWER_FACTOR_B): sensor.sensor_schema( + unit_of_measurement=UNIT_PERCENT, + accuracy_decimals=2, + device_class=DEVICE_CLASS_POWER_FACTOR, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional( + CONF_VOLTAGE_PGA_GAIN, + default="1x", + ): cv.one_of(*PGA_GAINS, lower=True), + cv.Optional( + CONF_CURRENT_PGA_GAIN_A, + default="1x", + ): cv.one_of(*PGA_GAINS, lower=True), + cv.Optional( + CONF_CURRENT_PGA_GAIN_B, + default="1x", + ): cv.one_of(*PGA_GAINS, lower=True), + cv.Optional(CONF_VOLTAGE_GAIN, default=0x400000): cv.hex_int_range( + min=0x100000, max=0x800000 + ), + cv.Optional(CONF_CURRENT_GAIN_A, default=0x400000): cv.hex_int_range( + min=0x100000, max=0x800000 + ), + cv.Optional(CONF_CURRENT_GAIN_B, default=0x400000): cv.hex_int_range( + min=0x100000, max=0x800000 + ), + cv.Optional(CONF_ACTIVE_POWER_GAIN_A, default=0x400000): cv.hex_int_range( + min=0x100000, max=0x800000 + ), + cv.Optional(CONF_ACTIVE_POWER_GAIN_B, default=0x400000): cv.hex_int_range( + min=0x100000, max=0x800000 + ), + } +).extend(cv.polling_component_schema("60s")) + + +async def register_ade7953(var, config): + await cg.register_component(var, config) + + if irq_pin_config := config.get(CONF_IRQ_PIN): + irq_pin = await cg.gpio_pin_expression(irq_pin_config) + cg.add(var.set_irq_pin(irq_pin)) + + cg.add(var.set_pga_v(PGA_GAINS[config.get(CONF_VOLTAGE_PGA_GAIN)])) + cg.add(var.set_pga_ia(PGA_GAINS[config.get(CONF_CURRENT_PGA_GAIN_A)])) + cg.add(var.set_pga_ib(PGA_GAINS[config.get(CONF_CURRENT_PGA_GAIN_B)])) + cg.add(var.set_vgain(config.get(CONF_VOLTAGE_GAIN))) + cg.add(var.set_aigain(config.get(CONF_CURRENT_GAIN_A))) + cg.add(var.set_bigain(config.get(CONF_CURRENT_GAIN_B))) + cg.add(var.set_awgain(config.get(CONF_ACTIVE_POWER_GAIN_A))) + cg.add(var.set_bwgain(config.get(CONF_ACTIVE_POWER_GAIN_B))) + + for key in [ + CONF_VOLTAGE, + CONF_FREQUENCY, + CONF_CURRENT_A, + CONF_CURRENT_B, + CONF_POWER_FACTOR_A, + CONF_POWER_FACTOR_B, + CONF_APPARENT_POWER_A, + CONF_APPARENT_POWER_B, + CONF_ACTIVE_POWER_A, + CONF_ACTIVE_POWER_B, + CONF_REACTIVE_POWER_A, + CONF_REACTIVE_POWER_B, + ]: + if key not in config: + continue + conf = config[key] + sens = await sensor.new_sensor(conf) + cg.add(getattr(var, f"set_{key}_sensor")(sens)) diff --git a/esphome/components/ade7953_base/ade7953_base.cpp b/esphome/components/ade7953_base/ade7953_base.cpp new file mode 100644 index 0000000000..af6fe0a5df --- /dev/null +++ b/esphome/components/ade7953_base/ade7953_base.cpp @@ -0,0 +1,129 @@ +#include "ade7953_base.h" +#include "esphome/core/log.h" + +namespace esphome { +namespace ade7953_base { + +static const char *const TAG = "ade7953"; + +void ADE7953::setup() { + if (this->irq_pin_ != nullptr) { + this->irq_pin_->setup(); + } + + // The chip might take up to 100ms to initialise + this->set_timeout(100, [this]() { + // this->ade_write_8(0x0010, 0x04); + this->ade_write_8(0x00FE, 0xAD); + this->ade_write_16(0x0120, 0x0030); + // Set gains + this->ade_write_8(PGA_V_8, pga_v_); + this->ade_write_8(PGA_IA_8, pga_ia_); + this->ade_write_8(PGA_IB_8, pga_ib_); + this->ade_write_32(AVGAIN_32, vgain_); + this->ade_write_32(AIGAIN_32, aigain_); + this->ade_write_32(BIGAIN_32, bigain_); + this->ade_write_32(AWGAIN_32, awgain_); + this->ade_write_32(BWGAIN_32, bwgain_); + // Read back gains for debugging + this->ade_read_8(PGA_V_8, &pga_v_); + this->ade_read_8(PGA_IA_8, &pga_ia_); + this->ade_read_8(PGA_IB_8, &pga_ib_); + this->ade_read_32(AVGAIN_32, &vgain_); + this->ade_read_32(AIGAIN_32, &aigain_); + this->ade_read_32(BIGAIN_32, &bigain_); + this->ade_read_32(AWGAIN_32, &awgain_); + this->ade_read_32(BWGAIN_32, &bwgain_); + this->is_setup_ = true; + }); +} + +void ADE7953::dump_config() { + LOG_PIN(" IRQ Pin: ", irq_pin_); + LOG_UPDATE_INTERVAL(this); + LOG_SENSOR(" ", "Voltage Sensor", this->voltage_sensor_); + LOG_SENSOR(" ", "Current A Sensor", this->current_a_sensor_); + LOG_SENSOR(" ", "Current B Sensor", this->current_b_sensor_); + LOG_SENSOR(" ", "Power Factor A Sensor", this->power_factor_a_sensor_); + LOG_SENSOR(" ", "Power Factor B Sensor", this->power_factor_b_sensor_); + LOG_SENSOR(" ", "Apparent Power A Sensor", this->apparent_power_a_sensor_); + LOG_SENSOR(" ", "Apparent Power B Sensor", this->apparent_power_b_sensor_); + LOG_SENSOR(" ", "Active Power A Sensor", this->active_power_a_sensor_); + LOG_SENSOR(" ", "Active Power B Sensor", this->active_power_b_sensor_); + LOG_SENSOR(" ", "Rective Power A Sensor", this->reactive_power_a_sensor_); + LOG_SENSOR(" ", "Reactive Power B Sensor", this->reactive_power_b_sensor_); + ESP_LOGCONFIG(TAG, " PGA_V_8: 0x%X", pga_v_); + ESP_LOGCONFIG(TAG, " PGA_IA_8: 0x%X", pga_ia_); + ESP_LOGCONFIG(TAG, " PGA_IB_8: 0x%X", pga_ib_); + ESP_LOGCONFIG(TAG, " VGAIN_32: 0x%08jX", (uintmax_t) vgain_); + ESP_LOGCONFIG(TAG, " AIGAIN_32: 0x%08jX", (uintmax_t) aigain_); + ESP_LOGCONFIG(TAG, " BIGAIN_32: 0x%08jX", (uintmax_t) bigain_); + ESP_LOGCONFIG(TAG, " AWGAIN_32: 0x%08jX", (uintmax_t) awgain_); + ESP_LOGCONFIG(TAG, " BWGAIN_32: 0x%08jX", (uintmax_t) bwgain_); +} + +#define ADE_PUBLISH_(name, val, factor) \ + if (err == 0 && this->name##_sensor_) { \ + float value = (val) / (factor); \ + this->name##_sensor_->publish_state(value); \ + } +#define ADE_PUBLISH(name, val, factor) ADE_PUBLISH_(name, val, factor) + +void ADE7953::update() { + if (!this->is_setup_) + return; + + bool err; + + uint32_t interrupts_a = 0; + uint32_t interrupts_b = 0; + if (this->irq_pin_ != nullptr) { + // Read and reset interrupts + this->ade_read_32(0x032E, &interrupts_a); + this->ade_read_32(0x0331, &interrupts_b); + } + + uint32_t val; + uint16_t val_16; + + // Power factor + err = this->ade_read_16(0x010A, &val_16); + ADE_PUBLISH(power_factor_a, (int16_t) val_16, (0x7FFF / 100.0f)); + err = this->ade_read_16(0x010B, &val_16); + ADE_PUBLISH(power_factor_b, (int16_t) val_16, (0x7FFF / 100.0f)); + + // Apparent power + err = this->ade_read_32(0x0310, &val); + ADE_PUBLISH(apparent_power_a, (int32_t) val, 154.0f); + err = this->ade_read_32(0x0311, &val); + ADE_PUBLISH(apparent_power_b, (int32_t) val, 154.0f); + + // Active power + err = this->ade_read_32(0x0312, &val); + ADE_PUBLISH(active_power_a, (int32_t) val, 154.0f); + err = this->ade_read_32(0x0313, &val); + ADE_PUBLISH(active_power_b, (int32_t) val, 154.0f); + + // Reactive power + err = this->ade_read_32(0x0314, &val); + ADE_PUBLISH(reactive_power_a, (int32_t) val, 154.0f); + err = this->ade_read_32(0x0315, &val); + ADE_PUBLISH(reactive_power_b, (int32_t) val, 154.0f); + + // Current + err = this->ade_read_32(0x031A, &val); + ADE_PUBLISH(current_a, (uint32_t) val, 100000.0f); + err = this->ade_read_32(0x031B, &val); + ADE_PUBLISH(current_b, (uint32_t) val, 100000.0f); + + // Voltage + err = this->ade_read_32(0x031C, &val); + ADE_PUBLISH(voltage, (uint32_t) val, 26000.0f); + + // Frequency + err = this->ade_read_16(0x010E, &val_16); + ADE_PUBLISH(frequency, 223750.0f, 1 + val_16); +} + +} // namespace ade7953_base +} // namespace esphome diff --git a/esphome/components/ade7953_base/ade7953_base.h b/esphome/components/ade7953_base/ade7953_base.h new file mode 100644 index 0000000000..f57a8aa1df --- /dev/null +++ b/esphome/components/ade7953_base/ade7953_base.h @@ -0,0 +1,121 @@ +#pragma once + +#include "esphome/core/component.h" +#include "esphome/core/hal.h" +#include "esphome/components/sensor/sensor.h" + +#include + +namespace esphome { +namespace ade7953_base { + +static const uint8_t PGA_V_8 = + 0x007; // PGA_V, (R/W) Default: 0x00, Unsigned, Voltage channel gain configuration (Bits[2:0]) +static const uint8_t PGA_IA_8 = + 0x008; // PGA_IA, (R/W) Default: 0x00, Unsigned, Current Channel A gain configuration (Bits[2:0]) +static const uint8_t PGA_IB_8 = + 0x009; // PGA_IB, (R/W) Default: 0x00, Unsigned, Current Channel B gain configuration (Bits[2:0]) + +static const uint32_t AIGAIN_32 = + 0x380; // AIGAIN, (R/W) Default: 0x400000, Unsigned,Current channel gain (Current Channel A)(32 bit) +static const uint32_t AVGAIN_32 = 0x381; // AVGAIN, (R/W) Default: 0x400000, Unsigned,Voltage channel gain(32 bit) +static const uint32_t AWGAIN_32 = + 0x382; // AWGAIN, (R/W) Default: 0x400000, Unsigned,Active power gain (Current Channel A)(32 bit) +static const uint32_t AVARGAIN_32 = + 0x383; // AVARGAIN, (R/W) Default: 0x400000, Unsigned, Reactive power gain (Current Channel A)(32 bit) +static const uint32_t AVAGAIN_32 = + 0x384; // AVAGAIN, (R/W) Default: 0x400000, Unsigned,Apparent power gain (Current Channel A)(32 bit) + +static const uint32_t BIGAIN_32 = + 0x38C; // BIGAIN, (R/W) Default: 0x400000, Unsigned,Current channel gain (Current Channel B)(32 bit) +static const uint32_t BVGAIN_32 = 0x38D; // BVGAIN, (R/W) Default: 0x400000, Unsigned,Voltage channel gain(32 bit) +static const uint32_t BWGAIN_32 = + 0x38E; // BWGAIN, (R/W) Default: 0x400000, Unsigned,Active power gain (Current Channel B)(32 bit) +static const uint32_t BVARGAIN_32 = + 0x38F; // BVARGAIN, (R/W) Default: 0x400000, Unsigned, Reactive power gain (Current Channel B)(32 bit) +static const uint32_t BVAGAIN_32 = + 0x390; // BVAGAIN, (R/W) Default: 0x400000, Unsigned,Apparent power gain (Current Channel B)(32 bit) + +class ADE7953 : public PollingComponent, public sensor::Sensor { + public: + void set_irq_pin(InternalGPIOPin *irq_pin) { irq_pin_ = irq_pin; } + + // Set PGA input gains: 0 1x, 1 2x, 0b10 4x + void set_pga_v(uint8_t pga_v) { pga_v_ = pga_v; } + void set_pga_ia(uint8_t pga_ia) { pga_ia_ = pga_ia; } + void set_pga_ib(uint8_t pga_ib) { pga_ib_ = pga_ib; } + + // Set input gains + void set_vgain(uint32_t vgain) { vgain_ = vgain; } + void set_aigain(uint32_t aigain) { aigain_ = aigain; } + void set_bigain(uint32_t bigain) { bigain_ = bigain; } + void set_awgain(uint32_t awgain) { awgain_ = awgain; } + void set_bwgain(uint32_t bwgain) { bwgain_ = bwgain; } + + void set_voltage_sensor(sensor::Sensor *voltage_sensor) { voltage_sensor_ = voltage_sensor; } + void set_frequency_sensor(sensor::Sensor *frequency_sensor) { frequency_sensor_ = frequency_sensor; } + + void set_power_factor_a_sensor(sensor::Sensor *power_factor_a) { power_factor_a_sensor_ = power_factor_a; } + void set_power_factor_b_sensor(sensor::Sensor *power_factor_b) { power_factor_b_sensor_ = power_factor_b; } + + void set_current_a_sensor(sensor::Sensor *current_a_sensor) { current_a_sensor_ = current_a_sensor; } + void set_current_b_sensor(sensor::Sensor *current_b_sensor) { current_b_sensor_ = current_b_sensor; } + + void set_apparent_power_a_sensor(sensor::Sensor *apparent_power_a) { apparent_power_a_sensor_ = apparent_power_a; } + void set_apparent_power_b_sensor(sensor::Sensor *apparent_power_b) { apparent_power_b_sensor_ = apparent_power_b; } + + void set_active_power_a_sensor(sensor::Sensor *active_power_a_sensor) { + active_power_a_sensor_ = active_power_a_sensor; + } + void set_active_power_b_sensor(sensor::Sensor *active_power_b_sensor) { + active_power_b_sensor_ = active_power_b_sensor; + } + + void set_reactive_power_a_sensor(sensor::Sensor *reactive_power_a) { reactive_power_a_sensor_ = reactive_power_a; } + void set_reactive_power_b_sensor(sensor::Sensor *reactive_power_b) { reactive_power_b_sensor_ = reactive_power_b; } + + void setup() override; + + void dump_config() override; + + void update() override; + + protected: + InternalGPIOPin *irq_pin_{nullptr}; + bool is_setup_{false}; + sensor::Sensor *voltage_sensor_{nullptr}; + sensor::Sensor *frequency_sensor_{nullptr}; + sensor::Sensor *current_a_sensor_{nullptr}; + sensor::Sensor *current_b_sensor_{nullptr}; + sensor::Sensor *apparent_power_a_sensor_{nullptr}; + sensor::Sensor *apparent_power_b_sensor_{nullptr}; + sensor::Sensor *active_power_a_sensor_{nullptr}; + sensor::Sensor *active_power_b_sensor_{nullptr}; + sensor::Sensor *reactive_power_a_sensor_{nullptr}; + sensor::Sensor *reactive_power_b_sensor_{nullptr}; + sensor::Sensor *power_factor_a_sensor_{nullptr}; + sensor::Sensor *power_factor_b_sensor_{nullptr}; + uint8_t pga_v_; + uint8_t pga_ia_; + uint8_t pga_ib_; + uint32_t vgain_; + uint32_t aigain_; + uint32_t bigain_; + uint32_t awgain_; + uint32_t bwgain_; + + virtual bool ade_write_8(uint16_t reg, uint8_t value) = 0; + + virtual bool ade_write_16(uint16_t reg, uint16_t value) = 0; + + virtual bool ade_write_32(uint16_t reg, uint32_t value) = 0; + + virtual bool ade_read_8(uint16_t reg, uint8_t *value) = 0; + + virtual bool ade_read_16(uint16_t reg, uint16_t *value) = 0; + + virtual bool ade_read_32(uint16_t reg, uint32_t *value) = 0; +}; + +} // namespace ade7953_base +} // namespace esphome diff --git a/esphome/components/ade7953_i2c/__init__.py b/esphome/components/ade7953_i2c/__init__.py new file mode 100644 index 0000000000..d3078a0b67 --- /dev/null +++ b/esphome/components/ade7953_i2c/__init__.py @@ -0,0 +1 @@ +CODEOWNERS = ["@angelnu"] diff --git a/esphome/components/ade7953_i2c/ade7953_i2c.cpp b/esphome/components/ade7953_i2c/ade7953_i2c.cpp new file mode 100644 index 0000000000..572337428a --- /dev/null +++ b/esphome/components/ade7953_i2c/ade7953_i2c.cpp @@ -0,0 +1,80 @@ +#include "ade7953_i2c.h" +#include "esphome/core/log.h" +#include "esphome/core/helpers.h" + +namespace esphome { +namespace ade7953_i2c { + +static const char *const TAG = "ade7953"; + +void AdE7953I2c::dump_config() { + ESP_LOGCONFIG(TAG, "ADE7953_i2c:"); + LOG_I2C_DEVICE(this); + ade7953_base::ADE7953::dump_config(); +} +bool AdE7953I2c::ade_write_8(uint16_t reg, uint8_t value) { + std::vector data(3); + data.push_back(reg >> 8); + data.push_back(reg >> 0); + data.push_back(value); + return this->write(data.data(), data.size()) != i2c::ERROR_OK; +} +bool AdE7953I2c::ade_write_16(uint16_t reg, uint16_t value) { + std::vector data(4); + data.push_back(reg >> 8); + data.push_back(reg >> 0); + data.push_back(value >> 8); + data.push_back(value >> 0); + return this->write(data.data(), data.size()) != i2c::ERROR_OK; +} +bool AdE7953I2c::ade_write_32(uint16_t reg, uint32_t value) { + std::vector data(6); + data.push_back(reg >> 8); + data.push_back(reg >> 0); + data.push_back(value >> 24); + data.push_back(value >> 16); + data.push_back(value >> 8); + data.push_back(value >> 0); + return this->write(data.data(), data.size()) != i2c::ERROR_OK; +} +bool AdE7953I2c::ade_read_8(uint16_t reg, uint8_t *value) { + uint8_t reg_data[2]; + reg_data[0] = reg >> 8; + reg_data[1] = reg >> 0; + i2c::ErrorCode err = this->write(reg_data, 2); + if (err != i2c::ERROR_OK) + return true; + err = this->read(value, 1); + return (err != i2c::ERROR_OK); +} +bool AdE7953I2c::ade_read_16(uint16_t reg, uint16_t *value) { + uint8_t reg_data[2]; + reg_data[0] = reg >> 8; + reg_data[1] = reg >> 0; + i2c::ErrorCode err = this->write(reg_data, 2); + if (err != i2c::ERROR_OK) + return true; + uint8_t recv[2]; + err = this->read(recv, 2); + if (err != i2c::ERROR_OK) + return true; + *value = encode_uint16(recv[0], recv[1]); + return false; +} +bool AdE7953I2c::ade_read_32(uint16_t reg, uint32_t *value) { + uint8_t reg_data[2]; + reg_data[0] = reg >> 8; + reg_data[1] = reg >> 0; + i2c::ErrorCode err = this->write(reg_data, 2); + if (err != i2c::ERROR_OK) + return true; + uint8_t recv[4]; + err = this->read(recv, 4); + if (err != i2c::ERROR_OK) + return true; + *value = encode_uint32(recv[0], recv[1], recv[2], recv[3]); + return false; +} + +} // namespace ade7953_i2c +} // namespace esphome diff --git a/esphome/components/ade7953_i2c/ade7953_i2c.h b/esphome/components/ade7953_i2c/ade7953_i2c.h new file mode 100644 index 0000000000..65dc30dddb --- /dev/null +++ b/esphome/components/ade7953_i2c/ade7953_i2c.h @@ -0,0 +1,28 @@ +#pragma once + +#include "esphome/core/component.h" +#include "esphome/core/hal.h" +#include "esphome/components/i2c/i2c.h" +#include "esphome/components/sensor/sensor.h" +#include "esphome/components/ade7953_base/ade7953_base.h" + +#include + +namespace esphome { +namespace ade7953_i2c { + +class AdE7953I2c : public ade7953_base::ADE7953, public i2c::I2CDevice { + public: + void dump_config() override; + + protected: + bool ade_write_8(uint16_t reg, uint8_t value) override; + bool ade_write_16(uint16_t reg, uint16_t value) override; + bool ade_write_32(uint16_t reg, uint32_t value) override; + bool ade_read_8(uint16_t reg, uint8_t *value) override; + bool ade_read_16(uint16_t reg, uint16_t *value) override; + bool ade_read_32(uint16_t reg, uint32_t *value) override; +}; + +} // namespace ade7953_i2c +} // namespace esphome diff --git a/esphome/components/ade7953_i2c/sensor.py b/esphome/components/ade7953_i2c/sensor.py new file mode 100644 index 0000000000..e52a44eced --- /dev/null +++ b/esphome/components/ade7953_i2c/sensor.py @@ -0,0 +1,27 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import i2c, ade7953_base +from esphome.const import CONF_ID + + +DEPENDENCIES = ["i2c"] +AUTO_LOAD = ["ade7953_base"] + +ade7953_ns = cg.esphome_ns.namespace("ade7953_i2c") +ADE7953 = ade7953_ns.class_("AdE7953I2c", ade7953_base.ADE7953, i2c.I2CDevice) + +CONFIG_SCHEMA = ( + cv.Schema( + { + cv.GenerateID(): cv.declare_id(ADE7953), + } + ) + .extend(ade7953_base.ADE7953_CONFIG_SCHEMA) + .extend(i2c.i2c_device_schema(0x38)) +) + + +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await i2c.register_i2c_device(var, config) + await ade7953_base.register_ade7953(var, config) diff --git a/esphome/components/ade7953_spi/__init__.py b/esphome/components/ade7953_spi/__init__.py new file mode 100644 index 0000000000..d3078a0b67 --- /dev/null +++ b/esphome/components/ade7953_spi/__init__.py @@ -0,0 +1 @@ +CODEOWNERS = ["@angelnu"] diff --git a/esphome/components/ade7953_spi/ade7953_spi.cpp b/esphome/components/ade7953_spi/ade7953_spi.cpp new file mode 100644 index 0000000000..cfd5d71d0a --- /dev/null +++ b/esphome/components/ade7953_spi/ade7953_spi.cpp @@ -0,0 +1,81 @@ +#include "ade7953_spi.h" +#include "esphome/core/log.h" +#include "esphome/core/helpers.h" + +namespace esphome { +namespace ade7953_spi { + +static const char *const TAG = "ade7953"; + +void AdE7953Spi::setup() { + this->spi_setup(); + ade7953_base::ADE7953::setup(); +} + +void AdE7953Spi::dump_config() { + ESP_LOGCONFIG(TAG, "ADE7953_spi:"); + LOG_PIN(" CS Pin: ", this->cs_); + ade7953_base::ADE7953::dump_config(); +} + +bool AdE7953Spi::ade_write_8(uint16_t reg, uint8_t value) { + this->enable(); + this->write_byte16(reg); + this->transfer_byte(0); + this->transfer_byte(value); + this->disable(); + return false; +} + +bool AdE7953Spi::ade_write_16(uint16_t reg, uint16_t value) { + this->enable(); + this->write_byte16(reg); + this->transfer_byte(0); + this->write_byte16(value); + this->disable(); + return false; +} + +bool AdE7953Spi::ade_write_32(uint16_t reg, uint32_t value) { + this->enable(); + this->write_byte16(reg); + this->transfer_byte(0); + this->write_byte16(value >> 16); + this->write_byte16(value & 0xFFFF); + this->disable(); + return false; +} + +bool AdE7953Spi::ade_read_8(uint16_t reg, uint8_t *value) { + this->enable(); + this->write_byte16(reg); + this->transfer_byte(0x80); + *value = this->read_byte(); + this->disable(); + return false; +} + +bool AdE7953Spi::ade_read_16(uint16_t reg, uint16_t *value) { + this->enable(); + this->write_byte16(reg); + this->transfer_byte(0x80); + uint8_t recv[2]; + this->read_array(recv, 4); + *value = encode_uint16(recv[0], recv[1]); + this->disable(); + return false; +} + +bool AdE7953Spi::ade_read_32(uint16_t reg, uint32_t *value) { + this->enable(); + this->write_byte16(reg); + this->transfer_byte(0x80); + uint8_t recv[4]; + this->read_array(recv, 4); + *value = encode_uint32(recv[0], recv[1], recv[2], recv[3]); + this->disable(); + return false; +} + +} // namespace ade7953_spi +} // namespace esphome diff --git a/esphome/components/ade7953_spi/ade7953_spi.h b/esphome/components/ade7953_spi/ade7953_spi.h new file mode 100644 index 0000000000..d96852b9bb --- /dev/null +++ b/esphome/components/ade7953_spi/ade7953_spi.h @@ -0,0 +1,32 @@ +#pragma once + +#include "esphome/core/component.h" +#include "esphome/core/hal.h" +#include "esphome/components/spi/spi.h" +#include "esphome/components/sensor/sensor.h" +#include "esphome/components/ade7953_base/ade7953_base.h" + +#include + +namespace esphome { +namespace ade7953_spi { + +class AdE7953Spi : public ade7953_base::ADE7953, + public spi::SPIDevice { + public: + void setup() override; + + void dump_config() override; + + protected: + bool ade_write_8(uint16_t reg, uint8_t value) override; + bool ade_write_16(uint16_t reg, uint16_t value) override; + bool ade_write_32(uint16_t reg, uint32_t value) override; + bool ade_read_8(uint16_t reg, uint8_t *value) override; + bool ade_read_16(uint16_t reg, uint16_t *value) override; + bool ade_read_32(uint16_t reg, uint32_t *value) override; +}; + +} // namespace ade7953_spi +} // namespace esphome diff --git a/esphome/components/ade7953_spi/sensor.py b/esphome/components/ade7953_spi/sensor.py new file mode 100644 index 0000000000..5f9682c711 --- /dev/null +++ b/esphome/components/ade7953_spi/sensor.py @@ -0,0 +1,27 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import spi, ade7953_base +from esphome.const import CONF_ID + + +DEPENDENCIES = ["spi"] +AUTO_LOAD = ["ade7953_base"] + +ade7953_ns = cg.esphome_ns.namespace("ade7953_spi") +ADE7953 = ade7953_ns.class_("AdE7953Spi", ade7953_base.ADE7953, spi.SPIDevice) + +CONFIG_SCHEMA = ( + cv.Schema( + { + cv.GenerateID(): cv.declare_id(ADE7953), + } + ) + .extend(ade7953_base.ADE7953_CONFIG_SCHEMA) + .extend(spi.spi_device_schema()) +) + + +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await spi.register_spi_device(var, config) + await ade7953_base.register_ade7953(var, config) diff --git a/tests/test11.5.yaml b/tests/test11.5.yaml index 9b25b9f273..685487e871 100644 --- a/tests/test11.5.yaml +++ b/tests/test11.5.yaml @@ -51,6 +51,15 @@ uart: i2c: frequency: 100khz +spi: + - id: spi_1 + clk_pin: 12 + mosi_pin: 13 + miso_pin: 14 + - id: spi_2 + clk_pin: 32 + mosi_pin: 33 + modbus: uart_id: uart_1 flow_control_pin: 5 @@ -574,6 +583,60 @@ sensor: temperature: name: Kuntze temperature + - platform: ade7953_i2c + irq_pin: 16 + voltage: + name: ADE7953 Voltage + current_a: + name: ADE7953 Current A + current_b: + name: ADE7953 Current B + power_factor_a: + name: "ADE7953 Power Factor A" + power_factor_b: + name: "ADE7953 Power Factor B" + apparent_power_a: + name: "ADE7953 Apparent Power A" + apparent_power_b: + name: "ADE7953 Apparent Power B" + active_power_a: + name: ADE7953 Active Power A + active_power_b: + name: ADE7953 Active Power B + reactive_power_a: + name: "ADE7953 Reactive Power A" + reactive_power_b: + name: "ADE7953 Reactive Power B" + update_interval: 1s + + - platform: ade7953_spi + spi_id: spi_1 + cs_pin: 04 + irq_pin: 16 + voltage: + name: ADE7953 Voltage + current_a: + name: ADE7953 Current A + current_b: + name: ADE7953 Current B + power_factor_a: + name: "ADE7953 Power Factor A" + power_factor_b: + name: "ADE7953 Power Factor B" + apparent_power_a: + name: "ADE7953 Apparent Power A" + apparent_power_b: + name: "ADE7953 Apparent Power B" + active_power_a: + name: ADE7953 Active Power A + active_power_b: + name: ADE7953 Active Power B + reactive_power_a: + name: "ADE7953 Reactive Power A" + reactive_power_b: + name: "ADE7953 Reactive Power B" + update_interval: 1s + script: - id: automation_test then: diff --git a/tests/test3.1.yaml b/tests/test3.1.yaml index 8884479f61..151e53fd62 100644 --- a/tests/test3.1.yaml +++ b/tests/test3.1.yaml @@ -169,7 +169,7 @@ sensor: - id: custom_sensor name: Custom Sensor - - platform: ade7953 + - platform: ade7953_i2c irq_pin: GPIO16 voltage: name: ADE7953 Voltage @@ -180,12 +180,50 @@ sensor: current_b: name: ADE7953 Current B id: ade7953_current_b + power_factor_a: + name: "ADE7953 Power Factor A" + power_factor_b: + name: "ADE7953 Power Factor B" + apparent_power_a: + name: "ADE7953 Apparent Power A" + apparent_power_b: + name: "ADE7953 Apparent Power B" active_power_a: name: ADE7953 Active Power A - id: ade7953_active_power_a active_power_b: name: ADE7953 Active Power B - id: ade7953_active_power_b + reactive_power_a: + name: "ADE7953 Reactive Power A" + reactive_power_b: + name: "ADE7953 Reactive Power B" + update_interval: 1s + + - platform: ade7953_spi + cs_pin: GPIO04 + irq_pin: GPIO16 + voltage: + name: ADE7953 Voltage + current_a: + name: ADE7953 Current A + current_b: + name: ADE7953 Current B + power_factor_a: + name: "ADE7953 Power Factor A" + power_factor_b: + name: "ADE7953 Power Factor B" + apparent_power_a: + name: "ADE7953 Apparent Power A" + apparent_power_b: + name: "ADE7953 Apparent Power B" + active_power_a: + name: ADE7953 Active Power A + active_power_b: + name: ADE7953 Active Power B + reactive_power_a: + name: "ADE7953 Reactive Power A" + reactive_power_b: + name: "ADE7953 Reactive Power B" + update_interval: 1s - platform: tmp102 name: TMP102 Temperature