ESPHome 2025.5.0
Loading...
Searching...
No Matches
ina2xx_base.cpp
Go to the documentation of this file.
1#include "ina2xx_base.h"
2#include "esphome/core/log.h"
3#include "esphome/core/hal.h"
5#include <cinttypes>
6#include <cmath>
7
8namespace esphome {
9namespace ina2xx_base {
10
11static const char *const TAG = "ina2xx";
12
13#define OKFAILED(b) ((b) ? "OK" : "FAILED")
14
15static const uint16_t ADC_TIMES[8] = {50, 84, 150, 280, 540, 1052, 2074, 4120};
16static const uint16_t ADC_SAMPLES[8] = {1, 4, 16, 64, 128, 256, 512, 1024};
17
18static const char *get_device_name(INAModel model) {
19 switch (model) {
21 return "INA228";
23 return "INA229";
25 return "INA238";
27 return "INA239";
29 return "INA237";
30 default:
31 return "UNKNOWN";
32 }
33};
34
35static bool check_model_and_device_match(INAModel model, uint16_t dev_id) {
36 switch (model) {
38 return dev_id == 0x228;
40 return dev_id == 0x229;
42 return dev_id == 0x238;
44 return dev_id == 0x239;
46 return dev_id == 0x237;
47 default:
48 return false;
49 }
50}
51
53 ESP_LOGCONFIG(TAG, "Setting up INA2xx...");
54
55 if (!this->reset_config_()) {
56 ESP_LOGE(TAG, "Reset failed, check connection");
57 this->mark_failed();
58 return;
59 }
60 delay(2);
61
62 if (!this->check_device_model_()) {
63 ESP_LOGE(TAG, "Device not supported or model selected improperly in yaml file");
64 this->mark_failed();
65 return;
66 }
67 delay(1);
68
70 delay(1);
71
72 this->configure_adc_();
73 delay(1);
74
75 this->configure_shunt_();
76 delay(1);
77
79 delay(1);
80
81 this->state_ = State::IDLE;
82}
83
85
87 ESP_LOGD(TAG, "Updating");
88 if (this->is_ready() && this->state_ == State::IDLE) {
89 ESP_LOGD(TAG, "Initiating new data collection");
90 this->state_ = State::DATA_COLLECTION_1;
91 return;
92 }
93}
94
96 if (this->is_ready()) {
97 switch (this->state_) {
99 case State::IDLE:
100 break;
101
103 this->full_loop_is_okay_ = true;
104
105 if (this->shunt_voltage_sensor_ != nullptr) {
106 float shunt_voltage{0};
107 this->full_loop_is_okay_ &= this->read_shunt_voltage_mv_(shunt_voltage);
108 this->shunt_voltage_sensor_->publish_state(shunt_voltage);
109 }
110 this->state_ = State::DATA_COLLECTION_2;
111 break;
112
114 if (this->bus_voltage_sensor_ != nullptr) {
115 float bus_voltage{0};
116 this->full_loop_is_okay_ &= this->read_bus_voltage_(bus_voltage);
117 this->bus_voltage_sensor_->publish_state(bus_voltage);
118 }
119 this->state_ = State::DATA_COLLECTION_3;
120 break;
121
123 if (this->die_temperature_sensor_ != nullptr) {
124 float die_temperature{0};
125 this->full_loop_is_okay_ &= this->read_die_temp_c_(die_temperature);
126 this->die_temperature_sensor_->publish_state(die_temperature);
127 }
128 this->state_ = State::DATA_COLLECTION_4;
129 break;
130
132 if (this->current_sensor_ != nullptr) {
133 float current{0};
134 this->full_loop_is_okay_ &= this->read_current_a_(current);
135 this->current_sensor_->publish_state(current);
136 }
137 this->state_ = State::DATA_COLLECTION_5;
138 break;
139
141 if (this->power_sensor_ != nullptr) {
142 float power{0};
143 this->full_loop_is_okay_ &= this->read_power_w_(power);
144 this->power_sensor_->publish_state(power);
145 }
146 this->state_ = State::DATA_COLLECTION_6;
147 break;
148
150 if (this->ina_model_ == INAModel::INA_228 || this->ina_model_ == INAModel::INA_229) {
151 if (this->energy_sensor_j_ != nullptr || this->energy_sensor_wh_ != nullptr ||
152 this->charge_sensor_c_ != nullptr || this->charge_sensor_ah_ != nullptr) {
154 }
155 if (this->energy_sensor_j_ != nullptr || this->energy_sensor_wh_ != nullptr) {
156 double energy_j{0}, energy_wh{0};
157 this->full_loop_is_okay_ &= this->read_energy_(energy_j, energy_wh);
158 if (this->energy_sensor_j_ != nullptr)
159 this->energy_sensor_j_->publish_state(energy_j);
160 if (this->energy_sensor_wh_ != nullptr)
161 this->energy_sensor_wh_->publish_state(energy_wh);
162 }
163 }
164 this->state_ = State::DATA_COLLECTION_7;
165 break;
166
168 if (this->ina_model_ == INAModel::INA_228 || this->ina_model_ == INAModel::INA_229) {
169 if (this->charge_sensor_c_ != nullptr || this->charge_sensor_ah_ != nullptr) {
170 double charge_c{0}, charge_ah{0};
171 this->full_loop_is_okay_ &= this->read_charge_(charge_c, charge_ah);
172 if (this->charge_sensor_c_ != nullptr)
173 this->charge_sensor_c_->publish_state(charge_c);
174 if (this->charge_sensor_ah_ != nullptr)
175 this->charge_sensor_ah_->publish_state(charge_ah);
176 }
177 }
178 this->state_ = State::DATA_COLLECTION_8;
179 break;
180
182 if (this->full_loop_is_okay_) {
183 this->status_clear_warning();
184 } else {
185 this->status_set_warning();
186 }
187 this->state_ = State::IDLE;
188 break;
189
190 default:
191 ESP_LOGW(TAG, "Unknown state of the component, might be due to memory corruption");
192 break;
193 }
194 }
195}
196
198 ESP_LOGCONFIG(TAG, "INA2xx:");
199 ESP_LOGCONFIG(TAG, " Device model = %s", get_device_name(this->ina_model_));
200
201 if (this->device_mismatch_) {
202 ESP_LOGE(TAG, " Device model mismatch. Found device with ID = %x. Please check your configuration.",
203 this->dev_id_);
204 }
205 if (this->is_failed()) {
206 ESP_LOGE(TAG, "Communication with INA2xx failed!");
207 }
208 LOG_UPDATE_INTERVAL(this);
209 ESP_LOGCONFIG(TAG, " Shunt resistance = %f Ohm", this->shunt_resistance_ohm_);
210 ESP_LOGCONFIG(TAG, " Max current = %f A", this->max_current_a_);
211 ESP_LOGCONFIG(TAG, " Shunt temp coeff = %d ppm/°C", this->shunt_tempco_ppm_c_);
212 ESP_LOGCONFIG(TAG, " ADCRANGE = %d (%s)", (uint8_t) this->adc_range_, this->adc_range_ ? "±40.96 mV" : "±163.84 mV");
213 ESP_LOGCONFIG(TAG, " CURRENT_LSB = %f", this->current_lsb_);
214 ESP_LOGCONFIG(TAG, " SHUNT_CAL = %d", this->shunt_cal_);
215
216 ESP_LOGCONFIG(TAG, " ADC Samples = %d; ADC times: Bus = %d μs, Shunt = %d μs, Temp = %d μs",
217 ADC_SAMPLES[0b111 & (uint8_t) this->adc_avg_samples_],
218 ADC_TIMES[0b111 & (uint8_t) this->adc_time_bus_voltage_],
219 ADC_TIMES[0b111 & (uint8_t) this->adc_time_shunt_voltage_],
220 ADC_TIMES[0b111 & (uint8_t) this->adc_time_die_temperature_]);
221
222 ESP_LOGCONFIG(TAG, " Device is %s", get_device_name(this->ina_model_));
223
224 LOG_SENSOR(" ", "Shunt Voltage", this->shunt_voltage_sensor_);
225 LOG_SENSOR(" ", "Bus Voltage", this->bus_voltage_sensor_);
226 LOG_SENSOR(" ", "Die Temperature", this->die_temperature_sensor_);
227 LOG_SENSOR(" ", "Current", this->current_sensor_);
228 LOG_SENSOR(" ", "Power", this->power_sensor_);
229
230 if (this->ina_model_ == INAModel::INA_228 || this->ina_model_ == INAModel::INA_229) {
231 LOG_SENSOR(" ", "Energy J", this->energy_sensor_j_);
232 LOG_SENSOR(" ", "Energy Wh", this->energy_sensor_wh_);
233 LOG_SENSOR(" ", "Charge C", this->charge_sensor_c_);
234 LOG_SENSOR(" ", "Charge Ah", this->charge_sensor_ah_);
235 }
236}
237
239 if (this->ina_model_ != INAModel::INA_228 && this->ina_model_ != INAModel::INA_229) {
240 return false;
241 }
242 ESP_LOGV(TAG, "reset_energy_counters");
243
245 auto ret = this->read_unsigned_16_(RegisterMap::REG_CONFIG, cfg.raw_u16);
246 cfg.RSTACC = true;
247 cfg.ADCRANGE = this->adc_range_;
248 ret = ret && this->write_unsigned_16_(RegisterMap::REG_CONFIG, cfg.raw_u16);
249
250 this->energy_overflows_count_ = 0;
251 this->charge_overflows_count_ = 0;
252 return ret;
253}
254
256 ESP_LOGV(TAG, "Reset");
258 cfg.RST = true;
259 return this->write_unsigned_16_(RegisterMap::REG_CONFIG, cfg.raw_u16);
260}
261
263 constexpr uint16_t manufacturer_ti = 0x5449; // "TI"
264
265 uint16_t manufacturer_id{0}, rev_id{0};
268 this->dev_id_ = 0;
269 ESP_LOGV(TAG, "Can't read device ID");
270 };
271 rev_id = this->dev_id_ & 0x0F;
272 this->dev_id_ >>= 4;
273 ESP_LOGI(TAG, "Manufacturer: 0x%04X, Device ID: 0x%04X, Revision: %d", manufacturer_id, this->dev_id_, rev_id);
274
275 if (manufacturer_id != manufacturer_ti) {
276 ESP_LOGE(TAG, "Manufacturer ID doesn't match original 0x5449");
277 this->device_mismatch_ = true;
278 return false;
279 }
280
281 if (this->dev_id_ == 0x228 || this->dev_id_ == 0x229) {
282 ESP_LOGI(TAG, "Supported device found: INA%x, 85-V, 20-Bit, Ultra-Precise Power/Energy/Charge Monitor",
283 this->dev_id_);
284 } else if (this->dev_id_ == 0x238 || this->dev_id_ == 0x239) {
285 ESP_LOGI(TAG, "Supported device found: INA%x, 85-V, 16-Bit, High-Precision Power Monitor", this->dev_id_);
286 } else if (this->dev_id_ == 0x0 || this->dev_id_ == 0xFF) {
287 ESP_LOGI(TAG, "We assume device is: INA237 85-V, 16-Bit, Precision Power Monitor");
288 this->dev_id_ = 0x237;
289 } else {
290 ESP_LOGE(TAG, "Unknown device ID %x.", this->dev_id_);
291 this->device_mismatch_ = true;
292 return false;
293 }
294
295 // Check user-selected model agains what we have found. Mark as failed if selected model != found model
296 if (!check_model_and_device_match(this->ina_model_, this->dev_id_)) {
297 ESP_LOGE(TAG, "Selected model %s doesn't match found device INA%x", get_device_name(this->ina_model_),
298 this->dev_id_);
299 this->device_mismatch_ = true;
300 return false;
301 }
302
303 // setup device coefficients
304 if (this->ina_model_ == INAModel::INA_228 || this->ina_model_ == INAModel::INA_229) {
305 this->cfg_.vbus_lsb = 0.0001953125f;
306 this->cfg_.v_shunt_lsb_range0 = 0.0003125f;
307 this->cfg_.v_shunt_lsb_range1 = 0.000078125f;
308 this->cfg_.shunt_cal_scale = 13107.2f * 1000000.0f;
309 this->cfg_.current_lsb_scale_factor = -19;
310 this->cfg_.die_temp_lsb = 0.0078125f;
311 this->cfg_.power_coeff = 3.2f;
312 this->cfg_.energy_coeff = 16.0f * 3.2f;
313 } else {
314 this->cfg_.vbus_lsb = 0.0031250000f;
315 this->cfg_.v_shunt_lsb_range0 = 0.0050000f;
316 this->cfg_.v_shunt_lsb_range1 = 0.001250000f;
317 this->cfg_.shunt_cal_scale = 819.2f * 1000000.0f;
318 this->cfg_.current_lsb_scale_factor = -15;
319 this->cfg_.die_temp_lsb = 0.1250000f;
320 this->cfg_.power_coeff = 0.2f;
321 this->cfg_.energy_coeff = 0.0f; // N/A
322 }
323
324 return true;
325}
326
328 ESP_LOGV(TAG, "Setting ADCRANGE = %d", (uint8_t) this->adc_range_);
330 auto ret = this->read_unsigned_16_(RegisterMap::REG_CONFIG, cfg.raw_u16);
331 cfg.ADCRANGE = this->adc_range_;
332 ret = ret && this->write_unsigned_16_(RegisterMap::REG_CONFIG, cfg.raw_u16);
333
334 return ret;
335}
336
338 bool ret{false};
339 AdcConfigurationRegister adc_cfg{0};
340 adc_cfg.MODE = 0x0F; // Fh = Continuous bus voltage, shunt voltage and temperature
341 adc_cfg.VBUSCT = this->adc_time_bus_voltage_;
342 adc_cfg.VSHCT = this->adc_time_shunt_voltage_;
343 adc_cfg.VTCT = this->adc_time_die_temperature_;
344 adc_cfg.AVG = this->adc_avg_samples_;
345 ret = this->write_unsigned_16_(RegisterMap::REG_ADC_CONFIG, adc_cfg.raw_u16);
346 return ret;
347}
348
350 this->current_lsb_ = ldexp(this->max_current_a_, this->cfg_.current_lsb_scale_factor);
351 this->shunt_cal_ = (uint16_t) (this->cfg_.shunt_cal_scale * this->current_lsb_ * this->shunt_resistance_ohm_);
352 if (this->adc_range_)
353 this->shunt_cal_ *= 4;
354
355 if (this->shunt_cal_ & 0x8000) {
356 // cant be more than 15 bits
357 ESP_LOGW(TAG, "Shunt value too high");
358 }
359 this->shunt_cal_ &= 0x7FFF;
360 ESP_LOGV(TAG, "Given Rshunt=%f Ohm and Max_current=%.3f", this->shunt_resistance_ohm_, this->max_current_a_);
361 ESP_LOGV(TAG, "New CURRENT_LSB=%f, SHUNT_CAL=%u", this->current_lsb_, this->shunt_cal_);
363}
364
366 // Only for 228/229
367 // unsigned 14-bit value
368 // 0x0000 = 0 ppm/°C
369 // 0x3FFF = 16383 ppm/°C
370 if ((this->ina_model_ == INAModel::INA_228 || this->ina_model_ == INAModel::INA_229) &&
371 this->shunt_tempco_ppm_c_ > 0) {
373 }
374 return true;
375}
376
377bool INA2XX::read_shunt_voltage_mv_(float &volt_out) {
378 // Two's complement value
379 // 228, 229 - 24bit: 20(23-4) + 4(3-0) res
380 // 237, 238, 239 - 16bit
381
382 bool ret{false};
383 float volt_reading{0};
384 uint64_t raw{0};
385 if (this->ina_model_ == INAModel::INA_228 || this->ina_model_ == INAModel::INA_229) {
387 raw >>= 4;
388 volt_reading = this->two_complement_(raw, 20);
389 } else {
391 volt_reading = this->two_complement_(raw, 16);
392 }
393
394 if (ret) {
395 volt_out = (this->adc_range_ ? this->cfg_.v_shunt_lsb_range1 : this->cfg_.v_shunt_lsb_range0) * volt_reading;
396 }
397
398 ESP_LOGV(TAG, "read_shunt_voltage_mv_ ret=%s, shunt_cal=%d, reading_lsb=%f", OKFAILED(ret), this->shunt_cal_,
399 volt_reading);
400
401 return ret;
402}
403
404bool INA2XX::read_bus_voltage_(float &volt_out) {
405 // Two's complement value
406 // 228, 229 - 24bit: 20(23-4) + 4(3-0) res
407 // 237, 238, 239 - 16bit
408
409 bool ret{false};
410 float volt_reading{0};
411 uint64_t raw{0};
412 if (this->ina_model_ == INAModel::INA_228 || this->ina_model_ == INAModel::INA_229) {
414 raw >>= 4;
415 volt_reading = this->two_complement_(raw, 20);
416 } else {
418 volt_reading = this->two_complement_(raw, 16);
419 }
420 if (ret) {
421 volt_out = this->cfg_.vbus_lsb * (float) volt_reading;
422 }
423
424 ESP_LOGV(TAG, "read_bus_voltage_ ret=%s, reading_lsb=%f", OKFAILED(ret), volt_reading);
425 return ret;
426}
427
428bool INA2XX::read_die_temp_c_(float &temp_out) {
429 // Two's complement value
430 // 228, 229 - 16bit
431 // 237, 238, 239 - 16bit: 12(15-4) + 4(3-0) res
432
433 bool ret{false};
434 float temp_reading{0};
435 uint64_t raw{0};
436
437 if (this->ina_model_ == INAModel::INA_228 || this->ina_model_ == INAModel::INA_229) {
439 temp_reading = this->two_complement_(raw, 16);
440 } else {
442 raw >>= 4;
443 temp_reading = this->two_complement_(raw, 12);
444 }
445 if (ret) {
446 temp_out = this->cfg_.die_temp_lsb * (float) temp_reading;
447 }
448
449 ESP_LOGV(TAG, "read_die_temp_c_ ret=%s, reading_lsb=%f", OKFAILED(ret), temp_reading);
450 return ret;
451}
452
453bool INA2XX::read_current_a_(float &amps_out) {
454 // Two's complement value
455 // 228, 229 - 24bit: 20(23-4) + 4(3-0) res
456 // 237, 238, 239 - 16bit
457 bool ret{false};
458 float amps_reading{0};
459 uint64_t raw{0};
460
461 if (this->ina_model_ == INAModel::INA_228 || this->ina_model_ == INAModel::INA_229) {
463 raw >>= 4;
464 amps_reading = this->two_complement_(raw, 20);
465 } else {
467 amps_reading = this->two_complement_(raw, 16);
468 }
469
470 ESP_LOGV(TAG, "read_current_a_ ret=%s. current_lsb=%f. reading_lsb=%f", OKFAILED(ret), this->current_lsb_,
471 amps_reading);
472 if (ret) {
473 amps_out = this->current_lsb_ * (float) amps_reading;
474 }
475
476 return ret;
477}
478
479bool INA2XX::read_power_w_(float &power_out) {
480 // Unsigned value
481 // 228, 229 - 24bit
482 // 237, 238, 239 - 24bit
483 uint64_t power_reading{0};
484 auto ret = this->read_unsigned_((uint8_t) RegisterMap::REG_POWER, 3, power_reading);
485
486 ESP_LOGV(TAG, "read_power_w_ ret=%s, reading_lsb=%" PRIu32, OKFAILED(ret), (uint32_t) power_reading);
487 if (ret) {
488 power_out = this->cfg_.power_coeff * this->current_lsb_ * (float) power_reading;
489 }
490
491 return ret;
492}
493
494bool INA2XX::read_energy_(double &joules_out, double &watt_hours_out) {
495 // Unsigned value
496 // 228, 229 - 40bit
497 // 237, 238, 239 - not available
498 if (this->ina_model_ != INAModel::INA_228 && this->ina_model_ != INAModel::INA_229) {
499 joules_out = 0;
500 return false;
501 }
502 uint64_t joules_reading = 0;
503 uint64_t previous_energy = this->energy_overflows_count_ * (((uint64_t) 1) << 40);
504 auto ret = this->read_unsigned_((uint8_t) RegisterMap::REG_ENERGY, 5, joules_reading);
505
506 ESP_LOGV(TAG, "read_energy_j_ ret=%s, reading_lsb=0x%" PRIX64 ", current_lsb=%f, overflow_cnt=%" PRIu32,
507 OKFAILED(ret), joules_reading, this->current_lsb_, this->energy_overflows_count_);
508 if (ret) {
509 joules_out = this->cfg_.energy_coeff * this->current_lsb_ * (double) joules_reading + (double) previous_energy;
510 watt_hours_out = joules_out / 3600.0;
511 }
512 return ret;
513}
514
515bool INA2XX::read_charge_(double &coulombs_out, double &amp_hours_out) {
516 // Two's complement value
517 // 228, 229 - 40bit
518 // 237, 238, 239 - not available
519 if (this->ina_model_ != INAModel::INA_228 && this->ina_model_ != INAModel::INA_229) {
520 coulombs_out = 0;
521 return false;
522 }
523
524 // and what to do with this? datasheet doesnt tell us what if charge is negative
525 uint64_t previous_charge = this->charge_overflows_count_ * (((uint64_t) 1) << 39);
526 double coulombs_reading = 0;
527 uint64_t raw{0};
528 auto ret = this->read_unsigned_((uint8_t) RegisterMap::REG_CHARGE, 5, raw);
529 coulombs_reading = this->two_complement_(raw, 40);
530
531 ESP_LOGV(TAG, "read_charge_c_ ret=%d, curr_charge=%f + 39-bit overflow_cnt=%" PRIu32, ret, coulombs_reading,
533 if (ret) {
534 coulombs_out = this->current_lsb_ * (double) coulombs_reading + (double) previous_charge;
535 amp_hours_out = coulombs_out / 3600.0;
536 }
537 return ret;
538}
539
541 if (this->ina_model_ != INAModel::INA_228 && this->ina_model_ != INAModel::INA_229) {
542 return false;
543 }
544
545 DiagnosticRegister diag{0};
546 auto ret = this->read_unsigned_16_(RegisterMap::REG_DIAG_ALRT, diag.raw_u16);
547 ESP_LOGV(TAG, "read_diagnostics_and_act_ ret=%s, 0x%04X", OKFAILED(ret), diag.raw_u16);
548
549 if (diag.ENERGYOF) {
550 this->energy_overflows_count_++; // 40-bit overflow
551 }
552
553 if (diag.CHARGEOF) {
554 this->charge_overflows_count_++; // 39-bit overflow
555 }
556
557 return ret;
558}
559
560bool INA2XX::write_unsigned_16_(uint8_t reg, uint16_t val) {
561 uint16_t data_out = byteswap(val);
562 auto ret = this->write_ina_register(reg, (uint8_t *) &data_out, 2);
563 if (!ret) {
564 ESP_LOGV(TAG, "write_unsigned_16_ FAILED reg=0x%02X, val=0x%04X", reg, val);
565 }
566 return ret;
567}
568
569bool INA2XX::read_unsigned_(uint8_t reg, uint8_t reg_size, uint64_t &data_out) {
570 static uint8_t rx_buf[5] = {0}; // max buffer size
571
572 if (reg_size > 5) {
573 return false;
574 }
575
576 auto ret = this->read_ina_register(reg, rx_buf, reg_size);
577
578 // Combine bytes
579 data_out = rx_buf[0];
580 for (uint8_t i = 1; i < reg_size; i++) {
581 data_out = (data_out << 8) | rx_buf[i];
582 }
583 ESP_LOGV(TAG, "read_unsigned_ reg=0x%02X, ret=%s, len=%d, val=0x%" PRIX64, reg, OKFAILED(ret), reg_size, data_out);
584
585 return ret;
586}
587
588bool INA2XX::read_unsigned_16_(uint8_t reg, uint16_t &out) {
589 uint16_t data_in{0};
590 auto ret = this->read_ina_register(reg, (uint8_t *) &data_in, 2);
591 out = byteswap(data_in);
592 ESP_LOGV(TAG, "read_unsigned_16_ 0x%02X, ret= %s, val=0x%04X", reg, OKFAILED(ret), out);
593 return ret;
594}
595
596int64_t INA2XX::two_complement_(uint64_t value, uint8_t bits) {
597 if (value > (1ULL << (bits - 1))) {
598 return (int64_t) (value - (1ULL << bits));
599 } else {
600 return (int64_t) value;
601 }
602}
603} // namespace ina2xx_base
604} // namespace esphome
uint8_t raw[35]
Definition bl0939.h:0
virtual void mark_failed()
Mark this component as failed.
bool is_failed() const
bool is_ready() const
void status_set_warning(const char *message="unspecified")
void status_clear_warning()
bool read_die_temp_c_(float &temp)
bool write_unsigned_16_(uint8_t reg, uint16_t val)
sensor::Sensor * bus_voltage_sensor_
bool read_unsigned_(uint8_t reg, uint8_t reg_size, uint64_t &data_out)
sensor::Sensor * energy_sensor_j_
bool read_bus_voltage_(float &volt_out)
sensor::Sensor * power_sensor_
bool read_unsigned_16_(uint8_t reg, uint16_t &out)
sensor::Sensor * charge_sensor_c_
sensor::Sensor * die_temperature_sensor_
sensor::Sensor * energy_sensor_wh_
bool read_shunt_voltage_mv_(float &volt_out)
virtual bool read_ina_register(uint8_t a_register, uint8_t *data, size_t len)=0
sensor::Sensor * charge_sensor_ah_
bool read_power_w_(float &power_out)
int64_t two_complement_(uint64_t value, uint8_t bits)
bool read_charge_(double &coulombs_out, double &amp_hours_out)
sensor::Sensor * current_sensor_
bool read_energy_(double &joules_out, double &watt_hours_out)
float get_setup_priority() const override
bool read_current_a_(float &amps_out)
struct esphome::ina2xx_base::INA2XX::@87 cfg_
sensor::Sensor * shunt_voltage_sensor_
virtual bool write_ina_register(uint8_t a_register, const uint8_t *data, size_t len)=0
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:39
mopeka_std_values val[4]
const float DATA
For components that import data from directly connected sensors like DHT.
Definition component.cpp:19
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
void IRAM_ATTR HOT delay(uint32_t ms)
Definition core.cpp:28
void byteswap()