Frankkkkk / python-pylontech

Python lib to talk to pylontech lithium batteries 🔋 (US2000, US3000, ...) using RS485
MIT License
67 stars 32 forks source link

Charge and Discharge current division factors #31

Closed rotorman closed 1 year ago

rotorman commented 1 year ago

According to my tests with US5000, the following lines: https://github.com/Frankkkkk/python-pylontech/blob/c45555ce9065c98ba19256dbeb180d7f44d6b6a1/pylontech/pylontech.py#L56 and https://github.com/Frankkkkk/python-pylontech/blob/c45555ce9065c98ba19256dbeb180d7f44d6b6a1/pylontech/pylontech.py#L62 should divide with 10 and not with 100 to get the output in A (Ampers). Although the divisor 100 is written in the official Pylontech RS485 protocol description to parse this query's response, I do believe this to be wrong. Would be sweet if anyone could double check. Thx.

Uksa007 commented 1 year ago

Hi,

Just wondering why you think it's 10 not 100?

I'm implementing this in a project and just trying to figure out what is right, the Pylon Protocol document(100) or 10?

Can you elaborate why you think it's 10?

edit also, the get values current, is 10 when the Protocol says 100, again which is righ? https://github.com/Frankkkkk/python-pylontech/blob/c45555ce9065c98ba19256dbeb180d7f44d6b6a1/pylontech/pylontech.py#L88

https://github.com/Frankkkkk/python-pylontech/blob/c45555ce9065c98ba19256dbeb180d7f44d6b6a1/pylontech/pylontech.py#L35

Thanks

rotorman commented 1 year ago

On brand new US5000, which according to specs has +/-100A charge/discharge limits, the output of _get_systemparameters 0x47 query 7e | 32 30 | 30 32 | 34 36 | 34 37 | 30 30 30 30 | 46 44 41 37 | 0d is: 7e | 32 30 | 30 32 | 34 36 | 30 30 | 42 30 33 32 | 31 31 | 30 45 34 32 | 30 42 45 41 | 30 41 46 30 | 30 44 30 33 | 30 41 34 37 | 30 33 45 38 | 44 32 46 30 | 42 33 42 30 | 41 37 46 38 | 30 44 30 33 | 30 41 34 37 | 46 43 31 38 | 46 32 37 45 | 0d that decodes to:

7e: SOI
32 30: VER 0x20
30 32: ADR: 0x02
34 36: CID1: 0x46
30 30: RTN = 0 = normal
42 30 33 32: Length 0x032 = 50, Checksum 0x42
31 31: INFOFLAG 0x11 = Exist unread switching value change, exist unread alarm value change
30 45 34 32: Cell high voltage limit 0x0E42 = 3650 = 3.65 V
30 42 45 41: Cell low voltage limit 0x0BEA = 3050 = 3.05 V
30 41 46 30: Cell under voltage limit
30 44 30 33: Charge high temperature limit
30 41 34 37: Charge low temperature limit
30 33 45 38: Charge current limit = 0x03E8 = 1000 -> 100.0 A
44 32 46 30: Module high voltage limit
42 33 42 30: Module low voltage limit
41 37 46 38: Module under voltage limit
30 44 30 33: Discharge high temperature limit
30 41 34 37: Discharge low teperature limit
46 43 31 38: Discharge current limit 0xFC18 = -1000 -> -100.0 A
46 32 37 45: Checksum
0d: EOI = CR
Uksa007 commented 1 year ago

Interesting, could you possibly send these and let me know what the reply is?

7E:32:30:30:32:34:36:34:32:45:30:30:32:30:32:46:44:33:33:0D //get values fixed 7E:32:30:30:32:34:36:39:32:45:30:30:32:30:32:46:44:32:45:0D //get management info 7E:32:30:30:32:34:36:36:31:45:30:30:32:30:32:46:44:33:32:0D //get values float?

Makes it hard when the protocol specification document is wrong!

rotorman commented 1 year ago

get management info 7e | 32 30 | 30 32 | 34 36 | 39 32 | 45 30 30 32 | 30 32 | 46 44 32 45 | 0d answers: 7e | 32 30 | 30 32 | 34 36 | 30 30 | 42 30 31 34 | 30 32 | 44 30 30 32 | 41 46 43 38 | 30 30 30 30 | 46 43 45 30 | 34 30 | 46 39 33 46 | 0d which interestingly lists discharge current limit of -80A that does not match the _get_systemparameters output above. Also note that the charge current limit is 0.

Decoding:

7e: SOI
32 30: VER 0x20
30 32: ADR 0x02
34 36: CID1 0x46 (const)
30 30: RTN = 0 = normal
42 30 31 34 = LENGTH = 0x14 = 20, Checksum 0x42
 INFO:
30 32: Command value 0x02
  Charge and discharge management value:
44 30 30 32: Charge voltage limit (uint16) 0xD002 = 53250 / 1000 = 53.25V
41 46 43 38: Discharge voltage limit (uint16) 0xAFC8 = 45000 / 1000 = 45.0V
30 30 30 30: Charge current limit (uint16) 0x0 = 0 / 10 = 0.0A ???
46 43 45 30: Discharge current limit (int16) 0xFCE0 = -800 / 10 = -80.0A ???
34 30: Charge, discharge status: 0x40, bit 7 - charge enable, bit 6 discharge enable, bit 5 charge immediately, bit 4 charge immediately, bit 3 full charge request
46 39 33 46: CHKSUM 0xF93F
0d: EOI
Uksa007 commented 1 year ago

Thanks for the decode!

Wow that's a bit strange, are you using RS232 or RS485 port, they can sometimes give different responses?

rotorman commented 1 year ago

I am using RS-485. _get_valuesfixed 7e | 32 30 | 30 32 | 34 36 | 34 32 | 45 30 30 32 | 30 32 | 46 44 33 33 | 0d gives me: 7e | 32 30 | 30 32 | 34 36 | 30 30 | 42 30 37 45 | 31 31 | 30 32 | 30 46 | 30 44 36 41 | 30 44 38 32 | 30 44 38 36 | 30 44 38 34 | 30 44 38 32 | 30 44 38 36 | 30 44 38 35 | 30 44 38 32 | 30 44 38 37 | 30 44 38 32 | 30 44 38 35 | 30 44 38 35 | 30 44 37 46 | 30 44 36 44 | 30 44 38 35 | 30 36 | 30 42 46 46 | 30 42 43 43 | 30 42 44 34 | 30 42 44 37 | 30 42 44 41 | 30 42 43 46 | 30 30 30 30 | 43 41 38 39 | 46 46 46 46 | 30 34 | 46 46 46 46 | 30 30 30 30 | 30 31 38 36 41 30 | 30 31 38 36 41 30 | 45 31 34 46 | 0d

that decodes to:

7e SOI
32 30: VER "20"
30 32: ADR "02" = Master battery
34 36: CID1: 0x46 = battery data
30 30: RTN: 0 = normal
42 30 37 45: LENGTH = 0x07E = 126, Checksum 0xB
     from here INFO field:
31 31: INFOFLAG 0x11 = Exist unread switching value change, exist unread alarm value change
      from here DATAI field:
30 32: Command value: 0x02
       from here Data of battery:
30 46: Number of cell = 0x0F = 15
30 44 36 41: Cell 1 voltage 0x0D6A (int16) = 3434 / 1000 = 3.434 V
30 44 38 32: Cell 2 voltage 0x0D82 = 3.458 V
30 44 38 36: Cell 3
30 44 38 34: Cell 4
30 44 38 32: Cell 5
30 44 38 36: Cell 6
30 44 38 35: Cell 7
30 44 38 32: Cell 8
30 44 38 37: Cell 9
30 44 38 32: Cell 10
30 44 38 35: Cell 11
30 44 38 35: Cell 12
30 44 37 46: Cell 13
30 44 36 44: Cell 14
30 44 38 35: Cell 15 0x0D85 = 3.461V
30 36: Number of temperatures 0x06 -> 6
30 42 46 46: Temperature of BMS board 0x0BFF (int16) = 3071 / 10 °K = 307.1°K = (-273,1) = 33.4°C
30 42 43 43: Avg. temp. of cell-pack1 0x0BCC (int16) = 302.0 - 273.1 = 28.9°C
30 42 44 34: Avg. temp. of cell-pack2
30 42 44 37: Avg. temp. of cell-pack3
30 42 44 41: Avg. temp. of cell-pack4
30 42 43 46: Avg. temp. of cell-pack5
30 30 30 30: Current 0x0 (int16) = 0 /10 [A]. Positive value is charge, negative value denotes discharge
43 41 38 39: Module voltage (uint16) 0xCA89 = 51849 / 1000 = 51.849 V
46 46 46 46: Remain capacity1: 0xFFFF (this field is unused for batteries with >= 65 Ah)
30 34: User defined items: 0x04 -> battery capacity > 65 Ah
46 46 46 46: Module total capacity1: 0xFFFF (this field is unused for batteries with >= 65 Ah)
30 30 30 30: Cycle number 0
30 31 38 36 41 30: Remain capacity2 (uint24): 0x0186A0 = 100000 / 1000 = 100.0 Ah
30 31 38 36 41 30: Module total capacity2 (uint24): 0x0186A0 = 100000 / 1000 = 100.0 Ah
45 31 34 46: CHKSUM 0xE14F = 57679
0d EOI = CR
rotorman commented 1 year ago

7E:32:30:30:32:34:36:36:31:45:30:30:32:30:32:46:44:33:32:0D //get values float?

Do you have docu for command 0x61 _get_valuesfloat parsing? The RS-485 protocol doc V3.3 does not list this command.

rotorman commented 1 year ago

I had a look at BatteryView and there the charge value 0 A and the discharge value -80 A are listed behind "System Advise charge current (A)" and "Advise discharge current (A)" which now then makes sense, as the battery is full and thus no charge is required at the moment and system recommends to limit discharge to -80A, whereas the BMS hard limit is -100A.

$$
pylon_debug>pwrsys 1
@
 Recommend chg voltage    : 53250    mV
 Recommend dsg voltage    : 45000    mV
 Recommend chg current    : 0        mA
 Recommend dsg current    : -80000   mA
Command completed successfully

The last command was via Console (RS-232C, 115200baud 8N1) and not via RS-485.

rotorman commented 1 year ago

I am now even more confident that the division needs to be /10 instead of /100 as in first post of this issue, as when issuing info command via console (RS-232C), I get back from BMS in ASCII (snippet):

Max Dischg Curr     : -100000mA
Max Charge Curr     : 100000mA

meaning +/- 100A and value 0x03E8 = 1000 needs to be divided thus with 10 to get a value in Amperes.