mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-03 09:49:32 +02:00
Make Solax use type settings in COMMON_IMAGE mode, add ignore contactors feature
This commit is contained in:
parent
efd6ca1349
commit
a718d99672
2 changed files with 59 additions and 12 deletions
|
@ -4,11 +4,7 @@
|
|||
#include "../datalayer/datalayer.h"
|
||||
#include "../devboard/utils/events.h"
|
||||
#include "../devboard/utils/logging.h"
|
||||
|
||||
#define NUMBER_OF_MODULES 0
|
||||
#define BATTERY_TYPE 0x50
|
||||
// If you are having BattVoltFault issues, configure the above values according to wiki page
|
||||
// https://github.com/dalathegreat/Battery-Emulator/wiki/Solax-inverters
|
||||
#include "../inverter/INVERTERS.h"
|
||||
|
||||
// __builtin_bswap64 needed to convert to ESP32 little endian format
|
||||
// Byte[4] defines the requested contactor state: 1 = Closed , 0 = Open
|
||||
|
@ -18,7 +14,7 @@
|
|||
void SolaxInverter::
|
||||
update_values() { //This function maps all the values fetched from battery CAN to the correct CAN messages
|
||||
// If not receiveing any communication from the inverter, open contactors and return to battery announce state
|
||||
if (millis() - LastFrameTime >= SolaxTimeout) {
|
||||
if (millis() - LastFrameTime >= SolaxTimeout && !configured_ignore_contactors) {
|
||||
datalayer.system.status.inverter_allows_contactor_closing = false;
|
||||
STATE = BATTERY_ANNOUNCE;
|
||||
}
|
||||
|
@ -73,7 +69,7 @@ void SolaxInverter::
|
|||
//BMS_Status
|
||||
SOLAX_1875.data.u8[0] = (uint8_t)temperature_average;
|
||||
SOLAX_1875.data.u8[1] = (temperature_average >> 8);
|
||||
SOLAX_1875.data.u8[2] = (uint8_t)NUMBER_OF_MODULES; // Number of slave batteries
|
||||
SOLAX_1875.data.u8[2] = (uint8_t)configured_number_of_modules; // Number of slave batteries
|
||||
SOLAX_1875.data.u8[4] = (uint8_t)0; // Contactor Status 0=off, 1=on.
|
||||
|
||||
//BMS_PackTemps (strange name, since it has voltages?)
|
||||
|
@ -88,7 +84,7 @@ void SolaxInverter::
|
|||
SOLAX_1876.data.u8[7] = (datalayer.battery.status.cell_min_voltage_mV >> 8);
|
||||
|
||||
//Unknown
|
||||
SOLAX_1877.data.u8[4] = (uint8_t)BATTERY_TYPE; // Battery type (Default 0x50)
|
||||
SOLAX_1877.data.u8[4] = (uint8_t)configured_battery_type; // Battery type (Default 0x50)
|
||||
SOLAX_1877.data.u8[6] = (uint8_t)0x22; // Firmware version?
|
||||
SOLAX_1877.data.u8[7] =
|
||||
(uint8_t)0x02; // The above firmware version applies to:02 = Master BMS, 10 = S1, 20 = S2, 30 = S3, 40 = S4
|
||||
|
@ -129,6 +125,26 @@ void SolaxInverter::map_can_frame_to_variable(CAN_frame rx_frame) {
|
|||
if (rx_frame.ID == 0x1871 && rx_frame.data.u8[0] == (0x01) ||
|
||||
rx_frame.ID == 0x1871 && rx_frame.data.u8[0] == (0x02)) {
|
||||
LastFrameTime = millis();
|
||||
|
||||
if (configured_ignore_contactors) {
|
||||
// Skip the state machine since we're not going to open/close contactors,
|
||||
// and the Solax would otherwise wait forever for us to do so.
|
||||
|
||||
datalayer.system.status.inverter_allows_contactor_closing = true;
|
||||
SOLAX_1875.data.u8[4] = (0x01); // Inform Inverter: Contactor 0=off, 1=on.
|
||||
transmit_can_frame(&SOLAX_187E);
|
||||
transmit_can_frame(&SOLAX_187A);
|
||||
transmit_can_frame(&SOLAX_1872);
|
||||
transmit_can_frame(&SOLAX_1873);
|
||||
transmit_can_frame(&SOLAX_1874);
|
||||
transmit_can_frame(&SOLAX_1875);
|
||||
transmit_can_frame(&SOLAX_1876);
|
||||
transmit_can_frame(&SOLAX_1877);
|
||||
transmit_can_frame(&SOLAX_1878);
|
||||
transmit_can_frame(&SOLAX_100A001);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (STATE) {
|
||||
case (BATTERY_ANNOUNCE):
|
||||
#ifdef DEBUG_LOG
|
||||
|
@ -209,6 +225,25 @@ void SolaxInverter::map_can_frame_to_variable(CAN_frame rx_frame) {
|
|||
}
|
||||
|
||||
bool SolaxInverter::setup(void) { // Performs one time setup at startup
|
||||
// Use user selected values if nonzero, otherwise use defaults
|
||||
if (user_selected_inverter_modules > 0) {
|
||||
configured_number_of_modules = user_selected_inverter_modules;
|
||||
} else {
|
||||
configured_number_of_modules = NUMBER_OF_MODULES;
|
||||
}
|
||||
|
||||
if (user_selected_inverter_battery_type > 0) {
|
||||
configured_battery_type = user_selected_inverter_battery_type;
|
||||
} else {
|
||||
configured_battery_type = BATTERY_TYPE;
|
||||
}
|
||||
|
||||
configured_ignore_contactors = user_selected_inverter_ignore_contactors;
|
||||
|
||||
if (!configured_ignore_contactors) {
|
||||
// Only prevent closing if we're not ignoring contactors
|
||||
datalayer.system.status.inverter_allows_contactor_closing = false; // The inverter needs to allow first
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,11 @@ class SolaxInverter : public CanInverterProtocol {
|
|||
static constexpr const char* Name = "SolaX Triple Power LFP over CAN bus";
|
||||
|
||||
private:
|
||||
static const int NUMBER_OF_MODULES = 0;
|
||||
static const int BATTERY_TYPE = 0x50;
|
||||
// If you are having BattVoltFault issues, configure the above values according to wiki page
|
||||
// https://github.com/dalathegreat/Battery-Emulator/wiki/Solax-inverters
|
||||
|
||||
// Timeout in milliseconds
|
||||
static const int SolaxTimeout = 2000;
|
||||
|
||||
|
@ -34,6 +39,13 @@ class SolaxInverter : public CanInverterProtocol {
|
|||
uint16_t capped_capacity_Wh;
|
||||
uint16_t capped_remaining_capacity_Wh;
|
||||
|
||||
int configured_number_of_modules = 0;
|
||||
int configured_battery_type = 0;
|
||||
// If true, the integration will ignore the inverter's requests to open the
|
||||
// battery contactors. Useful for batteries that can't open contactors on
|
||||
// request.
|
||||
bool configured_ignore_contactors = false;
|
||||
|
||||
//CAN message translations from this amazing repository: https://github.com/rand12345/solax_can_bus
|
||||
|
||||
CAN_frame SOLAX_1801 = {.FD = false,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue