[copy][atm90e32] Use Apply buttons

This commit is contained in:
J. Nick Koston
2026-10-19 12:48:08 -10:00
parent 01524a2ffd
commit 2bab0c5306
9 changed files with 83 additions and 253 deletions
+12
View File
@@ -637,6 +637,18 @@ float ATM90E32Component::get_chip_temperature_() {
return (float) ctemp;
}
void ATM90E32Component::press_calibration_button(EntityBase *entity, void (ATM90E32Component::*action)(),
const LogString *hint, const LogString *hint2) {
ESP_LOGI(TAG, "%s", entity->get_name().c_str());
if (hint != nullptr) {
ESP_LOGI(TAG, "%s", LOG_STR_ARG(hint));
}
if (hint2 != nullptr) {
ESP_LOGI(TAG, "%s", LOG_STR_ARG(hint2));
}
(this->*action)();
}
void ATM90E32Component::run_gain_calibrations() {
const char *cs = this->get_calibration_id_();
if (!this->enable_gain_calibration_) {
+3
View File
@@ -139,6 +139,9 @@ class ATM90E32Component final : public PollingComponent,
int16_t calibrate_offset(uint8_t phase, bool voltage);
int16_t calibrate_power_offset(uint8_t phase, bool reactive);
void run_gain_calibrations();
// Body of the calibration buttons: logs the button name and the hint lines, then runs action.
void press_calibration_button(EntityBase *entity, void (ATM90E32Component::*action)(),
const LogString *hint = nullptr, const LogString *hint2 = nullptr);
#ifdef USE_NUMBER
void set_reference_voltage(uint8_t phase, number::Number *ref_voltage) { ref_voltages_[phase] = ref_voltage; }
void set_reference_current(uint8_t phase, number::Number *ref_current) { ref_currents_[phase] = ref_current; }
+56 -75
View File
@@ -1,10 +1,9 @@
import esphome.codegen as cg
from esphome.components import button
import esphome.config_validation as cv
from esphome.const import CONF_ID, ENTITY_CATEGORY_CONFIG, ICON_SCALE
from esphome.helpers import cpp_string_escape
from esphome.types import ConfigType
from .. import atm90e32_ns
from ..sensor import ATM90E32Component
CONF_RUN_GAIN_CALIBRATION = "run_gain_calibration"
@@ -14,83 +13,65 @@ CONF_CLEAR_OFFSET_CALIBRATION = "clear_offset_calibration"
CONF_RUN_POWER_OFFSET_CALIBRATION = "run_power_offset_calibration"
CONF_CLEAR_POWER_OFFSET_CALIBRATION = "clear_power_offset_calibration"
ATM90E32GainCalibrationButton = atm90e32_ns.class_(
"ATM90E32GainCalibrationButton", button.Button
)
ATM90E32ClearGainCalibrationButton = atm90e32_ns.class_(
"ATM90E32ClearGainCalibrationButton", button.Button
)
ATM90E32OffsetCalibrationButton = atm90e32_ns.class_(
"ATM90E32OffsetCalibrationButton", button.Button
)
ATM90E32ClearOffsetCalibrationButton = atm90e32_ns.class_(
"ATM90E32ClearOffsetCalibrationButton", button.Button
)
ATM90E32PowerOffsetCalibrationButton = atm90e32_ns.class_(
"ATM90E32PowerOffsetCalibrationButton", button.Button
)
ATM90E32ClearPowerOffsetCalibrationButton = atm90e32_ns.class_(
"ATM90E32ClearPowerOffsetCalibrationButton", button.Button
)
def _calibration_button(icon: str) -> cv.Schema:
return button.button_schema(
button.ApplyButton, entity_category=ENTITY_CATEGORY_CONFIG, icon=icon
)
CONFIG_SCHEMA = {
cv.GenerateID(CONF_ID): cv.use_id(ATM90E32Component),
cv.Optional(CONF_RUN_GAIN_CALIBRATION): button.button_schema(
ATM90E32GainCalibrationButton,
entity_category=ENTITY_CATEGORY_CONFIG,
icon="mdi:scale-balance",
),
cv.Optional(CONF_CLEAR_GAIN_CALIBRATION): button.button_schema(
ATM90E32ClearGainCalibrationButton,
entity_category=ENTITY_CATEGORY_CONFIG,
icon="mdi:delete",
),
cv.Optional(CONF_RUN_OFFSET_CALIBRATION): button.button_schema(
ATM90E32OffsetCalibrationButton,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SCALE,
),
cv.Optional(CONF_CLEAR_OFFSET_CALIBRATION): button.button_schema(
ATM90E32ClearOffsetCalibrationButton,
entity_category=ENTITY_CATEGORY_CONFIG,
icon="mdi:delete",
),
cv.Optional(CONF_RUN_POWER_OFFSET_CALIBRATION): button.button_schema(
ATM90E32PowerOffsetCalibrationButton,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_SCALE,
),
cv.Optional(CONF_CLEAR_POWER_OFFSET_CALIBRATION): button.button_schema(
ATM90E32ClearPowerOffsetCalibrationButton,
entity_category=ENTITY_CATEGORY_CONFIG,
icon="mdi:delete",
),
cv.Optional(CONF_RUN_GAIN_CALIBRATION): _calibration_button("mdi:scale-balance"),
cv.Optional(CONF_CLEAR_GAIN_CALIBRATION): _calibration_button("mdi:delete"),
cv.Optional(CONF_RUN_OFFSET_CALIBRATION): _calibration_button(ICON_SCALE),
cv.Optional(CONF_CLEAR_OFFSET_CALIBRATION): _calibration_button("mdi:delete"),
cv.Optional(CONF_RUN_POWER_OFFSET_CALIBRATION): _calibration_button(ICON_SCALE),
cv.Optional(CONF_CLEAR_POWER_OFFSET_CALIBRATION): _calibration_button("mdi:delete"),
}
def _press(action: str, *hints: str) -> str:
args = "".join(f", LOG_STR({cpp_string_escape(hint)})" for hint in hints)
return f"press_calibration_button(entity, &{ATM90E32Component}::{action}{args})"
async def to_code(config: ConfigType) -> None:
parent = await cg.get_variable(config[CONF_ID])
if run_gain := config.get(CONF_RUN_GAIN_CALIBRATION):
b = await button.new_button(run_gain)
await cg.register_parented(b, parent)
if clear_gain := config.get(CONF_CLEAR_GAIN_CALIBRATION):
b = await button.new_button(clear_gain)
await cg.register_parented(b, parent)
if run_offset := config.get(CONF_RUN_OFFSET_CALIBRATION):
b = await button.new_button(run_offset)
await cg.register_parented(b, parent)
if clear_offset := config.get(CONF_CLEAR_OFFSET_CALIBRATION):
b = await button.new_button(clear_offset)
await cg.register_parented(b, parent)
if run_power := config.get(CONF_RUN_POWER_OFFSET_CALIBRATION):
b = await button.new_button(run_power)
await cg.register_parented(b, parent)
if clear_power := config.get(CONF_CLEAR_POWER_OFFSET_CALIBRATION):
b = await button.new_button(clear_power)
await cg.register_parented(b, parent)
buttons = button.sub_buttons(config, parent=config[CONF_ID])
await buttons(
CONF_RUN_GAIN_CALIBRATION,
None,
apply=_press(
"run_gain_calibrations",
"[CALIBRATION] Use gain_ct: & gain_voltage: under each phase_x: in your config file to save these values",
),
)
await buttons(
CONF_CLEAR_GAIN_CALIBRATION, None, apply=_press("clear_gain_calibrations")
)
await buttons(
CONF_RUN_OFFSET_CALIBRATION,
None,
apply=_press(
"run_offset_calibrations",
"[CALIBRATION] **NOTE: CTs and ACVs must be 0 during this process. USB power only**",
"[CALIBRATION] Use offset_voltage: & offset_current: under each phase_x: in your config file to save these values",
),
)
await buttons(
CONF_CLEAR_OFFSET_CALIBRATION, None, apply=_press("clear_offset_calibrations")
)
await buttons(
CONF_RUN_POWER_OFFSET_CALIBRATION,
None,
apply=_press(
"run_power_offset_calibrations",
"[CALIBRATION] **NOTE: CTs must be 0 during this process. Voltage reference should be present**",
"[CALIBRATION] Use offset_active_power: & offset_reactive_power: under each phase_x: in your config file to save these values",
),
)
await buttons(
CONF_CLEAR_POWER_OFFSET_CALIBRATION,
None,
apply=_press("clear_power_offset_calibrations"),
)
@@ -1,77 +0,0 @@
#include "atm90e32_button.h"
#include "esphome/core/component.h"
#include "esphome/core/log.h"
namespace esphome::atm90e32 {
ESPHOME_LOG_TAG(TAG, "atm90e32.button");
void ATM90E32GainCalibrationButton::press_action() {
if (this->parent_ == nullptr) {
ESP_LOGW(TAG, "[CALIBRATION] No meters assigned to Gain Calibration button [%s]", this->get_name().c_str());
return;
}
ESP_LOGI(TAG, "%s", this->get_name().c_str());
ESP_LOGI(TAG,
"[CALIBRATION] Use gain_ct: & gain_voltage: under each phase_x: in your config file to save these values");
this->parent_->run_gain_calibrations();
}
void ATM90E32ClearGainCalibrationButton::press_action() {
if (this->parent_ == nullptr) {
ESP_LOGW(TAG, "[CALIBRATION] No meters assigned to Clear Gain button [%s]", this->get_name().c_str());
return;
}
ESP_LOGI(TAG, "%s", this->get_name().c_str());
this->parent_->clear_gain_calibrations();
}
void ATM90E32OffsetCalibrationButton::press_action() {
if (this->parent_ == nullptr) {
ESP_LOGW(TAG, "[CALIBRATION] No meters assigned to Offset Calibration button [%s]", this->get_name().c_str());
return;
}
ESP_LOGI(TAG, "%s", this->get_name().c_str());
ESP_LOGI(TAG, "[CALIBRATION] **NOTE: CTs and ACVs must be 0 during this process. USB power only**");
ESP_LOGI(TAG, "[CALIBRATION] Use offset_voltage: & offset_current: under each phase_x: in your config file to save "
"these values");
this->parent_->run_offset_calibrations();
}
void ATM90E32ClearOffsetCalibrationButton::press_action() {
if (this->parent_ == nullptr) {
ESP_LOGW(TAG, "[CALIBRATION] No meters assigned to Clear Offset button [%s]", this->get_name().c_str());
return;
}
ESP_LOGI(TAG, "%s", this->get_name().c_str());
this->parent_->clear_offset_calibrations();
}
void ATM90E32PowerOffsetCalibrationButton::press_action() {
if (this->parent_ == nullptr) {
ESP_LOGW(TAG, "[CALIBRATION] No meters assigned to Power Calibration button [%s]", this->get_name().c_str());
return;
}
ESP_LOGI(TAG, "%s", this->get_name().c_str());
ESP_LOGI(TAG, "[CALIBRATION] **NOTE: CTs must be 0 during this process. Voltage reference should be present**");
ESP_LOGI(TAG, "[CALIBRATION] Use offset_active_power: & offset_reactive_power: under each phase_x: in your config "
"file to save these values");
this->parent_->run_power_offset_calibrations();
}
void ATM90E32ClearPowerOffsetCalibrationButton::press_action() {
if (this->parent_ == nullptr) {
ESP_LOGW(TAG, "[CALIBRATION] No meters assigned to Clear Power button [%s]", this->get_name().c_str());
return;
}
ESP_LOGI(TAG, "%s", this->get_name().c_str());
this->parent_->clear_power_offset_calibrations();
}
} // namespace esphome::atm90e32
@@ -1,57 +0,0 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/components/atm90e32/atm90e32.h"
#include "esphome/components/button/button.h"
namespace esphome::atm90e32 {
class ATM90E32GainCalibrationButton final : public button::Button, public Parented<ATM90E32Component> {
public:
ATM90E32GainCalibrationButton() = default;
protected:
void press_action() override;
};
class ATM90E32ClearGainCalibrationButton final : public button::Button, public Parented<ATM90E32Component> {
public:
ATM90E32ClearGainCalibrationButton() = default;
protected:
void press_action() override;
};
class ATM90E32OffsetCalibrationButton final : public button::Button, public Parented<ATM90E32Component> {
public:
ATM90E32OffsetCalibrationButton() = default;
protected:
void press_action() override;
};
class ATM90E32ClearOffsetCalibrationButton final : public button::Button, public Parented<ATM90E32Component> {
public:
ATM90E32ClearOffsetCalibrationButton() = default;
protected:
void press_action() override;
};
class ATM90E32PowerOffsetCalibrationButton final : public button::Button, public Parented<ATM90E32Component> {
public:
ATM90E32PowerOffsetCalibrationButton() = default;
protected:
void press_action() override;
};
class ATM90E32ClearPowerOffsetCalibrationButton final : public button::Button, public Parented<ATM90E32Component> {
public:
ATM90E32ClearPowerOffsetCalibrationButton() = default;
protected:
void press_action() override;
};
} // namespace esphome::atm90e32
+4 -13
View File
@@ -1,23 +1,16 @@
import esphome.codegen as cg
from esphome.components import button
import esphome.config_validation as cv
from esphome.const import (
CONF_DEVICE_CLASS,
CONF_ENTITY_CATEGORY,
CONF_ICON,
CONF_ID,
CONF_SOURCE_ID,
)
from esphome.core.entity_helpers import inherit_property_from
from esphome.types import ConfigType
from .. import copy_ns
CopyButton = copy_ns.class_("CopyButton", button.Button, cg.Component)
CONFIG_SCHEMA = (
button.button_schema(CopyButton)
button.button_schema(button.ApplyButton)
.extend(
{
cv.Required(CONF_SOURCE_ID): cv.use_id(button.Button),
@@ -34,8 +27,6 @@ FINAL_VALIDATE_SCHEMA = cv.All(
async def to_code(config: ConfigType) -> None:
var = cg.new_Pvariable(config[CONF_ID])
await button.register_button(var, config)
await cg.register_component(var, config)
await cg.add_variable(var.set_source, config[CONF_SOURCE_ID])
await button.sub_buttons(config, parent=config[CONF_SOURCE_ID]).create(
config, None, apply="press()"
)
@@ -1,12 +0,0 @@
#include "copy_button.h"
#include "esphome/core/log.h"
namespace esphome::copy {
ESPHOME_LOG_TAG(TAG, "copy.button");
void CopyButton::dump_config() { LOG_BUTTON("", "Copy Button", this); }
void CopyButton::press_action() { source_->press(); }
} // namespace esphome::copy
@@ -1,19 +0,0 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/components/button/button.h"
namespace esphome::copy {
class CopyButton final : public button::Button, public Component {
public:
void set_source(button::Button *source) { source_ = source; }
void dump_config() override;
protected:
void press_action() override;
button::Button *source_;
};
} // namespace esphome::copy
+8
View File
@@ -24,3 +24,11 @@ select:
- platform: copy
source_id: test_select
name: Test Select Copy
button:
- platform: template
id: copy_source_button
name: Source Button
- platform: copy
source_id: copy_source_button
name: Button Copy