[REQUEST] Commissioning a Native Sailfish OS App for Bluetooth BMS

I have a Bluetooth BMS in use. Unfortunately I have no idea what brand it is, it’s built-in…
The android app ist just called “iBMS”. If there is an easy way to install SailBMS I’ll give it a try.

hi. I just saw this. I’ve been preparing to code an app to connect to the litech bms in my pev. I’d be happy to test if you still need and my unit is compatible.

(So far, I can connect by BLE to my Vesc computer to get the voltage, but I realize I really ought to be going for the BMS to be able to read temps as well.)

I have JK BMS invertor PB type, 14S battery.
I will try.


OK, I need to get it. I suggest put it on OpenRepos, as that’s where I am looking for it.

1 Like

Today, I published an initial prototype for SailBMS on openrepos. Only JBD has been tested, but parsers for different protocols are already included and might or might not work. Kindly report your obervations on email directly.

@rw007, unfortunately we have not heard from you since you requested such app, hope it benefits you and others nonetheless.

4 Likes

I gave it a try today on my VESC onewheel an it saw the VESC computer’s bluetooth and it was not grayed out, but it had my actual BMS listed but grayed out.

It ID’d the VESC (which isn’t working as the BMS) as antBMS but my LiTech BMS wasn’t allowed to connect. If I did comnect the VESC computer, the app never advanced past the awaiting response screen.

Hi everyone. I haven’t been in touch for a long time because I had to switch to Android in the meantime, as I had to do without too many things on Sailfish. However, I could use an old Sailfish device to test the connection if necessary.

Hi,
unfortunately LiTech does not publish info on their protocols to access BMS over BLE, so it is not implemented yet. With a little help we MIGHT still be able to get some data. Would you be able to download an app called “nRF Connect for Mobile” e.g. on an Android phone, run a Bluetooth scan and click CONNECT where your BMS shows up. Then a list like this should appear:

Generic Access 00001800-0000-1000-8000-00805f9b34fb
Generic Attribute 00001801-0000-1000-8000-00805f9b34fb
Unknown Service xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Unknown Characteristic
Properties: READ, WRITE
Unknown Characteristic
Properties: NOTIFY

Could you send me a screenshot on email? The Unknown Service and its characteristics are the important ones. If we get an UUID here, we might also be able to squeeze some data out next. No promises… BMS protocols are a jungle.

1 Like

I don’t have an actual Android phone, just AAS. :sweat_smile: I will do this if I find that that app runs on the J2, or maybe get someone with an android at work to throw me a bone!

Added a Button in Settings which produces a log file including Bluetooth BLE and GATT info of all devices nearby … if you prefer not to download an Android app mentioned earlier. This hopefully shows us UUIDs and available services LiTech uses. Maybe send me an email if you like to try?

3 Likes

Hi tp.labs,

First of all, thank you for your work on this app! It is really awesome that you are addressing a need tgat some of us SFOS users have. The less we have to rely on Android apps, the better! I recently aquired a LifePo4 battery with Bluetooth BMS capability and tried out your application. Unfortunately, it doesn’t fully work with my model, though it instantly sees the battery when scanning. If SailBMS could be updated to be compatible with my model, I’d absolutely love it because Sailfish is my daily driver and even though Android app works with AAS with the new beta AppSupport Bluetooth from Jolla Store enabled, I strongly prefer to use native Sailfish apps whenever it is possible. That said, I am mostly posting this to support and encourage SF native app development and contribute in a helpful way wherever I can, so if you don’t have time or are not interested, I would totally understand.

Here are the details:

Phone: Xperia 10 III Running Build 5.1.0.11 (Pispala)
App Version: SailBMS install via Storeman 0.1-2, About shows last updated 09.09.2026

Battery Make: Must Model: LP15-12100 Battery Type: LifePo4 100ah

Specsheet from the retailer I purchased it from:

https://prodidec.com/producto/bateria-de-litio-must-12-8v-100ah/

Android App used to connect: Dyness

https://play.google.com/store/apps/details?id=com.dyness.emssmart&hl=en

Bluetooth BMS Type: Nations Technologies Bluetooth BMS stack *

  • According to the manual, this battery is supposed to have a Xiaoxiang JBD stack, but there must have been some kind of mix-up at the factory in China, or perhaps they changed chipsets in newer generations and didn’t udate the manual. I’m not sure, but it definitely isn’t JBD. None of the Xiaoxiang/JBD apps can see it across multiple devices and android versions. After troubleshooting with nRF Connect, I came to realize it was actually a Nations Technologies stack, and downloaded the Dyness app which is made for that type. Dyness instantly connected and provides accurate info. But wow it would be lovely to use SailBMS instead!

Please find attached a screenshot from nRF Connect with all detected details, a screenshot from SailBMS showing it detects while scanning (though you can’t advance beyond that), some screenshots from the Dyness app with battery details and overview, and finally the output of sailbms-probe.txt from your app. If you need any other data or would like me to run any tests at all, please just let me know. I’m happy to do so.

Thanks again for developing this.

Kind Regards,

-PK

Output of sailbms-probe.txt

==================================================
SailBMS GATT PROBE SESSION

DATE: 2026-10-03T13:06:38.229Z

GATT PROBE: QUEUE CREATED
GATT PROBE: devices = 1

GATT PROBE: DEVICE 1 of 1

GATT PROBE: CONNECTING

GATT PROBE: attempt = 1
GATT PROBE: path = /org/bluez/hci0/dev_EF_05_01_0E_35_37
GATT PROBE: CONNECT SUCCESS
GATT PROBE: waiting for GATT discovery…
GATT PROBE: READING BLUEZ GATT DATABASE
device = /org/bluez/hci0/dev_EF_05_01_0E_35_37

BLE: DEVICE TO PROBE

BLE: path = /org/bluez/hci0/dev_EF_05_01_0E_35_37
BLE: address = EF:05:01:0E:35:37
BLE: name = BMS-508251061305099D
BLE: alias = BMS-508251061305099D
BLE: RSSI = undefined
BLE: ADVERTISED UUIDs = {“0”:“00001800-0000-1000-8000-00805f9b34fb”,“1”:“00001801-0000-1000-8000-00805f9b34fb”,“2”:“0000180a-0000-1000-8000-00805f9b34fb”,“3”:“00002760-08c2-11e1-9073-0e8ac72e1001”}

GATT SERVICE
path = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0001
UUID = 00001800-0000-1000-8000-00805f9b34fb
Primary = true
Device = /org/bluez/hci0/dev_EF_05_01_0E_35_37

GATT CHARACTERISTIC
path = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0001/char0002
UUID = 00002a00-0000-1000-8000-00805f9b34fb
Service = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0001
Flags = [“read”,“write”]
Notifying = undefined

GATT CHARACTERISTIC
path = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0001/char0004
UUID = 00002a01-0000-1000-8000-00805f9b34fb
Service = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0001
Flags = [“read”]
Notifying = undefined

GATT SERVICE
path = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0006
UUID = 00001801-0000-1000-8000-00805f9b34fb
Primary = true
Device = /org/bluez/hci0/dev_EF_05_01_0E_35_37

GATT CHARACTERISTIC
path = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0006/char0007
UUID = 00002a05-0000-1000-8000-00805f9b34fb
Service = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0006
Flags = [“indicate”]
Notifying = false

GATT DESCRIPTOR
  path           = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0006/char0007/desc0009
  UUID           = 00002902-0000-1000-8000-00805f9b34fb
  Characteristic = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0006/char0007

GATT CHARACTERISTIC
path = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0006/char000a
UUID = 00002b29-0000-1000-8000-00805f9b34fb
Service = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0006
Flags = [“read”,“write”]
Notifying = undefined

GATT CHARACTERISTIC
path = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0006/char000c
UUID = 00002b2a-0000-1000-8000-00805f9b34fb
Service = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0006
Flags = [“read”]
Notifying = undefined

GATT SERVICE
path = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service000e
UUID = 0000180a-0000-1000-8000-00805f9b34fb
Primary = true
Device = /org/bluez/hci0/dev_EF_05_01_0E_35_37

GATT CHARACTERISTIC
path = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service000e/char000f
UUID = 00002a29-0000-1000-8000-00805f9b34fb
Service = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service000e
Flags = [“read”]
Notifying = undefined

GATT CHARACTERISTIC
path = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service000e/char0011
UUID = 00002a24-0000-1000-8000-00805f9b34fb
Service = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service000e
Flags = [“read”]
Notifying = undefined

GATT CHARACTERISTIC
path = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service000e/char0013
UUID = 00002a25-0000-1000-8000-00805f9b34fb
Service = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service000e
Flags = [“read”]
Notifying = undefined

GATT CHARACTERISTIC
path = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service000e/char0015
UUID = 00002a27-0000-1000-8000-00805f9b34fb
Service = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service000e
Flags = [“read”]
Notifying = undefined

GATT CHARACTERISTIC
path = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service000e/char0017
UUID = 00002a26-0000-1000-8000-00805f9b34fb
Service = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service000e
Flags = [“read”]
Notifying = undefined

GATT CHARACTERISTIC
path = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service000e/char0019
UUID = 00002a28-0000-1000-8000-00805f9b34fb
Service = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service000e
Flags = [“read”]
Notifying = undefined

GATT CHARACTERISTIC
path = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service000e/char001b
UUID = 00002a23-0000-1000-8000-00805f9b34fb
Service = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service000e
Flags = [“read”]
Notifying = undefined

GATT CHARACTERISTIC
path = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service000e/char001d
UUID = 00002a2a-0000-1000-8000-00805f9b34fb
Service = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service000e
Flags = [“read”]
Notifying = undefined

GATT CHARACTERISTIC
path = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service000e/char001f
UUID = 00002a50-0000-1000-8000-00805f9b34fb
Service = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service000e
Flags = [“read”]
Notifying = undefined

GATT SERVICE
path = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0021
UUID = 00002760-08c2-11e1-9073-0e8ac72e1001
Primary = true
Device = /org/bluez/hci0/dev_EF_05_01_0E_35_37

GATT CHARACTERISTIC
path = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0021/char0022
UUID = 00002760-08c2-11e1-9073-0e8ac72e0001
Service = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0021
Flags = [“write-without-response”]
Notifying = undefined

GATT DESCRIPTOR
  path           = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0021/char0022/desc0024
  UUID           = 00002901-0000-1000-8000-00805f9b34fb
  Characteristic = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0021/char0022

GATT CHARACTERISTIC
path = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0021/char0025
UUID = 00002760-08c2-11e1-9073-0e8ac72e0002
Service = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0021
Flags = [“notify”]
Notifying = false

GATT DESCRIPTOR
  path           = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0021/char0025/desc0027
  UUID           = 00002902-0000-1000-8000-00805f9b34fb
  Characteristic = /org/bluez/hci0/dev_EF_05_01_0E_35_37/service0021/char0025

BLE: UUID COMPARISON

advertised BLE UUIDs = {“0”:“00001800-0000-1000-8000-00805f9b34fb”,“1”:“00001801-0000-1000-8000-00805f9b34fb”,“2”:“0000180a-0000-1000-8000-00805f9b34fb”,“3”:“00002760-08c2-11e1-9073-0e8ac72e1001”}
discovered GATT UUIDs = [“00001800-0000-1000-8000-00805f9b34fb”,“00002a00-0000-1000-8000-00805f9b34fb”,“00002a01-0000-1000-8000-00805f9b34fb”,“00001801-0000-1000-8000-00805f9b34fb”,“00002a05-0000-1000-8000-00805f9b34fb”,“00002902-0000-1000-8000-00805f9b34fb”,“00002b29-0000-1000-8000-00805f9b34fb”,“00002b2a-0000-1000-8000-00805f9b34fb”,“0000180a-0000-1000-8000-00805f9b34fb”,“00002a29-0000-1000-8000-00805f9b34fb”,“00002a24-0000-1000-8000-00805f9b34fb”,“00002a25-0000-1000-8000-00805f9b34fb”,“00002a27-0000-1000-8000-00805f9b34fb”,“00002a26-0000-1000-8000-00805f9b34fb”,“00002a28-0000-1000-8000-00805f9b34fb”,“00002a23-0000-1000-8000-00805f9b34fb”,“00002a2a-0000-1000-8000-00805f9b34fb”,“00002a50-0000-1000-8000-00805f9b34fb”,“00002760-08c2-11e1-9073-0e8ac72e1001”,“00002760-08c2-11e1-9073-0e8ac72e0001”,“00002901-0000-1000-8000-00805f9b34fb”,“00002760-08c2-11e1-9073-0e8ac72e0002”,“00002902-0000-1000-8000-00805f9b34fb”]

BLE: BMS identification: EF:05:01:0E:35:37 | type: unknown | supported: false | confidence: none | service: | RX: | TX:

GATT PROBE: DATABASE SUMMARY
services = 4
characteristics = 16
descriptors = 3

GATT PROBE: DISCONNECTING
GATT PROBE: disconnect path = /org/bluez/hci0/dev_EF_05_01_0E_35_37
GATT PROBE: DISCONNECTED
GATT PROBE: THIS DEVICE FINISHED

==================================================

GATT PROBE: ALL DEVICES FINISHED

  • Edits to improve formatting, consolidate images and hide scan output for easier scrolling.
1 Like

Hi @paulwk,
have been working on implementing your NationsBMS. Would you send me an email - see About page - so I can forward you a beta for testing?

1 Like

Thank you so much, that is very kind of you! I’ve just sent you an email per your request. I’m happy to test as needed.

Kind Regards,

-PK