Daly BMS improvements (#3388)

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
Co-authored-by: Samuel Sieb <samuel-github@sieb.net>
This commit is contained in:
matthias882
2023-08-10 07:05:01 +02:00
committed by GitHub
parent 0ed0bdc655
commit 5b0b9da0b9
6 changed files with 217 additions and 180 deletions
+156 -85
View File
@@ -1,6 +1,6 @@
#include "daly_bms.h"
#include "esphome/core/log.h"
#include <vector>
#include "esphome/core/log.h"
namespace esphome {
namespace daly_bms {
@@ -19,7 +19,7 @@ static const uint8_t DALY_REQUEST_STATUS = 0x94;
static const uint8_t DALY_REQUEST_CELL_VOLTAGE = 0x95;
static const uint8_t DALY_REQUEST_TEMPERATURE = 0x96;
void DalyBmsComponent::setup() {}
void DalyBmsComponent::setup() { this->next_request_ = 1; }
void DalyBmsComponent::dump_config() {
ESP_LOGCONFIG(TAG, "Daly BMS:");
@@ -27,20 +27,78 @@ void DalyBmsComponent::dump_config() {
}
void DalyBmsComponent::update() {
this->request_data_(DALY_REQUEST_BATTERY_LEVEL);
this->request_data_(DALY_REQUEST_MIN_MAX_VOLTAGE);
this->request_data_(DALY_REQUEST_MIN_MAX_TEMPERATURE);
this->request_data_(DALY_REQUEST_MOS);
this->request_data_(DALY_REQUEST_STATUS);
this->request_data_(DALY_REQUEST_CELL_VOLTAGE);
this->request_data_(DALY_REQUEST_TEMPERATURE);
this->trigger_next_ = true;
this->next_request_ = 0;
}
std::vector<uint8_t> get_battery_level_data;
int available_data = this->available();
if (available_data >= DALY_FRAME_SIZE) {
get_battery_level_data.resize(available_data);
this->read_array(get_battery_level_data.data(), available_data);
this->decode_data_(get_battery_level_data);
void DalyBmsComponent::loop() {
const uint32_t now = millis();
if (this->receiving_ && (now - this->last_transmission_ >= 200)) {
// last transmission too long ago. Reset RX index.
ESP_LOGW(TAG, "Last transmission too long ago. Reset RX index.");
this->data_.clear();
this->receiving_ = false;
}
if ((now - this->last_transmission_ >= 250) && !this->trigger_next_) {
// last transmittion longer than 0.25s ago -> trigger next request
this->last_transmission_ = now;
this->trigger_next_ = true;
}
if (available())
this->last_transmission_ = now;
while (available()) {
uint8_t c;
read_byte(&c);
if (!this->receiving_) {
if (c != 0xa5)
continue;
this->receiving_ = true;
}
this->data_.push_back(c);
if (this->data_.size() == 4)
this->data_count_ = c;
if ((this->data_.size() > 4) and (data_.size() == this->data_count_ + 5)) {
this->decode_data_(this->data_);
this->data_.clear();
this->receiving_ = false;
}
}
if (this->trigger_next_) {
this->trigger_next_ = false;
switch (this->next_request_) {
case 0:
this->request_data_(DALY_REQUEST_BATTERY_LEVEL);
this->next_request_ = 1;
break;
case 1:
this->request_data_(DALY_REQUEST_MIN_MAX_VOLTAGE);
this->next_request_ = 2;
break;
case 2:
this->request_data_(DALY_REQUEST_MIN_MAX_TEMPERATURE);
this->next_request_ = 3;
break;
case 3:
this->request_data_(DALY_REQUEST_MOS);
this->next_request_ = 4;
break;
case 4:
this->request_data_(DALY_REQUEST_STATUS);
this->next_request_ = 5;
break;
case 5:
this->request_data_(DALY_REQUEST_CELL_VOLTAGE);
this->next_request_ = 6;
break;
case 6:
this->request_data_(DALY_REQUEST_TEMPERATURE);
this->next_request_ = 7;
break;
case 7:
default:
break;
}
}
}
@@ -49,21 +107,23 @@ float DalyBmsComponent::get_setup_priority() const { return setup_priority::DATA
void DalyBmsComponent::request_data_(uint8_t data_id) {
uint8_t request_message[DALY_FRAME_SIZE];
request_message[0] = 0xA5; // Start Flag
request_message[1] = addr_; // Communication Module Address
request_message[2] = data_id; // Data ID
request_message[3] = 0x08; // Data Length (Fixed)
request_message[4] = 0x00; // Empty Data
request_message[5] = 0x00; // |
request_message[6] = 0x00; // |
request_message[7] = 0x00; // |
request_message[8] = 0x00; // |
request_message[9] = 0x00; // |
request_message[10] = 0x00; // |
request_message[11] = 0x00; // Empty Data
request_message[0] = 0xA5; // Start Flag
request_message[1] = this->addr_; // Communication Module Address
request_message[2] = data_id; // Data ID
request_message[3] = 0x08; // Data Length (Fixed)
request_message[4] = 0x00; // Empty Data
request_message[5] = 0x00; // |
request_message[6] = 0x00; // |
request_message[7] = 0x00; // |
request_message[8] = 0x00; // |
request_message[9] = 0x00; // |
request_message[10] = 0x00; // |
request_message[11] = 0x00; // Empty Data
request_message[12] = (uint8_t) (request_message[0] + request_message[1] + request_message[2] +
request_message[3]); // Checksum (Lower byte of the other bytes sum)
ESP_LOGV(TAG, "Request datapacket Nr %x", data_id);
this->write_array(request_message, sizeof(request_message));
this->flush();
}
@@ -82,6 +142,7 @@ void DalyBmsComponent::decode_data_(std::vector<uint8_t> data) {
if (checksum == it[12]) {
switch (it[2]) {
#ifdef USE_SENSOR
case DALY_REQUEST_BATTERY_LEVEL:
if (this->voltage_sensor_) {
this->voltage_sensor_->publish_state((float) encode_uint16(it[4], it[5]) / 10);
@@ -95,36 +156,37 @@ void DalyBmsComponent::decode_data_(std::vector<uint8_t> data) {
break;
case DALY_REQUEST_MIN_MAX_VOLTAGE:
if (this->max_cell_voltage_) {
this->max_cell_voltage_->publish_state((float) encode_uint16(it[4], it[5]) / 1000);
if (this->max_cell_voltage_sensor_) {
this->max_cell_voltage_sensor_->publish_state((float) encode_uint16(it[4], it[5]) / 1000);
}
if (this->max_cell_voltage_number_) {
this->max_cell_voltage_number_->publish_state(it[6]);
if (this->max_cell_voltage_number_sensor_) {
this->max_cell_voltage_number_sensor_->publish_state(it[6]);
}
if (this->min_cell_voltage_) {
this->min_cell_voltage_->publish_state((float) encode_uint16(it[7], it[8]) / 1000);
if (this->min_cell_voltage_sensor_) {
this->min_cell_voltage_sensor_->publish_state((float) encode_uint16(it[7], it[8]) / 1000);
}
if (this->min_cell_voltage_number_) {
this->min_cell_voltage_number_->publish_state(it[9]);
if (this->min_cell_voltage_number_sensor_) {
this->min_cell_voltage_number_sensor_->publish_state(it[9]);
}
break;
case DALY_REQUEST_MIN_MAX_TEMPERATURE:
if (this->max_temperature_) {
this->max_temperature_->publish_state(it[4] - DALY_TEMPERATURE_OFFSET);
if (this->max_temperature_sensor_) {
this->max_temperature_sensor_->publish_state(it[4] - DALY_TEMPERATURE_OFFSET);
}
if (this->max_temperature_probe_number_) {
this->max_temperature_probe_number_->publish_state(it[5]);
if (this->max_temperature_probe_number_sensor_) {
this->max_temperature_probe_number_sensor_->publish_state(it[5]);
}
if (this->min_temperature_) {
this->min_temperature_->publish_state(it[6] - DALY_TEMPERATURE_OFFSET);
if (this->min_temperature_sensor_) {
this->min_temperature_sensor_->publish_state(it[6] - DALY_TEMPERATURE_OFFSET);
}
if (this->min_temperature_probe_number_) {
this->min_temperature_probe_number_->publish_state(it[7]);
if (this->min_temperature_probe_number_sensor_) {
this->min_temperature_probe_number_sensor_->publish_state(it[7]);
}
break;
#endif
case DALY_REQUEST_MOS:
#ifdef USE_TEXT_SENSOR
if (this->status_text_sensor_ != nullptr) {
switch (it[4]) {
case 0:
@@ -140,20 +202,27 @@ void DalyBmsComponent::decode_data_(std::vector<uint8_t> data) {
break;
}
}
if (this->charging_mos_enabled_) {
this->charging_mos_enabled_->publish_state(it[5]);
#endif
#ifdef USE_BINARY_SENSOR
if (this->charging_mos_enabled_binary_sensor_) {
this->charging_mos_enabled_binary_sensor_->publish_state(it[5]);
}
if (this->discharging_mos_enabled_) {
this->discharging_mos_enabled_->publish_state(it[6]);
if (this->discharging_mos_enabled_binary_sensor_) {
this->discharging_mos_enabled_binary_sensor_->publish_state(it[6]);
}
if (this->remaining_capacity_) {
this->remaining_capacity_->publish_state((float) encode_uint32(it[8], it[9], it[10], it[11]) / 1000);
#endif
#ifdef USE_SENSOR
if (this->remaining_capacity_sensor_) {
this->remaining_capacity_sensor_->publish_state((float) encode_uint32(it[8], it[9], it[10], it[11]) /
1000);
}
#endif
break;
#ifdef USE_SENSOR
case DALY_REQUEST_STATUS:
if (this->cells_number_) {
this->cells_number_->publish_state(it[4]);
if (this->cells_number_sensor_) {
this->cells_number_sensor_->publish_state(it[4]);
}
break;
@@ -171,71 +240,73 @@ void DalyBmsComponent::decode_data_(std::vector<uint8_t> data) {
case DALY_REQUEST_CELL_VOLTAGE:
switch (it[4]) {
case 1:
if (this->cell_1_voltage_) {
this->cell_1_voltage_->publish_state((float) encode_uint16(it[5], it[6]) / 1000);
if (this->cell_1_voltage_sensor_) {
this->cell_1_voltage_sensor_->publish_state((float) encode_uint16(it[5], it[6]) / 1000);
}
if (this->cell_2_voltage_) {
this->cell_2_voltage_->publish_state((float) encode_uint16(it[7], it[8]) / 1000);
if (this->cell_2_voltage_sensor_) {
this->cell_2_voltage_sensor_->publish_state((float) encode_uint16(it[7], it[8]) / 1000);
}
if (this->cell_3_voltage_) {
this->cell_3_voltage_->publish_state((float) encode_uint16(it[9], it[10]) / 1000);
if (this->cell_3_voltage_sensor_) {
this->cell_3_voltage_sensor_->publish_state((float) encode_uint16(it[9], it[10]) / 1000);
}
break;
case 2:
if (this->cell_4_voltage_) {
this->cell_4_voltage_->publish_state((float) encode_uint16(it[5], it[6]) / 1000);
if (this->cell_4_voltage_sensor_) {
this->cell_4_voltage_sensor_->publish_state((float) encode_uint16(it[5], it[6]) / 1000);
}
if (this->cell_5_voltage_) {
this->cell_5_voltage_->publish_state((float) encode_uint16(it[7], it[8]) / 1000);
if (this->cell_5_voltage_sensor_) {
this->cell_5_voltage_sensor_->publish_state((float) encode_uint16(it[7], it[8]) / 1000);
}
if (this->cell_6_voltage_) {
this->cell_6_voltage_->publish_state((float) encode_uint16(it[9], it[10]) / 1000);
if (this->cell_6_voltage_sensor_) {
this->cell_6_voltage_sensor_->publish_state((float) encode_uint16(it[9], it[10]) / 1000);
}
break;
case 3:
if (this->cell_7_voltage_) {
this->cell_7_voltage_->publish_state((float) encode_uint16(it[5], it[6]) / 1000);
if (this->cell_7_voltage_sensor_) {
this->cell_7_voltage_sensor_->publish_state((float) encode_uint16(it[5], it[6]) / 1000);
}
if (this->cell_8_voltage_) {
this->cell_8_voltage_->publish_state((float) encode_uint16(it[7], it[8]) / 1000);
if (this->cell_8_voltage_sensor_) {
this->cell_8_voltage_sensor_->publish_state((float) encode_uint16(it[7], it[8]) / 1000);
}
if (this->cell_9_voltage_) {
this->cell_9_voltage_->publish_state((float) encode_uint16(it[9], it[10]) / 1000);
if (this->cell_9_voltage_sensor_) {
this->cell_9_voltage_sensor_->publish_state((float) encode_uint16(it[9], it[10]) / 1000);
}
break;
case 4:
if (this->cell_10_voltage_) {
this->cell_10_voltage_->publish_state((float) encode_uint16(it[5], it[6]) / 1000);
if (this->cell_10_voltage_sensor_) {
this->cell_10_voltage_sensor_->publish_state((float) encode_uint16(it[5], it[6]) / 1000);
}
if (this->cell_11_voltage_) {
this->cell_11_voltage_->publish_state((float) encode_uint16(it[7], it[8]) / 1000);
if (this->cell_11_voltage_sensor_) {
this->cell_11_voltage_sensor_->publish_state((float) encode_uint16(it[7], it[8]) / 1000);
}
if (this->cell_12_voltage_) {
this->cell_12_voltage_->publish_state((float) encode_uint16(it[9], it[10]) / 1000);
if (this->cell_12_voltage_sensor_) {
this->cell_12_voltage_sensor_->publish_state((float) encode_uint16(it[9], it[10]) / 1000);
}
break;
case 5:
if (this->cell_13_voltage_) {
this->cell_13_voltage_->publish_state((float) encode_uint16(it[5], it[6]) / 1000);
if (this->cell_13_voltage_sensor_) {
this->cell_13_voltage_sensor_->publish_state((float) encode_uint16(it[5], it[6]) / 1000);
}
if (this->cell_14_voltage_) {
this->cell_14_voltage_->publish_state((float) encode_uint16(it[7], it[8]) / 1000);
if (this->cell_14_voltage_sensor_) {
this->cell_14_voltage_sensor_->publish_state((float) encode_uint16(it[7], it[8]) / 1000);
}
if (this->cell_15_voltage_) {
this->cell_15_voltage_->publish_state((float) encode_uint16(it[9], it[10]) / 1000);
if (this->cell_15_voltage_sensor_) {
this->cell_15_voltage_sensor_->publish_state((float) encode_uint16(it[9], it[10]) / 1000);
}
break;
case 6:
if (this->cell_16_voltage_) {
this->cell_16_voltage_->publish_state((float) encode_uint16(it[5], it[6]) / 1000);
if (this->cell_16_voltage_sensor_) {
this->cell_16_voltage_sensor_->publish_state((float) encode_uint16(it[5], it[6]) / 1000);
}
break;
}
break;
#endif
default:
break;
}
} else {
ESP_LOGW(TAG, "Checksum-Error on Packet %x", it[4]);
}
std::advance(it, DALY_FRAME_SIZE);
} else {