Open tomascrespo opened 1 year ago
Finally I get it working. At least most of the times.
p.get_values_single(1) works always p.get_system_parameters() works always
However p.get_values() only works sometimes. Other times it fails with a weird response, I do not why 😕
What I did: Change address from 2 to 1 into get_values() and into get_system_parameters() Modify constructor to allow communication at 4800 speed rate:
def __init__(self, serial_port='/dev/ttyUSB0', baudrate=1200):
self.s = serial.Serial(serial_port, baudrate, bytesize=8, parity=serial.PARITY_NONE, stopbits=1, timeout=6)
self.s.write(bytes([0x7E, 0x32, 0x30, 0x30, 0x31, 0x34, 0x36, 0x39, 0x31, 0x45, 0x30, 0x30, 0x32, 0x30, 0x33, 0x46, 0x44, 0x32, 0x46, 0x0D])) # Sets speed to 4800
time.sleep(1)
self.s.close()
self.s = serial.Serial(serial_port, 4800, bytesize=8, parity=serial.PARITY_NONE, stopbits=1, timeout=2)
self.s.isOpen()
self.s.flush()
Change read_frame() to read until '\n' (end of frame)
def read_frame(self):
#raw_frame = self.s.readline()
raw_frame = self.s.read_until(b'\r')
f = self._decode_hw_frame(raw_frame=raw_frame)
parsed = self._decode_frame(f)
return parsed
As mentioned, p.get_system_parameters() does never fail.
----> Sending: b'~200146470000FDA8\r'
7e323030313436343730303030464441380d
<---- Receiving: b'~20014600B032000E420BEA0B540D0D0A3D03FCD2F0B3B0ADD40D0D0A3DFC18F240\r'
7e3230303134363030423033323030304534323042454130423534304430443041334430334643443246304233423041444434304430443041334446433138463234300d
Container:
CellHighVoltageLimit = 3.65
CellLowVoltageLimit = 3.05
CellUnderVoltageLimit = 2.9
ChargeHighTemperatureLimit = 61.0
ChargeLowTemperatureLimit = -11.0
ChargeCurrentLimit = 10.2
ModuleHighVoltageLimit = 54.0
ModuleLowVoltageLimit = 46.0
ModuleUnderVoltageLimit = 44.5
DischargeHighTemperatureLimit = 61.0
DischargeLowTemperatureLimit = -11.0
DischargeCurrentLimit = -10.0
p.get_values_single(1) does not fail:
----> Sending: b'~20014642E00201FD35\r'
7e3230303134363432453030323031464433350d
<---- Receiving: b'~20014600C06E00010F0CF80CF80CFA0CF90CF70CFA0CF90CF70CF90CFA0CF90CF90CF80CF90CF9050BA50B870B870B870B87FFF6C293A60402C3500001E47C\r'
7e3230303134363030433036453030303130463043463830434638304346413043463930434637304346413043463930434637304346393043464130434639304346393043463830434639304346393035304241353042383730423837304238373042383746464636433239334136303430324333353030303031453437430d
Container:
NumberOfModule = 1
NumberOfCells = 15
CellVoltages = ListContainer:
3.32
3.32
3.322
3.321
3.319
3.322
3.321
3.319
3.321
3.322
3.321
3.321
3.32
3.321
3.321
NumberOfTemperatures = 5
AverageBMSTemperature = 25.0
GroupedCellsTemperatures = ListContainer:
22.0
22.0
22.0
22.0
Current = -1.0
Voltage = 49.811
Power = -49.811
CycleNumber = 1
RemainingCapacity = 42.5
TotalCapacity = 50.0
TotalPower = -49.811
StateOfCharge = 0.85
But p.get_values() fails most of the times (one good each a lot of bads):
----> Sending: b'~20014642E002FFFD0A\r'
7e3230303134363432453030324646464430410d
<---- Receiving: b'~20014600B0D800020F0CF80CF80CF70CF90CF80CF80CF80CF80CF80CF80CF90CF80CF70CF90CF7050BA50B870B870B870B87FFF5C288A60402C35000010F0CF80CF80CF60CF70CF80CF80CF70CF80CF80CF90CF90CF90CF80CF80CF8050B9B0B870B870B870B87FFF4C287A7F802C3500280CC47\r'
7e323030313436303042304438303030323046304346383043463830434637304346393043463830434638304346383043463830434638304346383043463930434638304346373043463930434637303530424135304238373042383730423837304238374646463543323838413630343032433335303030303130463043463830434638304346363043463730434638304346383043463730434638304346383043463930434639304346393043463830434638304346383035304239423042383730423837304238373042383746464634433238374137463830324333353030323830434334370d
Container:
NumberOfModules = 2
Module = ListContainer:
Container:
NumberOfCells = 15
CellVoltages = ListContainer:
3.32
3.32
3.319
3.321
3.32
3.32
3.32
3.32
3.32
3.32
3.321
3.32
3.319
3.321
3.319
NumberOfTemperatures = 5
AverageBMSTemperature = 25.0
GroupedCellsTemperatures = ListContainer:
22.0
22.0
22.0
22.0
Current = -1.1
Voltage = 49.8
Power = -54.78
CycleNumber = 1
RemainingCapacity = 42.5
TotalCapacity = 50.0
Container:
NumberOfCells = 15
CellVoltages = ListContainer:
3.32
3.32
3.318
3.319
3.32
3.32
3.319
3.32
3.32
3.321
3.321
3.321
3.32
3.32
3.32
NumberOfTemperatures = 5
AverageBMSTemperature = 24.0
GroupedCellsTemperatures = ListContainer:
22.0
22.0
22.0
22.0
Current = -1.2
Voltage = 49.799
Power = -59.758799999999994
CycleNumber = 640
RemainingCapacity = 43.0
TotalCapacity = 50.0
TotalPower = -114.5388
StateOfCharge = 0.855
Bad:
----> Sending: b'~20014642E002FFFD0A\r'
7e3230303134363432453030324646464430410d
<---- Receiving: b'~20014600B0D800020F0CF60CF70CF80CFA0CF\r'
7e323030313436303042304438303030323046304346363043463730434638304346413043460d
Traceback (most recent call last):
File "/home/pi/python-pylontech/tommy_test.py", line 4, in <module>
print(p.get_values())
File "/home/pi/python-pylontech/pylontech/pylontech.py", line 284, in get_values
f = self.read_frame()
File "/home/pi/python-pylontech/pylontech/pylontech.py", line 214, in read_frame
f = self._decode_hw_frame(raw_frame=raw_frame)
File "/home/pi/python-pylontech/pylontech/pylontech.py", line 192, in _decode_hw_frame
assert got_frame_checksum == int(frame_chksum, 16)
AssertionError
Bad:
----> Sending: b'~20014642E002FFFD0A\r'
7e3230303134363432453030324646464430410d
<---- Receiving: b'~20014600B0D800020F0CF80CF60CF90CF80CF70CF80CF90CF80CF90CFA0CFB0CFB0CF90CFA0CFA050BA50B870B870B870B87FFF5C295A60402C35000010F0CF80CF80CF70CF80CF80CF70CF80CF70CF80CF~20024692E00202FD2E\r'
7e323030313436303042304438303030323046304346383043463630434639304346383043463730434638304346393043463830434639304346413043464230434642304346393043464130434641303530424135304238373042383730423837304238374646463543323935413630343032433335303030303130463043463830434638304346373043463830434638304346373043463830434637304346383043467e3230303234363932453030323032464432450d
Traceback (most recent call last):
File "/home/pi/python-pylontech/tommy_test.py", line 4, in <module>
print(p.get_values())
File "/home/pi/python-pylontech/pylontech/pylontech.py", line 284, in get_values
f = self.read_frame()
File "/home/pi/python-pylontech/pylontech/pylontech.py", line 214, in read_frame
f = self._decode_hw_frame(raw_frame=raw_frame)
File "/home/pi/python-pylontech/pylontech/pylontech.py", line 192, in _decode_hw_frame
assert got_frame_checksum == int(frame_chksum, 16)
AssertionError
Bad:
----> Sending: b'~20014642E002FFFD0A\r'
7e3230303134363432453030324646464430410d
<---- Receiving: b''
Traceback (most recent call last):
File "/home/pi/python-pylontech/tommy_test.py", line 4, in <module>
print(p.get_values())
File "/home/pi/python-pylontech/pylontech/pylontech.py", line 284, in get_values
f = self.read_frame()
File "/home/pi/python-pylontech/pylontech/pylontech.py", line 214, in read_frame
f = self._decode_hw_frame(raw_frame=raw_frame)
File "/home/pi/python-pylontech/pylontech/pylontech.py", line 192, in _decode_hw_frame
assert got_frame_checksum == int(frame_chksum, 16)
ValueError: invalid literal for int() with base 16: b''
Some clue? Perhaps is something normal and the packets in this protocol get corrupted sometimes, more probabbly if they are greater? Does this happen with RS485?
One of the most received error frame is this: b'~200146060000FDAD\r' could someone break it down for me? It has to specify some type of error in some field
Hi tomascrespo, i had the same idea as you described/ask, let's use the serial console. Can you please do a fork/share your code ,so we can work together on it?
I have two UP5000 which i plan to monitor .. BTW, beside the RS485 communication document, there also exists document from pylontech regarding the RS232 communication.
KR
Hi, I completely forgot about this issue :(. I didn't know that the rs232 proto was documented.; maybe I should find + upload the PDF here?
Indeed, merging both protocols would be awesome!
Happy new year :-)
On December 29, 2023 5:38:08 PM GMT+01:00, MC68030 @.***> wrote:
Hi tomascrespo, i had the same idea as you described/ask, let's use the serial console. Can you please do a fork/share your code ,so we can work together on it?
I have two UP5000 which i plan to monitor .. BTW, beside the RS485 communication document, there also exists document from pylontech regarding the RS232 communication.
KR
-- Reply to this email directly or view it on GitHub: https://github.com/Frankkkkk/python-pylontech/issues/29#issuecomment-1872208412 You are receiving this because you are subscribed to this thread.
Message ID: @.***>
Just search for "PYLON LFP Battery communication protocol - RS232" :-) And happy new year too!
Hi Frakkkkk!
I have read your code and it is great
I would like to make it work through RS232 because my Pylon are using RS485 interface to communicate with my inversor.
As far as I know Pylontech RS485 protocol and RS232 are almost the same, but I am not completly sure.
My batteries communicate with RS232 with BatteryView (Pylontech software) perfectly, using and RS232 to USB adapter connected to console port.
I think the first step is putting the serial port in 1200 bps, because this is the default for Pylontech RS232 (although they could go faster setting them up with a specific command)
Before I deep more into this I want to know if someone has tried before or your knowledge, if it is possible or not
Lots of thanks
Let's start!
Changing only the baud rate from 115200 to 1200 and adding some print for debug (same port, /dev/ttyUSB0)
Error parsing number of modules... 🤔 So now I have changed the address from 2 to 1 in _getvalues(): From this:
To this
No what I get is:
🤔 I think we have not caught the full response. So I updated the timeout from 2 to 3. Now I get:
This response looks quite longer, but same error. I am thinking in changing the self.s.read() for something like _readuntil('\r') or something similar, I mean reading until certain byte value, to detect the end of the frame and avoid receiving garbage. What do you think? Have you seen something I can not see?
I would like learning to break down the response. I have read the protocol PDF but I will need some detailed example