ESPHome 2026.5.0
Loading...
Searching...
No Matches
atm90e32.h
Go to the documentation of this file.
1#pragma once
2
3#include <span>
4#include <unordered_map>
5#include "atm90e32_reg.h"
10#include "esphome/core/gpio.h"
13
14namespace esphome::atm90e32 {
15
17 public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_HIGH,
18 spi::CLOCK_PHASE_TRAILING, spi::DATA_RATE_1MHZ> {
19 public:
20 static const uint8_t PHASEA = 0;
21 static const uint8_t PHASEB = 1;
22 static const uint8_t PHASEC = 2;
23 const char *phase_labels[3] = {"A", "B", "C"};
24 // these registers are not sucessive, so we can't just do 'base + phase'
25 const uint16_t voltage_gain_registers[3] = {ATM90E32_REGISTER_UGAINA, ATM90E32_REGISTER_UGAINB,
26 ATM90E32_REGISTER_UGAINC};
27 const uint16_t current_gain_registers[3] = {ATM90E32_REGISTER_IGAINA, ATM90E32_REGISTER_IGAINB,
28 ATM90E32_REGISTER_IGAINC};
29 const uint16_t voltage_offset_registers[3] = {ATM90E32_REGISTER_UOFFSETA, ATM90E32_REGISTER_UOFFSETB,
30 ATM90E32_REGISTER_UOFFSETC};
31 const uint16_t current_offset_registers[3] = {ATM90E32_REGISTER_IOFFSETA, ATM90E32_REGISTER_IOFFSETB,
32 ATM90E32_REGISTER_IOFFSETC};
33 const uint16_t power_offset_registers[3] = {ATM90E32_REGISTER_POFFSETA, ATM90E32_REGISTER_POFFSETB,
34 ATM90E32_REGISTER_POFFSETC};
35 const uint16_t reactive_power_offset_registers[3] = {ATM90E32_REGISTER_QOFFSETA, ATM90E32_REGISTER_QOFFSETB,
36 ATM90E32_REGISTER_QOFFSETC};
37 const uint16_t over_voltage_flags[3] = {ATM90E32_STATUS_S0_OVPHASEAST, ATM90E32_STATUS_S0_OVPHASEBST,
38 ATM90E32_STATUS_S0_OVPHASECST};
39 const uint16_t voltage_sag_flags[3] = {ATM90E32_STATUS_S1_SAGPHASEAST, ATM90E32_STATUS_S1_SAGPHASEBST,
40 ATM90E32_STATUS_S1_SAGPHASECST};
41 const uint16_t phase_loss_flags[3] = {ATM90E32_STATUS_S1_PHASELOSSAST, ATM90E32_STATUS_S1_PHASELOSSBST,
42 ATM90E32_STATUS_S1_PHASELOSSCST};
43 void loop() override;
44 void setup() override;
45 void dump_config() override;
46 float get_setup_priority() const override;
47 void update() override;
48 void set_voltage_sensor(int phase, sensor::Sensor *obj) { this->phase_[phase].voltage_sensor_ = obj; }
49 void set_current_sensor(int phase, sensor::Sensor *obj) { this->phase_[phase].current_sensor_ = obj; }
50 void set_power_sensor(int phase, sensor::Sensor *obj) { this->phase_[phase].power_sensor_ = obj; }
51 void set_reactive_power_sensor(int phase, sensor::Sensor *obj) { this->phase_[phase].reactive_power_sensor_ = obj; }
52 void set_apparent_power_sensor(int phase, sensor::Sensor *obj) { this->phase_[phase].apparent_power_sensor_ = obj; }
54 this->phase_[phase].forward_active_energy_sensor_ = obj;
55 }
57 this->phase_[phase].reverse_active_energy_sensor_ = obj;
58 }
59 void set_power_factor_sensor(int phase, sensor::Sensor *obj) { this->phase_[phase].power_factor_sensor_ = obj; }
60 void set_phase_angle_sensor(int phase, sensor::Sensor *obj) { this->phase_[phase].phase_angle_sensor_ = obj; }
62 this->phase_[phase].harmonic_active_power_sensor_ = obj;
63 }
64 void set_peak_current_sensor(int phase, sensor::Sensor *obj) { this->phase_[phase].peak_current_sensor_ = obj; }
65 void set_volt_gain(int phase, uint16_t gain) {
66 this->phase_[phase].voltage_gain_ = gain;
67 this->has_config_voltage_gain_[phase] = true;
68 }
69 void set_ct_gain(int phase, uint16_t gain) {
70 this->phase_[phase].ct_gain_ = gain;
71 this->has_config_current_gain_[phase] = true;
72 }
73 void set_voltage_offset(uint8_t phase, int16_t offset) {
74 this->offset_phase_[phase].voltage_offset_ = offset;
75 this->has_config_voltage_offset_[phase] = true;
76 }
77 void set_current_offset(uint8_t phase, int16_t offset) {
78 this->offset_phase_[phase].current_offset_ = offset;
79 this->has_config_current_offset_[phase] = true;
80 }
81 void set_active_power_offset(uint8_t phase, int16_t offset) {
82 this->power_offset_phase_[phase].active_power_offset = offset;
83 this->has_config_active_power_offset_[phase] = true;
84 }
85 void set_reactive_power_offset(uint8_t phase, int16_t offset) {
86 this->power_offset_phase_[phase].reactive_power_offset = offset;
87 this->has_config_reactive_power_offset_[phase] = true;
88 }
89 void set_freq_sensor(sensor::Sensor *freq_sensor) { freq_sensor_ = freq_sensor; }
91 void set_chip_temperature_sensor(sensor::Sensor *chip_temperature_sensor) {
92 chip_temperature_sensor_ = chip_temperature_sensor;
93 }
94 void set_line_freq(int freq) { line_freq_ = freq; }
95 void set_current_phases(int phases) { current_phases_ = phases; }
96 void set_pga_gain(uint16_t gain) { pga_gain_ = gain; }
104 void set_instance_id(const char *id) { instance_id_ = id; }
105 int16_t calibrate_offset(uint8_t phase, bool voltage);
106 int16_t calibrate_power_offset(uint8_t phase, bool reactive);
108#ifdef USE_NUMBER
109 void set_reference_voltage(uint8_t phase, number::Number *ref_voltage) { ref_voltages_[phase] = ref_voltage; }
110 void set_reference_current(uint8_t phase, number::Number *ref_current) { ref_currents_[phase] = ref_current; }
111#endif
112 float get_reference_voltage(uint8_t phase) {
113#ifdef USE_NUMBER
114 return (phase < 3 && ref_voltages_[phase]) ? ref_voltages_[phase]->state : 120.0; // Default voltage
115#else
116 return 120.0; // Default voltage
117#endif
118 }
119 float get_reference_current(uint8_t phase) {
120#ifdef USE_NUMBER
121 return (phase < 3 && ref_currents_[phase]) ? ref_currents_[phase]->state : 5.0f; // Default current
122#else
123 return 5.0f; // Default current
124#endif
125 }
126 bool using_saved_calibrations_ = false; // Track if stored calibrations are being used
127#ifdef USE_TEXT_SENSOR
128 void check_phase_status();
129 void check_freq_status();
130 void check_over_current();
132 this->phase_status_text_sensor_[phase] = sensor;
133 }
135#endif
136 uint16_t calculate_voltage_threshold(int line_freq, uint16_t ugain, float multiplier);
137
138 protected:
139#ifdef USE_NUMBER
140 number::Number *ref_voltages_[3]{nullptr, nullptr, nullptr};
141 number::Number *ref_currents_[3]{nullptr, nullptr, nullptr};
142#endif
143 uint16_t read16_(uint16_t a_register);
144 int read32_(uint16_t addr_h, uint16_t addr_l);
145 void write16_(uint16_t a_register, uint16_t val, bool validate = true);
146 float get_local_phase_voltage_(uint8_t phase);
147 float get_local_phase_current_(uint8_t phase);
148 float get_local_phase_active_power_(uint8_t phase);
149 float get_local_phase_reactive_power_(uint8_t phase);
150 float get_local_phase_apparent_power_(uint8_t phase);
151 float get_local_phase_power_factor_(uint8_t phase);
152 float get_local_phase_forward_active_energy_(uint8_t phase);
153 float get_local_phase_reverse_active_energy_(uint8_t phase);
154 float get_local_phase_angle_(uint8_t phase);
155 float get_local_phase_harmonic_active_power_(uint8_t phase);
156 float get_local_phase_peak_current_(uint8_t phase);
157 float get_phase_voltage_(uint8_t phase);
158 float get_phase_voltage_avg_(uint8_t phase);
159 float get_phase_current_(uint8_t phase);
160 float get_phase_current_avg_(uint8_t phase);
161 float get_phase_active_power_(uint8_t phase);
162 float get_phase_reactive_power_(uint8_t phase);
163 float get_phase_apparent_power_(uint8_t phase);
164 float get_phase_power_factor_(uint8_t phase);
165 float get_phase_forward_active_energy_(uint8_t phase);
166 float get_phase_reverse_active_energy_(uint8_t phase);
167 float get_phase_angle_(uint8_t phase);
168 float get_phase_harmonic_active_power_(uint8_t phase);
169 float get_phase_peak_current_(uint8_t phase);
170 float get_frequency_();
171 float get_chip_temperature_();
180 void write_offsets_to_registers_(uint8_t phase, int16_t voltage_offset, int16_t current_offset);
181 void write_power_offsets_to_registers_(uint8_t phase, int16_t p_offset, int16_t q_offset);
183 bool verify_gain_writes_();
184 bool validate_spi_read_(uint16_t expected, const char *context = nullptr);
186 const char *get_calibration_id_();
187 void get_cs_summary_(std::span<char, GPIO_SUMMARY_MAX_LEN> buffer);
188
221
226
228
233
235
237 uint16_t voltage_gain{1};
238 uint16_t current_gain{1};
240
242
243 bool has_config_voltage_offset_[3]{false, false, false};
244 bool has_config_current_offset_[3]{false, false, false};
245 bool has_config_active_power_offset_[3]{false, false, false};
246 bool has_config_reactive_power_offset_[3]{false, false, false};
247 bool has_config_voltage_gain_[3]{false, false, false};
248 bool has_config_current_gain_[3]{false, false, false};
249
253
255#ifdef USE_TEXT_SENSOR
258#endif
260 uint16_t pga_gain_{0x15};
261 int line_freq_{60};
267 const char *instance_id_{nullptr};
272 bool offset_calibration_mismatch_[3]{false, false, false};
273 bool power_offset_calibration_mismatch_[3]{false, false, false};
274 bool gain_calibration_mismatch_[3]{false, false, false};
275};
276
277} // namespace esphome::atm90e32
This class simplifies creating components that periodically check a state.
Definition component.h:602
void set_chip_temperature_sensor(sensor::Sensor *chip_temperature_sensor)
Definition atm90e32.h:91
void set_freq_sensor(sensor::Sensor *freq_sensor)
Definition atm90e32.h:89
float get_local_phase_reactive_power_(uint8_t phase)
Definition atm90e32.cpp:513
float get_phase_forward_active_energy_(uint8_t phase)
Definition atm90e32.cpp:596
void set_freq_status_text_sensor(text_sensor::TextSensor *sensor)
Definition atm90e32.h:134
float get_phase_current_avg_(uint8_t phase)
Definition atm90e32.cpp:555
float get_local_phase_apparent_power_(uint8_t phase)
Definition atm90e32.cpp:515
void write16_(uint16_t a_register, uint16_t val, bool validate=true)
Definition atm90e32.cpp:492
void set_apparent_power_sensor(int phase, sensor::Sensor *obj)
Definition atm90e32.h:52
text_sensor::TextSensor * freq_status_text_sensor_
Definition atm90e32.h:257
ESPPreferenceObject power_offset_pref_
Definition atm90e32.h:251
const uint16_t voltage_gain_registers[3]
Definition atm90e32.h:25
float get_phase_voltage_avg_(uint8_t phase)
Definition atm90e32.cpp:541
void write_power_offsets_to_registers_(uint8_t phase, int16_t p_offset, int16_t q_offset)
Definition atm90e32.cpp:878
const uint16_t current_gain_registers[3]
Definition atm90e32.h:27
float get_reference_voltage(uint8_t phase)
Definition atm90e32.h:112
number::Number * ref_voltages_[3]
Definition atm90e32.h:140
void set_power_sensor(int phase, sensor::Sensor *obj)
Definition atm90e32.h:50
struct esphome::atm90e32::ATM90E32Component::GainCalibration gain_phase_[3]
void set_current_offset(uint8_t phase, int16_t offset)
Definition atm90e32.h:77
const uint16_t current_offset_registers[3]
Definition atm90e32.h:31
static const uint8_t PHASEB
Definition atm90e32.h:21
float get_phase_reverse_active_energy_(uint8_t phase)
Definition atm90e32.cpp:607
void set_reactive_power_offset(uint8_t phase, int16_t offset)
Definition atm90e32.h:85
float get_local_phase_harmonic_active_power_(uint8_t phase)
Definition atm90e32.cpp:529
float get_phase_angle_(uint8_t phase)
Definition atm90e32.cpp:623
float get_local_phase_current_(uint8_t phase)
Definition atm90e32.cpp:509
bool validate_spi_read_(uint16_t expected, const char *context=nullptr)
void set_peak_current_sensor(int phase, sensor::Sensor *obj)
Definition atm90e32.h:64
const uint16_t reactive_power_offset_registers[3]
Definition atm90e32.h:35
const uint16_t over_voltage_flags[3]
Definition atm90e32.h:37
void set_reverse_active_energy_sensor(int phase, sensor::Sensor *obj)
Definition atm90e32.h:56
float get_phase_voltage_(uint8_t phase)
Definition atm90e32.cpp:535
void set_current_sensor(int phase, sensor::Sensor *obj)
Definition atm90e32.h:49
GainCalibration config_gain_phase_[3]
Definition atm90e32.h:241
int16_t calibrate_offset(uint8_t phase, bool voltage)
float get_local_phase_reverse_active_energy_(uint8_t phase)
Definition atm90e32.cpp:523
void set_harmonic_active_power_sensor(int phase, sensor::Sensor *obj)
Definition atm90e32.h:61
void set_current_phases(int phases)
Definition atm90e32.h:95
float get_local_phase_forward_active_energy_(uint8_t phase)
Definition atm90e32.cpp:519
OffsetCalibration config_offset_phase_[3]
Definition atm90e32.h:227
struct esphome::atm90e32::ATM90E32Component::OffsetCalibration offset_phase_[3]
void set_active_power_offset(uint8_t phase, int16_t offset)
Definition atm90e32.h:81
uint16_t calculate_voltage_threshold(int line_freq, uint16_t ugain, float multiplier)
float get_local_phase_power_factor_(uint8_t phase)
Definition atm90e32.cpp:517
float get_phase_reactive_power_(uint8_t phase)
Definition atm90e32.cpp:580
void set_enable_gain_calibration(bool flag)
Definition atm90e32.h:103
const uint16_t phase_loss_flags[3]
Definition atm90e32.h:41
float get_phase_apparent_power_(uint8_t phase)
Definition atm90e32.cpp:585
float get_local_phase_voltage_(uint8_t phase)
Definition atm90e32.cpp:507
void set_phase_status_text_sensor(uint8_t phase, text_sensor::TextSensor *sensor)
Definition atm90e32.h:131
void set_pga_gain(uint16_t gain)
Definition atm90e32.h:96
void set_reference_current(uint8_t phase, number::Number *ref_current)
Definition atm90e32.h:110
ESPPreferenceObject gain_calibration_pref_
Definition atm90e32.h:252
void set_instance_id(const char *id)
Definition atm90e32.h:104
void write_offsets_to_registers_(uint8_t phase, int16_t voltage_offset, int16_t current_offset)
Definition atm90e32.cpp:862
static const uint8_t PHASEA
Definition atm90e32.h:20
struct esphome::atm90e32::ATM90E32Component::PowerOffsetCalibration power_offset_phase_[3]
float get_reference_current(uint8_t phase)
Definition atm90e32.h:119
number::Number * ref_currents_[3]
Definition atm90e32.h:141
float get_phase_peak_current_(uint8_t phase)
Definition atm90e32.cpp:628
void set_voltage_offset(uint8_t phase, int16_t offset)
Definition atm90e32.h:73
float get_phase_harmonic_active_power_(uint8_t phase)
Definition atm90e32.cpp:618
const uint16_t voltage_sag_flags[3]
Definition atm90e32.h:39
float get_phase_active_power_(uint8_t phase)
Definition atm90e32.cpp:575
PowerOffsetCalibration config_power_offset_phase_[3]
Definition atm90e32.h:234
void get_cs_summary_(std::span< char, GPIO_SUMMARY_MAX_LEN > buffer)
Definition atm90e32.cpp:130
static const uint8_t PHASEC
Definition atm90e32.h:22
const uint16_t power_offset_registers[3]
Definition atm90e32.h:33
float get_setup_priority() const override
Definition atm90e32.cpp:459
uint16_t read16_(uint16_t a_register)
Definition atm90e32.cpp:464
int read32_(uint16_t addr_h, uint16_t addr_l)
Definition atm90e32.cpp:479
sensor::Sensor * chip_temperature_sensor_
Definition atm90e32.h:259
float get_phase_power_factor_(uint8_t phase)
Definition atm90e32.cpp:590
void set_voltage_sensor(int phase, sensor::Sensor *obj)
Definition atm90e32.h:48
float get_local_phase_angle_(uint8_t phase)
Definition atm90e32.cpp:527
const uint16_t voltage_offset_registers[3]
Definition atm90e32.h:29
void set_ct_gain(int phase, uint16_t gain)
Definition atm90e32.h:69
void set_phase_angle_sensor(int phase, sensor::Sensor *obj)
Definition atm90e32.h:60
void set_reference_voltage(uint8_t phase, number::Number *ref_voltage)
Definition atm90e32.h:109
void set_power_factor_sensor(int phase, sensor::Sensor *obj)
Definition atm90e32.h:59
void set_forward_active_energy_sensor(int phase, sensor::Sensor *obj)
Definition atm90e32.h:53
void set_volt_gain(int phase, uint16_t gain)
Definition atm90e32.h:65
text_sensor::TextSensor * phase_status_text_sensor_[3]
Definition atm90e32.h:256
float get_phase_current_(uint8_t phase)
Definition atm90e32.cpp:569
void set_peak_current_signed(bool flag)
Definition atm90e32.h:90
float get_local_phase_peak_current_(uint8_t phase)
Definition atm90e32.cpp:533
void set_publish_interval_flag_(bool flag)
Definition atm90e32.h:173
int16_t calibrate_power_offset(uint8_t phase, bool reactive)
struct esphome::atm90e32::ATM90E32Component::ATM90E32Phase phase_[3]
void set_enable_offset_calibration(bool flag)
Definition atm90e32.h:102
ESPPreferenceObject offset_pref_
Definition atm90e32.h:250
void set_reactive_power_sensor(int phase, sensor::Sensor *obj)
Definition atm90e32.h:51
float get_local_phase_active_power_(uint8_t phase)
Definition atm90e32.cpp:511
Base-class for all numbers.
Definition number.h:29
Base-class for all sensors.
Definition sensor.h:47
The SPIDevice is what components using the SPI will create.
Definition spi.h:429
uint16_t id
AlsGain501 gain
mopeka_std_values val[3]
static void uint32_t