Louisvdw / dbus-serialbattery

Battery Monitor driver for serial battery in VenusOS GX systems
MIT License
539 stars 165 forks source link

JBD-BMS, SOC different in Xiaoxiang app and dbus-serialbattery #729

Closed OutOfSync1 closed 1 year ago

OutOfSync1 commented 1 year ago

Describe the bug

The new SOC calculation leads to different SOC values shown in the Xiaoxiang app (via bluetooth on iOS) and in dbus-serialbattery. https://github.com/Louisvdw/dbus-serialbattery/blob/86a6b956e15bee21d5a298283c9d121f0eb82a02/etc/dbus-serialbattery/bms/lltjbd.py#L405 I think the issue here is that two values can be set for the capacity in the BMS: "total battery capacity" (in my case 280 Ah) and "total cycle capacity" (in my case 260 Ah). The JBD-BMS uses the cycle capacity as 100% SOC value, e.g. when 260 Ah is the remaining capacity and 260 Ah is set as "total cycle capacity" then the SOC is 100%. The calculation in serialbattery however uses the total capacity value as 100% SOC value, in this case 280 Ah. As a result the calculation in the example is 260 Ah/280 Ah which leads to 92.7% SOC. In this case 100% is never reached. This can lead to multiple problems, e.g. charge current is not reduced although battery is already full etc.

Unfortunately the serial data read via command_general only includes "total battery capacity" and not "total cycle capacity". A workaround may be to set both total and cycle capacity to the same value in the BMS.

I suggest to revert this change and use the soc reported by the BMS although it is an integer value. Otherwise provide a recommendation to set cycle and total capacity to the same value.

How to reproduce

Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior

SOC reported via BMS and calculated in serial-battery should be the same

Driver version

1.0.20230531

Venus OS device type

Raspberry Pi

Venus OS version

3.00

BMS type

Smart BMS (LLT, JBD, Overkill Solar)

Cell count

16

Connection type

Serial USB adapter to RS485

Config file

[DEFAULT]

; If you want to add custom values/settings, then check the values/settings you want to change in "config.default.ini"
; and insert them below to persist future driver updates.

; Example (remove the semicolon ";" to uncomment and activate the value/setting)
MAX_BATTERY_CHARGE_CURRENT = 100.0
MAX_BATTERY_DISCHARGE_CURRENT = 100.0

; --------- Cell Voltages ---------
; Description: Cell min/max voltages which are used to calculate the min/max battery voltage
; Example: 16 cells * 3.45V/cell = 55.2V max charge voltage. 16 cells * 2.90V = 46.4V min discharge voltage
MIN_CELL_VOLTAGE   = 2.900
; Max voltage can seen as absorption voltage
MAX_CELL_VOLTAGE   = 3.470 
; was 3.450
FLOAT_CELL_VOLTAGE = 3.45
; was 3.375

; --------- BMS disconnect behaviour ---------
; Description: Block charge and discharge when the communication to the BMS is lost. If you are removing the
;              BMS on purpose, then you have to restart the driver/system to reset the block.
; False: Charge and discharge is not blocked on BMS communication loss
; True: Charge and discharge is blocked on BMS communication loss, it's unblocked when connection is established
;       again or the driver/system is restarted
BLOCK_ON_DISCONNECT = False

; --------- Charge mode ---------
; Choose the mode for voltage / current limitations (True / False)
; False is a step mode: This is the default with limitations on hard boundary steps
; True is a linear mode:
;     For CCL and DCL the values between the steps are calculated for smoother values (by WaldemarFech)
;     For CVL max battery voltage is calculated dynamically in order that the max cell voltage is not exceeded
LINEAR_LIMITATION_ENABLE = True

; Specify in seconds how often the linear values should be recalculated
LINEAR_RECALCULATION_EVERY = 60
; Specify in percent when the linear values should be recalculated immediately
; Example: 5 for a immediate change, when the value changes by more than 5%
LINEAR_RECALCULATION_ON_PERC_CHANGE = 5

; --------- Charge Voltage limitation (affecting CVL) ---------
; Description: Limit max charging voltage (MAX_CELL_VOLTAGE * cell count), switch from max voltage to float
;              voltage (FLOAT_CELL_VOLTAGE * cell count) and back
;     False: Max charging voltage is always kept
;     True: Max charging voltage is reduced based on charge mode
;         Step mode: After max voltage is reached for MAX_VOLTAGE_TIME_SEC it switches to float voltage. After
;                    SoC is below SOC_LEVEL_TO_RESET_VOLTAGE_LIMIT it switches back to max voltage.
;         Linear mode: After max voltage is reachend and cell voltage difference is smaller or equal to
;                      CELL_VOLTAGE_DIFF_KEEP_MAX_VOLTAGE_UNTIL it switches to float voltage after 300 (fixed)
;                      additional seconds.
;                      After cell voltage difference is greater or equal to CELL_VOLTAGE_DIFF_TO_RESET_VOLTAGE_LIMIT
;                      OR
;                      SoC is below SOC_LEVEL_TO_RESET_VOLTAGE_LIMIT
;                      it switches back to max voltage.
; Example: The battery reached max voltage of 55.2V and hold it for 900 seconds, the the CVL is switched to
;          float voltage of 53.6V to don't stress the batteries. Allow max voltage of 55.2V again, if SoC is
;          once below 90%
;          OR
;          The battery reached max voltage of 55.2V and the max cell difference is 0.010V, then switch to float
;          voltage of 53.6V after 300 additional seconds to don't stress the batteries. Allow max voltage of
;          55.2V again if max cell difference is above 0.080V or SoC below 90%.
; Charge voltage control management enable (True/False).
CVCM_ENABLE = True

; -- CVL reset based on cell voltage diff (linear mode)
; Specify cell voltage diff where CVL limit is kept until diff is equal or lower
CELL_VOLTAGE_DIFF_KEEP_MAX_VOLTAGE_UNTIL = 0.010
; Specify cell voltage diff where CVL limit is reset to max voltage, if value get above
; the cells are considered as imbalanced, if the cell diff exceeds 5% of the nominal cell voltage
; e.g. 3.2 V * 5 / 100 = 0.160 V
CELL_VOLTAGE_DIFF_TO_RESET_VOLTAGE_LIMIT = 0.080

; -- CVL reset based on SoC option (step mode)
; Specify how long the max voltage should be kept, if reached then switch to float voltage
MAX_VOLTAGE_TIME_SEC = 900
; Specify SoC where CVL limit is reset to max voltage, if value gets below
SOC_LEVEL_TO_RESET_VOLTAGE_LIMIT = 90

; --------- Cell Voltage Current limitation (affecting CCL/DCL) ---------
; Description: Maximal charge / discharge current will be in-/decreased depending on min and max cell voltages
; Example: 18 cells * 3.55V/cell = 63.9V max charge voltage
;          18 cells * 2.70V/cell = 48.6V min discharge voltage
;          But in reality not all cells reach the same voltage at the same time. The (dis)charge current
;          will be (in-/)decreased, if even ONE SINGLE BATTERY CELL reaches the limits

; Charge current control management referring to cell-voltage enable (True/False).
CCCM_CV_ENABLE = True
; Discharge current control management referring to cell-voltage enable (True/False).
DCCM_CV_ENABLE = True

; Set steps to reduce battery current
; The current will be changed linear between those steps if LINEAR_LIMITATION_ENABLE is set to True
CELL_VOLTAGES_WHILE_CHARGING   = 3.55, 3.50, 3.48, 3.30 
; was 3.55, 3.50, 3.45, 3.30
MAX_CHARGE_CURRENT_CV_FRACTION =    0, 0.05,  0.5,    1

CELL_VOLTAGES_WHILE_DISCHARGING   = 2.70, 2.80, 2.90, 3.10
MAX_DISCHARGE_CURRENT_CV_FRACTION =    0,  0.1,  0.5,    1

; --------- Temperature limitation (affecting CCL/DCL) ---------
; Description: Maximal charge / discharge current will be in-/decreased depending on temperature
; Example: The temperature limit will be monitored to control the currents. If there are two temperature senors,
;          then the worst case will be calculated and the more secure lower current will be set.
; Charge current control management referring to temperature enable (True/False).
CCCM_T_ENABLE = True
; Charge current control management referring to temperature enable (True/False).
DCCM_T_ENABLE = True

; Set steps to reduce battery current
; The current will be changed linear between those steps if LINEAR_LIMITATION_ENABLE is set to True
TEMPERATURE_LIMITS_WHILE_CHARGING = 0,   2,   5,  10,  15, 20, 35,  40, 55
MAX_CHARGE_CURRENT_T_FRACTION     = 0, 0.1, 0.2, 0.4, 0.8,  1,  1, 0.4,  0

TEMPERATURE_LIMITS_WHILE_DISCHARGING = -20,   0,   5,  10, 15, 45, 55
MAX_DISCHARGE_CURRENT_T_FRACTION     =   0, 0.2, 0.3, 0.4,  1,  1,  0

; --------- SOC limitation (affecting CCL/DCL) ---------
; Description: Maximal charge / discharge current will be increased / decreased depending on State of Charge,
;              see CC_SOC_LIMIT1 etc.
; Example: The SoC limit will be monitored to control the currents.
; Charge current control management enable (True/False).
CCCM_SOC_ENABLE = True
; Discharge current control management enable (True/False).
DCCM_SOC_ENABLE = True

; Charge current soc limits
CC_SOC_LIMIT1 = 98
CC_SOC_LIMIT2 = 95
CC_SOC_LIMIT3 = 91

; Charge current limits
CC_CURRENT_LIMIT1_FRACTION = 0.1
CC_CURRENT_LIMIT2_FRACTION = 0.3
CC_CURRENT_LIMIT3_FRACTION = 0.5

; Discharge current soc limits
DC_SOC_LIMIT1 = 10
DC_SOC_LIMIT2 = 20
DC_SOC_LIMIT3 = 30

; Discharge current limits
DC_CURRENT_LIMIT1_FRACTION = 0.1
DC_CURRENT_LIMIT2_FRACTION = 0.3
DC_CURRENT_LIMIT3_FRACTION = 0.5

; --------- Time-To-Go ---------
; Description: Calculates the time to go shown in the GUI
;              Recalculation is done based on TIME_TO_SOC_RECALCULATE_EVERY
TIME_TO_GO_ENABLE = True

; --------- Time-To-Soc ---------
; Description: Calculates the time to a specific SoC
; Example: TIME_TO_SOC_POINTS = 50, 25, 15, 0
;          6h 24m remaining until 50% SoC
;          17h 36m remaining until 25% SoC
;          22h 5m remaining until 15% SoC
;          28h 48m remaining until 0% SoC
; Set of SoC percentages to report on dbus and MQTT. The more you specify the more it will impact system performance.
; [Valid values 0-100, comma separated list. More that 20 intervals are not recommended]
; Example: TIME_TO_SOC_POINTS = 100, 95, 90, 85, 75, 50, 25, 20, 10, 0
; Leave empty to disable
TIME_TO_SOC_POINTS = 100, 95, 90, 85, 75, 50, 25, 20, 10, 0
; Specify TimeToSoc value type [Valid values 1, 2, 3]
; 1 Seconds
; 2 Time string <days>d <hours>h <minutes>m <seconds>s
; 3 Both seconds and time string "<seconds> [<days>d <hours>h <minutes>m <seconds>s]"
TIME_TO_SOC_VALUE_TYPE = 2
; Specify in seconds how often the TimeToSoc should be recalculated
; Minimum are 5 seconds to prevent CPU overload
TIME_TO_SOC_RECALCULATE_EVERY = 60
; Include TimeToSoC points when moving away from the SoC point [Valid values True, False]
; These will be as negative time. Disabling this improves performance slightly
TIME_TO_SOC_INC_FROM = False

; --------- Additional settings ---------
; Specify only one BMS type to load else leave empty to try to load all available
; -- Available BMS:
; Daly, Ecs, HeltecModbus, HLPdataBMS4S, Jkbms, Lifepower, LltJbd, Renogy, Seplos
; -- Available BMS, but disabled by default:
; https://louisvdw.github.io/dbus-serialbattery/general/install#how-to-enable-a-disabled-bms
; Ant, MNB, Sinowealth
BMS_TYPE = 

; Publish the config settings to the dbus path "/Info/Config/"
PUBLISH_CONFIG_VALUES = 1

; Select the format of cell data presented on dbus [Valid values 0,1,2,3]
; 0 Do not publish all the cells (only the min/max cell data as used by the default GX)
; 1 Format: /Voltages/Cell (also available for display on Remote Console)
; 2 Format: /Cell/#/Volts
; 3 Both formats 1 and 2
BATTERY_CELL_DATA_FORMAT = 1

; Simulate Midpoint graph (True/False).
MIDPOINT_ENABLE = False

; Battery temperature
; Specify how the battery temperature is assembled
; 0 Get mean of temperature sensor 1 to sensor 4
; 1 Get only temperature from temperature sensor 1
; 2 Get only temperature from temperature sensor 2
; 3 Get only temperature from temperature sensor 3
; 4 Get only temperature from temperature sensor 4
TEMP_BATTERY = 0

; Temperature sensor 1 name
TEMP_1_NAME = Temp 1

; Temperature sensor 2 name
TEMP_2_NAME = Temp 2

; Temperature sensor 2 name
TEMP_3_NAME = Temp 3

; Temperature sensor 2 name
TEMP_4_NAME = Temp 4

; --------- BMS specific settings ---------

; -- LltJbd settings
; SoC low levels
; NOTE: SOC_LOW_WARNING is also used to calculate the Time-To-Go even if you are not using a LltJbd BMS
SOC_LOW_WARNING = 20
SOC_LOW_ALARM   = 10

; -- Daly settings
; Battery capacity (amps), if the BMS does not support reading it
BATTERY_CAPACITY = 50
; Invert Battery Current. Default non-inverted. Set to -1 to invert
INVERT_CURRENT_MEASUREMENT = 1

; -- ESC GreenMeter and Lipro device settings
GREENMETER_ADDRESS  = 1
LIPRO_START_ADDRESS = 2
LIPRO_END_ADDRESS   = 4
LIPRO_CELL_COUNT = 15

; -- HeltecModbus (Heltec SmartBMS/YYBMS) settings
; Set the Modbus addresses from the adapters
; Separate each address to check by a comma like: 1, 2, 3, ...
; factory default address will be 1
HELTEC_MODBUS_ADDR = 1

; --------- Battery monitor specific settings ---------
; If you are using a SmartShunt or something else as a battery monitor, the battery voltage reported
; from the BMS and SmartShunt could differ. This causes, that the driver never goapplies the float voltage,
; since max voltage is never reached.
; Example:
;     cell count: 16
;     MAX_CELL_VOLTAGE = 3.45
;     max voltage calculated = 16 * 3.45 = 55.20
;     CVL is set to 55.20 and the battery is now charged until the SmartShunt measures 55.20 V. The BMS
;     now measures 55.05 V since there is a voltage drop of 0.15 V. Since the dbus-serialbattery measures
;     55.05 V the max voltage is never reached for the driver and max voltage is kept forever.
;     Set VOLTAGE_DROP to 0.15
VOLTAGE_DROP = 0.00

Relevant log output

@4000000064943c0e1962b204 INFO:SerialBattery:Starting dbus-serialbattery
@4000000064943c0e197a7fc4 INFO:SerialBattery:dbus-serialbattery v1.0.20230531
@4000000064943c0e19848a14 INFO:SerialBattery:Testing Daly
@4000000064943c0e212f1c0c ERROR:SerialBattery:>>> ERROR: No reply - returning
@4000000064943c0e213d1a14 INFO:SerialBattery:Testing Daly
@4000000064943c0e28e8d4ec ERROR:SerialBattery:>>> ERROR: No reply - returning
@4000000064943c0e2905cee4 INFO:SerialBattery:Testing Ecs
@4000000064943c0e2d19e40c ERROR:SerialBattery:>>> ERROR: No reply - returning
@4000000064943c0e2d24a5f4 INFO:SerialBattery:Testing HeltecModbus
@4000000064943c0f0fd5e2ec WARNING:SerialBattery:Error reading settings from BMS, retry (1/10): Checksum error in rtu mode: '\x12a' instead of 'a\x91' . The response is: '\x01\x01\x03\x12a' (plain response: '\x01\x01\x03\x12a')
@4000000064943c0f28767f64 WARNING:SerialBattery:Error reading settings from BMS, retry (2/10): Checksum error in rtu mode: '\x12a' instead of 'a\x91' . The response is: '\x01\x01\x03\x12a' (plain response: '\x01\x01\x03\x12a')
@4000000064943c10056606d4 WARNING:SerialBattery:Error reading settings from BMS, retry (3/10): Checksum error in rtu mode: '\x12a' instead of 'a\x91' . The response is: '\x01\x01\x03\x12a' (plain response: '\x01\x01\x03\x12a')
@4000000064943c101de0fe94 WARNING:SerialBattery:Error reading settings from BMS, retry (4/10): Checksum error in rtu mode: '\x12a' instead of 'a\x91' . The response is: '\x01\x01\x03\x12a' (plain response: '\x01\x01\x03\x12a')
@4000000064943c10365700cc WARNING:SerialBattery:Error reading settings from BMS, retry (5/10): Checksum error in rtu mode: '\x12a' instead of 'a\x91' . The response is: '\x01\x01\x03\x12a' (plain response: '\x01\x01\x03\x12a')
@4000000064943c11132f2fac WARNING:SerialBattery:Error reading settings from BMS, retry (6/10): Checksum error in rtu mode: '\x12a' instead of 'a\x91' . The response is: '\x01\x01\x03\x12a' (plain response: '\x01\x01\x03\x12a')
@4000000064943c112b9f9c34 WARNING:SerialBattery:Error reading settings from BMS, retry (7/10): Checksum error in rtu mode: '\x12a' instead of 'a\x91' . The response is: '\x01\x01\x03\x12a' (plain response: '\x01\x01\x03\x12a')
@4000000064943c1209321a64 WARNING:SerialBattery:Error reading settings from BMS, retry (8/10): Checksum error in rtu mode: '\x12a' instead of 'a\x91' . The response is: '\x01\x01\x03\x12a' (plain response: '\x01\x01\x03\x12a')
@4000000064943c122151da94 WARNING:SerialBattery:Error reading settings from BMS, retry (9/10): Checksum error in rtu mode: '\x12a' instead of 'a\x91' . The response is: '\x01\x01\x03\x12a' (plain response: '\x01\x01\x03\x12a')
@4000000064943c1239e1d154 WARNING:SerialBattery:Error reading settings from BMS, retry (10/10): Checksum error in rtu mode: '\x12a' instead of 'a\x91' . The response is: '\x01\x01\x03\x12a' (plain response: '\x01\x01\x03\x12a')
@4000000064943c1239edeee4 INFO:SerialBattery:Testing HLPdataBMS4S
@4000000064943c171d6d802c ERROR:SerialBattery:>>> ERROR: No reply - returning
@4000000064943c171d6da73c INFO:SerialBattery:Testing Jkbms
@4000000064943c172dcb2ec4 ERROR:SerialBattery:>>> ERROR: No reply - returning
@4000000064943c172e011b74 INFO:SerialBattery:Testing Lifepower
@4000000064943c18027da06c ERROR:SerialBattery:>>> ERROR: No reply - returning
@4000000064943c1802b759c4 INFO:SerialBattery:Testing LltJbd
@4000000064943c182d496434 INFO:SerialBattery:Connection established to LltJbd
@4000000064943c182d5454fc INFO:SerialBattery:Battery LLT/JBD connected to dbus from /dev/ttyACM0
@4000000064943c182d5d6934 INFO:SerialBattery:========== Settings ==========
@4000000064943c182d67c974 INFO:SerialBattery:> Connection voltage: 55.67V | Current: 0.0A | SoC: 92.72%
@4000000064943c182d70b2b4 INFO:SerialBattery:> Cell count: 16 | Cells populated: 16
@4000000064943c182d79da74 INFO:SerialBattery:> LINEAR LIMITATION ENABLE: True
@4000000064943c182d832944 INFO:SerialBattery:> MAX BATTERY CHARGE CURRENT: 100.0A | MAX BATTERY DISCHARGE CURRENT: 100.0A
@4000000064943c182d8e50bc INFO:SerialBattery:> MAX BATTERY CHARGE CURRENT: 200.0A | MAX BATTERY DISCHARGE CURRENT: 200.0A (read from BMS)
@4000000064943c182d986e94 INFO:SerialBattery:> CVCM:     True
@4000000064943c182da226dc INFO:SerialBattery:> MIN CELL VOLTAGE: 2.9V | MAX CELL VOLTAGE: 3.47V
@4000000064943c182dab5284 INFO:SerialBattery:> CCCM CV:  True  | DCCM CV:  True
@4000000064943c182db4477c INFO:SerialBattery:> CCCM T:   True  | DCCM T:   True
@4000000064943c182dbd1d34 INFO:SerialBattery:> CCCM SOC: True  | DCCM SOC: True
@4000000064943c1830f30f2c INFO:SerialBattery:DeviceInstance = 1
@4000000064943c183102de0c INFO:SerialBattery:com.victronenergy.battery.ttyACM0
@4000000064943c190e141e4c INFO:SerialBattery:publish config values = 1

Any other information that may be helpful

No response

mr-manuel commented 1 year ago

@idstein maybe you can take a look at this?

idstein commented 1 year ago

Currently, I’m very busy, but the cycle capacity can be read via the factory mode at the beginning as we read the max current.

mr-manuel commented 1 year ago

There is no rush. If you have some spare time in the next weeks :-)

idstein commented 1 year ago

This should be resolved by the open PR.

mr-manuel commented 1 year ago

The PR was merged.