-
-
Notifications
You must be signed in to change notification settings - Fork 21
Binding for Growatt SPH10000-TL3-BH-UP CAN protocol #85
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
Comments
Yeah, that's not a protocol I've seen before. Have you tried to contact Growatt support and as for the CAN specification? |
Many have tried but they are extremly tight lipped. |
Let me fix that for you. |
and bonus track > all possible errors |
What kind of magic superpowers do you possess? |
Probably all kind of magic, but I still need to "kick" my self to start learning how CAN communication and translation works inclusing python and all that fancy stuff. I worked in R&D and testing equipment with all kind of brands. Equipment like IFR, Agilent, Yello, Keyence and many more. Whirpool, Asko, Gorenje, Arçelik, Candy, Bosch.. I work very closely with growatt engineering team since I start working for company that fix issues :) |
Do you have the low voltage protocol also, the version I have is half chinese half english? |
@romanbetwo sweet! I will check them out later and provide a new binding for the Growatt HV over the holidays |
@ErikssonPer, @romanbetwo FYI: I've implemented the Growatt HV and LV CAN bindings for inverter and BMS and are ready for further testing 😉 |
@ai-republic But when I started it the following happens, |
I will do the test tomorrow, but it looks like an issue |
@ErikssonPer oh, thanks for finding that. It should be fixed now. Please Clean install again. Thanks! |
okay so , I've been playin arround and finaly figure out that .. i have bad HAT for this application.. 2xRS 1xCAN .. however I need 2xCAN... the log >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2025-01-08 17:21:47.127 | DEBUG | Thread-3 | ocol.can.JavaCANPort:115 | CAN frame sending: Buffer (HEX): [0x00, 0x00, 0x31, 0x10, 0x08, 0x00, 0x00, 0x00, 0x09, 0x24, 0x00, 0xC8, 0xFF, 0x38, 0x00, 0x00] 2025-01-08 17:21:47.129 | DEBUG | Thread-3 | verter.core.Inverter:188 | Calling inverter plugin (onSend): SimulatedBatteryPackPlugin 2025-01-08 17:21:47.135 | DEBUG | Thread-3 | ocol.can.JavaCANPort:115 | CAN frame sending: Buffer (HEX): [0x00, 0x00, 0x31, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] 2025-01-08 17:21:47.138 | DEBUG | Thread-3 | verter.core.Inverter:188 | Calling inverter plugin (onSend): SimulatedBatteryPackPlugin 2025-01-08 17:21:47.141 | DEBUG | Thread-3 | ocol.can.JavaCANPort:115 | CAN frame sending: Buffer (HEX): [0x00, 0x00, 0x31, 0x30, 0x08, 0x00, 0x00, 0x00, 0x07, 0xD0, 0x00, 0x00, 0x00, 0xFA, 0x18, 0x64] 2025-01-08 17:21:47.496 | INFO | Thread-2 | verter.BmsToInverter:268 | Reading BMS #1 NONE on none... 2025-01-08 17:21:47.501 | INFO | Thread-2 | verter.BmsToInverter:390 | BMS alarms: 2025-01-08 17:21:48.150 | DEBUG | Thread-3 | verter.core.Inverter:150 | Inverter GROWATT_HV_CAN received: Buffer (HEX): [0x00, 0x42, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06] 2025-01-08 17:21:48.151 | DEBUG | Thread-3 | verter.core.Inverter:156 | Calling inverter plugin (onReceive): SimulatedBatteryPackPlugin 2025-01-08 17:21:48.156 | DEBUG | Thread-3 | verter.core.Inverter:171 | Calling inverter plugin (onBatteryAggregation): SimulatedBatteryPackPlugin 2025-01-08 17:21:48.163 | DEBUG | Thread-3 | InverterCANProcessor:205 | Sending alarms: Buffer (HEX): [0x00, 0x00, 0x31, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] 2025-01-08 17:21:48.166 | DEBUG | Thread-3 | InverterCANProcessor:225 | Sending battery status: Buffer (HEX): [0x00, 0x00, 0x31, 0x30, 0x08, 0x00, 0x00, 0x00, 0x07, 0xD0, 0x00, 0x00, 0x00, 0xFA, 0x18, 0x64] 2025-01-08 17:21:48.169 | ERROR | Thread-3 | InverterCANProcessor:78 | Error creating send frames: 2025-01-08 17:21:48.178 | DEBUG | Thread-3 | ocol.can.JavaCANPort:115 | CAN frame sending: Buffer (HEX): [0x00, 0x00, 0x31, 0x10, 0x08, 0x00, 0x00, 0x00, 0x09, 0x24, 0x00, 0xC8, 0xFF, 0x38, 0x00, 0x00] 2025-01-08 17:21:48.179 | DEBUG | Thread-3 | verter.core.Inverter:188 | Calling inverter plugin (onSend): SimulatedBatteryPackPlugin 2025-01-08 17:21:48.185 | DEBUG | Thread-3 | ocol.can.JavaCANPort:115 | CAN frame sending: Buffer (HEX): [0x00, 0x00, 0x31, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] 2025-01-08 17:21:48.187 | DEBUG | Thread-3 | verter.core.Inverter:188 | Calling inverter plugin (onSend): SimulatedBatteryPackPlugin 2025-01-08 17:21:48.192 | DEBUG | Thread-3 | ocol.can.JavaCANPort:115 | CAN frame sending: Buffer (HEX): [0x00, 0x00, 0x31, 0x30, 0x08, 0x00, 0x00, 0x00, 0x07, 0xD0, 0x00, 0x00, 0x00, 0xFA, 0x18, 0x64] ^C2025-01-08 17:21:48.476 | INFO | Thread-1 | verter.BmsToInverter:426 | Shutting down BMS and inverter threads...FAILED Different storry If I set for pylon -HV CAN it start to charge battery ( i know its dangerous but I am okay with that) end of storry Another try > SPH CAN > Batt can > parallel CAN dongle > For some resason I was told that my battery should have Pylon HV can but I am not able to read much from it.... When I connect battery CAN > SPH CAN direct I am able to finaly scan some data with USB>CAN.. which does not look like specs ...
With this configuration: todo: get a 2x can hat /current is usable for MOD or huawei |
Ran a quick test with it connected inbetween the inverter on can0 and battery on can1. The heartbeat message that's sent out on can1 to the bms looks like this, So the battery won't respond with any data. It looks like an error is reported in the log. |
So I'll try to answer one by one 😉
PS: When doing tests please disable the webserver as it makes the log file hard to read 😉 |
Will do sir 🫡 |
I'm not having any luck, If I start the App it wont send anything out on either. Extract from log, 2025-01-18 18:22:46.010 | INFO | main | til.SystemProperties:22 | Loading config.properties from: config/config.properties |
hmm, it looks like its something with your CAN configuration for your CAN adapter is not correctly set up. Or its not (yet) started properly. The error message comes straight from the SocketCAN unix module. |
Did a new test today, setup as BMS on CAN1 and inverter on CAN0 Data sent out on CAN1 with 1 second interval So it is able to send but fails to read. Log, ./start.sh2025-01-20 22:31:02.490 | INFO | main | til.SystemProperties:22 | Loading config.properties from: config/config.properties2025-01-20 22:31:02.574 | DEBUG | main | ging.LoggerProviders:152 | Logging Provider: org.jboss.logging.Log4j2LoggerProvider2025-01-20 22:31:04.504 | INFO | main | ore.InverterProducer:76 | Created inverter binding: GROWATT_HV_CAN2025-01-20 22:31:04.612 | INFO | main | verter.core.Inverter:53 | Using plugins: []2025-01-20 22:31:04.668 | INFO | main | core.BMSListProducer:105 | Intialized BMS #1[GROWATT_HV_CAN] on port can12025-01-20 22:31:04.687 | INFO | main | verter.BmsToInverter:261 | Starting BMS receiver...2025-01-20 22:31:04.692 | INFO | Thread-2 | verter.BmsToInverter:268 | Reading BMS #1 GROWATT_HV_CAN on can1...2025-01-20 22:31:04.696 | INFO | Thread-2 | toinverter.core.Port:111 | Opening can1 ...2025-01-20 22:31:04.748 | INFO | Thread-2 | toinverter.core.Port:113 | Opening port can1 SUCCESSFUL2025-01-20 22:31:04.753 | DEBUG | Thread-2 | attHVBmsCANProcessor:115 | SEND: Buffer (HEX): [0x00, 0x00, 0x31, 0x11, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] Ifconfig while app is running shows both can ports active can1: flags=193<UP,RUNNING,NOARP> mtu 72 When testing with a short simple python script both can0 and can1 work for both send and recieve. |
This part is the crucial part: This implies that the socket it not available. So either in use, not initialized yet, or not configured correctly. |
It's a waveshare 2 channel fd can hat Can't figure it out, everything seems to check out and I can send and recieve on both channels using command line or a simple python script. And the app is able to send |
Gonna try to use it in legacy mode and see what that does. |
Maybe also try to re-install the Waveshare hat on a fresh Raspian OS installation and reconfigure it without adding any other libraries like the python scripts etc. |
Both channels are set to 500kbit and I can log data being sent from both the inverter and bms with candump so it's correct. I noticed something today, for fun I ran the configurator again and set it to pylon hv bms and growatt hv inverter. With those settings it sends out a different heartbeat to the bms, (ID 4200) which is correct for pylon protocol. Remember it sends this when setup as growatt_hv: But it doesn't show any errors in the log now, jevlar@rpi:~ $ ./start.sh 2025-01-29 20:05:59.272 | DEBUG | Thread-2 | ocol.can.JavaCANPort:115 | CAN frame sending: Buffer (HEX): [0x00, 0x42, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] 2025-01-29 20:05:59.277 | DEBUG | Thread-2 | ocol.can.JavaCANPort:76 | CAN frame read... 2025-01-29 20:06:00.282 | INFO | main | verter.BmsToInverter:290 | Starting inverter sender... Could this be a clue? |
I don't get who sends the 0x3111 ID? Neither the PYLON_HV_CAN nor the GROWATT_HV_CAN bindings send these IDs |
Trust me, it's sent with a 1 second interval as soon as I start the app with it setup for Growatt hv BMS 22:31:04.668 | INFO | main | core.BMSListProducer:105 | Intialized BMS #1[GROWATT_HV_CAN] on port can1 |
Good evening, So config is Growatt_HV_CAN for BMS, NONE for Inverter. Using that with Log-Level Info as is default it looked good, no error in the log - but no data visible via Web-Server. Setting Log-Level to Debug revealed the following Problem:
Do you have an idea what could be wrong there ? BTW, I've not seen other errors so far, just the lines above repeating for every received frame, regardless what ID the frames have (if you need full log I can provide it) Thank you for you great work! |
@cmax1-gmx I fixed the NPE. Please let me know if it works for you and also please attach the log file again. I'm curious what command you receive that is not mapped |
@ErikssonPer I had a look again at the code. Yes, it will send out the 0x3111 to communicate with the second BMS.
Could you try to configure your BMS ID to 0 please? |
Looks better, but still a problem:
as before the result for all IDs is identical. This is what is logged at the end of one cycle:
IDs seen: 0x3010 0x3020 0x3030 0x3110 0x3120 0x3130 0x3140 0x3150 0x3160 0x3170 0x3180 0x3190 0x3200 0x3220 0x3230 0x3240 0x3250 0x3260 0x3270 0x3280 0x3F00 Full Log: |
an update: it seems that the problem is in line 151 in File GrowattHVBmsCANProcessor.java
After changing that to
I get correct results (at least these look good to me) for most of the defined CAN IDs with exception of 0x3110, 0x3160 and 0x3170: 0x3110 - BufferUnderflowException For details see attached partial Log (I've added Debug-Log-Enttries for the processed Command too): The other IDs that I've seen as listed in my post above are not processed at the moment as they are not defined. I hope my infos can help - I've only very basic java-skills so I'm not able to do more then trying to help identifying the problem. |
@cmax1-gmx , @ErikssonPer, The issue with the initial readings of 0x3010-0x3030 I also covered 😄 |
@ai-republic - have you overlooked my comment above related to the problem in File GrowattHVBmsCANProcessor.java or was it intentionally not to change that ?
Without that change I did not get any message parsed. Otherwise good news - no more exceptions thrown, the IDs defined are parsed. Some more comments about the values received: Looking at the Line printed in the log
it is obvious that the values are not correct (LiFePo Cells have a Voltage of ~3.2V, my Battery with three blocks should have ~150 to 160V. This is a Byte-Order-Problem, converting the values above to Big-Endian gives the following:
Some of the other parsed IDs have additional small errors respectively few missing values. If needed I can provide details on that. Sometimes it ist difficult to get the right info out of the Growatt-Protocol-PDF (naming is misleading, wrong explications etc. - so for example for ID 0x3030 they mention that Time is epoch - that is completely wrong, each part of the date is just converted to hex, e.g. Year = 19, Month = 02, Day = 0A etc.) I noticed that each time when the programm is started my inverter restarted too (Growatt's 5 Mins Startup Check). I suppose the app is sending out each received frame, not taking into account that I have configured "Inverter: NONE". After commenting out the send command no more restart, so perhaps you could take that into consideration (not sending anything when inverter is NONE - the dummy inverter does not send frames, but the BMS-Code does when NONE-Inverter is configured). |
Finaly getting back to life ,.. just joking still no time at all .. 2025-02-12 15:37:58.095 | ERROR | Thread-4 | InverterCANProcessor:78 | Error creating send frames: this is probably last issue preventing to "run" log>> cheers |
@romanbetwo I'd like to compare what I can get via canbus vs modbus. |
Hi I'll request for latest and let you know. |
Thanks a lot ! |
@cmax1-gmx , I removed the response mask and changed the frame to big endian. Let's see if you can get some correct values now! 😄 |
@cmax1-gmx still no answer from growatt about latest and "greatest" modbus document .. they are so lazy after new year :D @ai-republic I am still playing arround with SPH and pylon HV battery, Last issue seems to be gone but I do believe there is anotheone seems that pylon HV see 2#BMS I want to continue in this threat, because its SPH related even if other part of build can be a problem. 2 logs > SPH shows that battery is OPEN, which means there is 0 voltage on terminals which is probably just a data from 2nd BMS. |
@ai-republic changing the whole frame to big endian is problematic - that changes the CAN ID too and decoding does not work any more. To test I just moved that command further down
to see if it would work - and it does. But I think a cleaner solution would be to define a buffer for just the data part of the can-frame (the 8 Bytes at the end). To check the results I compiled a table to compare my manual decoding of the frames for IDs 3110-3200 coming out of my system using the Protocol-PDF from above with the values spit out from bms-to-inverter - see attached file. |
Thanks @cmax1-gmx I will have a look at it. Very busy at the moment and currently suffering from the flu |
@cmax1-gmx I moved the setting to big endian like you suggested. I hope it works 😉 |
Yes, it does - Thank you !
Digging a bit deeper I found the following:
I think a possible way to adress that could be by defining the CAN-Bus Byte Order as a Config-Value and taking care of the byte order for the receiving buffer once directly in JavaCANPort.java when reading the frame, that could make it easier to add new Devices. |
Hi again,
I have a Growatt SPH10000-TL3-BH-UP and ARK bms with 4 modules.
I did a quick test setting the app up for PYLON_HV_CAN but that didn't work, inverter reported bms error.
So I've pulled some logs to try and figure out the protocol.
It seems growatt has went away from pylon protocol and made it's own, this is what I found so far.
Tomorrow i'll disconnect 1 module and run logs again with only 3 and see if I can find what changes.
Inverter sends this until the BMS responds
3010 8 0E DF 14 00 00 00 00 00
4200 8 02 00 00 00 00 00 00 E3
4200 8 00 00 00 00 00 00 00 E3
8210 8 AA 00 00 00 00 00 00 00
3010 8 0E E0 14 00 00 00 00 00
And so on.......
3010 byte 0 and 1 seem to be a counter beacuse it's always incrementing with 1, the rest never changes.
When BMS is powered up and responds for the first time inverter only sends this with 1 second interval, byte 0 and 1 still increments with 1.
3010 8 0E EF 14 00 00 00 00 00
BMS response look like this, ID's not matching anything I've seen and the data is arranged differently also.
(213,6V, no charge/discharge 24C SOC 100% SOH100%)
3020 [8] 00 00 00 00 00 00 00 00 Never changes
3030 [8] 18 0C 13 17 1C 17 00 01 Some type of counter, maybe Time and date?
3110 [8] 08 E0 00 00 00 FA 30 41 08E0 Max voltage 227.2 00FA 25A 00FA 25A Max discharge and charge
3120 [8] 00 00 00 00 00 00 00 00 Never changes
3130 [8] 08 58 00 00 00 F0 64 64 0848 =213,6V 0000 Charge/discharge current (Decimal from signed 2's complement )
00F0 24C 64 SOC 100% 64 SOH 100%
3140 [8] 13 4A 13 4C 47 54 01 28 0128 = 296 Number of cycles
3150 [8] 07 60 01 27 00 40 00 04 0760 never changes 0127 29,5 highest cell temp? 40 64 cells? 04 4 Modules?
3160 [8] 00 00 04 2D 01 18 00 DD 00DD 22.1 Lowest cell temp?
3170 [8] 01 03 04 0E 64 05 01 70
3180 [8] 00 00 00 01 00 40 00 41
3190 [8] 00 0D 12 0D 09 00 00 00
3200 [8] 00 00 02 00 00 00 0E 10
3220 [8] 00 00 00 00 00 00 00 02
3230 [8] 01 30 30 32 32 33 34 30
3240 [8] 01 04 DD B9 01 05 51 0B
3250 [8] 11 FF 11 FF 11 FF 11 FF Never changes
3260 [8] 00 00 00 00 00 00 00 00 Never changes
3270 [8] 00 00 00 00 00 00 00 00
3F00 [8] 00 00 00 00 00 00 00 00 Never changes
3110 BYTE 7
01 = Idle?
02 =Charging
03 =Discharge
41 = Balancing?
42 = fully charged?
61 = Initiating?
At startup shows 61 then 41 then 01 until charge or discharge begins
When fully charged shows 42 for a brief moment then 41
Growatt SPH inverter with ARK bms startup.txt
The text was updated successfully, but these errors were encountered: