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

Feature: add daren 485v2 / SNS01 BMS support #168

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
TEST for controller optimizations, commit will be reverted later
Added PID-Controller
  • Loading branch information
mr-manuel committed Jan 9, 2025
commit 1c8a4b73c2ae89b7d65913c9e6407cc45249c313
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* Changes to `config.default.ini`: `CELL_VOLTAGE_DIFF_KEEP_MAX_VOLTAGE_TIME_RESTART` was superseeded by `SWITCH_TO_FLOAT_CELL_VOLTAGE_DEVIATION`, which has a different behavior
* Changes to `config.default.ini`: `CELL_VOLTAGE_DIFF_KEEP_MAX_VOLTAGE_UNTIL` was replaced by `SWITCH_TO_FLOAT_CELL_VOLTAGE_DIFF`
* Changes to `config.default.ini`: `CELL_VOLTAGE_DIFF_TO_RESET_VOLTAGE_LIMIT` was replaced by `SWITCH_TO_BULK_CELL_VOLTAGE_DIFF`
* Changes to `config.default.ini`: `CVL_ICONTROLLER_FACTOR` was replaced by `CVL_CONTROLLER_KI`
* Changes to `config.default.ini`: `CVL_ICONTROLLER_MODE` was superseeded by `CVL_CONTROLLER_MODE`, which has a different behavior
* Changes to `config.default.ini`: `LINEAR_LIMITATION_ENABLE` was superseeded by `CHARGE_MODE`, which has a different behavior
* Changes to `config.default.ini`: `LINEAR_RECALCULATION_EVERY` was replaced by `CVL_RECALCULATION_EVERY`
Expand Down Expand Up @@ -52,9 +53,11 @@
* Added: Felicity BMS by @versager
* Added: JKBMS CAN - Extended protocol with version V2 by @Hooorny and @mr-manuel
* Added: LiTime BMS by @calledit
* Added: D-Controller for managing CVL on high cell voltage by @mr-manuel
* Added: Make battery data available on MQTT under a single topic by enabling `PUBLISH_BATTERY_DATA_AS_JSON` by @mr-manuel
* Added: Min/Max lifetime temperature to history class and battery template by @mr-manuel
* Added: Pace BMS by @KoljaWindeler
* Added: PID-Controller for managing CVL on high cell voltage by @mr-manuel
* Added: Possibility to add external sensor for SoC by @mr-manuel
* Added: Signal handler for clean service restart/shutdown by @mr-manuel
* Changed: A lot of under the hood optimizations by @mr-manuel
Expand All @@ -77,6 +80,7 @@
* Changed: The setting `CELL_VOLTAGE_DIFF_KEEP_MAX_VOLTAGE_TIME_RESTART` was superseeded by `SWITCH_TO_FLOAT_CELL_VOLTAGE_DEVIATION`, which has a different behavior by @mr-manuel
* Changed: The setting `CELL_VOLTAGE_DIFF_KEEP_MAX_VOLTAGE_UNTIL` was replaced by `SWITCH_TO_FLOAT_CELL_VOLTAGE_DIFF` by @mr-manuel
* Changed: The setting `CELL_VOLTAGE_DIFF_TO_RESET_VOLTAGE_LIMIT` was replaced by `SWITCH_TO_BULK_CELL_VOLTAGE_DIFF` by @mr-manuel
* Changed: The setting `CVL_ICONTROLLER_FACTOR` was replaced by `CVL_CONTROLLER_KI` in the `config.default.ini` by @mr-manuel
* Changed: The setting `CVL_ICONTROLLER_MODE` was superseeded by `CVL_CONTROLLER_MODE`, which has a different behavior by @mr-manuel
* Changed: The setting `EXTERNAL_CURRENT_SENSOR_DBUS_DEVICE` was replaced by `EXTERNAL_SENSOR_DBUS_DEVICE` in the `config.default.ini` by @mr-manuel
* Changed: The setting `EXTERNAL_CURRENT_SENSOR_DBUS_PATH` was replaced by `EXTERNAL_SENSOR_DBUS_PATH_CURRENT` in the `config.default.ini` by @mr-manuel
Expand Down
78 changes: 60 additions & 18 deletions dbus-serialbattery/battery.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
from abc import ABC, abstractmethod
import sys

if utils.CHARGE_MODE == 4:
from simple_pid import PID


class Protection(object):
"""
Expand Down Expand Up @@ -664,6 +667,7 @@ def manage_charge_voltage_limit(self) -> None:
time_diff = 0
control_voltage = 0
current_time = int(time())
debug = None

try:
voltage_sum = self.get_cell_voltage_sum()
Expand Down Expand Up @@ -748,51 +752,88 @@ def manage_charge_voltage_limit(self) -> None:

if found_high_cell_voltage:
# reduce voltage by penalty sum
# keep penalty above min battery voltage and below max battery voltage
control_voltage = min(
max(
voltage_sum - penalty_sum,
self.min_battery_voltage,
),
self.max_battery_voltage,
)
control_voltage = voltage_sum - (penalty_sum * utils.CVL_CONTROLLER_KP)
else:
control_voltage = self.max_battery_voltage

# use I-Controller
# use I-Controller (is the current code really an I-Controller?)
elif utils.CVL_CONTROLLER_MODE == 2:
if self.control_voltage:
control_voltage = self.control_voltage - (
(self.get_max_cell_voltage() - cell_voltage_max_allowed - utils.SWITCH_TO_FLOAT_CELL_VOLTAGE_DIFF) * utils.CVL_ICONTROLLER_FACTOR
# (self.get_max_cell_voltage() - cell_voltage_max_allowed - utils.SWITCH_TO_FLOAT_CELL_VOLTAGE_DIFF) * utils.CVL_CONTROLLER_KI
(self.get_max_cell_voltage() - cell_voltage_max_allowed)
* utils.CVL_CONTROLLER_KI
)
else:
control_voltage = self.max_battery_voltage

control_voltage = min(
max(control_voltage, self.min_battery_voltage),
self.max_battery_voltage,
)
"""
# New untested I-Controller from GitHub Copilot
# Initialize integral term
self.integral_term = 0

if self.control_voltage:
# Calculate the error
error = self.get_max_cell_voltage() - cell_voltage_max_allowed - utils.SWITCH_TO_FLOAT_CELL_VOLTAGE_DIFF

# Accumulate the error to the integral term
self.integral_term += error

# Adjust the control voltage using the integral term
control_voltage = self.control_voltage - (self.integral_term * utils.CVL_CONTROLLER_KI)
else:
control_voltage = self.max_battery_voltage
"""

# use D-Controller (untested)
elif utils.CVL_CONTROLLER_MODE == 3:
if not hasattr(self, "previous_error"):
self.previous_error = 0

# Calculate the error
error = self.get_max_cell_voltage() - cell_voltage_max_allowed

# Calculate the derivative of the error
derivative = error - self.previous_error

# Adjust the control voltage using the derivative term
control_voltage = self.control_voltage - (derivative * utils.CVL_CONTROLLER_KD)

# Update previous error
self.previous_error = error

# use PID-Controller (untested)
elif utils.CVL_CONTROLLER_MODE == 4:
pid_controller = PID(Kp=utils.CVL_CONTROLLER_KP, Ki=utils.CVL_CONTROLLER_KI, Kd=utils.CVL_CONTROLLER_KD, setpoint=self.max_battery_voltage)
control_voltage = pid_controller(voltage_sum)

# use no controller
else:
control_voltage = self.max_battery_voltage

# set control voltage
# keep control voltage above min battery voltage and below max battery voltage
# 6 decimals are needed for a proper controller working
# https://github.com/Louisvdw/dbus-serialbattery/issues/1041
self.control_voltage = round(control_voltage, 6)
self.control_voltage = round(
min(
max(control_voltage, self.min_battery_voltage),
self.max_battery_voltage,
),
6,
)

self.charge_mode = "Bulk" if self.max_voltage_start_time is None else "Absorption"

# If control voltage is not equal to max battery voltage, then a high cell voltage was detected
if control_voltage != self.max_battery_voltage:
self.charge_mode += " (Cell OVP)" # Cell over voltage protection
self.charge_mode += ", Cell OVP " # Cell over voltage protection

if self.max_battery_voltage == self.soc_reset_battery_voltage:
self.charge_mode += " & SoC Reset"
self.charge_mode += ", SoC Reset"

if self.get_balancing() and voltage_cell_diff >= utils.SWITCH_TO_BULK_CELL_VOLTAGE_DIFF:
self.charge_mode += " + Balancing"
self.charge_mode += ", Balancing"

# Float mode
else:
Expand Down Expand Up @@ -860,6 +901,7 @@ def manage_charge_voltage_limit(self) -> None:

self.charge_mode_debug = (
f"driver started: {formatted_time} • running since: {self.get_seconds_to_string(int(time()) - self.driver_start_time)}\n"
+ (f"{debug}\n" if debug else "")
+ f"max_battery_voltage: {(self.max_battery_voltage):.2f} V • "
+ f"control_voltage: {self.control_voltage:.2f} V\n"
+ f"voltage: {self.voltage:.2f} V • "
Expand Down
12 changes: 9 additions & 3 deletions dbus-serialbattery/config.default.ini
Original file line number Diff line number Diff line change
Expand Up @@ -302,9 +302,15 @@ SWITCH_TO_BULK_CELL_VOLTAGE_DIFF = 0.080
; 0: Disabled
; 1: P-Controller (penalty sum method)
; 2: I-Controller
CVL_CONTROLLER_MODE = 0
; I-Controller factor (V/Vs)
CVL_ICONTROLLER_FACTOR = 0.2
; 3: D-Controller (untested)
; 4: PID-Controller (untested)
CVL_CONTROLLER_MODE = 1
; Proportional component (Kp)
CVL_CONTROLLER_KP = 0.99
; Integral component (Ki)
CVL_CONTROLLER_KI = 0.20
; Derivative component (Kd)
CVL_CONTROLLER_KD = 0.10


; --------- Cell Voltage Current Limitation (affecting CCL/DCL) ---------
Expand Down
1 change: 1 addition & 0 deletions dbus-serialbattery/ext/simple_pid/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from simple_pid.pid import PID as PID
Loading
Loading