Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Seplos V3.0 BMS Multi Pack #112

Open
DpunktS opened this issue Oct 1, 2024 · 29 comments
Open

Seplos V3.0 BMS Multi Pack #112

DpunktS opened this issue Oct 1, 2024 · 29 comments

Comments

@DpunktS
Copy link

DpunktS commented Oct 1, 2024

Hallo,

ich habe mein Seplos V3.0 BMS mit einem 2. BMS aufgerüstet (Multi Pack). Leider bekomme ich sehr viele CRC Fehler für das 2. BMS und somit keine vernünftigen Sensorwerte.

[20:52:04][W][modbus:114]: Modbus CRC Check failed! 9E67!=100
[20:52:04][W][modbus:114]: Modbus CRC Check failed! 31C2!=E8

Wie kann ich meinen Speicher weiterhin auslesen?

@syssi
Copy link
Owner

syssi commented Oct 1, 2024

Wie genau sieht deine YAML-Konfiguration aus? Wie häufig fragst du die Geräte nach neuen Werten?

@DpunktS
Copy link
Author

DpunktS commented Oct 1, 2024

Im Grunde ist es deine Standard YAML für den ESP32 mit allem Werten und 10s intervall.

Mir ist auch aufgefallen wenn ich meinen selbst gebauten RS485 USB Adapter verwende erreiche ich mit dem Laptop das erst BMS nicht, das 2. BMS hat angeblich die Adresse 3 und der Wechselrichter hat keine Kommunikation zum BMS mehr. Laut Seplos Anleitung hat die RJ45 Buchse noch 2 Adressierungspins (4,5). Ich habe mir jetzt nochmal den originalen Adapter bestellt zum testen.

Einzeln hat mein Setup bis jetzt fehlerfrei funktioniert und auch die Kommunikation zwischen den beiden BMSs funktioniert.

@DpunktS
Copy link
Author

DpunktS commented Oct 2, 2024

Ich glaube, die Lösung für mein Problem ist dieser Lösungsansatz #80

Leider wurde die YAML nicht mit den Zellspannungen vervollständigt.

@DpunktS
Copy link
Author

DpunktS commented Oct 7, 2024

Ich habe es jetzt geschafft, meine 2 Speicher auszulesen. Es wäre schön, wenn ihr es in euer Projekt aufnehmen könntet, weil ESPHome bald die Unterstützung für "Custom Sensor Component" einstellt.

// *****************************************************************
// *          ESPHome Custom Component Modbus sniffer for          *
// *          Seplos v3                                            *
// *****************************************************************
//02 04 10 00 00 12 74 F4 
//02 04 24 15 20 19 EC 36 09 71 48 00 1A 01 DD 03 E8 00 01 0D 34 0B AD 0D 3C 0D 2F 0B B4 0B A9 00 00 00 B4 00 B4 03 E8 88 55 
//02 04 11 00 00 1A 74 CE 
//02 04 34 0D 31 0D 2F 0D 34 0D 35 0D 31 0D 30 0D 39 0D 3C 0D 36 0D 31 0D 30 0D 32 0D 36 0D 3A 0D 32 0D 36 0B AF 0B AA 0B A9 0B B4 0A AB 0A AB 0A AB 0A AB 0B B3 0B AC 1C 77 
//02 01 12 00 00 90 39 2D 
//02 01 12 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 03 00 00 E9 99 
//01 04 24 15 1D 21 39 43 10 71 48 04 99 02 50 03 E3 00 32 0D 32 0B B3 0D 40 0D 2B 0B B6 0B B0 00 00 00 B4 00 B4 03 E8 D8 60 
//01 04 34 0D 2B 0D 31 0D 34 0D 2E 0D 35 0D 31 0D 34 0D 32 0D 40 0D 31 0D 33 0D 30 0D 30 0D 2F 0D 37 0D 2C 0B B0 0B B6 0B B4 0B B5 0A AB 0A AB 0A AB 0A AB 0B B4 0B B2 9F 90 
//01 01 12 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 03 00 00 DA AA 

#include "esphome.h"

class solivia : public PollingComponent, public Sensor, public UARTDevice {
  public:
    solivia(UARTComponent *parent) : PollingComponent(200), UARTDevice(parent) {}
    Sensor *bms1_pack_voltage = new Sensor();
    Sensor *bms1_current = new Sensor();
    Sensor *bms1_remaining_capacity = new Sensor();
    Sensor *bms1_total_capacity = new Sensor();
    Sensor *bms1_total_discharge_capacity = new Sensor();
    Sensor *bms1_soc = new Sensor();
    Sensor *bms1_soh = new Sensor();
    Sensor *bms1_cycle = new Sensor();
    Sensor *bms1_average_cell_voltage = new Sensor();
    Sensor *bms1_average_cell_temp = new Sensor();
    Sensor *bms1_max_cell_voltage = new Sensor();
    Sensor *bms1_min_cell_voltage = new Sensor();
    Sensor *bms1_max_cell_temp = new Sensor();
    Sensor *bms1_min_cell_temp = new Sensor();
    Sensor *bms1_maxdiscurt = new Sensor();
    Sensor *bms1_maxchgcurt = new Sensor();

    Sensor *bms1_cell_1 = new Sensor();
    Sensor *bms1_cell_2 = new Sensor();
    Sensor *bms1_cell_3 = new Sensor();
    Sensor *bms1_cell_4 = new Sensor();
    Sensor *bms1_cell_5 = new Sensor();
    Sensor *bms1_cell_6 = new Sensor();
    Sensor *bms1_cell_7 = new Sensor();
    Sensor *bms1_cell_8 = new Sensor();
    Sensor *bms1_cell_9 = new Sensor();
    Sensor *bms1_cell_10 = new Sensor();
    Sensor *bms1_cell_11 = new Sensor();
    Sensor *bms1_cell_12 = new Sensor();
    Sensor *bms1_cell_13 = new Sensor();
    Sensor *bms1_cell_14 = new Sensor();
    Sensor *bms1_cell_15 = new Sensor();
    Sensor *bms1_cell_16 = new Sensor();
    Sensor *bms1_cell_temp_1 = new Sensor();
    Sensor *bms1_cell_temp_2 = new Sensor();
    Sensor *bms1_cell_temp_3 = new Sensor();
    Sensor *bms1_cell_temp_4 = new Sensor();
    Sensor *bms1_case_temp = new Sensor();
    Sensor *bms1_power_temp = new Sensor();

    Sensor *bms0_pack_voltage = new Sensor();
    Sensor *bms0_current = new Sensor();
    Sensor *bms0_remaining_capacity = new Sensor();
    Sensor *bms0_total_capacity = new Sensor();
    Sensor *bms0_total_discharge_capacity = new Sensor();
    Sensor *bms0_soc = new Sensor();
    Sensor *bms0_soh = new Sensor();
    Sensor *bms0_cycle = new Sensor();
    Sensor *bms0_average_cell_voltage = new Sensor();
    Sensor *bms0_average_cell_temp = new Sensor();
    Sensor *bms0_max_cell_voltage = new Sensor();
    Sensor *bms0_min_cell_voltage = new Sensor();
    Sensor *bms0_max_cell_temp = new Sensor();
    Sensor *bms0_min_cell_temp = new Sensor();
    Sensor *bms0_maxdiscurt = new Sensor();
    Sensor *bms0_maxchgcurt = new Sensor();

    Sensor *bms0_cell_1 = new Sensor();
    Sensor *bms0_cell_2 = new Sensor();
    Sensor *bms0_cell_3 = new Sensor();
    Sensor *bms0_cell_4 = new Sensor();
    Sensor *bms0_cell_5 = new Sensor();
    Sensor *bms0_cell_6 = new Sensor();
    Sensor *bms0_cell_7 = new Sensor();
    Sensor *bms0_cell_8 = new Sensor();
    Sensor *bms0_cell_9 = new Sensor();
    Sensor *bms0_cell_10 = new Sensor();
    Sensor *bms0_cell_11 = new Sensor();
    Sensor *bms0_cell_12 = new Sensor();
    Sensor *bms0_cell_13 = new Sensor();
    Sensor *bms0_cell_14 = new Sensor();
    Sensor *bms0_cell_15 = new Sensor();
    Sensor *bms0_cell_16 = new Sensor();
    Sensor *bms0_cell_temp_1 = new Sensor();
    Sensor *bms0_cell_temp_2 = new Sensor();
    Sensor *bms0_cell_temp_3 = new Sensor();
    Sensor *bms0_cell_temp_4 = new Sensor();
    Sensor *bms0_case_temp = new Sensor();
    Sensor *bms0_power_temp = new Sensor();



  
  void setup() override {

  }

  std::vector<int> bytes;

  void update() {
    while(available() > 0) {
      bytes.push_back(read());      
      //make sure at least 8 header bytes are available for check
      if(bytes.size() < 5)       
      {
        continue;  
      }
      //ESP_LOGD("custom", "Checking for inverter package: %i", bytes.size());

      if (!((bytes[0] == 0x02 && bytes[1] == 0x04 && (bytes[2] == 0x24 || bytes[2] == 0x34)) || (bytes[0] == 0x01 && bytes[1] == 0x04 && (bytes[2] == 0x24 || bytes[2] == 0x34)))) {
 
        bytes.erase(bytes.begin()); //remove first byte from buffer
        continue;  
      }
     
      if(bytes.size() == 36+5 && bytes[0] == 0x02 && bytes[1] == 0x04 && bytes[2] == 0x24) {

        TwoByte bms1_pack_voltage_data;
        bms1_pack_voltage_data.Byte[0] = bytes[1 +3];
        bms1_pack_voltage_data.Byte[1] = bytes[0 +3];

        TwoByte bms1_current_data;
        bms1_current_data.Byte[0] = bytes[3 +3];
        bms1_current_data.Byte[1] = bytes[2 +3];

        TwoByte bms1_remaining_capacity_data;
        bms1_remaining_capacity_data.Byte[0] = bytes[5 +3];
        bms1_remaining_capacity_data.Byte[1] = bytes[4 +3]; 

        TwoByte bms1_total_capacity_data;
        bms1_total_capacity_data.Byte[0] = bytes[7 +3];
        bms1_total_capacity_data.Byte[1] = bytes[6 +3];

        TwoByte bms1_total_discharge_capacity_data;
        bms1_total_discharge_capacity_data.Byte[0] = bytes[9 +3];
        bms1_total_discharge_capacity_data.Byte[1] = bytes[8 +3];

        TwoByte bms1_soc_data;
        bms1_soc_data.Byte[0] = bytes[11 +3];
        bms1_soc_data.Byte[1] = bytes[10 +3];

        TwoByte bms1_soh_data;
        bms1_soh_data.Byte[0] = bytes[13 +3];
        bms1_soh_data.Byte[1] = bytes[12 +3];

        TwoByte bms1_cycle_data;
        bms1_cycle_data.Byte[0] = bytes[15 +3];
        bms1_cycle_data.Byte[1] = bytes[14 +3];

        TwoByte bms1_average_cell_voltage_data;
        bms1_average_cell_voltage_data.Byte[0] = bytes[17 +3];
        bms1_average_cell_voltage_data.Byte[1] = bytes[16 +3];

        TwoByte bms1_average_cell_temp_data;
        bms1_average_cell_temp_data.Byte[0] = bytes[19 +3];
        bms1_average_cell_temp_data.Byte[1] = bytes[18 +3];

        TwoByte bms1_max_cell_voltage_data;
        bms1_max_cell_voltage_data.Byte[0] = bytes[21 +3];
        bms1_max_cell_voltage_data.Byte[1] = bytes[20 +3];

        TwoByte bms1_min_cell_voltage_data;
        bms1_min_cell_voltage_data.Byte[0] = bytes[23 +3];
        bms1_min_cell_voltage_data.Byte[1] = bytes[22 +3];

        TwoByte bms1_max_cell_temp_data;
        bms1_max_cell_temp_data.Byte[0] = bytes[25 +3];
        bms1_max_cell_temp_data.Byte[1] = bytes[24 +3];

        TwoByte bms1_min_cell_temp_data;
        bms1_min_cell_temp_data.Byte[0] = bytes[27 +3];
        bms1_min_cell_temp_data.Byte[1] = bytes[26 +3];

        TwoByte bms1_maxdiscurt_data;
        bms1_maxdiscurt_data.Byte[0] = bytes[31 +3];
        bms1_maxdiscurt_data.Byte[1] = bytes[30 +3];

        TwoByte bms1_maxchgcurt_data;
        bms1_maxchgcurt_data.Byte[0] = bytes[33 +3];
        bms1_maxchgcurt_data.Byte[1] = bytes[32 +3];

        bms1_pack_voltage->publish_state(bms1_pack_voltage_data.UInt16);
        bms1_current->publish_state(bms1_current_data.Int16);
        bms1_remaining_capacity->publish_state(bms1_remaining_capacity_data.UInt16);
        bms1_total_capacity->publish_state(bms1_total_capacity_data.UInt16);
        bms1_total_discharge_capacity->publish_state(bms1_total_discharge_capacity_data.UInt16);
        bms1_soc->publish_state(bms1_soc_data.UInt16);
        bms1_soh->publish_state(bms1_soh_data.UInt16);
        bms1_cycle->publish_state(bms1_cycle_data.UInt16);
        bms1_average_cell_voltage->publish_state(bms1_average_cell_voltage_data.UInt16);
        bms1_average_cell_temp->publish_state(bms1_average_cell_temp_data.UInt16/10 - 273.15);
        bms1_max_cell_voltage->publish_state(bms1_max_cell_voltage_data.UInt16);
        bms1_min_cell_voltage->publish_state(bms1_min_cell_voltage_data.UInt16);
        bms1_max_cell_temp->publish_state(bms1_max_cell_temp_data.UInt16/10 - 273.15);
        bms1_min_cell_temp->publish_state(bms1_min_cell_temp_data.UInt16/10 - 273.15);
        bms1_maxdiscurt->publish_state(bms1_maxdiscurt_data.UInt16);
        bms1_maxchgcurt->publish_state(bms1_maxchgcurt_data.UInt16);    
        
        bytes.clear();
        continue; 
      } 
      if(bytes.size() == 52+5 && bytes[0] == 0x02 && bytes[1] == 0x04 && bytes[2] == 0x34) {
 
        TwoByte bms1_cell_1_data;
        bms1_cell_1_data.Byte[0] = bytes[1 +3];
        bms1_cell_1_data.Byte[1] = bytes[0 +3];

        TwoByte bms1_cell_2_data;
        bms1_cell_2_data.Byte[0] = bytes[3 +3];
        bms1_cell_2_data.Byte[1] = bytes[2 +3];

        TwoByte bms1_cell_3_data;
        bms1_cell_3_data.Byte[0] = bytes[5 +3];
        bms1_cell_3_data.Byte[1] = bytes[4 +3];

        TwoByte bms1_cell_4_data;
        bms1_cell_4_data.Byte[0] = bytes[7 +3];
        bms1_cell_4_data.Byte[1] = bytes[6 +3];

        TwoByte bms1_cell_5_data;
        bms1_cell_5_data.Byte[0] = bytes[9 +3];
        bms1_cell_5_data.Byte[1] = bytes[8 +3];

        TwoByte bms1_cell_6_data;
        bms1_cell_6_data.Byte[0] = bytes[11 +3];
        bms1_cell_6_data.Byte[1] = bytes[10 +3];

        TwoByte bms1_cell_7_data;
        bms1_cell_7_data.Byte[0] = bytes[13 +3];
        bms1_cell_7_data.Byte[1] = bytes[12 +3];

        TwoByte bms1_cell_8_data;
        bms1_cell_8_data.Byte[0] = bytes[15 +3];
        bms1_cell_8_data.Byte[1] = bytes[14 +3];

        TwoByte bms1_cell_9_data;
        bms1_cell_9_data.Byte[0] = bytes[17 +3];
        bms1_cell_9_data.Byte[1] = bytes[16 +3];

        TwoByte bms1_cell_10_data;
        bms1_cell_10_data.Byte[0] = bytes[19 +3];
        bms1_cell_10_data.Byte[1] = bytes[18 +3];

        TwoByte bms1_cell_11_data;
        bms1_cell_11_data.Byte[0] = bytes[21 +3];
        bms1_cell_11_data.Byte[1] = bytes[20 +3];

        TwoByte bms1_cell_12_data;
        bms1_cell_12_data.Byte[0] = bytes[23 +3];
        bms1_cell_12_data.Byte[1] = bytes[22 +3];

        TwoByte bms1_cell_13_data;
        bms1_cell_13_data.Byte[0] = bytes[25 +3];
        bms1_cell_13_data.Byte[1] = bytes[24 +3];

        TwoByte bms1_cell_14_data;
        bms1_cell_14_data.Byte[0] = bytes[27 +3];
        bms1_cell_14_data.Byte[1] = bytes[26 +3];

        TwoByte bms1_cell_15_data;
        bms1_cell_15_data.Byte[0] = bytes[29 +3];
        bms1_cell_15_data.Byte[1] = bytes[28 +3];

        TwoByte bms1_cell_16_data;
        bms1_cell_16_data.Byte[0] = bytes[31 +3];
        bms1_cell_16_data.Byte[1] = bytes[30 +3];

        TwoByte bms1_cell_temp_1_data;
        bms1_cell_temp_1_data.Byte[0] = bytes[33 +3];
        bms1_cell_temp_1_data.Byte[1] = bytes[32 +3];

        TwoByte bms1_cell_temp_2_data;
        bms1_cell_temp_2_data.Byte[0] = bytes[35 +3];
        bms1_cell_temp_2_data.Byte[1] = bytes[34 +3];

        TwoByte bms1_cell_temp_3_data;
        bms1_cell_temp_3_data.Byte[0] = bytes[37 +3];
        bms1_cell_temp_3_data.Byte[1] = bytes[36 +3];

        TwoByte bms1_cell_temp_4_data;
        bms1_cell_temp_4_data.Byte[0] = bytes[39 +3];
        bms1_cell_temp_4_data.Byte[1] = bytes[38 +3];

        TwoByte bms1_case_temp_data;
        bms1_case_temp_data.Byte[0] = bytes[49 +3];
        bms1_case_temp_data.Byte[1] = bytes[48 +3];

        TwoByte bms1_power_temp_data;
        bms1_power_temp_data.Byte[0] = bytes[51 +3];
        bms1_power_temp_data.Byte[1] = bytes[50 +3];

        bms1_cell_1->publish_state(bms1_cell_1_data.UInt16);
        bms1_cell_2->publish_state(bms1_cell_2_data.UInt16);
        bms1_cell_3->publish_state(bms1_cell_3_data.UInt16);
        bms1_cell_4->publish_state(bms1_cell_4_data.UInt16);
        bms1_cell_5->publish_state(bms1_cell_5_data.UInt16);
        bms1_cell_6->publish_state(bms1_cell_6_data.UInt16);
        bms1_cell_7->publish_state(bms1_cell_7_data.UInt16);
        bms1_cell_8->publish_state(bms1_cell_8_data.UInt16);
        bms1_cell_9->publish_state(bms1_cell_9_data.UInt16);
        bms1_cell_10->publish_state(bms1_cell_10_data.UInt16);
        bms1_cell_11->publish_state(bms1_cell_11_data.UInt16);
        bms1_cell_12->publish_state(bms1_cell_12_data.UInt16);
        bms1_cell_13->publish_state(bms1_cell_13_data.UInt16);
        bms1_cell_14->publish_state(bms1_cell_14_data.UInt16);
        bms1_cell_15->publish_state(bms1_cell_15_data.UInt16);
        bms1_cell_16->publish_state(bms1_cell_16_data.UInt16);
        bms1_cell_temp_1->publish_state(bms1_cell_temp_1_data.UInt16/10 - 273.15);
        bms1_cell_temp_2->publish_state(bms1_cell_temp_2_data.UInt16/10 - 273.15);
        bms1_cell_temp_3->publish_state(bms1_cell_temp_3_data.UInt16/10 - 273.15);
        bms1_cell_temp_4->publish_state(bms1_cell_temp_4_data.UInt16/10 - 273.15);
        bms1_case_temp->publish_state(bms1_case_temp_data.UInt16/10 - 273.15);
        bms1_power_temp->publish_state(bms1_power_temp_data.UInt16/10 - 273.15);
     
        bytes.clear();
        continue; 
      }        

      if(bytes.size() == 36+5 && bytes[0] == 0x01 && bytes[1] == 0x04 && bytes[2] == 0x24) {

        TwoByte bms0_pack_voltage_data;
        bms0_pack_voltage_data.Byte[0] = bytes[1 +3];
        bms0_pack_voltage_data.Byte[1] = bytes[0 +3];

        TwoByte bms0_current_data;
        bms0_current_data.Byte[0] = bytes[3 +3];
        bms0_current_data.Byte[1] = bytes[2 +3];

        TwoByte bms0_remaining_capacity_data;
        bms0_remaining_capacity_data.Byte[0] = bytes[5 +3];
        bms0_remaining_capacity_data.Byte[1] = bytes[4 +3]; 

        TwoByte bms0_total_capacity_data;
        bms0_total_capacity_data.Byte[0] = bytes[7 +3];
        bms0_total_capacity_data.Byte[1] = bytes[6 +3];

        TwoByte bms0_total_discharge_capacity_data;
        bms0_total_discharge_capacity_data.Byte[0] = bytes[9 +3];
        bms0_total_discharge_capacity_data.Byte[1] = bytes[8 +3];

        TwoByte bms0_soc_data;
        bms0_soc_data.Byte[0] = bytes[11 +3];
        bms0_soc_data.Byte[1] = bytes[10 +3];

        TwoByte bms0_soh_data;
        bms0_soh_data.Byte[0] = bytes[13 +3];
        bms0_soh_data.Byte[1] = bytes[12 +3];

        TwoByte bms0_cycle_data;
        bms0_cycle_data.Byte[0] = bytes[15 +3];
        bms0_cycle_data.Byte[1] = bytes[14 +3];

        TwoByte bms0_average_cell_voltage_data;
        bms0_average_cell_voltage_data.Byte[0] = bytes[17 +3];
        bms0_average_cell_voltage_data.Byte[1] = bytes[16 +3];

        TwoByte bms0_average_cell_temp_data;
        bms0_average_cell_temp_data.Byte[0] = bytes[19 +3];
        bms0_average_cell_temp_data.Byte[1] = bytes[18 +3];

        TwoByte bms0_max_cell_voltage_data;
        bms0_max_cell_voltage_data.Byte[0] = bytes[21 +3];
        bms0_max_cell_voltage_data.Byte[1] = bytes[20 +3];

        TwoByte bms0_min_cell_voltage_data;
        bms0_min_cell_voltage_data.Byte[0] = bytes[23 +3];
        bms0_min_cell_voltage_data.Byte[1] = bytes[22 +3];

        TwoByte bms0_max_cell_temp_data;
        bms0_max_cell_temp_data.Byte[0] = bytes[25 +3];
        bms0_max_cell_temp_data.Byte[1] = bytes[24 +3];

        TwoByte bms0_min_cell_temp_data;
        bms0_min_cell_temp_data.Byte[0] = bytes[27 +3];
        bms0_min_cell_temp_data.Byte[1] = bytes[26 +3];

        TwoByte bms0_maxdiscurt_data;
        bms0_maxdiscurt_data.Byte[0] = bytes[31 +3];
        bms0_maxdiscurt_data.Byte[1] = bytes[30 +3];

        TwoByte bms0_maxchgcurt_data;
        bms0_maxchgcurt_data.Byte[0] = bytes[33 +3];
        bms0_maxchgcurt_data.Byte[1] = bytes[32 +3];

        bms0_pack_voltage->publish_state(bms0_pack_voltage_data.UInt16);
        bms0_current->publish_state(bms0_current_data.Int16);
        bms0_remaining_capacity->publish_state(bms0_remaining_capacity_data.UInt16);
        bms0_total_capacity->publish_state(bms0_total_capacity_data.UInt16);
        bms0_total_discharge_capacity->publish_state(bms0_total_discharge_capacity_data.UInt16);
        bms0_soc->publish_state(bms0_soc_data.UInt16);
        bms0_soh->publish_state(bms0_soh_data.UInt16);
        bms0_cycle->publish_state(bms0_cycle_data.UInt16);
        bms0_average_cell_voltage->publish_state(bms0_average_cell_voltage_data.UInt16);
        bms0_average_cell_temp->publish_state(bms0_average_cell_temp_data.UInt16/10 - 273.15);
        bms0_max_cell_voltage->publish_state(bms0_max_cell_voltage_data.UInt16);
        bms0_min_cell_voltage->publish_state(bms0_min_cell_voltage_data.UInt16);
        bms0_max_cell_temp->publish_state(bms0_max_cell_temp_data.UInt16/10 - 273.15);
        bms0_min_cell_temp->publish_state(bms0_min_cell_temp_data.UInt16/10 - 273.15);
        bms0_maxdiscurt->publish_state(bms0_maxdiscurt_data.UInt16);
        bms0_maxchgcurt->publish_state(bms0_maxchgcurt_data.UInt16);

        bytes.clear();
        continue; 
      }

      if(bytes.size() == 52+5 && bytes[0] == 0x01 && bytes[1] == 0x04 && bytes[2] == 0x34) {

        TwoByte bms0_cell_1_data;
        bms0_cell_1_data.Byte[0] = bytes[1 +3];
        bms0_cell_1_data.Byte[1] = bytes[0 +3];

        TwoByte bms0_cell_2_data;
        bms0_cell_2_data.Byte[0] = bytes[3 +3];
        bms0_cell_2_data.Byte[1] = bytes[2 +3];

        TwoByte bms0_cell_3_data;
        bms0_cell_3_data.Byte[0] = bytes[5 +3];
        bms0_cell_3_data.Byte[1] = bytes[4 +3];

        TwoByte bms0_cell_4_data;
        bms0_cell_4_data.Byte[0] = bytes[7 +3];
        bms0_cell_4_data.Byte[1] = bytes[6 +3];

        TwoByte bms0_cell_5_data;
        bms0_cell_5_data.Byte[0] = bytes[9 +3];
        bms0_cell_5_data.Byte[1] = bytes[8 +3];

        TwoByte bms0_cell_6_data;
        bms0_cell_6_data.Byte[0] = bytes[11 +3];
        bms0_cell_6_data.Byte[1] = bytes[10 +3];

        TwoByte bms0_cell_7_data;
        bms0_cell_7_data.Byte[0] = bytes[13 +3];
        bms0_cell_7_data.Byte[1] = bytes[12 +3];

        TwoByte bms0_cell_8_data;
        bms0_cell_8_data.Byte[0] = bytes[15 +3];
        bms0_cell_8_data.Byte[1] = bytes[14 +3];

        TwoByte bms0_cell_9_data;
        bms0_cell_9_data.Byte[0] = bytes[17 +3];
        bms0_cell_9_data.Byte[1] = bytes[16 +3];

        TwoByte bms0_cell_10_data;
        bms0_cell_10_data.Byte[0] = bytes[19 +3];
        bms0_cell_10_data.Byte[1] = bytes[18 +3];

        TwoByte bms0_cell_11_data;
        bms0_cell_11_data.Byte[0] = bytes[21 +3];
        bms0_cell_11_data.Byte[1] = bytes[20 +3];

        TwoByte bms0_cell_12_data;
        bms0_cell_12_data.Byte[0] = bytes[23 +3];
        bms0_cell_12_data.Byte[1] = bytes[22 +3];

        TwoByte bms0_cell_13_data;
        bms0_cell_13_data.Byte[0] = bytes[25 +3];
        bms0_cell_13_data.Byte[1] = bytes[24 +3];

        TwoByte bms0_cell_14_data;
        bms0_cell_14_data.Byte[0] = bytes[27 +3];
        bms0_cell_14_data.Byte[1] = bytes[26 +3];

        TwoByte bms0_cell_15_data;
        bms0_cell_15_data.Byte[0] = bytes[29 +3];
        bms0_cell_15_data.Byte[1] = bytes[28 +3];

        TwoByte bms0_cell_16_data;
        bms0_cell_16_data.Byte[0] = bytes[31 +3];
        bms0_cell_16_data.Byte[1] = bytes[30 +3];

        TwoByte bms0_cell_temp_1_data;
        bms0_cell_temp_1_data.Byte[0] = bytes[33 +3];
        bms0_cell_temp_1_data.Byte[1] = bytes[32 +3];

        TwoByte bms0_cell_temp_2_data;
        bms0_cell_temp_2_data.Byte[0] = bytes[35 +3];
        bms0_cell_temp_2_data.Byte[1] = bytes[34 +3];

        TwoByte bms0_cell_temp_3_data;
        bms0_cell_temp_3_data.Byte[0] = bytes[37 +3];
        bms0_cell_temp_3_data.Byte[1] = bytes[36 +3];

        TwoByte bms0_cell_temp_4_data;
        bms0_cell_temp_4_data.Byte[0] = bytes[39 +3];
        bms0_cell_temp_4_data.Byte[1] = bytes[38 +3];

        TwoByte bms0_case_temp_data;
        bms0_case_temp_data.Byte[0] = bytes[49 +3];
        bms0_case_temp_data.Byte[1] = bytes[48 +3];

        TwoByte bms0_power_temp_data;
        bms0_power_temp_data.Byte[0] = bytes[51 +3];
        bms0_power_temp_data.Byte[1] = bytes[50 +3];

        bms0_cell_1->publish_state(bms0_cell_1_data.UInt16);
        bms0_cell_2->publish_state(bms0_cell_2_data.UInt16);
        bms0_cell_3->publish_state(bms0_cell_3_data.UInt16);
        bms0_cell_4->publish_state(bms0_cell_4_data.UInt16);
        bms0_cell_5->publish_state(bms0_cell_5_data.UInt16);
        bms0_cell_6->publish_state(bms0_cell_6_data.UInt16);
        bms0_cell_7->publish_state(bms0_cell_7_data.UInt16);
        bms0_cell_8->publish_state(bms0_cell_8_data.UInt16);
        bms0_cell_9->publish_state(bms0_cell_9_data.UInt16);
        bms0_cell_10->publish_state(bms0_cell_10_data.UInt16);
        bms0_cell_11->publish_state(bms0_cell_11_data.UInt16);
        bms0_cell_12->publish_state(bms0_cell_12_data.UInt16);
        bms0_cell_13->publish_state(bms0_cell_13_data.UInt16);
        bms0_cell_14->publish_state(bms0_cell_14_data.UInt16);
        bms0_cell_15->publish_state(bms0_cell_15_data.UInt16);
        bms0_cell_16->publish_state(bms0_cell_16_data.UInt16);
        bms0_cell_temp_1->publish_state(bms0_cell_temp_1_data.UInt16/10 - 273.15);
        bms0_cell_temp_2->publish_state(bms0_cell_temp_2_data.UInt16/10 - 273.15);
        bms0_cell_temp_3->publish_state(bms0_cell_temp_3_data.UInt16/10 - 273.15);
        bms0_cell_temp_4->publish_state(bms0_cell_temp_4_data.UInt16/10 - 273.15);
        bms0_case_temp->publish_state(bms0_case_temp_data.UInt16/10 - 273.15);
        bms0_power_temp->publish_state(bms0_power_temp_data.UInt16/10 - 273.15);

        bytes.clear();
        continue; 
      }
      else {
      }    
    }    
  }

  typedef union
  {
    unsigned char Byte[2];
    int16_t Int16;
    uint16_t UInt16;
    unsigned char UChar;
    char Char;
  }TwoByte;};
substitutions:
  bms_name0: bms0
  bms_name1: bms1

esphome:
  includes:
    - ./seplos_v3_sniffer.h

esp32:
  board: esp32dev
  framework:
    type: arduino

# Disable logging over UART (required)
logger:
  baud_rate: 0

# Enable Home Assistant API
api:

ota:

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  ap:

captive_portal:

uart:
- id: uart_0
  tx_pin: GPIO17
  rx_pin: GPIO16
  baud_rate: 19200
  rx_buffer_size: 1024

sensor:
  - platform: custom
    lambda: |-
      auto delta = new solivia(id(uart_0));
      App.register_component(delta);
      return {delta->bms1_pack_voltage,delta->bms1_current,delta->bms1_remaining_capacity,delta->bms1_total_capacity,delta->bms1_total_discharge_capacity,delta->bms1_soc,delta->bms1_soh,delta->bms1_cycle,delta->bms1_average_cell_voltage,delta->bms1_average_cell_temp,delta->bms1_max_cell_voltage,delta->bms1_min_cell_voltage,delta->bms1_max_cell_temp,delta->bms1_min_cell_temp,delta->bms1_maxdiscurt,delta->bms1_maxchgcurt,delta->bms1_cell_1,delta->bms1_cell_2,delta->bms1_cell_3,delta->bms1_cell_4,delta->bms1_cell_5,delta->bms1_cell_6,delta->bms1_cell_7,delta->bms1_cell_8,delta->bms1_cell_9,delta->bms1_cell_10,delta->bms1_cell_11,delta->bms1_cell_12,delta->bms1_cell_13,delta->bms1_cell_14,delta->bms1_cell_15,delta->bms1_cell_16,delta->bms1_cell_temp_1,delta->bms1_cell_temp_2,delta->bms1_cell_temp_3,delta->bms1_cell_temp_4,delta->bms1_case_temp,delta->bms1_power_temp,delta->bms0_pack_voltage,delta->bms0_current,delta->bms0_remaining_capacity,delta->bms0_total_capacity,delta->bms0_total_discharge_capacity,delta->bms0_soc,delta->bms0_soh,delta->bms0_cycle,delta->bms0_average_cell_voltage,delta->bms0_average_cell_temp,delta->bms0_max_cell_voltage,delta->bms0_min_cell_voltage,delta->bms0_max_cell_temp,delta->bms0_min_cell_temp,delta->bms0_maxdiscurt,delta->bms0_maxchgcurt,delta->bms0_cell_1,delta->bms0_cell_2,delta->bms0_cell_3,delta->bms0_cell_4,delta->bms0_cell_5,delta->bms0_cell_6,delta->bms0_cell_7,delta->bms0_cell_8,delta->bms0_cell_9,delta->bms0_cell_10,delta->bms0_cell_11,delta->bms0_cell_12,delta->bms0_cell_13,delta->bms0_cell_14,delta->bms0_cell_15,delta->bms0_cell_16,delta->bms0_cell_temp_1,delta->bms0_cell_temp_2,delta->bms0_cell_temp_3,delta->bms0_cell_temp_4,delta->bms0_case_temp,delta->bms0_power_temp};

    #bms1
    sensors:
    - name: "${bms_name1} Pack Voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 2
      filters:
        - multiply: 0.01
        - throttle: 5s
    
    - name: "${bms_name1} Current"
      device_class: current
      unit_of_measurement: A
      accuracy_decimals: 2
      filters:
        - multiply: 0.01
        - throttle: 5s

    - name: "${bms_name1} remaining Capacity"
      unit_of_measurement: Ah
      accuracy_decimals: 2
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name1} Total Capacity"
      unit_of_measurement: Ah
      accuracy_decimals: 2
      filters:
        - multiply: 0.01
        - throttle: 5s

    - name: "${bms_name1} Total Discharge Capacity"
      unit_of_measurement: Ah
      filters:
        - multiply: 10
        - throttle: 5s

    - name: "${bms_name1} SOC"
      filters:
        - multiply: 0.1
        - throttle: 5s
      accuracy_decimals: 1
      unit_of_measurement: '%'

    - name: "${bms_name1} SOH"
      filters:
        - multiply: 0.1
        - throttle: 5s
      accuracy_decimals: 1
      unit_of_measurement: '%'

    - name: "${bms_name1} cycle"
      device_class: voltage
      accuracy_decimals: 0
      filters:
        - multiply: 1
        - throttle: 5s

    - name: "${bms_name1} average_cell_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s
        
    - name: "${bms_name1} average_cell_temp"
      unit_of_measurement: °C
      device_class: temperature
      accuracy_decimals: 1
      filters:
        - throttle: 5s

    - name: "${bms_name1} max_cell_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name1} min_cell_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name1} max_cell_temp"
      unit_of_measurement: °C
      device_class: temperature
      accuracy_decimals: 1
      filters:
        - throttle: 5s

    - name: "${bms_name1} min_cell_temp"
      unit_of_measurement: °C
      device_class: temperature
      accuracy_decimals: 1
      filters:
        - throttle: 5s

    - name: "${bms_name1} maxdiscurt"
      unit_of_measurement: A
      device_class: current
      accuracy_decimals: 2
      filters:
        - throttle: 5s

    - name: "${bms_name1} maxchgcurt"
      unit_of_measurement: A
      device_class: current
      accuracy_decimals: 2
      filters:
        - throttle: 5s

    - name: "${bms_name1} cell_1_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name1} cell_2_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name1} cell_3_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name1} cell_4_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name1} cell_5_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name1} cell_6_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name1} cell_7_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name1} cell_8_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name1} cell_9_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name1} cell_10_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name1} cell_11_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name1} cell_12_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name1} cell_13_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name1} cell_14_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name1} cell_15_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name1} cell_16_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name1} cell_temp_1"
      unit_of_measurement: °C
      device_class: temperature
      accuracy_decimals: 1
      filters:
        - throttle: 5s

    - name: "${bms_name1} cell_temp_2"
      unit_of_measurement: °C
      device_class: temperature
      accuracy_decimals: 1
      filters:
        - throttle: 5s

    - name: "${bms_name1} cell_temp_3"
      unit_of_measurement: °C
      device_class: temperature
      accuracy_decimals: 1
      filters:
        - throttle: 5s

    - name: "${bms_name1} cell_temp_4"
      unit_of_measurement: °C
      device_class: temperature
      accuracy_decimals: 1
      filters:
        - throttle: 5s

    - name: "${bms_name1} case_temp"
      unit_of_measurement: °C
      device_class: temperature
      accuracy_decimals: 1
      filters:
        - throttle: 5s

    - name: "${bms_name1} power_temp"
      unit_of_measurement: °C
      device_class: temperature
      accuracy_decimals: 1
      filters:
        - throttle: 5s

    #bms0
    - name: "${bms_name0} Pack Voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 2
      filters:
        - multiply: 0.01
        - throttle: 5s
    
    - name: "${bms_name0} Current"
      device_class: current
      unit_of_measurement: A
      accuracy_decimals: 2
      filters:
        - multiply: 0.01
        - throttle: 5s

    - name: "${bms_name0} remaining Capacity"
      unit_of_measurement: Ah
      accuracy_decimals: 2
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name0} Total Capacity"
      unit_of_measurement: Ah
      accuracy_decimals: 2
      filters:
        - multiply: 0.01
        - throttle: 5s

    - name: "${bms_name0} Total Discharge Capacity"
      unit_of_measurement: Ah
      filters:
        - multiply: 10
        - throttle: 5s

    - name: "${bms_name0} SOC"
      filters:
        - multiply: 0.1
        - throttle: 5s
      accuracy_decimals: 1
      unit_of_measurement: '%'

    - name: "${bms_name0} SOH"
      filters:
        - multiply: 0.1
        - throttle: 5s
      accuracy_decimals: 1
      unit_of_measurement: '%'

    - name: "${bms_name0} cycle"
      device_class: voltage
      accuracy_decimals: 0
      filters:
        - multiply: 1
        - throttle: 5s

    - name: "${bms_name0} average_cell_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s
        
    - name: "${bms_name0} average_cell_temp"
      unit_of_measurement: °C
      device_class: temperature
      accuracy_decimals: 1
      filters:
        - throttle: 5s

    - name: "${bms_name0} max_cell_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name0} min_cell_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name0} max_cell_temp"
      unit_of_measurement: °C
      device_class: temperature
      accuracy_decimals: 1
      filters:
        - throttle: 5s

    - name: "${bms_name0} min_cell_temp"
      unit_of_measurement: °C
      device_class: temperature
      accuracy_decimals: 1
      filters:
        - throttle: 5s

    - name: "${bms_name0} maxdiscurt"
      unit_of_measurement: A
      device_class: current
      accuracy_decimals: 2
      filters:
        - throttle: 5s

    - name: "${bms_name0} maxchgcurt"
      unit_of_measurement: A
      device_class: current
      accuracy_decimals: 2
      filters:
        - throttle: 5s

    - name: "${bms_name0} cell_1_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name0} cell_2_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name0} cell_3_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name0} cell_4_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name0} cell_5_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name0} cell_6_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name0} cell_7_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name0} cell_8_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name0} cell_9_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name0} cell_10_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name0} cell_11_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name0} cell_12_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name0} cell_13_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name0} cell_14_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name0} cell_15_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name0} cell_16_voltage"
      unit_of_measurement: V
      device_class: voltage
      accuracy_decimals: 3
      filters:
        - multiply: 0.001
        - throttle: 5s

    - name: "${bms_name0} cell_temp_1"
      unit_of_measurement: °C
      device_class: temperature
      accuracy_decimals: 1
      filters:
        - throttle: 5s

    - name: "${bms_name0} cell_temp_2"
      unit_of_measurement: °C
      device_class: temperature
      accuracy_decimals: 1
      filters:
        - throttle: 5s

    - name: "${bms_name0} cell_temp_3"
      unit_of_measurement: °C
      device_class: temperature
      accuracy_decimals: 1
      filters:
        - throttle: 5s

    - name: "${bms_name0} cell_temp_4"
      unit_of_measurement: °C
      device_class: temperature
      accuracy_decimals: 1
      filters:
        - throttle: 5s

    - name: "${bms_name0} case_temp"
      unit_of_measurement: °C
      device_class: temperature
      accuracy_decimals: 1
      filters:
        - throttle: 5s

    - name: "${bms_name0} power_temp"
      unit_of_measurement: °C
      device_class: temperature
      accuracy_decimals: 1
      filters:
        - throttle: 5s

@DpunktS
Copy link
Author

DpunktS commented Oct 8, 2024

So sehen die empfangenen Nachrichten aus:

2024.10.04 15:28:39:798:Total Len:266
02 04 10 00 00 12 74 F4 02 04 24 15 20 19 D7 36 09 71 48 00 1A 01 DD 03 E8 00 01 0D 33 0B AD 0D 3B 0D 2F 0B B4 0B A9 00 00 00 B4 00 B4 03 E8 EF EB 02 04 11 00 00 1A 74 CE 02 04 34 0D 31 0D 2F 0D 34 0D 35 0D 31 0D 30 0D 39 0D 3B 0D 36 0D 31 0D 30 0D 32 0D 36 0D 39 0D 32 0D 36 0B AF 0B AA 0B A9 0B B4 0A AB 0A AB 0A AB 0A AB 0B B3 0B AC B2 0C 02 01 12 00 00 90 39 2D 02 01 12 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 03 00 00 E9 99 01 04 24 15 1D 21 1F 43 10 71 48 04 99 02 50 03 E3 00 32 0D 31 0B B3 0D 40 0D 2B 0B B6 0B B0 00 00 00 B4 00 B4 03 E8 75 E8 01 04 34 0D 2B 0D 31 0D 33 0D 2E 0D 35 0D 31 0D 34 0D 32 0D 40 0D 31 0D 32 0D 30 0D 30 0D 2F 0D 37 0D 2C 0B B0 0B B6 0B B4 0B B5 0A AB 0A AB 0A AB 0A AB 0B B4 0B B2 08 D5 01 01 12 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 03 00 00 DA AA 

2024.10.04 15:28:40:000:Total Len:266
02 04 10 00 00 12 74 F4 02 04 24 15 20 19 EC 36 09 71 48 00 1A 01 DD 03 E8 00 01 0D 34 0B AD 0D 3C 0D 2F 0B B4 0B A9 00 00 00 B4 00 B4 03 E8 88 55 02 04 11 00 00 1A 74 CE 02 04 34 0D 31 0D 2F 0D 34 0D 35 0D 31 0D 30 0D 39 0D 3C 0D 36 0D 31 0D 30 0D 32 0D 36 0D 3A 0D 32 0D 36 0B AF 0B AA 0B A9 0B B4 0A AB 0A AB 0A AB 0A AB 0B B3 0B AC 1C 77 02 01 12 00 00 90 39 2D 02 01 12 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 03 00 00 E9 99 01 04 24 15 1D 21 39 43 10 71 48 04 99 02 50 03 E3 00 32 0D 32 0B B3 0D 40 0D 2B 0B B6 0B B0 00 00 00 B4 00 B4 03 E8 D8 60 01 04 34 0D 2B 0D 31 0D 34 0D 2E 0D 35 0D 31 0D 34 0D 32 0D 40 0D 31 0D 33 0D 30 0D 30 0D 2F 0D 37 0D 2C 0B B0 0B B6 0B B4 0B B5 0A AB 0A AB 0A AB 0A AB 0B B4 0B B2 9F 90 01 01 12 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 03 00 00 DA AA 

2024.10.04 15:28:40:203:Total Len:266
02 04 10 00 00 12 74 F4 02 04 24 15 20 19 FE 36 09 71 48 00 1A 01 DD 03 E8 00 01 0D 34 0B AD 0D 3C 0D 30 0B B4 0B A9 00 00 00 B4 00 B4 03 E8 BA CC 02 04 11 00 00 1A 74 CE 02 04 34 0D 31 0D 30 0D 34 0D 35 0D 31 0D 30 0D 39 0D 3C 0D 36 0D 31 0D 31 0D 32 0D 36 0D 3A 0D 33 0D 36 0B AF 0B AA 0B A9 0B B4 0A AB 0A AB 0A AB 0A AB 0B B3 0B AC 3F 53 02 01 12 00 00 90 39 2D 02 01 12 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 03 00 00 E9 99 01 04 24 15 1D 21 4E 43 10 71 48 04 99 02 50 03 E3 00 32 0D 32 0B B3 0D 40 0D 2B 0B B6 0B B0 00 00 00 B4 00 B4 03 E8 9C 71 01 04 34 0D 2B 0D 31 0D 34 0D 2E 0D 35 0D 31 0D 34 0D 33 0D 40 0D 31 0D 33 0D 30 0D 30 0D 2F 0D 37 0D 2C 0B B0 0B B6 0B B4 0B B5 0A AB 0A AB 0A AB 0A AB 0B B4 0B B2 83 00 01 01 12 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 03 00 00 DA AA 

@jolly12f
Copy link

could you make a guide on the work to be done?

@DpunktS
Copy link
Author

DpunktS commented Oct 11, 2024

Du musst den ersten Code als seplos_v3_sniffer.h speichern und an den selben Ort der ESPHome YAML schieben.

Der 2. Code ist die Konfiguration für ESPHome die du wie gehabt bearbeitest.

Ich meinem Beispiel ist keine CRC Prüfung eingebaut weshalb ab und zu mal ein falscher Wert auftaucht.

@sunnysingh-84
Copy link

I attempted this and got the following error when installing:

INFO ESPHome 2024.9.2
INFO Reading configuration /config/esphome/seplos-bms.yaml...
Failed config

esphome: [source /config/esphome/seplos-bms.yaml:6]

'name' is a required option for [esphome].
includes:
- ./seplos_v3_sniffer.h

@DpunktS
Copy link
Author

DpunktS commented Oct 12, 2024

Der Fehler sagt, dass er die Datei nicht an den angegebenen Speicherort findet.

@Alexandros89
Copy link

Ho provato a farlo e ho ricevuto il seguente errore durante l'installazione:

INFO ESPHome 2024.9.2 INFO Lettura configurazione /config/esphome/seplos-bms.yaml... Configurazione non riuscita

esphome: [sorgente /config/esphome/seplos-bms.yaml:6]

'name' è un'opzione obbligatoria per [esphome]. Comprende: - ./seplos_v3_sniffer.h

the point should be the name of the esphome path

@nammto
Copy link

nammto commented Nov 19, 2024

Hi! I'm using the sniffer and it works fantastic for up to two batteries. I have 4 batteries set up and get sometimes weird values for voltages and temperatures in 3rd battery. On 4th battery I get those weird values most of the time. There I read mostly 4000 degrees battery temperature. If I modify the code to read only 4th battery the issues remain the same. What could be wrong there? Does anyone else have more than 2 batteries in their setup?

@DpunktS
Copy link
Author

DpunktS commented Nov 19, 2024

Es ist möglich das dein Bus leicht gestört ist und die fehlende CRC-Prüfung es nicht filtert. Oder du hast bei der Erweiterung einen Fehler gemacht. Vielleicht ist auch der Nachrichten Puffer (rx_buffer_size: 1024) zu klein. Weil 2 Akkus haben schon 266 bytes.

@nammto
Copy link

nammto commented Nov 20, 2024

Thanks for fast reponse. I suppose if i had a typo in code, there would be false readings all the time. Tried wirh rx buffer 2048 and also with two separate esp32 and each having separate rs485 converter for each pack pair but the result is same. Always 3rd and 4th pack readings fail. Even if i just try to read 4th pack, I get these wierd values.
Below You can see how different pack current reults are received.
Screenshot_20241120_063954_Home Assistant
Screenshot_20241120_064013_Home Assistant
Screenshot_20241120_064034_Home Assistant

What else could I do? Is it possible I miss something in .h file code except battery address?

@DpunktS
Copy link
Author

DpunktS commented Nov 20, 2024

So wie ich das sehe sind das nur vereinzelte falsche Wert die die CRC-Prüfung filtern würde. Die Akkus senden alles 200ms ihren Status somit fallen ein paar gefilterte Wert nicht auf.

Ich werde es als Laie mal versuchen eine CRC-Prüfung zu integrieren :). Oder vielleicht bekommst du das schneller hin. Es müsste von diesem Projekt https://github.com/ferelarg/Seplos3MQTT auf ESPHome angepasst werden.

@nammto
Copy link

nammto commented Nov 20, 2024

:-) I don't think my knowledge reached that far to do it.

@DpunktS
Copy link
Author

DpunktS commented Nov 20, 2024

Probiere mal bitte diesen Sniffer mit CRC Prüfung
seplos_v3_sniffer.zip

@nammto
Copy link

nammto commented Nov 20, 2024

Got home to test it. I'm now with Your CRC code able to read pack 1&2 data, also pack 3&4 data if I read only 2 packs at a time. If I try to read all 4 packs, I get only data for pack 3 and 4.
Edit: I forgot to add battery pack addresses in first address if statement :-D
Now works like charm. Huge thanks for that!

@DpunktS
Copy link
Author

DpunktS commented Nov 20, 2024

@nammto wie hast du diese Zeile für den 3 . und 4. Akku geändert?
if (!((bytes[0] == 0x02 && bytes[1] == 0x04 && (bytes[2] == 0x24 || bytes[2] == 0x34)) || (bytes[0] == 0x01 && bytes[1] == 0x04 && (bytes[2] == 0x24 || bytes[2] == 0x34)))) {

@nammto
Copy link

nammto commented Nov 20, 2024

@nammto wie hast du diese Zeile für den 3 . und 4. Akku geändert? if (!((bytes[0] == 0x02 && bytes[1] == 0x04 && (bytes[2] == 0x24 || bytes[2] == 0x34)) || (bytes[0] == 0x01 && bytes[1] == 0x04 && (bytes[2] == 0x24 || bytes[2] == 0x34)))) {

This is for all 4 packs: if (!((bytes[0] == 0x02 && bytes[1] == 0x04 && (bytes[2] == 0x24 || bytes[2] == 0x34)) || (bytes[0] == 0x01 && bytes[1] == 0x04 && (bytes[2] == 0x24 || bytes[2] == 0x34)) || (bytes[0] == 0x03 && bytes[1] == 0x04 && (bytes[2] == 0x24 || bytes[2] == 0x34)) || (bytes[0] == 0x04 && bytes[1] == 0x04 && (bytes[2] == 0x24 || bytes[2] == 0x34)))) {

@DpunktS
Copy link
Author

DpunktS commented Dec 18, 2024

@nammto probierst du diesen seplos_v3_sniffer bitte mit deinen 4 Akkus aus. Mit meinen 2 Akkus funktioniert es gut.
https://github.com/DpunktS/seplos_v3_sniffer/tree/main

@nammto
Copy link

nammto commented Dec 18, 2024

@DpunktS Working like charm out of the box. Just need to add the declarations for the rest of the BMSs in YAML file.
Few errors i've found in .cpp file:

  • remaining capacity is showing 10 times less than actual (found it just now, that same issue also in old .h file), so just *10 must be added in variable calculation.
  • only in new version, maxdiscurt and maxchgcurt are showing 100 times lower values than actual. (You have /100 in Yout code, take it away)
    Excellent work! If You add now automatic variable declaration according to discovered BMSs, it will be a full product plug'n play. If You don't configure more than two BMSs in YAML, then it will say in LOG, that found something also on address 3 and 4.

@DpunktS
Copy link
Author

DpunktS commented Dec 19, 2024

Ich danke dir für dein Lob. :)
Die Fehler habe ich korrigiert. Dein Vorschlag mit den automatischen anlegen der Sensoren wollte ich auch realisieren leider ist mit kein weg bekannt den ESPHome unterstützt.

@tugsi
Copy link

tugsi commented Dec 20, 2024

@DpunktS Kleine Frage am Rande, hast Du zusätzlich den CAN am Wechselrichter angeschlossen?
Mir ist noch nicht so ganz klar, ob das geht, also CAN am (in meinem Fall) Victron und gleichzeitig mit Deiner Lösung alles per RS485 auslesen.
Finde SEPLOS irgendwie konfus, habe zwei Packs mit V3 parallel angeschlossen und zack ist einer per Bluetooth nicht mehr erreichbar, der andere ja.
Deswegen würde ich auch gerne mehr Infos auslesen im Betrieb.

@DpunktS
Copy link
Author

DpunktS commented Dec 20, 2024

Ja meine 2 Seplos V3 sind per CAN am Wechselrichter angeschlossen. Zum Verständnis bei Modbus RS485 kann es nur einen Master geben und das ist bei mehreren Akkus immer bms0 also, der wo CAN angeschlossen ist. Deswegen ist auch nur noch der Master per Bluetooth erreichbar. Der ESP mit den bisherigen Projekten würde auch wieder ein Master sein und deswegen funktioniert die Kommunikation ab 2 Akkus nicht mehr. Meine Lösung liest nur die Kommunikation zwischen Master und Slave's mit und wertet diese aus.

@tugsi
Copy link

tugsi commented Dec 20, 2024

Danke für die Rückmeldung. Das Verständnis Modbus habe ich (hab beruflich mit Bus-Systemen zu tun, u.a. auch Modbus). Mir war nur nicht klar, ob gleichzeitig dann noch CAN sauber funktioniert, da in diversen Foren auch vieles widersprüchliche liest. Und dann kommt noch Seplos V3 oder alt etc.
Dann schau ich mal, wann ich Zeit dazu finde und baue mir das mal nach. Danke Dir.

@tugsi
Copy link

tugsi commented Dec 28, 2024

@DpunktS Nur zum Verständnis, hast Du zwischen dem ESP und dem Seplos noch ein RS485-TTL-Wandler dazwischen und wenn ja welchen?

@DpunktS
Copy link
Author

DpunktS commented Dec 28, 2024

Ich habe diesen Konverter verwendet. Es kann aber jeder ttl rs485 Konverter verwendet werden.
ttl-rs485-modul-3 3volt

@tugsi
Copy link

tugsi commented Dec 28, 2024

Danke, ich dachte ich hatte noch einen, aber leider nicht.
Genau den Typ hab ich gerade bei Ali bestellt 10Stck für knapp über 5€, dann hat man Reserve ;-)

@syssi
Copy link
Owner

syssi commented Dec 28, 2024

Je nach Konverter ist manuelle Flusskontrolle über einen zusätzlichen GPIO notwendig. Das obige Modul kommt ohne diese Fusskontrolle aus, deshalb nutze ich es lieber.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants