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

Tian Power (Revov) BMS Integration #14

Closed
6 tasks
NicholasHerbst opened this issue Apr 26, 2021 · 24 comments
Closed
6 tasks

Tian Power (Revov) BMS Integration #14

NicholasHerbst opened this issue Apr 26, 2021 · 24 comments
Labels
enhancement New feature or request

Comments

@NicholasHerbst
Copy link

NicholasHerbst commented Apr 26, 2021

Integrate the Tian Power BMS via RS485 to Victron Venus OS-equipped devices.

  • SOC
  • Battery voltage
  • Charge/discharge current
  • Temprature
  • Min/max cell voltages
  • protection notifications

It uses CRC-16-ANSI function

def calc_crc(data):
    crc = 0xFFFF
    for pos in data:
        crc ^= pos 
        for i in range(8):
            if ((crc & 1) != 0):
                crc >>= 1
                crc ^= 0xA001
            else:
                crc >>= 1
    return crc

@Louisvdw
Copy link
Owner

@NicholasHerbst are the communications protocol available for these BMS? I do not see anything on Tian Power's website.

@Louisvdw Louisvdw added the enhancement New feature or request label May 16, 2021
@NicholasHerbst
Copy link
Author

@Louisvdw yes, I have access to the communication protocol. Where would be the most appropriate place to share this document?

@Louisvdw
Copy link
Owner

@NicholasHerbst You should be able to attach the doc to a comment here.

@NicholasHerbst
Copy link
Author

@csloz
Copy link
Contributor

csloz commented May 2, 2022

I've started some work on this myself.
The protocol pdf appears to be completely incorrect for the TianPower BMS - at least from what i'm seeing so far.

Added some progress here -
https://powerforum.co.za/topic/4044-the-dreaded-revovs-on-sale/page/3/

I need to work out where some of the variables sit tomorrow.
Have identified 4 commands so far.

@Louisvdw
Copy link
Owner

Louisvdw commented May 3, 2022

Nice work @csloz
Once you have something that can read the basics, create a branch and do a pull request.

@csloz
Copy link
Contributor

csloz commented May 3, 2022

Will do.

It's progressing fast. Can read the battery voltage, and individual cells now, although some of the details are still MIA.
Having fun working it out though.

Take a look at the thread on powerforum for progress. (linked above)

Ideally I need someone else to do some testing to make sure params are correct. @NicholasHerbst are you up for some beta testing?

@csloz
Copy link
Contributor

csloz commented May 3, 2022

Ok, have forked it, and made a pull request.

It's a BETA version. Will still make some updates as I'm missing some data still (need to work out where it sits).
It's also extremely chatty.

Example logs below;

2022-05-03 17:41:50.031904500 WARNING:SerialBattery:Modbus Address: 124
2022-05-03 17:41:50.032398500 WARNING:SerialBattery:Modbus Type : 1
2022-05-03 17:41:50.032860500 WARNING:SerialBattery:Modbus Command: 1
2022-05-03 17:41:50.033304500 WARNING:SerialBattery:Modbus PackLen: 118
2022-05-03 17:41:50.033791500 WARNING:SerialBattery:Modbus Packet : [7C:01:01:76:01:10:0C:F2:0C:F4:0C:F4:0C:F5:8C:F4:0C:F3:8C:F5:0C:F5:0C:F4:0C:F4:0C:F6:8C:FB:0C:F3:0C:F4:0C:F5:0C:F7:02:01:77:A2:03:01:24:7E:04:01:46:50:05:03:00:48:00:48:20:49:06:05:00:00:00:02:00:00:00:00:00:00:07:01:00:85:08:01:14:BA:09:01:27:10:0A:01:00:00:0B:01:00:00:83:00:0C:01:00:00:37:AE:0D:01:00:40:00:00:0E:01:00:40:00:00:0F:01:00:1A:3A:1B:10:01:00:09:57:AD:DE:0D]
2022-05-03 17:41:50.034225500 WARNING:SerialBattery:== Modbus packet good ==
2022-05-03 17:41:50.034727500 WARNING:SerialBattery:Voltage Data: [53.06v]
2022-05-03 17:41:50.035194500 WARNING:SerialBattery:Battery Cycles: [133]
2022-05-03 17:41:50.035660500 WARNING:SerialBattery:Battery Capacity: [180.0Ah]
2022-05-03 17:41:50.036118500 WARNING:SerialBattery:Cell count: [16]
2022-05-03 17:41:50.036595500 WARNING:SerialBattery:Raw Cell Data: [0C:F2:0C:F4:0C:F4:0C:F5:8C:F4:0C:F3:8C:F5:0C:F5:0C:F4:0C:F4:0C:F6:8C:FB:0C:F3:0C:F4:0C:F5:0C:F7]
2022-05-03 17:41:50.037137500 WARNING:SerialBattery:Cell [01] 3.314v 0x0CF2 0b110011110010
2022-05-03 17:41:50.037652500 WARNING:SerialBattery:Cell [02] 3.316v 0x0CF4 0b110011110100
2022-05-03 17:41:50.038165500 WARNING:SerialBattery:Cell [03] 3.316v 0x0CF4 0b110011110100
2022-05-03 17:41:50.038666500 WARNING:SerialBattery:Cell [04] 3.317v 0x0CF5 0b110011110101
2022-05-03 17:41:50.039182500 WARNING:SerialBattery:Cell [05] 3.608v 0x8CF4 0b1000110011110100
2022-05-03 17:41:50.039686500 WARNING:SerialBattery:Cell [06] 3.315v 0x0CF3 0b110011110011
2022-05-03 17:41:50.040260500 WARNING:SerialBattery:Cell [07] 3.608v 0x8CF5 0b1000110011110101
2022-05-03 17:41:50.040769500 WARNING:SerialBattery:Cell [08] 3.317v 0x0CF5 0b110011110101
2022-05-03 17:41:50.041383500 WARNING:SerialBattery:Cell [09] 3.316v 0x0CF4 0b110011110100
2022-05-03 17:41:50.041904500 WARNING:SerialBattery:Cell [10] 3.316v 0x0CF4 0b110011110100
2022-05-03 17:41:50.042409500 WARNING:SerialBattery:Cell [11] 3.318v 0x0CF6 0b110011110110
2022-05-03 17:41:50.042922500 WARNING:SerialBattery:Cell [12] 3.609v 0x8CFB 0b1000110011111011
2022-05-03 17:41:50.043424500 WARNING:SerialBattery:Cell [13] 3.315v 0x0CF3 0b110011110011
2022-05-03 17:41:50.043990500 WARNING:SerialBattery:Cell [14] 3.316v 0x0CF4 0b110011110100
2022-05-03 17:41:50.044473500 WARNING:SerialBattery:Cell [15] 3.317v 0x0CF5 0b110011110101
2022-05-03 17:41:50.044978500 WARNING:SerialBattery:Cell [16] 3.319v 0x0CF7 0b110011110111
2022-05-03 17:41:50.045448500 WARNING:SerialBattery:Cell Total: 53.94v

@csloz
Copy link
Contributor

csloz commented May 4, 2022

I realised I'm a bit dof just now.

Their data format is quite straightforward - I just didn't notice that till now.

Sample info packet:

[7C:01:01:76:01:10:8D:20:0D:17:8D:21:0D:2F:8D:3B:0D:32:CD:E3:0D:B3:8D:23:0D:0D:8D:24:0D:24:0D:11:8D:21:0D:18:8D:21:02:01:75:30:03:01:27:10:04:01:46:50:05:03:00:49:00:48:20:4B:06:05:00:00:10:10:00:00:00:00:00:01:07:01:00:85:08:01:15:24:09:01:27:10:0A:01:00:01:0B:01:00:00:83:00:0C:01:00:00:37:AE:0D:01:00:40:00:00:0E:01:00:40:00:00:0F:01:00:1A:3A:04:10:01:00:09:57:AD:BA:0D]

Once I spotted that they seperate out the packet info with byte/length pairs suddenly the data makes much more sense.

7C:01:01:76 (bus/cmd/req/length)
Then from there its simply
01:10 with length 16 (10 in HEX) is our battery cell info
02:01 75:30 = 3000 -> 30
03:01 27:10 = 10000 ->100
04:01 46:50 = 18000 ->180
05:03 00:49 00:49 20:4A = 3 pairs? 73/73/8266 ??
06:05 00:00 10:10 00:00 00:00 00:01 Alarm bits
07:01 00:85 = 133 -> Cycles
08:01 15:3C = 5436 -> Volts (54.36)
09:01 27:10 = 10000 -> 100
0A:01 00:01 = 1
0B:01 00:00 83:66 = 0, 33670 (3.367?)
0C:01 00:00 37:AE = 0, 14254 (0.14254?)
0D:01 00:40 00:00 = 64, 0
0E:01 00:40 00:00 = 64, 0
0F:01 00:1A 4A:3F = 26, 190007 (unsigned? signed, tbd...)
10:01 00:09 57:AD = 9, 22445 (22.445?)

I'll have a play looking at the byte pair values in word/float signed/unsigned etc to see if the weirder values make more sense, but, by George, I think he's got it!

@NicholasHerbst
Copy link
Author

NicholasHerbst commented May 4, 2022 via email

@csloz
Copy link
Contributor

csloz commented May 6, 2022

Haven't had a chance to do any code changes since i noticed the packet format, but the code is up at the revov branch in my github if you want to pull it to test.

I need to rewrite the parser code to correctly interpret each data size. Will hopefully get time next week. Its usable as is, and seems pretty stable, even if missing some values still. I've had it running on mine for almost a week now.

https://github.com/csloz/dbus-serialbattery/tree/revov

@ghost
Copy link

ghost commented Jun 23, 2022

I also have a Revov battery with the BMS supplied by them and wish to, specifically, get the SoC data fed into the Victron Cerbo GX.
If there is anything I can help with, kindly let me know.
I have a Raspberry Pi with a 2-CH_RS485_HAT mounted on it. So, if I get the right Python script, I can perhaps use that to “extract” the right protocol.

@ghost
Copy link

ghost commented Jun 24, 2022

I am trying to find answers to an issue I picked up since the installation of the dbus-serialbattery system and upgrading the Cerbo GX Firmware to get the former to work.

Yesterday, due to the cloud cover and low charging rate through the MPPT and the looming load shedding, I wanted to charge the batteries (Rovov) through the inverter and thus started the Scheduled Charge. I immediately noticed that the charging rate was very low compared to what I witnessed before. I unplugged the USB cable from the battery’s BMS hoping that would solve the issue, without any success. I then upgraded the inverter’s firmware, again with no success.

This morning, I decided to look for reasons and the first I came across was the “charge current control management” under the features. In there it is said that the “CCCM limits the current when the battery is close to full or close to empty. When your battery is full, the reduced charge current will give the balancers in your BMS time to work When your battery is close to empty the reduced discharge current will limit that a sudden large load will pull your battery cells below their protection values. The CCCM limits the charge/discharge current depending on the SOC - between 99% - 100% => 5A charge - between 95% - 98% => 1/4 Max charge - between 91% - 95% => 1/2 Max charge”.

With the Revov battery SoC remaining at 100%, I am wondering if that is the reason for poor rate of charge?

@Louisvdw
Copy link
Owner

It would be limiting your charge yes.
In your utils.py go change CCCM_ENABLE = False around line 25 and restart to see if that helps. That setting in still experimental.

@ghost
Copy link

ghost commented Jun 24, 2022

I made the changes in the utils.py and restarted the system through by running “sh /data/etc/dbus-serialbattery/installrelease.sh” and rebooted the Cerbo GX. The charging then worked as expected until I plugged the USB back in. I then got a low voltage alarm on the inverter which I had to clear before restarting the entire system (inverter and Cerbo GX) for it to work. So, now the USB cable is unplugged wating for the new revov.py script.

I want to repeat my offer. If there is anything I can help with, let me know.

@Louisvdw
Copy link
Owner

Anyone want to test a new beta please https://github.com/Louisvdw/dbus-serialbattery/releases/tag/v0.12b4
We've added a new battery driver that seem to be the same BMS as the Revov batteries. In this beta above the revov driver is disabled and the LifePower enabled. Please give it a test with the Revov batteries and check if it works and if more data is available . @bertiebez @csloz

@TianPower
Copy link

Hello, I’m the online sales manager of Tian Power, if you need, I can call our technical experts to help you. and if you have any questions about our products, please feel free to contact me!

@Louisvdw
Copy link
Owner

Louisvdw commented Jan 12, 2023

@TianPower what could really help would be if you have a BMS that you could send that I can test with. It's not easy solving problems virtually.
It does not need to be big or new. It just need to run the same protocols.
You can send me a PM at energytalk.co.za and we can chat.

@pchiquit
Copy link
Contributor

@TianPower I guess having the documented BMS protocol would also help. The current implementation is based on the reverse engineering (as documented here #212 ). Having the official protocol would help us to improve the implementation and add more features.

@mike-marcacci
Copy link

@TianPower I've been working on a prometheus exporter for your BMS, largely using the work done here and on related projects to help reverse engineer the communication protocol. So far, I haven't been able to figure out the checksum algorithm, and have resorted to hardcoding messages. To second @pchiquit's request: if you could publish the communication protocol, this would be immensely helpful.

Thanks in advance (and also to everybody here whose work has given me a place to start)!

@TianPower
Copy link

I'm very sorry not to reply your message in time, now I will follow up your questions ,Can you provide the model of the BMS? @mike-marcacci Do you mean Upper computer?

@mike-marcacci
Copy link

mike-marcacci commented Mar 13, 2023

Thanks @TianPower! "Upper computer" may be what I mean by checksum, I'm not entirely sure; @slim-bean put together what is probably the most useful document I've found here, from his reverse-engineering efforts.

When observing requests made by the Windows tool supplied by EG4, the second-to-last byte contains a value that I haven't been able to predict, and I assumed was some form of checksum, despite it not matching any CRC algorithm I've tried.

For example, requests for current battery metrics appear to be the following, based on the address of the queried battery:

Start Byte Address Command Length? Checksum? End Byte
7E 00 01 00 FC OD
7E 01 01 00 FE OD
7E 02 01 00 FC OD
7E 03 01 00 FE OD
7E 04 01 00 F8 OD
7E 05 01 00 FE OD

I'm not entirely sure what the specific model of the BMS is – it's the one used in the EG4 LifePower4 batteries. A video showing the battery teardown reveals some numbers on the main board that didn't mean anything to me, but might to you:

S/N:
RoHS
05J11
QT_PBMS_EPBMS_48100_16S100Z0-V2.0.7

EDIT: the below questions appear to be somewhat answered by this post.

I do have a number of other questions that I'm struggling to answer via reverse-engineering, but which would probably be covered in a communication protocol documentation. For example, group 4 of the response appears to return the battery's "full capacity" in cAh, but this differs from what the UI displays. (In my case the message on one of my batteries reports 101.32Ah while the UI reports what I believe is a truncated 100.00Ah.) It makes sense that the UI might try and make some "friendlier" numbers, but is my inference that this is "full capacity" even correct?

Similarly, group 3 appears to contain either the state-of-charge in percentage * 100, or the "remaining capacity" in cAh – both of which report identically on the UI. If the former assertion about "full capacity" is correct, though, then these numbers shouldn't actually be the same, and it's unclear which value this group actually represents.


Apologies for hijacking this thread a bit, but thanks so much for your time @TianPower – you all are making some great products, and I'm looking forward to getting better visibility into our battery performance!

@cybertza
Copy link

Hey Gents,

What was the max amount of batteries you guys were able to integrate with this mod?

And i furthermore assume no additional hardware is required besides the USB-RS485?

@LilDucky
Copy link

LilDucky commented Sep 11, 2024

I have a couple of different Tian Power BMS and can assist with testing / data collection. The BMS are both 48V 15/16S, one is 50AH and other is 100Ah. They seem to have a charge / discharge limiting board installed on them.
I have used the Lifepower driver with some success; mainly the temperature group is har coded for 6 values and the 50Ah model only has 4. The protocol reflects this correctly, sand I kludged my copy to work correctly.
The next issue is that when a cell OV warning comes up it displays as 19-20V ish because only the top bit is masked for alarms. AFAIK the two top bits need to be masked, I think that the top bit is OV alarm, and the next bit is warning. I am in the process of rebuilding the 100Ah battery and can test with that soon. I may be able to put together a 50Ah unit with less cells in parallel for testing.

Please let me know if this has been of assistance and if I can do anything else.
Simon

ETA
Just found my earlier work on decoding the protocol.

LiPo Protocol.pdf

I also have a few different copies of the OEM windows software

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

8 participants