Skip to content

Commit

Permalink
Renogy fixes (#224)
Browse files Browse the repository at this point in the history
* Add support for Renogy RBT100LFP12SH (#205)
May have fixed incorrectly reporting of total and current amp hours
for other Renogy batteries as well.

Co-authored-by: Johan Anderholm <[email protected]>
  • Loading branch information
Louisvdw and janderholm authored Sep 30, 2022
1 parent 799d817 commit b831e5e
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 18 deletions.
5 changes: 3 additions & 2 deletions etc/dbus-serialbattery/dbus-serialbattery.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@ def get_battery_type(_port):
Daly(port=_port, baud=9600, address=b"\x80"),
Jkbms(port=_port, baud=115200),
Sinowealth(port=_port, baud=9600),
Renogy(port=_port, baud=9600),
Lifepower(port=_port, baud=9600),
Revov (port=_port, baud=9600),
Renogy(port=_port, baud=9600, address=b"\x30"),
Renogy(port=_port, baud=9600, address=b"\xF7"),
# Revov (port=_port, baud=9600),
Ecs (port=_port, baud=19200),
# MNB(port=_port, baud=9600),
]
Expand Down
47 changes: 32 additions & 15 deletions etc/dbus-serialbattery/renogy.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@ class RenogyCell(Cell):

class Renogy(Battery):

def __init__(self, port,baud):
def __init__(self, port, baud, address):
super(Renogy, self).__init__(port,baud)
self.type = self.BATTERYTYPE

# The RBT100LFP12SH-G1 uses 0xF7, another battery uses 0x30
self.command_address = address

BATTERYTYPE = "Renogy"
LENGTH_CHECK = 4
LENGTH_POS = 2

# command bytes [Address field][Function code (03 = Read register)][Register Address (2 bytes)][Data Length (2 bytes)][CRC (2 bytes little endian)]
# Battery addresses start at 0 ascii, 30 hex
command_address = b"0"
command_read = b"\x03"
# Core data = voltage, temp, current, soc
command_cell_count = b"\x13\x88\x00\x01" #Register 5000
Expand All @@ -46,6 +47,7 @@ def test_connection(self):
try:
result = self.read_gen_data()
except:
logger.exception("Unexpected exception encountered")
pass

return result
Expand Down Expand Up @@ -76,24 +78,38 @@ def read_gen_data(self):
# check if connection success
if model is False:
return False
model_num = unpack('16s',model)[0]
self.hardware_version = "Renogy " + str(model_num)
# may contain null bytes that we don't want
model_num, _, _ = unpack('16s', model)[0].decode('utf-8').partition('\0')

manufacturer = self.read_serial_data_renogy(self.command_manufacturer)
if manufacturer is False:
self.hardware_version = model_num
else:
# may contain null bytes that we don't want
manufacturer, _, _ = unpack('16s', manufacturer)[0].decode('utf-8').partition('\0')
self.hardware_version = f'{manufacturer} {model_num}'

logger.info(self.hardware_version)

# TODO: This isn't really accurate I think.
self.temp_sensors = 2

if self.cell_count is None:
cc = self.read_serial_data_renogy(self.command_cell_count)
self.cell_count = struct.unpack('>H',cc)[0]

for c in range(self.cell_count):
self.cells.append(RenogyCell(False))

firmware = self.read_serial_data_renogy(self.command_firmware_version)
firmware_major, firmware_minor = unpack_from('2s2s', firmware)
self.version = float(str(firmware_major) + "." + str(firmware_minor))
firmware_major = firmware_major.decode('utf-8')
firmware_minor = firmware_minor.decode('utf-8')
self.version = float(f"{firmware_major}.{firmware_minor}")

capacity = self.read_serial_data_renogy(self.command_capacity)
self.capacity = unpack('>L',capacity)[0]
self.capacity = unpack('>L',capacity)[0] / 1000.0

return True

def read_soc_data(self):
Expand All @@ -102,10 +118,11 @@ def read_soc_data(self):
if soc_data is False:
return False

current, voltage, self.capacity_remain = unpack_from('>hhL', soc_data)
self.current = current / 100
self.voltage = voltage / 10
self.soc = self.capacity_remain / self.capacity * 100
current, voltage, capacity_remain = unpack_from('>hhL', soc_data)
self.capacity_remain = capacity_remain / 1000.0
self.current = current / 100.0
self.voltage = voltage / 10.0
self.soc = (self.capacity_remain / self.capacity) * 100
return True

def read_cell_data(self):
Expand All @@ -129,7 +146,7 @@ def read_temp_data(self):
return False
self.temp1 = unpack('>H',temp1)[0] / 10
self.temp2 = unpack('>H',temp2)[0] / 10

return True

def read_bms_config(self):
Expand All @@ -138,15 +155,15 @@ def read_bms_config(self):
def calc_crc(self, data):
crc = 0xFFFF
for pos in data:
crc ^= pos
crc ^= pos
for i in range(8):
if ((crc & 1) != 0):
crc >>= 1
crc ^= 0xA001
else:
crc >>= 1
return struct.pack('<H',crc)

def generate_command(self, command):
buffer = bytearray(self.command_address)
buffer += self.command_read
Expand Down
2 changes: 1 addition & 1 deletion etc/dbus-serialbattery/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

# Constants - Need to dynamically get them in future
DRIVER_VERSION = 0.12
DRIVER_SUBVERSION = 'b3'
DRIVER_SUBVERSION = '~4'
zero_char = chr(48)
degree_sign = u'\N{DEGREE SIGN}'
# Cell min/max voltages - used with the cell count to get the min/max battery voltage
Expand Down

0 comments on commit b831e5e

Please sign in to comment.