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

add 12v 100a Ecoworthy battery #164

Open
4 tasks done
nezra opened this issue Feb 2, 2025 · 29 comments · May be fixed by #199
Open
4 tasks done

add 12v 100a Ecoworthy battery #164

nezra opened this issue Feb 2, 2025 · 29 comments · May be fixed by #199
Assignees
Labels
enhancement New feature or request

Comments

@nezra
Copy link

nezra commented Feb 2, 2025

Checklist

  • I have filled out the template to the best of my ability.
  • I have understood that this integration is only about battery management systems with Bluetooth Low Energy support.
  • This only contains 1 feature request (if you have multiple feature requests, open one feature request for each feature request).
  • This issue is not a duplicate of any previous feature requests.

Please describe the enhancement you would like to have.

Would like the Ecoworthy 100AH IOT battery & BW02 adaptor. from the ESPhome BT proxy using VERY_VERBOSE

[13:38:02][VV][esp32_ble_tracker:434]: Parse Result:
[13:38:02][VV][esp32_ble_tracker:453]: Address: B4:C2:E0:FA:B8:F0 (PUBLIC)
[13:38:02][VV][esp32_ble_tracker:456]: RSSI: -30
[13:38:02][VV][esp32_ble_tracker:457]: Name: 'ECO-WORTHY 02_B8EF'
[13:38:02][VV][esp32_ble_tracker:465]: Ad Flag: 6
[13:38:02][VV][esp32_ble_tracker:479]: Manufacturer ID: 0xC2B4, data: E0.FA.B8.F0
[13:38:02][VV][esp32_ble_tracker:489]: Adv data: 02.01.06.13.09.45.43.4F.2D.57.4F.52.54.48.59.20.30.32.5F.42.38.45.46.07.FF.B4.C2.E0.FA.B8.F0 (31)
[13:38:09][V][bluetooth_proxy:058]: Proxying raw packet from B4:C2:E0:FA:B8:F0, length 31. RSSI: -29 dB
[13:38:14][VV][api.service:345]: send_bluetooth_le_raw_advertisements_response:
BluetoothLERawAdvertisementsResponse {
advertisements: BluetoothLERawAdvertisement {
address: 198749091182832
rssi: -30
address_type: 0
data: '���� ECO-WORTHY 02_B8EF�\xff\xb4\xc2\xe0\xfa\xb8\xf0'
}
}

calculated out - 0xC2B4 -> 49844

i don't have a bluetooth adaptor, just an ESPhome BT Proxy; which works fine for the other BLE device & Integration i have, (a ruuvi tag); so i can't run bluetoothctl commands from the terminal. I also can't add Debug to the integration, since it refuses to start/be added; with the only error "No supported devices found via Bluetooth."; so i can't get the service uuid

Additional context

came here, from here: https://community.home-assistant.io/t/eco-worthy-100ah-iot-battery-integration/792000/4

the 100ah and 280ah(mentioned in the post above) versions share the same bw02 adaptor.

Battery details here: https://www.eco-worthy.com/collections/lithium-batteries/products/lifepo4-12v-100ah-lithium-battery-with-bluetooth-and-battery-status-display-100a-bms-with-low-temperature-protection

@nezra nezra added the enhancement New feature or request label Feb 2, 2025
@nezra
Copy link
Author

nezra commented Feb 2, 2025

managed to locate the Service UUID

0000ff00-0000-1000-8000-00805f9b34fb

Looks to match the other eco-worthy batteries in Manifest.json

@patman15
Copy link
Owner

patman15 commented Feb 2, 2025

Hi @nezra! Please try the linked branch in this ticket via manual install and provide me a debug log, so I can verify the detection and add matching tests for the future.

@patman15 patman15 self-assigned this Feb 2, 2025
@nezra
Copy link
Author

nezra commented Feb 2, 2025

Thanks @patman15 !

Returned this:

and attempting to add it yielded this from step 7.:
Image

i can't enable debug to display anything, since there is no option to do so from the troubleshooting steps:
Image

question, shouldn't the management_id list in jbd_bms.py have the hex code of 0xc2b4 like the other ones; and not the DEC equivelent? either dec or hex in the management_id list still yields the same result as above though.

i did add a BT adapter, and i can connect &disconnect the device.

and i verified the BLE device isn't paired or connected to anything else just in case.

Image

@patman15
Copy link
Owner

patman15 commented Feb 2, 2025

@nezra The adapter (in contrast to the normal batteries) seems not to broadcast the service_id. I removed it, can you please try again?

@nezra
Copy link
Author

nezra commented Feb 2, 2025

@patman15
one step closer. It let me add the integration, and it now shows up; but with an error:

Image

oh. and i really appreciate all of the time and patience with this.

@patman15
Copy link
Owner

patman15 commented Feb 2, 2025

Uh, that's not good. That hints towards a different setup. Can you please see if you are able to capture the Bluetooth traffic on Android or iOS while using the vendor app with the battery?
Unfortunately, I need more info.

@nezra
Copy link
Author

nezra commented Feb 2, 2025

@patman15

i've been able to connect to it with 3rd party tools; but i am not sure how to watch the BT traffic on it when it's connected to the app. It only connects to one at a time.

not sure if this is what you mean. the notify option flips between 0xA1 and 0xA2. here are some samples:

Image

Image

from what i was able to glean from the post that sent me here, there's the following:

0xA1
Position
0-5 MAC address
6 Packet Type
22-23 Available capacity
24-25 Total capacity (0x64 =100)
26-27 Battery voltage (centivolts)
28-29 Battery load (centi-amps) signed int so 0x0001 = 1 = 0.01A 0x8000 = -1 = -0.01A

0xA2
Position
0-5 MAC address
6 Packet Type
21 Number of cells (reads 4)
22-23 Cell 1 voltage (mv)
24-25 Cell 2 voltage (mv)
26-27 Cell 3 voltage (mv)
28-29 Cell 4 voltage (mv)
30-85 (Unused but could be further cell voltages if larger battery)
86-87 Number of cells (0 indexed - reads 3)

i did buy and slap a BT adapter in my machine, and i can connect & disconnect to it through bluetoothctl if that helps from the HA terminal.

@nezra
Copy link
Author

nezra commented Feb 2, 2025

Oh! and because it at least connected, i was able to get this now in case it's needed:

2025-02-02 09:45:05.987 DEBUG (MainThread) [custom_components.bms_ble] Setup of <ConfigEntry entry_id=01JK3GXD0XATXCQST4BXZ0K41J version=1 domain=bms_ble title=ECO-WORTHY 02_B8EF state=ConfigEntryState.SETUP_IN_PROGRESS unique_id=B4:C2:E0:FA:B8:F0>
2025-02-02 09:45:05.988 DEBUG (MainThread) [custom_components.bms_ble.plugins.jbd_bms] ECO-WORTHY 02_B8EF[B8:F0]: initializing Jiabaida Smart BMS, BT address: B4:C2:E0:FA:B8:F0
2025-02-02 09:45:05.988 DEBUG (MainThread) [custom_components.bms_ble] Initializing coordinator for ECO-WORTHY 02_B8EF (B4:C2:E0:FA:B8:F0) as Jiabaida Smart BMS
2025-02-02 09:45:05.988 DEBUG (MainThread) [custom_components.bms_ble] ECO-WORTHY 02_B8EF: advertisement: {'name': 'ECO-WORTHY 02_B8EF', 'address': 'B4:C2:E0:FA:B8:F0', 'rssi': -42, 'manufacturer_data': {49844: b'\xe0\xfa\xb8\xf0'}, 'service_data': {}, 'service_uuids': ['00001800-0000-1000-8000-00805f9b34fb', '00001801-0000-1000-8000-00805f9b34fb', '0000fff0-0000-1000-8000-00805f9b34fb'], 'source': '74:3A:F4:FF:9C:B2', 'advertisement': AdvertisementData(local_name='ECO-WORTHY 02_B8EF', manufacturer_data={49844: b'\xe0\xfa\xb8\xf0'}, service_uuids=['00001800-0000-1000-8000-00805f9b34fb', '00001801-0000-1000-8000-00805f9b34fb', '0000fff0-0000-1000-8000-00805f9b34fb'], rssi=-42), 'device': BLEDevice(B4:C2:E0:FA:B8:F0, ECO-WORTHY 02_B8EF), 'connectable': True, 'time': 4008.483948946, 'tx_power': None}
2025-02-02 09:45:05.988 DEBUG (MainThread) [custom_components.bms_ble] ECO-WORTHY 02_B8EF: BMS data update
2025-02-02 09:45:05.988 DEBUG (MainThread) [custom_components.bms_ble.plugins.jbd_bms] ECO-WORTHY 02_B8EF[B8:F0]: connecting BMS
2025-02-02 09:45:05.989 DEBUG (MainThread) [bleak_retry_connector] B4:C2:E0:FA:B8:F0 - B4:C2:E0:FA:B8:F0: Connection attempt: 1
2025-02-02 09:45:06.832 DEBUG (MainThread) [bleak_retry_connector] B4:C2:E0:FA:B8:F0 - B4:C2:E0:FA:B8:F0: Connected after 1 attempts
2025-02-02 09:45:06.832 INFO (MainThread) [custom_components.bms_ble.plugins.jbd_bms] ECO-WORTHY 02_B8EF[B8:F0]: failed to initialize BMS connection (BleakCharacteristicNotFoundError)
2025-02-02 09:45:06.832 DEBUG (MainThread) [custom_components.bms_ble.plugins.jbd_bms] ECO-WORTHY 02_B8EF[B8:F0]: disconnecting BMS
2025-02-02 09:45:09.281 DEBUG (MainThread) [custom_components.bms_ble.plugins.jbd_bms] ECO-WORTHY 02_B8EF[B8:F0]: disconnected from BMS
2025-02-02 09:45:09.281 DEBUG (MainThread) [custom_components.bms_ble] ECO-WORTHY 02_B8EF: device communicating failed: Characteristic ff01 was not found! (BleakCharacteristicNotFoundError)
2025-02-02 09:45:09.281 DEBUG (MainThread) [custom_components.bms_ble] Finished fetching ECO-WORTHY 02_B8EF data in 3.293 seconds (success: False)
2025-02-02 09:45:09.282 DEBUG (MainThread) [custom_components.bms_ble] Shutting down BMS device (ECO-WORTHY 02_B8EF)

@nezra
Copy link
Author

nezra commented Feb 2, 2025

@patman15

Think i got it. it's the whole log. let me know if you need the "BT SNOOP" variant instead.

@patman15
Copy link
Owner

patman15 commented Feb 2, 2025

BT snoop would be easier for me, thanks.

@nezra
Copy link
Author

nezra commented Feb 2, 2025

Untitled 2.log

@patman15

Attached.

@patman15
Copy link
Owner

patman15 commented Feb 2, 2025

Perfect, but this is a new type of protocol so I need to do a bit more work to get it integrated. Does not seem to be too complicated but it requires a few sessions of a few hours. I have been ordered out of the country next week, so this will unfortunately need to wait till I'm back to my PC, unless you want to try yourself.

@patman15 patman15 removed their assignment Feb 2, 2025
@nezra
Copy link
Author

nezra commented Feb 2, 2025

i may have to wait on this one. it's about 2 steps outside of my knowledge and understanding.

a few things i did notice.

I initially said the service id was 0000ff00-0000-1000-8000-00805f9b34fb; but it turns out it's 0000fff0-0000-1000-8000-00805f9b34fb. This probably started me down the wrong path; and maybe why the services id caused an issue before?

3 F's in the first part; not 2.

if i am learning anything from this, does this then mean the UUID TX should be fff2; and the RX should be fff1; and the uuid services id should be fff0 based on the images above from the custom service/characteristic?

Given the two different headers; i'm assuming it(head_rsp) needs to be handled with an if/elif statement; bit in init like with ogt_bms.py?

@Scope666
Copy link

Scope666 commented Feb 3, 2025

Sounds like I might be in a similar boat ... my ECO-WORTHY 150 AH (metal case) battery is only a few months old, perhaps they updated the BMS chip again.

#169

@patman15
Copy link
Owner

patman15 commented Feb 8, 2025

Sounds like I might be in a similar boat ... my ECO-WORTHY 150 AH (metal case) battery is only a few months old, perhaps they updated the BMS chip again.

It's unfortunately not the same issue, here they really changed the BMS, for yours, @Scope666 it was just the auto-detection.

@patman15 patman15 self-assigned this Feb 8, 2025
@nezra
Copy link
Author

nezra commented Feb 9, 2025

@patman15

Disregard everything I said above about registers and a whole slew of stuff. I may not be able to understand or the code in python; and definitely cannot do Github/pull requests, but i may have useful information to aide in this.

after reverse engineering the hardware, sniffing it, making it fault, and digging through the responses/commands i found the following:

  1. The BLE stuff comes out to fff0 as the start, and FFF1 is the notify part; and FFF2 i think is the write.
  2. BLE notify response starts with A1 for general info, and A2 for cell info and temps.
  3. the next set of bytes is always the same regardless of the first bytes: 00:00:65:00:00:00:00:00:18
  4. the next set of bytes after that in both cases are identical to the modbus communication direct from the battery. same length every time. if i understand correctly, 01:03 is the id & read command, with 56:00 for A2 responses and 44:00 for for A1
  5. the last two at the checksum, modbus CRC-16 Big endian.
  6. the load voltage is a signed 2's complement.

breaking down the responses using the sample byte string from the images above on A1 responses:

Byte -> usage
1: denotes what data set is coming through
2-11: header maybe? its always the same.
12-16: appears to be modbus stuff
17-18: available capacity
19-20: total capacity
21-22: Voltage
23-24: load. signed 2's complement
25-26: not sure
27-28: note sure
29-30: not useful, but denotes a load is connected. 1=on, 0=off
31-32: charging mosfets are enabled. 1 is on 2 is off
33-38: unknown
39-40: denotes charging is occuring
41-42: denotes discharging is occurring
43-44: denotes status. 2=discharging, 1= charging, 0=nothing(staying here for 3 minutes will actually disable the port)
45-50: not sure
51-52: denotes Over Voltage Protection fault. 1: fault, 0=no fault
53-54: not sure
55-56: denotes state of "Buzzer Alarm Function Switch" from the app. 0=on, 1=off. not sure what it does since changing it yields nothing.
57-82: not sure.
83-84: Checksum. CRC-16 modbus big endian

and the A2 responses:
1: denotes what data set is coming through
2-11: header maybe? its always the same.
12-15: appears to be modbus stuff
16: i believe this is cell count. looks to be based on 2 different peoples sets of data though.
17-18: cell 1 voltage
19-20: cell 2 voltage
21-22: cell 3 voltage
23-24: cell 4 voltage
25-80: Likely other cell voltages if more were present in here somewhere.
81-82: temp sensor indexed at 0
83-84: temp sensor 1
85-86: temp sensor 2
87-88: temp sensor 3
89-100: looks to be temp sensors that aren't present
101-102: checksum, CRC-16 Modbus Big Endian

i don't understand much to help in the way of detecting and determining how to tell the integration is this is the device since if i understand, ecoworthy is doing poorly with the BLE stuff to define what it is.

in case anyone else cares to help, on the port itself, pins 1 and 3 are A, 2 & 4 are B, 5 & 6 are ground, and pins 7 & 8 are 5v(5.3v measured); and the 5v is also switched off when idle. the rs485 transceiver is a MS1285. For the uart headers on the BW02 the inside headers are between the STM MCU and the transceiver, and the outer header is between the hi-link wifi chip and the MCU. both baud rates are 115200 8N1.

Sending "01:03:16:00:00:2B:01:9D" through a transceiver will yield the response from A2, and sending "01:03:15:00:00:22:C1:DF" will return the response from A1. communication is not required to keep the port active

Let me know if this helps.

@patman15
Copy link
Owner

patman15 commented Feb 9, 2025

Excellent analysis! Thanks @nezra. I will definitely follow up with that soon.
Best regards,
Patrick

@patman15
Copy link
Owner

patman15 commented Feb 18, 2025

@nezra

Sending "01:03:16:00:00:2B:01:9D" through a transceiver will yield the response from A2, and sending
"01:03:15:00:00:22:C1:DF" will return the response from A1. communication is not required to keep the port active

I checked the packet log of the app, but I can't find any such commands being sent.
The only write command looks like 0110180000060c07e900020002000a0026002acef1 and I would guess on writing a timestamp. I'll do a test implementation without write commands and let's see what happens.

@patman15
Copy link
Owner

patman15 commented Feb 19, 2025

@nezra just pushed an initial implementation to the branch. Can you test an provide me a debug log? I'm still missing a few values, but I will have detailed look later.
EDIT: I needed to do corrections to your findings, as some fields were not correct, e.g. 19-20: total capacity is actually SoH, while 17-18: available capacity is actually SoC and more.

@nezra
Copy link
Author

nezra commented Feb 20, 2025

@patman15

Looks like it's working! However. i had to add "ecoworthy_bms" to the const.py to make this branch work since i am guessing it needed to be added there in order to correctly reference it.

@nezra
Copy link
Author

nezra commented Feb 20, 2025

@patman15

Oh, and i'd forget the write command. Even eco-worthy can't tell me what that "buzzer switch" is for. The Storage switch i haven't monkeyed with; and i believe it falls under the "Things that affect stuff i don't want to screw with" category i.e. "shall not be used for safety relevant operations!"

@patman15
Copy link
Owner

Looks like it's working!

Great! I could not find a cycle.counter. There are still some unknown values, so if you have an idea, please let me know. Since the app shows none, it's not obvious.
Could you please still get me a debug log for me to have some more test data?

However. i had to add "ecoworthy_bms" to the const.py to make this branch work

Sorry for that, I need to fix that and add a test to circumvent that for the future. Thanks!

@nezra
Copy link
Author

nezra commented Feb 20, 2025

in the app, there isn't a cycle counter, so i am not sure it's actually asking for it from the RS485 bus/battery. The transceiver i mentioned above is one i built using a max485 & an ESP32. i sniffed the data commands via the 2 uarts on the BW02; so it's hard coded what it's asking for from the battery. however, in attempting to work out how/if i could be of use in the programming side of things before the branch update, i botched the mess up(lack of understand on how it all works on my end, but trying to learn) but did find something interesting. the adapter device does respond to normal modbus commands, just that it didn't know how to respond. i saved this snippet:

2025-02-15 19:49:14.531 DEBUG (MainThread) [custom_components.bms_ble.plugins.jbd_bms] ECO-WORTHY 02_B8EF[B8:F0]: TX BLE data: dd a5 03 00 ff fd 77
2025-02-15 19:49:14.631 DEBUG (MainThread) [custom_components.bms_ble.plugins.jbd_bms] ECO-WORTHY 02_B8EF[B8:F0]: RX BLE data (start): bytearray(b'\xaa\xaa\xaa\xaa\xaa')

my guess is the cycle count is in there and it is available, but it's not being requested automatically; but could be requested if the right packet is generated with the right coil or register. i'll see if i can sort this out by flipping that buzzer switch, as that write command above is likely when i flipped the buzzer switch in the app and figure out exactly what it's doing to the byte string as it comes in from the hi-link wifi chip on one uart; and then when it goes back out to it's built in transceiver on the other uart.

Unfortunately, i removed my botched attempt when i replaced it with the branch.

back to your request:

Here's a log where it was discharging & then charging.

home-assistant_bms_ble_2025-02-20T11-49-21.142Z.log

i'll flip another log once it hit's the OVP error.

Side note, did get my hands on another BW02; and that detected just fine. i'm using that one just to check with the app since the integration doesn't release the connection and i don't want it to; but i can still compare with the app and get logs via the packet logger app. while not concurrent, i haven't sorted actually sniffing the rs485 modbus traffic.

@patman15 patman15 linked a pull request Feb 20, 2025 that will close this issue
@nezra
Copy link
Author

nezra commented Feb 20, 2025

and the OVP log if needed.

home-assistant_bms_ble_2025-02-20T16-21-57.581Z.log

@patman15
Copy link
Owner

the adapter device does respond to normal modbus commands, just that it didn't know how to respond. i saved this snippet:

True, but the response is crap ...
There are still some numbers we do not know about. You could run it for a while and let's see if some number as incremented in a few days from now. Or do you have any idea, how many cycles the battery could have at the moment?
What about 24 or 836? These numbers occur in your log ...

@nezra
Copy link
Author

nezra commented Feb 21, 2025

not surprising, since the request itself i sent was crap. garbage in garbage out.

As for the cycle count, definitely not either. Battery cycles about once every 4 days.gets close to dying, around 10% and recharged to 98% before starting again. What bytes were you looking at that we don't know? i could run a longer log and compile data with the suspect fields.

@patman15
Copy link
Owner

not surprising, since the request itself i sent was crap. garbage in garbage out.

Well that command from the original try with a JBD BMS:

2025-02-15 19:49:14.531 DEBUG (MainThread) [custom_components.bms_ble.plugins.jbd_bms] ECO-WORTHY 02_B8EF[B8:F0]: TX BLE data: dd a5 03 00 ff fd 77

Is a correct one, but the answer was still crap.

What bytes were you looking at that we don't know?

b"\xa1\x00\x00\x00e\x00\x00\x00\x00\x00\x18\x01\x03D\x00\x18\x00d\x00d\x05\x83\x00\x00\x00\x05\...
^^ <--> ^^ I was looking at about those.
The ones before the voltage \x05\x83. If at all, I would suspect the cycle in the A1 message and the rest is 0 or 1, so not realistic.

@nezra
Copy link
Author

nezra commented Feb 24, 2025

oh! i can answer some of this now. 24 and 836. 24 i'm not sure of.

the 836 though, that one i know. my logic analyzer had an issue with it as well. it's not 836, but looks like it. it took it as x03x44; but its not. it's actually x01x03x44. the analyzer decodes it wrong because it's all 1 byte off for the pair.

i.e. as an example.
a request is sent to the battery from the adaptor:
0103150022dfc1 (DeviceID: 0x01, Func: Holding Registers (0x03), StartAddr: 0x1500, Qty: 0x22, ChkSum: 0xDFC1)
the response from the battery to the adaptor:
010344.....0065ff
the broadcast from the adaptor to HA(or the app
A10000065000000000018 followed by the 0103....00 from above, minus the checksum from the battery(65ff), and with a new checksum added.

836->x03x44

assuming thats from the A1 string, its a byte off(missing the x01) since this is where the response in modbus format tacked onto the header of A10000065000000000018

x01x03x44 is the device, holding register acknowledgement, and byte count from the response from the battery.

0x18->24 is the first real byte of the actual BMS data.

for reference, you i believe you literally ignore the following bits:

A10000065000000000018010344
A200000065000000000018010356

010344 & 010356 are both the modbus acknowledgements; the rest is garbage the adaptor tacks in on top of the actual modbus bms response to reading specific registers.

If it helps, A2's info is from 010316002b9d01 (DeviceID: 0x01, Func: Holding Registers (0x03), StartAddr: 0x1600, Qty: 0x2B, ChkSum: 0x9D01).

@patman15
Copy link
Owner

@nezra Ok, makes a lot of sense, but that doesn't help to get further data, right? What we would need is to see if we can send commands that go through to the BMS (despite the adapters queries). If not, we are limited to the adapters responses, i.e. no cycle counter possible. Or maybe you send me another log to identify the cycle counter (if there at all).
As you like, I can also close the issue with the current state. Let me know.

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

Successfully merging a pull request may close this issue.

3 participants