10 static const char *
const TAG =
"cse7766";
13 const uint32_t now =
millis();
27 this->raw_data_index_ = 0;
32 if (this->raw_data_index_ == 23) {
37 this->raw_data_index_ = (this->raw_data_index_ + 1) % 24;
46 return !((byte != 0x55) && ((byte & 0xF0) != 0xF0) && (byte != 0xAA));
51 ESP_LOGV(TAG,
"Invalid Header 2 Start: 0x%02X!", byte);
59 for (uint8_t i = 2; i < 23; i++) {
64 ESP_LOGW(TAG,
"Invalid checksum from CSE7766: 0x%02X != 0x%02X", checksum, this->
raw_data_[23]);
73 #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE 76 ss <<
"Raw data:" << std::hex << std::uppercase << std::setfill(
'0');
77 for (uint8_t i = 0; i < 23; i++) {
78 ss << ' ' << std::setw(2) << static_cast<unsigned>(this->
raw_data_[i]);
80 ESP_LOGVV(TAG,
"%s", ss.str().c_str());
87 if (header1 == 0xAA) {
88 ESP_LOGE(TAG,
"CSE7766 not calibrated!");
92 bool power_cycle_exceeds_range =
false;
93 if ((header1 & 0xF0) == 0xF0) {
95 ESP_LOGE(TAG,
"CSE7766 reports abnormal external circuit or chip damage: (0x%02X)", header1);
96 if (header1 & (1 << 3)) {
97 ESP_LOGE(TAG,
" Voltage cycle exceeds range.");
99 if (header1 & (1 << 2)) {
100 ESP_LOGE(TAG,
" Current cycle exceeds range.");
102 if (header1 & (1 << 0)) {
103 ESP_LOGE(TAG,
" Coefficient storage area is abnormal.");
110 power_cycle_exceeds_range = header1 & (1 << 1);
123 bool have_power = adj & 0x10;
124 bool have_current = adj & 0x20;
125 bool have_voltage = adj & 0x40;
127 float voltage = 0.0f;
129 voltage = voltage_coeff / float(voltage_cycle);
142 this->cf_pulses_last_ = cf_pulses;
143 energy = this->
cf_pulses_total_ * float(power_coeff) / 1000000.0f / 3600.0f;
148 if (power_cycle_exceeds_range) {
154 }
else if (have_power) {
155 power = power_coeff / float(power_cycle);
161 float current = 0.0f;
162 float calculated_current = 0.0f;
165 if (have_power && voltage > 1.0f) {
166 calculated_current = power / voltage;
169 if (calculated_current > 0.05f) {
170 current = current_coeff / float(current_cycle);
177 if (have_voltage && have_current) {
178 const float apparent_power = voltage * current;
183 const float reactive_power = apparent_power - power;
184 if (reactive_power < 0.0f) {
185 ESP_LOGD(TAG,
"Impossible reactive power: %.4f is negative", reactive_power);
193 if (apparent_power > 0) {
194 pf = power / apparent_power;
195 if (pf < 0 || pf > 1) {
196 ESP_LOGD(TAG,
"Impossible power factor: %.4f not in interval [0, 1]", pf);
199 }
else if (apparent_power == 0 && power == 0) {
202 }
else if (current == 0 && calculated_current <= 0.05f) {
204 ESP_LOGV(TAG,
"Can't calculate power factor (current below minimum for CSE7766)");
206 ESP_LOGW(TAG,
"Can't calculate power factor from P = %.4f W, S = %.4f VA", power, apparent_power);
212 #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE 214 std::stringstream ss;
217 ss <<
" V=" << voltage <<
"V";
220 ss <<
" I=" << current * 1000.0f <<
"mA (~" << calculated_current * 1000.0f <<
"mA)";
223 ss <<
" P=" << power <<
"W";
225 if (energy != 0.0f) {
226 ss <<
" E=" << energy <<
"kWh (" << cf_pulses <<
")";
228 ESP_LOGVV(TAG,
"%s", ss.str().c_str());
234 return (uint32_t(this->
raw_data_[start_index]) << 16) | (uint32_t(this->
raw_data_[start_index + 1]) << 8) |
235 uint32_t(this->
raw_data_[start_index + 2]);
239 ESP_LOGCONFIG(TAG,
"CSE7766:");
sensor::Sensor * power_sensor_
const float DATA
For components that import data from directly connected sensors like DHT.
void status_set_warning(const char *message="unspecified")
sensor::Sensor * power_factor_sensor_
uint32_t get_24_bit_uint_(uint8_t start_index)
sensor::Sensor * energy_sensor_
uint32_t IRAM_ATTR HOT millis()
void check_uart_settings(uint32_t baud_rate, uint8_t stop_bits=1, UARTParityOptions parity=UART_CONFIG_PARITY_NONE, uint8_t data_bits=8)
Check that the configuration of the UART bus matches the provided values and otherwise print a warnin...
uint32_t cf_pulses_total_
bool read_byte(uint8_t *data)
void status_clear_warning()
void publish_state(float state)
Publish a new state to the front-end.
void dump_config() override
float get_setup_priority() const override
Implementation of SPI Controller mode.
bool has_state() const
Return whether this sensor has gotten a full state (that passed through all filters) yet...
sensor::Sensor * current_sensor_
uint32_t last_transmission_
sensor::Sensor * apparent_power_sensor_
sensor::Sensor * voltage_sensor_
sensor::Sensor * reactive_power_sensor_