JK-BMS BD6A32S10P rs-485

в першому запиті напруга, в другому струм.
Ці дані скоріше за все будуть не синхронізовані.
На момент отримання струму напруга вже застаріла.
До того ж код виконується явно не в реалтайм системі.


ці конструкції
if not error else 0
додають хаосу. Струм може дорівнювати 0 але чи то помилка отримання даних чи такий і є. Треба чітко відрізняти дані від помилок обміну інформацією.
Я взагалі не розумію всі ці запити, скрипти та інші речі. Все робив за допомогою ШІ, тому я б з радістю все виправив, але не знаю, як це зробити)) Та вже дякувати, що взагалі вийшло, я цих данних не міг витягнути близько неділі. Реалтайм та синхронізація для моєї задачі необов'язкові, тому що дані спочатку будуть йти в БД, потім в моніторинг з певною затримкою, тому ідеально все підганяти не бачу сенсу.. моя задача була - віддалено моніторити стан батареї за необхідності у побутовому форматі, це - головне. Вчора після роботи зовсім без сил, але з ентузіазмом все ж таки зміг втілити головний етап. Сьогодні сподіваюся встигнути все інтегрувати та опишу всі основні моменти, щоб інші люди так не мучилися) в інтернеті дуже мало інформації саме по роботі з цим протоколом та бмс. Більшість інфи водить до esp чи інших інверторів, а ці пристрої мають вже вбудований механізм взаємодії. А якщо є необхідність "з нуля" подружити якийсь пристрій з бмс на лінуксі чи його подібних, будуть вже перші зачіпки)) Я розумію, що можливо підхід не зовсім правильний і т.п., але хочу наголосити, я самоучка, та не програміст, не електронщик, не фізик, не хімік і т.д. взагалі. В мене залізнична освіта це все - просто хоббі, яке мені ще й даю велику користь у такий нелегкий час) Дуже всім дякую за відповіді
 
Я взагалі не розумію всі ці запити, скрипти та інші речі. Все робив за допомогою ШІ, тому я б з радістю все виправив, але не знаю, як це зробити)) Та вже дякувати, що взагалі вийшло, я цих данних не міг витягнути близько неділі. Реалтайм та синхронізація для моєї задачі необов'язкові, тому що дані спочатку будуть йти в БД, потім в моніторинг з певною затримкою, тому ідеально все підганяти не бачу сенсу.. моя задача була - віддалено моніторити стан батареї за необхідності у побутовому форматі, це - головне. Вчора після роботи зовсім без сил, але з ентузіазмом все ж таки зміг втілити головний етап. Сьогодні сподіваюся встигнути все інтегрувати та опишу всі основні моменти, щоб інші люди так не мучилися) в інтернеті дуже мало інформації саме по роботі з цим протоколом та бмс. Більшість інфи водить до esp чи інших інверторів, а ці пристрої мають вже вбудований механізм взаємодії. А якщо є необхідність "з нуля" подружити якийсь пристрій з бмс на лінуксі чи його подібних, будуть вже перші зачіпки)) Я розумію, що можливо підхід не зовсім правильний і т.п., але хочу наголосити, я самоучка, та не програміст, не електронщик, не фізик, не хімік і т.д. взагалі. В мене залізнична освіта це все - просто хоббі, яке мені ще й даю велику користь у такий нелегкий час) Дуже всім дякую за відповіді
П.с Але систему з нуля зробив сам)))
 
в першому запиті отримується значення напруги, в другому значення струму.
Між цими запитами пройшов деякий час і напруга вже могла змінитися.
Розрахунок потужності скоріше за все буде на розсинхронізованих значеннях струма та напруги.
Саме тому треба в бмс запитувати значення потужності

До того ж код виконується явно не в реалтайм системі.


ці конструкції
if not error else 0
додають хаосу. Струм може дорівнювати 0 але чи то помилка отримання даних чи такий і є. Треба чітко відрізняти дані від помилок обміну інформацією.
Нарешті вночі тільки закінчив, бо з'явилося трохи часу...
 

Вкладення

  • IMG_20260216_035109_654.PNG
    IMG_20260216_035109_654.PNG
    222,3 Кб · Перегляди: 6
  • IMG_20260216_035111_986.PNG
    IMG_20260216_035111_986.PNG
    137,9 Кб · Перегляди: 6
  • IMG_20260216_035113_517.PNG
    IMG_20260216_035113_517.PNG
    130,6 Кб · Перегляди: 6
Отже. Я завершив всі основні налаштування, які мені було необхідно зробити, тож тепер можу розповісти, як я все реалізував. Для початку - дані та специфікація:
Плата БМС JK-BD6A32S10P, підтримує 32с збірки, струм балансування - 0.6А (буває також 1А, але в момент замовлення технічної можливості придбати таку не було). Придбати можна під замовлення, в мене час очікування виготовлення зайняв приблизно 10 днів, ще 10 - доставка. Підкреслюю - більше ніде я не знайшов взагалі, де можна знайти цю плату, дуже рідка специфікація, аж до 118.4 вольта в номіналі, а взагалі - які і інші плати цього бренду, її можна налаштувати під різні типи батареї. Замовляв у цього продавця (відповідала дівчина Luna):
https://www.alibaba.com/product-detail/JK-BD6A32S10P-JK-BMS-for-Home_1601601691783.html
Вартість плати з пересилкою вийшла 4500 грн (маленький лайфхак - на алібаба, якщо аккаунт вперше замовляє, алібаба дарує знижку на доставку 20$, тому раджу робити так, адже на алі доставка дуже недешева). В комплекті з платою було наступне - Плата, проводи балансування, гвинти для кріплення силових кабелів, кабель для підключення RS485/UART, та невеликий силовий провід для підключення підігріву батареї (на платі є окремий силовий вивід для підігріву батареї самою батареєю). Також в комплект окремо продавець поклала кнопку увімкнення у подарунок. Для включення БМС без кнопки потрібно після підключення її до аккумулятора подати напругу (наприклад, включити зарядку), АЛЕ НЕ МЕНШЕ, НІЖ НА АКБ, бо може не увімкнутись. Плата - топ. Документацію, включаючи характеристики до неї - вклав до запису в pdf файлі. Якщо по платі будуть запитання, пишіть, за можливості одразу відповім.
Робочий сервер - Asus rs300-e7/ps4, OS Ubuntu 24.04.3 LTS
Адаптер USB - RS485 - перехідник "свисток" на чіпі max485 (в мене ще жодного разу не сбоїв, дуже стабільний), коштував 60 грн, купляв тут РКС-компоненти
ПЗ - Telegraf, Grafana, InfluxDB та в моєму випадку, ModBus, який вже йде з убунтою у комплекті, якщо не помиляюсь.
ПК на ОС Windows 11 - для перевірки

Задача - зв'язати бмс з сервером та підключити її до системи моніторингу серверу.
Я не буду описувати весь треш, з яким я зустрівся, поки це все зробив, а одразу розкажу, як саме в мене це вийшло :D

1. Спочатку я взяв кабель, який був у комплекті з платою (4 піни, жовтий, білий (для 485) та червоний+чорний для UART, якщо не помиляюсь - просто жовтий та білий проводи підключив до свистка, як того потребує зазвичай. (А та В піни). Червоний та чорний я просто залишив, бо вони не для потрібного мені інтерфейсу. Іншу сторону роз'єму, відповідно підключив до бмс.
2. Спочатку підключив цей свисток до ПК в звичайний юсб порт для перевірки правильності підключенні та успішного читання даних з плати в офіційній програмі моніторингу від виробника "JK-BMS-MONITOR 2.7.0" Сторінка виробника.
Потім я зі смартфону підключився по блютуз до бмс, що б налаштувати підключення по RS485. Поставив так:
device adrr: 1
Протокол uart 1: 001 - JK BMS RD485 Modbus V1.0
Протокол uart 2: 001 - JK BMS RD485 Modbus V1.0.

Все запрацювало. Окремо дякую RomanN за пораду з тестом. Важливо - програма JK-BMS-MONITOR написана для 64-бітних систем, на старому залізі з процесорами 32 біти, навіть на віндовс 8.1 в мене на ноуті не запрацювала!
3. Після успішного випробування я переключив юсб свисток на сервер та почав роботу з ПЗ.
В першу чергу я перевірив правильність розпізнавання інтерфейсу, та одразу подивився, який саме порт в меня з'явився, у моєму випадку USB1. Після цього я дууууже довго мучився, щоб залізо "розуміло" один одного по цьому протколу, тому що інфи в інтернеті майже немає для мого випадку (так я опинився на цьому форумі :)
Якимось дивом ШІ мені зміг написати скрипт Python, який почав перебирати всі блоки, регістри і все це (я в цьому нічого не розумію) com-порту, щоб зрозуміти, по яким саме точкам йдуть дані та через день-два я отримав всі, необхідні мені потоки (Напруга (вона там не загальна, а по кожній комірці, потім складається), SOC, струм, температури та потужність. Там є набагато більше всієї інфи, але мені потрібна була тільки ця.
4. Після успішного отримання необхідних мені, даних, далі все залишилось за технікою - був написаний готовий Python-скрипт, який нарешті зіставив дані, запрацював, як "перекладач" для БД та ПЗ системи моніторингу. Саме цей скрипт я не міг дуже довго нормально зробити і він його створення в мене забрало найбільше часу:
Скрипт Python:
Python:
from pymodbus.client import ModbusSerialClient

client = ModbusSerialClient(
    port="/dev/ttyUSB1",
    baudrate=115200,
    parity="N",
    stopbits=1,
    timeout=0.5
)

if not client.connect():
    exit(1)

try:
    # Напряжение
    r = client.read_holding_registers(address=4832, count=4)
    voltage = r.registers[2] / 100.0 if not r.isError() else 0

    # Ток
    r = client.read_holding_registers(address=4762, count=1)
    val = r.registers[0] if not r.isError() else 0
    current = (val if val <= 32767 else val - 65536) / 1000.0

    power = voltage * current

    # Полная ёмкость
    r = client.read_holding_registers(address=4776, count=4)
    capacity = r.registers[3] / 1000.0 if not r.isError() else 40.0

    # Остаток
    r = client.read_holding_registers(address=4772, count=4)
    remain = r.registers[3] / 1000.0 if not r.isError() else 0

    soc = remain / capacity * 100 if capacity > 0 else 0

    # Температуры
    r = client.read_holding_registers(address=4764, count=4)
    t1 = r.registers[0] / 10.0 if not r.isError() else 0
    t2 = r.registers[1] / 10.0 if not r.isError() else 0

    r = client.read_holding_registers(address=4744, count=4)
    mosfet = r.registers[1] / 10.0 if not r.isError() else 0

    # Вывод в Influx Line Protocol
    print(
        f"battery,device=jk_bms "
        f"voltage={voltage},"
        f"current={current},"
        f"power={power},"
        f"soc={soc},"
        f"capacity_ah={capacity},"
        f"remain_ah={remain},"
        f"temp_t1={t1},"
        f"temp_t2={t2},"
        f"temp_mosfet={mosfet}"
    )

except:
    pass

client.close()

5. І нарешті, цей скрипт я вже підключив до БД InfluxDB, яка все записую в собі, а ПЗ для моніторингу Grafana вже з БД бере всі дані.
Та вже потім, в створив всі, необхідні для мене показники, сценарії та інше. В бонус створив телеграм-бота, який повідомляє мені, якщо в системі зафіксовано задані мною події (Наприклад, що батарея повністю заряджена, чи почались стрибки напруги, чи взагалі пропала напруга і т.д.). І тепер нарешті в мене з'явився час написати свій шлях до реалізації цієї ідеї та поділитись своїм досвідом з іншими, бо я впевнений, що комусь він дуже полегшить реалізацію подібних ідей. Можливо, я щось десь не вказав, то запитуйте, по можливості - відповім, звичайно)) Результат роботи можете побачити у вкладеннях) Всім гарного настрою та стабільної енергії)))
 

Вкладення

  • JK_BD6A32S_10P主动均衡保护板使用说明书_V202025_10_13_02_03_50 (2).pdf
    1,2 Mб · Перегляди: 1
  • вк5.jpg
    вк5.jpg
    107,5 Кб · Перегляди: 4
  • вк4.PNG
    вк4.PNG
    235,5 Кб · Перегляди: 3
  • вк3.PNG
    вк3.PNG
    95 Кб · Перегляди: 3
  • вк2.PNG
    вк2.PNG
    157,3 Кб · Перегляди: 4
  • вк1.PNG
    вк1.PNG
    227,4 Кб · Перегляди: 4
  • вк9.jpg
    вк9.jpg
    237,2 Кб · Перегляди: 4
  • вк8.jpg
    вк8.jpg
    103,9 Кб · Перегляди: 4
  • вк7.jpg
    вк7.jpg
    95,3 Кб · Перегляди: 3
  • вк6.jpg
    вк6.jpg
    237,8 Кб · Перегляди: 4
Якщо не секрет. Яке основне призначення отого сервера? Сподіваюсь не моніторинг цієї батареї? :)
 
Якщо не секрет. Яке основне призначення отого сервера? Сподіваюсь не моніторинг цієї батареї? :)
Ахаха, ні, моніторинг - це просто доповнення))))) сервер - це моє хобі, яке я поєдную з корисним))
 
Звідки інфо, що так треба зчитувати?
Ток
r = client.read_holding_registers(address=4762, count=1)

Бо в мене щось не співпадає
Параметр знайшов скрипт. Там було два параметри, один надає інформацію про саме силу струму, яка йде в чи з батареї, в другий - це заявлена ємність. Тобто там один із параметрів - динамічний, один - статичний. Це можна звичайно перевірити, давши якесь навантаження батареї, та два- три рази виконати скрипи, і один із виводів буде змінюватися. Це і є сила струму. А інший, це вже саме "Заявлена ємність", що вказується у додатку при налаштуванні батареї.
 
Чому адреса= 4762 і count= 1 ?
 
Останнє редагування:
Чому адреса= 4762 і count= 1 ?
Count = 1, тому що цей параметр займає рівно 1 регістр. А чому сканер знайшов струм саме за цією адресою, це не дивно, адже є не одна серія плати jk bms, в моєму випадку, рахується, як PB серія, якщо не помиляюсь і в цих серіях modbus передає цей параметр саме в цій адресі
 
І ось цей параметр в мене пишеться в БД, та виводиться
 

Вкладення

  • Screenshot_2026-02-20-08-25-23-147_com.android.chrome-edit.jpg
    Screenshot_2026-02-20-08-25-23-147_com.android.chrome-edit.jpg
    351,9 Кб · Перегляди: 1
Адреса 4760 в десятичному форматі , count це кількість байтів , що лежить по даній адресі згідно протоколу.

А в тебе 4762 і 1 байт. Тобто ти вихопив 1 байт з чотирьох (міліампери), підігнав під ампери і вуаля

Треба було зчитати 4 байти по адресу 4760 (струм в міліамперах) , потім конвертувати в ампери без втрати точністі
 
Останнє редагування:
Яка версія firmware? Найбільш вірогідно, що в нас вони відрізняються та в мене є зміщення, а даній документації вказано "офіційно". Просто в мене плата можна сказати, ще "тепла", її тільки в кінці 11 місяця 25 року випустили з заводу.
 
Не може бути струм в одному байті (count=1)
 
Не може бути струм в одному байті (count=1)
Я створював цей скрип в grok і запитав його саме про це, він надав правильну відповідь, що я хочу сказати саме про прошивку: Почему у тебя 4762 вместо 4760
Это не "вихопив 1 байт з чотирьох" — твой скрипт читает полноценный 16-битный регистр (2 байта), а не один байт.
Разница в +2 регистра (4762 = 4760 + 2) встречается довольно часто в JK PB-серии по нескольким причинам:

В разных версиях firmware (15.xx) JK иногда сдвигает карту на 1–2 регистра (reserved поля, или для совместимости с другими моделями).
Некоторые готовые скрипты/программы (включая твою основу) используют эмпирически проверенные адреса — протестировали на реальной железке и увидели, что ток приходит именно с 4762.
В pymodbus (и других клиентах) иногда бывает offset +1 или +2 из-за того, как интерпретируют 0-based vs 1-based адресацию (Modbus официально 1-based, но в hex-картах JK часто пишут base 0x1000 как старт).
В некоторых картах регистров Current стоит на 0x129A (4762 dec) вместо 0x1298.

Из реальных источников (esphome-jk-bms, форумы Louisvdw/dbus-serialbattery, GitHub-issues):

Большинство используют 4760 (0x1298) для Current.
Но есть случаи, когда люди пишут "на моей BMS ток на +2" — и оно работает.
Твой ток правильно signed (val if <=32767 else val-65536) → это подтверждает, что ты читаешь полноценный INT16, а не "половину".

Вывод: кто прав?

Он прав по официальной документации (V1.0/V1.1): Current обычно на 4760, и часто рекомендуют читать count=4 (или хотя бы count=2–4) вокруг адреса, чтобы не было ошибок alignment.
Ты прав на практике: на твоей конкретной BMS (модель + firmware) значение тока лежит именно по адресу 4762, и count=1 достаточно, потому что BMS отдаёт его именно там. Это не хак и не "1 байт из четырёх" — это полный 16-битный регистр.
 
Я помилився (чі ні) мабуть, коли писав що count 1 = зчитуванню 1 байт в даному випадку.
Чи то пайтон так інтерпретує отриману інформацію
 
Останнє редагування:
Адреса 4760 в десятичному форматі , count це кількість байтів , що лежить по даній адресі згідно протоколу.

А в тебе 4762 і 1 байт. Тобто ти вихопив 1 байт з чотирьох (міліампери), підігнав під ампери і вуаля

Треба було зчитати 4 байти по адресу 4760 (струм в міліамперах) , потім конвертувати в ампери без втрати точністі
Я знайшов той шматок діалог с грок, де я теж так думав, але сканер показав, що при заряді/розряді цей регістр статичний. Я робив все "на живу" та особисто спостерігав зміни, так 4760 був статичний, в 4762 - динамічній, і 4762 відповідав саме точному показнику струму відповідно до блютуз-додатка бмс. На скрінв показав. Я ж кажу, це просто особливості ПЗ, в цьому і була деяка головна біль, з якою я мучився))
 

Вкладення

  • Screenshot_2026-02-20-08-59-42-017_com.android.chrome-edit.jpg
    Screenshot_2026-02-20-08-59-42-017_com.android.chrome-edit.jpg
    205,4 Кб · Перегляди: 4
Назад
Угорі