diff --git a/docs/docs/general/features.md b/docs/docs/general/features.md
index a7b2434c..2ed2e9b3 100644
--- a/docs/docs/general/features.md
+++ b/docs/docs/general/features.md
@@ -83,7 +83,7 @@ CCCM limits the charge/discharge current depending on the highest/lowest cell vo
* between `2.8V - 2.9V` → `5A `discharge
* below `<= 2.70V` → `0A` discharge
-### Temprature
+### Temperature
* `CCCM_T_ENABLE = True/False`
* `DCCM_T_ENABLE = True/False`
@@ -121,27 +121,27 @@ If the `MAX_CELL_VOLTAGE` \* `cell count` is reached for `MAX_VOLTAGE_TIME_SEC`
## BMS feature comparison
-| Feature | Ant | Daly | ECS | HLPdataBMS4S | JK BMS | Life/Tian Power | LLT/JBD | MNB (1) | Renogy | Seplos | Sinowealth (1) |
-| ---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
-| Voltage | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
-| Current | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
-| Power | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
-| State Of Charge | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
-| Battery temperature | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
-| MOSFET temperature | No | No | No | No | Yes | No | Yes | No | No | No | No |
-| Consumed Ah | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
-| Time-to-go | Calc | Calc | Calc | Calc | Calc | Calc | Calc | Calc | Calc | Calc | Calc |
-| Min/max cell voltages | Yes | Yes | No | Yes | Yes | Yes | Yes | No | Yes | Yes | Yes |
-| Min/max temperature | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
-| Installed capacity | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
-| Available capacity | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
-| Cell details | No | Yes | Yes | Yes | Yes | Yes | Yes | No | Yes | Yes | ? |
-| Balancing status | Yes | No | Yes | No | Yes | Yes | No | No | No | No | ? |
-| Raise alarms from the BMS | Yes | Yes | Yes (2) | Yes | Yes | Yes | Yes | Yes | Yes | Yes | ? |
-| History of charge cycles | Yes | Yes | No | No | Yes | Yes | Yes | No | Yes | Yes | Yes |
-| Get CCL/DCL from the BMS | No | No | No | No | Yes | No | No | No | No | No | No |
-| Charge current control management (CCCM) | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
-| Set battery parameters (DVCC) | Calc | Calc | Yes | Yes | Calc | Calc | Calc | Yes | Calc | Calc | Calc |
+| Feature | Ant | Daly | ECS | Heltec | HLPdataBMS4S | JK BMS | Life/Tian Power | LLT/JBD | MNB (1) | Renogy | Seplos | Sinowealth (1) |
+| ---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
+| Voltage | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
+| Current | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
+| Power | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
+| State Of Charge | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
+| Battery temperature | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
+| MOSFET temperature | No | No | No | Yes | No | Yes | No | Yes | No | No | No | No |
+| Consumed Ah | Yes | Yes | Yes | No | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
+| Time-to-go | Calc | Calc | Calc | Calc | Calc | Calc | Calc | Calc | Calc | Calc | Calc | Calc |
+| Min/max cell voltages | Yes | Yes | No | Yes | Yes | Yes | Yes | Yes | No | Yes | Yes | Yes |
+| Min/max temperature | Yes | Yes | Yes | No | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
+| Installed capacity | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
+| Available capacity | Yes | Yes | Yes | No | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
+| Cell details | No | Yes | Yes | Yes | Yes | Yes | Yes | Yes | No | Yes | Yes | ? |
+| Balancing status | Yes | No | Yes | Yes | No | Yes | Yes | No | No | No | No | ? |
+| Raise alarms from the BMS | Yes | Yes | Yes (2) | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | ? |
+| History of charge cycles | Yes | Yes | No | No | No | Yes | Yes | Yes | No | Yes | Yes | Yes |
+| Get CCL/DCL from the BMS | No | No | No | Yes | No | Yes | No | No | No | No | No | No |
+| Charge current control management (CCCM) | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
+| Set battery parameters (DVCC) | Calc | Calc | Yes | Calc | Yes | Calc | Calc | Calc | Yes | Calc | Calc | Calc |
`Calc` means that the value is calculated by the driver.
diff --git a/docs/docs/general/install.md b/docs/docs/general/install.md
index 56c891bc..4b30e030 100644
--- a/docs/docs/general/install.md
+++ b/docs/docs/general/install.md
@@ -122,7 +122,7 @@ Select `2` for `nightly build` and then select the branch you want to install fr
### BMS specific settings
* ECS BMS → https://github.com/Louisvdw/dbus-serialbattery/issues/254#issuecomment-1275924313
-
+* HeltecModbus → in case the modbus slave address of the BMS was adjusted from the factory default, configure the slave addresses to query in config.ini:HELTEC_MODBUS_ADDR. As always the battery settings shall be configured in the BMS already via app or computer.
## How to change the default limits
diff --git a/docs/docs/general/supported-bms.md b/docs/docs/general/supported-bms.md
index 416e7362..ff247950 100644
--- a/docs/docs/general/supported-bms.md
+++ b/docs/docs/general/supported-bms.md
@@ -22,6 +22,9 @@ Disabled by default since driver version `v0.14.0` as it causes other issues. Se
### • ECS GreenMeter with LiPro
+### • HeltecModbus SmartBMS (YanYang BMS)
+Communication to the Heltec SmartBMS (which is a rebranded YYBMS) via Modbus/RS485.
+
### • HLPdataBMS4S
### • [JKBMS](https://www.jkbms.com/products/) / Heltec BMS
diff --git a/etc/dbus-serialbattery/bms/heltecmodbus.py b/etc/dbus-serialbattery/bms/heltecmodbus.py
new file mode 100644
index 00000000..9291fd26
--- /dev/null
+++ b/etc/dbus-serialbattery/bms/heltecmodbus.py
@@ -0,0 +1,439 @@
+# -*- coding: utf-8 -*-
+# known limitations:
+# - only BMS variants with 2 cell temperature sensors supported
+# - some "interesting" datapoints are not read (e. g. registers 52: switch type, 62: bootloader and firmware version)
+# - SOC not yet resettable from Venus (similary to Daly for support of writing SOC), but modbus write to 120 should be
+# fairly possible)
+
+
+from battery import Battery, Cell
+from utils import logger
+import utils
+import serial
+import time
+import minimalmodbus
+from typing import Dict
+import threading
+
+# the Heltec BMS is not always as responsive as it should, so let's try it up to (RETRYCNT - 1) times to talk to it
+RETRYCNT = 10
+
+# the wait time after a communication - normally this should be as defined by modbus RTU and handled in minimalmodbus,
+# but yeah, it seems we need it for the Heltec BMS
+SLPTIME = 0.03
+
+mbdevs: Dict[int, minimalmodbus.Instrument] = {}
+locks: Dict[int, any] = {}
+
+
+class HeltecModbus(Battery):
+ def __init__(self, port, baud, address):
+ super(HeltecModbus, self).__init__(port, baud, address)
+ self.type = "Heltec_Smart"
+
+ def test_connection(self):
+ # call a function that will connect to the battery, send a command and retrieve the result.
+ # The result or call should be unique to this BMS. Battery name or version, etc.
+ # Return True if success, False for failure
+ for self.address in utils.HELTEC_MODBUS_ADDR:
+ logger.info("Testing on slave address " + str(self.address))
+ found = False
+ if self.address not in locks:
+ locks[self.address] = threading.Lock()
+
+ # TODO: We need to lock not only based on the address, but based on the port as soon as multiple BMSs
+ # are supported on the same serial interface. Then locking on the port will be enough.
+
+ with locks[self.address]:
+ mbdev = minimalmodbus.Instrument(
+ self.port,
+ slaveaddress=self.address,
+ mode="rtu",
+ close_port_after_each_call=True,
+ debug=False,
+ )
+ mbdev.serial.parity = minimalmodbus.serial.PARITY_NONE
+ mbdev.serial.stopbits = serial.STOPBITS_ONE
+ mbdev.serial.baudrate = 9600
+ # yes, 400ms is long but the BMS is sometimes really slow in responding, so this is a good compromise
+ mbdev.serial.timeout = 0.4
+ mbdevs[self.address] = mbdev
+
+ for n in range(1, RETRYCNT):
+ try:
+ string = mbdev.read_string(7, 13)
+ time.sleep(SLPTIME)
+ found = True
+ logger.info(
+ "found in try "
+ + str(n)
+ + "/"
+ + str(RETRYCNT)
+ + " for "
+ + self.port
+ + "("
+ + str(self.address)
+ + "): "
+ + string
+ )
+ except Exception as e:
+ logger.warn(
+ "testing failed ("
+ + str(e)
+ + ") "
+ + str(n)
+ + "/"
+ + str(RETRYCNT)
+ + " for "
+ + self.port
+ + "("
+ + str(self.address)
+ + ")"
+ )
+ continue
+ break
+ if found:
+ self.type = "#" + str(self.address) + "_Heltec_Smart"
+ break
+
+ return (
+ found
+ and self.read_status_data()
+ and self.get_settings()
+ and self.refresh_data()
+ )
+
+ def get_settings(self):
+ self.max_battery_voltage = self.max_cell_voltage * self.cell_count
+ self.min_battery_voltage = self.min_cell_voltage * self.cell_count
+
+ return True
+
+ def refresh_data(self):
+ # call all functions that will refresh the battery data.
+ # This will be called for every iteration (1 second)
+ # Return True if success, False for failure
+ return self.read_soc_data() and self.read_cell_data()
+
+ def read_status_data(self):
+ mbdev = mbdevs[self.address]
+
+ with locks[self.address]:
+ for n in range(1, RETRYCNT):
+ try:
+ ccur = mbdev.read_register(191, 0, 3, False)
+ self.max_battery_charge_current = (
+ (int)(((ccur & 0xFF) << 8) | ((ccur >> 8) & 0xFF))
+ ) / 100
+ time.sleep(SLPTIME)
+
+ dc = mbdev.read_register(194, 0, 3, False)
+ self.max_battery_discharge_current = (
+ ((dc & 0xFF) << 8) | ((dc >> 8) & 0xFF)
+ ) / 100
+ time.sleep(SLPTIME)
+
+ cap = mbdev.read_register(118, 0, 3, False)
+ self.capacity = (((cap & 0xFF) << 8) | ((cap >> 8) & 0xFF)) / 10
+ time.sleep(SLPTIME)
+
+ cap = mbdev.read_register(119, 0, 3, False)
+ self.actual_capacity = (
+ ((cap & 0xFF) << 8) | ((cap >> 8) & 0xFF)
+ ) / 10
+ time.sleep(SLPTIME)
+
+ cap = mbdev.read_register(126, 0, 3, False)
+ self.learned_capacity = (
+ ((cap & 0xFF) << 8) | ((cap >> 8) & 0xFF)
+ ) / 10
+ time.sleep(SLPTIME)
+
+ volt = mbdev.read_register(169, 0, 3, False)
+ self.max_cell_voltage = (
+ ((volt & 0xFF) << 8) | ((volt >> 8) & 0xFF)
+ ) / 1000
+ time.sleep(SLPTIME)
+
+ volt = mbdev.read_register(172, 0, 3, False)
+ self.min_cell_voltage = (
+ ((volt & 0xFF) << 8) | ((volt >> 8) & 0xFF)
+ ) / 1000
+ time.sleep(SLPTIME)
+
+ string = mbdev.read_string(7, 13)
+ self.hwTypeName = string
+ time.sleep(SLPTIME)
+
+ string = mbdev.read_string(41, 6)
+ self.devName = string
+ time.sleep(SLPTIME)
+
+ serial1 = mbdev.read_registers(2, number_of_registers=4)
+ self.unique_identifier = "-".join(
+ "{:04x}".format(x) for x in serial1
+ )
+ time.sleep(SLPTIME)
+
+ self.pw = mbdev.read_string(47, 2)
+ time.sleep(SLPTIME)
+
+ tmp = mbdev.read_register(75)
+ # h: batterytype: 0: Ternery Lithium, 1: Iron Lithium, 2: Lithium Titanat
+ # l: #of cells
+
+ self.cell_count = (tmp >> 8) & 0xFF
+ tmp = tmp & 0xFF
+ if tmp == 0:
+ self.cellType = "Ternary Lithium"
+ elif tmp == 1:
+ self.cellType = "Iron Lithium"
+ elif tmp == 2:
+ self.cellType = "Lithium Titatnate"
+ else:
+ self.cellType = "unknown"
+ time.sleep(SLPTIME)
+
+ self.hardware_version = (
+ self.devName
+ + "("
+ + str((mbdev.read_register(38) >> 8) & 0xFF)
+ + ")"
+ )
+ time.sleep(SLPTIME)
+
+ date = mbdev.read_long(39, 3, True, minimalmodbus.BYTEORDER_LITTLE)
+ self.production_date = (
+ str(date & 0xFFFF)
+ + "-"
+ + str((date >> 24) & 0xFF)
+ + "-"
+ + str((date >> 16) & 0xFF)
+ )
+ time.sleep(SLPTIME)
+
+ # we finished all readings without trouble, so let's break from the retry loop
+ break
+ except Exception as e:
+ logger.warn(
+ "Error reading settings from BMS, retry ("
+ + str(n)
+ + "/"
+ + str(RETRYCNT)
+ + "): "
+ + str(e)
+ )
+ continue
+
+ logger.info(self.hardware_version)
+ logger.info("Heltec-" + self.hwTypeName)
+ logger.info(" Dev name: " + self.devName)
+ logger.info(" Serial: " + self.unique_identifier)
+ logger.info(" Made on: " + self.production_date)
+ logger.info(" Cell count: " + str(self.cell_count))
+ logger.info(" Cell type: " + self.cellType)
+ logger.info(" BT password: " + self.pw)
+ logger.info(" rated capacity: " + str(self.capacity))
+ logger.info(" actual capacity: " + str(self.actual_capacity))
+ logger.info(" learned capacity: " + str(self.learned_capacity))
+
+ return True
+
+ def read_soc_data(self):
+ mbdev = mbdevs[self.address]
+
+ with locks[self.address]:
+ for n in range(1, RETRYCNT):
+ try:
+ self.voltage = (
+ mbdev.read_long(76, 3, True, minimalmodbus.BYTEORDER_LITTLE)
+ / 1000
+ )
+ time.sleep(SLPTIME)
+
+ self.current = -(
+ mbdev.read_long(78, 3, True, minimalmodbus.BYTEORDER_LITTLE)
+ / 100
+ )
+ time.sleep(SLPTIME)
+
+ runState1 = mbdev.read_long(
+ 152, 3, True, minimalmodbus.BYTEORDER_LITTLE
+ )
+ time.sleep(SLPTIME)
+
+ # bit 29 is discharge protection
+ if (runState1 & 0x20000000) == 0:
+ self.discharge_fet = True
+ else:
+ self.discharge_fet = False
+
+ # bit 28 is charge protection
+ if (runState1 & 0x10000000) == 0:
+ self.charge_fet = True
+ else:
+ self.charge_fet = False
+
+ warnings = mbdev.read_long(
+ 156, 3, True, minimalmodbus.BYTEORDER_LITTLE
+ )
+ if (warnings & (1 << 3)) or (
+ warnings & (1 << 15)
+ ): # 15 is full protection, 3 is total overvoltage
+ self.voltage_high = 2
+ else:
+ self.voltage_high = 0
+
+ if warnings & (1 << 0):
+ self.protection.voltage_cell_high = 2
+ # we handle a single cell OV as total OV, as long as cell_high is not explicitly handled
+ self.protection.voltage_high = 1
+ else:
+ self.protection.voltage_cell_high = 0
+
+ if warnings & (1 << 1):
+ self.protection.voltage_cell_low = 2
+ else:
+ self.protection.voltage_cell_low = 0
+
+ if warnings & (1 << 4):
+ self.protection.voltage_low = 2
+ else:
+ self.protection.voltage_low = 0
+
+ if warnings & (1 << 5):
+ self.protection.current_over = 2
+ else:
+ self.protection.current_over = 0
+
+ if warnings & (1 << 7):
+ self.protection.current_under = 2
+ elif warnings & (1 << 6):
+ self.protection.current_under = 1
+ else:
+ self.protection.current_under = 0
+
+ if warnings & (1 << 8): # this is a short circuit
+ self.protection.current_over = 2
+
+ if warnings & (1 << 9):
+ self.protection.temp_high_charge = 2
+ else:
+ self.protection.temp_high_charge = 0
+
+ if warnings & (1 << 10):
+ self.protection.temp_low_charge = 2
+ else:
+ self.protection.temp_low_charge = 0
+
+ if warnings & (1 << 11):
+ self.protection.temp_high_discharge = 2
+ else:
+ self.protection.temp_high_discharge = 0
+
+ if warnings & (1 << 12):
+ self.protection.temp_low_discharge = 2
+ else:
+ self.protection.temp_low_discharge = 0
+
+ if warnings & (1 << 13): # MOS overtemp
+ self.protection.temp_high_internal = 2
+ else:
+ self.protection.temp_high_internal = 0
+
+ if warnings & (1 << 14): # SOC low
+ self.protection.soc_low = 2
+ else:
+ self.protection.soc_low = 0
+
+ if warnings & (0xFFFF0000): # any other fault
+ self.protection.internal_failure = 2
+ else:
+ self.protection.internal_failure = 0
+
+ socsoh = mbdev.read_register(120, 0, 3, False)
+ self.soh = socsoh & 0xFF
+ self.soc = (socsoh >> 8) & 0xFF
+ time.sleep(SLPTIME)
+
+ # we could read min and max temperature, here, but I have a BMS with only 2 sensors,
+ # so I couldn't test the logic and read therefore only the first two temperatures
+ # tminmax = mbdev.read_register(117, 0, 3, False)
+ # nmin = (tminmax & 0xFF)
+ # nmax = ((tminmax >> 8) & 0xFF)
+
+ temps = mbdev.read_register(113, 0, 3, False)
+ self.temp1 = (temps & 0xFF) - 40
+ self.temp2 = ((temps >> 8) & 0xFF) - 40
+ time.sleep(SLPTIME)
+
+ temps = mbdev.read_register(112, 0, 3, False)
+ most = (temps & 0xFF) - 40
+ balt = ((temps >> 8) & 0xFF) - 40
+ # balancer temperature is not handled separately in dbus-serialbattery,
+ # so let's display the max of both temperatures inside the BMS as mos temperature
+ self.temp_mos = max(most, balt)
+ time.sleep(SLPTIME)
+
+ return True
+
+ except Exception as e:
+ logger.warn(
+ "Error reading SOC, retry ("
+ + str(n)
+ + "/"
+ + str(RETRYCNT)
+ + ") "
+ + str(e)
+ )
+ continue
+ break
+ logger.warn("Error reading SOC, failed")
+ return False
+
+ def read_cell_data(self):
+ result = False
+ mbdev = mbdevs[self.address]
+
+ with locks[self.address]:
+ for n in range(1, RETRYCNT):
+ try:
+ cells = mbdev.read_registers(
+ 81, number_of_registers=self.cell_count
+ )
+ time.sleep(SLPTIME)
+
+ balancing = mbdev.read_long(
+ 139, 3, signed=False, byteorder=minimalmodbus.BYTEORDER_LITTLE
+ )
+ time.sleep(SLPTIME)
+
+ result = True
+ except Exception as e:
+ logger.warn(
+ "read_cell_data() failed ("
+ + str(e)
+ + ") "
+ + str(n)
+ + "/"
+ + str(RETRYCNT)
+ )
+ continue
+ break
+ if result is False:
+ return False
+
+ if len(self.cells) != self.cell_count:
+ self.cells = []
+ for idx in range(self.cell_count):
+ self.cells.append(Cell(False))
+
+ i = 0
+ for cell in cells:
+ cellV = ((cell & 0xFF) << 8) | ((cell >> 8) & 0xFF)
+ self.cells[i].voltage = cellV / 1000
+ self.cells[i].balance = balancing & (1 << i) != 0
+
+ i = i + 1
+
+ return True
diff --git a/etc/dbus-serialbattery/config.default.ini b/etc/dbus-serialbattery/config.default.ini
index e9b4f403..25762314 100644
--- a/etc/dbus-serialbattery/config.default.ini
+++ b/etc/dbus-serialbattery/config.default.ini
@@ -240,6 +240,12 @@ 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
diff --git a/etc/dbus-serialbattery/dbus-serialbattery.py b/etc/dbus-serialbattery/dbus-serialbattery.py
index b50c938c..6530ace1 100644
--- a/etc/dbus-serialbattery/dbus-serialbattery.py
+++ b/etc/dbus-serialbattery/dbus-serialbattery.py
@@ -24,6 +24,7 @@
# import battery classes
from bms.daly import Daly
from bms.ecs import Ecs
+from bms.heltecmodbus import HeltecModbus
from bms.hlpdatabms4s import HLPdataBMS4S
from bms.jkbms import Jkbms
from bms.lifepower import Lifepower
@@ -39,6 +40,7 @@
{"bms": Daly, "baud": 9600, "address": b"\x40"},
{"bms": Daly, "baud": 9600, "address": b"\x80"},
{"bms": Ecs, "baud": 19200},
+ {"bms": HeltecModbus, "baud": 9600},
{"bms": HLPdataBMS4S, "baud": 9600},
{"bms": Jkbms, "baud": 115200},
{"bms": Lifepower, "baud": 9600},
diff --git a/etc/dbus-serialbattery/utils.py b/etc/dbus-serialbattery/utils.py
index c854c4f3..8769d5a0 100644
--- a/etc/dbus-serialbattery/utils.py
+++ b/etc/dbus-serialbattery/utils.py
@@ -321,6 +321,11 @@ def _get_list_from_config(
LIPRO_END_ADDRESS = int(config["DEFAULT"]["LIPRO_END_ADDRESS"])
LIPRO_CELL_COUNT = int(config["DEFAULT"]["LIPRO_CELL_COUNT"])
+# -- HeltecModbus device settings
+HELTEC_MODBUS_ADDR = _get_list_from_config(
+ "DEFAULT", "HELTEC_MODBUS_ADDR", lambda v: int(v)
+)
+
# --------- Battery monitor specific settings ---------
# If you are using a SmartShunt or something else as a battery monitor, the battery voltage reported