Daly BMS: различия между версиями

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску
 
(не показано 13 промежуточных версий этого же участника)
Строка 4: Строка 4:
 
[[Категория:Linux]]
 
[[Категория:Linux]]
 
[[Категория:SNMP]]
 
[[Категория:SNMP]]
  +
[[Категория:Zabbix]]
 
=Daly BMS=
 
=Daly BMS=
 
Идея а том что бы снимать данные и складывать в заббикс
 
Идея а том что бы снимать данные и складывать в заббикс
Строка 104: Строка 105:
   
   
  +
=<code>collect_batt_status.sh</code>=
=1=
 
  +
Запускаю из крона (<code>/etc/cron.d/batt_dale_status</code>):
  +
<PRE>
  +
*/3 * * * * root /etc/nut/collect_batt_status.sh
  +
</PRE>
  +
Конечный результат в файле <code>/var/lib/snmp/daly.json</code> (который разбираем для SNMP)
  +
  +
<PRE>
  +
#!/usr/bin/env bash
  +
  +
  +
DEV="/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A5XK3RJT-if00-port0"
  +
  +
sudo -u nut \
  +
/usr/local/virtualenvs/daly-bms-cli/bin/python3 \
  +
/usr/local/virtualenvs/daly-bms-cli/bin/daly-bms-cli -d ${DEV} --all > /tmp/daly.json 2>>/var/lib/snmp/daly.err && \
  +
mv /tmp/daly.json /var/lib/snmp/daly.json
  +
  +
</PRE>
  +
{{#spoiler:show=Пример результата|
  +
  +
<PRE>
  +
{
  +
"soc": {
  +
"total_voltage": 56.1,
  +
"current": 0.6,
  +
"soc_percent": 94.1
  +
},
  +
"cell_voltage_range": {
  +
"highest_voltage": 3.592,
  +
"highest_cell": 9,
  +
"lowest_voltage": 3.409,
  +
"lowest_cell": 15
  +
},
  +
"temperature_range": {
  +
"highest_temperature": 24,
  +
"highest_sensor": 1,
  +
"lowest_temperature": 24,
  +
"lowest_sensor": 1
  +
},
  +
"mosfet_status": {
  +
"mode": "stationary",
  +
"charging_mosfet": true,
  +
"discharging_mosfet": true,
  +
"capacity_ah": 263.48
  +
},
  +
"status": {
  +
"cells": 16,
  +
"temperature_sensors": 2,
  +
"charger_running": false,
  +
"load_running": false,
  +
"states": {
  +
"DI1": false
  +
},
  +
"cycles": 3
  +
},
  +
"cell_voltages": {
  +
"1": 3.487,
  +
"2": 3.525,
  +
"3": 3.475,
  +
"4": 3.482,
  +
"5": 3.539,
  +
"6": 3.363,
  +
"7": 3.526,
  +
"8": 3.559,
  +
"9": 3.592,
  +
"10": 3.498,
  +
"11": 3.512,
  +
"12": 3.516,
  +
"13": 3.46,
  +
"14": 3.478,
  +
"15": 3.409,
  +
"16": 3.531
  +
},
  +
"temperatures": {
  +
"1": 24,
  +
"2": 24
  +
},
  +
"balancing_status": {
  +
"error": "not implemented"
  +
},
  +
"errors": [
  +
"one stage warning of unit over voltage"
  +
]
  +
}
  +
</PRE>
  +
}}
  +
=<code>SNMP</code>=
  +
Для того что бы дергать скрипт на пайтоне через SNMP и отдавать данные заббиксу делаю так
  +
<PRE>
  +
pass .1.3.6.1.4.1.418 /etc/nut/batt-dale-snmp.py
  +
</PRE>
  +
  +
=<code>batt-dale-snmp.py</code>=
  +
{{#spoiler:show=batt-dale-snmp.py|
  +
  +
<PRE>
  +
#!/usr/bin/env python3
  +
  +
import sys
  +
import subprocess
  +
import logging
  +
import json
  +
from logging.handlers import RotatingFileHandler
  +
  +
LOGFILE = "/var/log/snmp/snmp-batt-test.log"
  +
DATA_FILE="/var/lib/snmp/daly.json"
  +
UPS_NAME = "mpp"
  +
  +
def flatten_dict(d, parent_key="", sep="_"):
  +
flat = {}
  +
for key, value in d.items():
  +
new_key = f"{parent_key}{sep}{key}" if parent_key else str(key)
  +
if isinstance(value, dict):
  +
flat.update(flatten_dict(value, new_key, sep=sep))
  +
else:
  +
flat[new_key] = value
  +
return flat
  +
  +
  +
def get_oid_data(key):
  +
with open(DATA_FILE, 'r') as file:
  +
data = json.load(file)
  +
flat = flatten_dict(data)
  +
logger.debug(f"[get_oid_data] data: {data} б flat: {flat}")
  +
val = flat.get(key)
  +
logger.debug(f"[get_oid_data] value: {val}")
  +
return str(val)
  +
  +
  +
def batt_status(nut, nut_key):
  +
val = get_oid_data(nut, nut_key)
  +
s = str(batt_status_code(val))
  +
logger.debug("[batt_status] Status: {s}")
  +
return s
  +
  +
def mosfet_status(key):
  +
with open(DATA_FILE, 'r') as file:
  +
data = json.load(file)
  +
flat = flatten_dict(data)
  +
logger.debug(f"mosfet_status] data: {data} flat: {flat}")
  +
  +
val = flat.get(key)
  +
logger.debug(f"[mosfet_status] value: {val}")
  +
  +
if key == "mosfet_status_mode":
  +
if val == "discharging":
  +
return "1"
  +
else:
  +
return "0"
  +
elif key == "mosfet_status_charging_mosfet":
  +
if val:
  +
return "1"
  +
else:
  +
return "0"
  +
elif key == "mosfet_status_discharging_mosfet":
  +
if val:
  +
return "1"
  +
else:
  +
return "0"
  +
else:
  +
return str(val)
  +
  +
def status_status(key):
  +
with open(DATA_FILE, 'r') as file:
  +
data = json.load(file)
  +
flat = flatten_dict(data)
  +
logger.debug(f"status_status] data: {data} flat: {flat}")
  +
  +
val = flat.get(key)
  +
logger.debug(f"[status_status] value: {val}")
  +
if key == "status_charger_running":
  +
if val:
  +
return "1"
  +
else:
  +
return "0"
  +
elif key == "status_load_running":
  +
if val:
  +
return "1"
  +
else:
  +
return "0"
  +
elif key == "status_states_DI1":
  +
if val:
  +
return "1"
  +
else:
  +
return "0"
  +
else:
  +
return str(val)
  +
  +
  +
OIDS = {
  +
# SOC
  +
"1.3.6.1.4.1.418.1.1": {
  +
"name": "DALYBMS-MIB::soc_total_voltage",
  +
"object_key": "soc_total_voltage",
  +
"max_value": 60
  +
},
  +
"1.3.6.1.4.1.418.1.2": {
  +
"name": "DALYBMS-MIB::soc_current",
  +
"object_key": "soc_current",
  +
"max_value": 100,
  +
"min_value": -80,
  +
  +
},
  +
"1.3.6.1.4.1.418.1.3": {
  +
"name": "DALYBMS-MIB::soc_soc_percent",
  +
"object_key": "soc_soc_percent",
  +
},
  +
# CELL VOLTAGE
  +
"1.3.6.1.4.1.418.2.1": {
  +
"name": "DALYBMS-MIB::cell_voltage_range_highest_voltage",
  +
"object_key": "cell_voltage_range_highest_voltage",
  +
},
  +
"1.3.6.1.4.1.418.2.2": {
  +
"name": "DALYBMS-MIB::cell_voltage_range_highest_cell",
  +
"object_key": "cell_voltage_range_highest_cell",
  +
},
  +
"1.3.6.1.4.1.418.2.3": {
  +
"name": "DALYBMS-MIB::cell_voltage_range_lowest_voltage",
  +
"object_key": "cell_voltage_range_lowest_voltage",
  +
},
  +
"1.3.6.1.4.1.418.3.4": {
  +
"name": "DALYBMS-MIB::cell_voltage_range_lowest_cell",
  +
"object_key": "cell_voltage_range_lowest_cell",
  +
},
  +
# TEMPERATURE RANGE
  +
"1.3.6.1.4.1.418.3.1": {
  +
"name": "DALYBMS-MIB::temperature_range_highest_temperature",
  +
"object_key": "temperature_range_highest_temperature",
  +
"max_value": 35
  +
},
  +
"1.3.6.1.4.1.418.3.2": {
  +
"name": "DALYBMS-MIB::temperature_range_highest_sensor",
  +
"object_key": "temperature_range_highest_sensor",
  +
},
  +
"1.3.6.1.4.1.418.3.3": {
  +
"name": "DALYBMS-MIB::temperature_range_lowest_temperature",
  +
"object_key": "temperature_range_lowest_temperature",
  +
"min_value":0
  +
},
  +
"1.3.6.1.4.1.418.3.4": {
  +
"name": "DALYBMS-MIB::temperature_range_lowest_sensor",
  +
"object_key": "temperature_range_lowest_sensor",
  +
},
  +
# MOSFET STATUS
  +
"1.3.6.1.4.1.418.4.1": {
  +
"name": "DALYBMS-MIB::mosfet_status_mode",
  +
"object_key": "mosfet_status_mode",
  +
"get_oid_method": mosfet_status,
  +
},
  +
"1.3.6.1.4.1.418.4.2": {
  +
"name": "DALYBMS-MIB::mosfet_status_charging_mosfet",
  +
"object_key": "mosfet_status_charging_mosfet",
  +
"get_oid_method": mosfet_status,
  +
},
  +
"1.3.6.1.4.1.418.4.3": {
  +
"name": "DALYBMS-MIB::mosfet_status_discharging_mosfet",
  +
"object_key": "mosfet_status_discharging_mosfet",
  +
"get_oid_method": mosfet_status,
  +
},
  +
"1.3.6.1.4.1.418.4.4": {
  +
"name": "DALYBMS-MIB::mosfet_status_capacity_ah",
  +
"object_key": "mosfet_status_capacity_ah",
  +
"get_oid_method": mosfet_status,
  +
"max_value": 400,
  +
"min_value": 0,
  +
},
  +
#
  +
#status_cycles
  +
"1.3.6.1.4.1.418.5.1.0": {
  +
"name": "DALYBMS-MIB::status_cells",
  +
"object_key": "status_cells",
  +
},
  +
"1.3.6.1.4.1.418.5.2.0": {
  +
"name": "DALYBMS-MIB::status_temperature_sensors",
  +
"object_key": "status_temperature_sensors",
  +
},
  +
"1.3.6.1.4.1.418.5.3.0": {
  +
"name": "DALYBMS-MIB::status_charger_running",
  +
"object_key": "status_charger_running",
  +
"get_oid_method": status_status,
  +
},
  +
"1.3.6.1.4.1.418.5.4.0": {
  +
"name": "DALYBMS-MIB::status_load_running",
  +
"object_key": "status_load_running",
  +
"get_oid_method": status_status,
  +
},
  +
"1.3.6.1.4.1.418.5.5.0": {
  +
"name": "DALYBMS-MIB::status_states_DI1",
  +
"object_key": "status_states_DI1",
  +
"get_oid_method": status_status,
  +
},
  +
"1.3.6.1.4.1.418.5.6.0": {
  +
"name": "DALYBMS-MIB::status_cycles",
  +
"object_key": "status_cycles",
  +
},
  +
# cell_voltages
  +
"1.3.6.1.4.1.418.6.1": {
  +
"name": "DALYBMS-MIB::cell_voltages_1",
  +
"object_key": "cell_voltages_1",
  +
"min_value": 2.7,
  +
},
  +
"1.3.6.1.4.1.418.6.2": {
  +
"name": "DALYBMS-MIB::cell_voltages_2",
  +
"object_key": "cell_voltages_2",
  +
"min_value": 2.7,
  +
},
  +
"1.3.6.1.4.1.418.6.3": {
  +
"name": "DALYBMS-MIB::cell_voltages_3",
  +
"object_key": "cell_voltages_3",
  +
"min_value": 2.7,
  +
},
  +
"1.3.6.1.4.1.418.6.4": {
  +
"name": "DALYBMS-MIB::cell_voltages_4",
  +
"object_key": "cell_voltages_4",
  +
"min_value": 2.7,
  +
},
  +
"1.3.6.1.4.1.418.6.5": {
  +
"name": "DALYBMS-MIB::cell_voltages_5",
  +
"object_key": "cell_voltages_5",
  +
"min_value": 2.7,
  +
},
  +
"1.3.6.1.4.1.418.6.6": {
  +
"name": "DALYBMS-MIB::cell_voltages_6",
  +
"object_key": "cell_voltages_6",
  +
"min_value": 2.7,
  +
},
  +
"1.3.6.1.4.1.418.6.7": {
  +
"name": "DALYBMS-MIB::cell_voltages_6",
  +
"object_key": "cell_voltages_7",
  +
"min_value": 2.7,
  +
},
  +
"1.3.6.1.4.1.418.6.8": {
  +
"name": "DALYBMS-MIB::cell_voltages_8",
  +
"object_key": "cell_voltages_8",
  +
"min_value": 2.7,
  +
},
  +
"1.3.6.1.4.1.418.6.9": {
  +
"name": "DALYBMS-MIB::cell_voltages_9",
  +
"object_key": "cell_voltages_9",
  +
"min_value": 2.7,
  +
},
  +
"1.3.6.1.4.1.418.6.10": {
  +
"name": "DALYBMS-MIB::cell_voltages_10",
  +
"object_key": "cell_voltages_10",
  +
"min_value": 2.7,
  +
},
  +
"1.3.6.1.4.1.418.6.11": {
  +
"name": "DALYBMS-MIB::cell_voltages_11",
  +
"object_key": "cell_voltages_11",
  +
"min_value": 2.7,
  +
},
  +
"1.3.6.1.4.1.418.6.12": {
  +
"name": "DALYBMS-MIB::cell_voltages_12",
  +
"object_key": "cell_voltages_12",
  +
"min_value": 2.7,
  +
},
  +
"1.3.6.1.4.1.418.6.13": {
  +
"name": "DALYBMS-MIB::cell_voltages_13",
  +
"object_key": "cell_voltages_13",
  +
"min_value": 2.7,
  +
},
  +
"1.3.6.1.4.1.418.6.14": {
  +
"name": "DALYBMS-MIB::cell_voltages_14",
  +
"object_key": "cell_voltages_14",
  +
"min_value": 2.7,
  +
},
  +
"1.3.6.1.4.1.418.6.15": {
  +
"name": "DALYBMS-MIB::cell_voltages_15",
  +
"object_key": "cell_voltages_15",
  +
"min_value": 2.7,
  +
},
  +
"1.3.6.1.4.1.418.6.16": {
  +
"name": "DALYBMS-MIB::cell_voltages_16",
  +
"object_key": "cell_voltages_16",
  +
"min_value": 2.7,
  +
},
  +
  +
# temperatures
  +
"1.3.6.1.4.1.418.7.1": {
  +
"name": "DALYBMS-MIB::temperatures_1",
  +
"object_key": "temperatures_1",
  +
},
  +
"1.3.6.1.4.1.418.7.2": {
  +
"name": "DALYBMS-MIB::temperatures_2",
  +
"object_key": "temperatures_2",
  +
},
  +
}
  +
  +
  +
  +
def get_logger():
  +
logger = logging.getLogger("snmp_test_oid")
  +
if logger.handlers:
  +
return logger
  +
  +
# logger.setLevel(logging.INFO)
  +
logger.setLevel(logging.DEBUG)
  +
  +
handler = RotatingFileHandler(
  +
LOGFILE,
  +
maxBytes=200_000_000,
  +
backupCount=3,
  +
)
  +
fmt = logging.Formatter(
  +
"%(asctime)s [%(levelname)s] %(message)s",
  +
"%Y-%m-%dT%H:%M:%S",
  +
)
  +
handler.setFormatter(fmt)
  +
logger.addHandler(handler)
  +
  +
return logger
  +
  +
  +
logger = get_logger()
  +
  +
# Это нужно что бы сортировать OID правильно
  +
# строковая сортировка в лоб дает неправильнй результат
  +
# ".1.3.6.1.2.1.33.1.10" < ".1.3.6.1.2.1.33.1.2" как строки
  +
# а по SNMP-логике должно быть наоборот (10 > 2).
  +
def oid_key(oid: str):
  +
return tuple(int(x) for x in oid.strip(".").split(".") if x)
  +
  +
def batt_status_code(status_str: str) -> int:
  +
"""
  +
UPS-MIB upsBatteryStatus:
  +
1=unknown, 2=normal, 3=low, 4=depleted
  +
"""
  +
if "LB" in status_str:
  +
return 3
  +
if "OB" in status_str or "OL" in status_str:
  +
return 2
  +
return 1
  +
  +
  +
def value_for_oid(oid: str):
  +
"""Вернуть (type, value) или (None, None), если OID не знаем."""
  +
# По умолчанию
  +
OID = OIDS.get(oid)
  +
logger.debug(f"OID object: {OID}")
  +
if OID:
  +
logger.debug(f"[value_for_oid] OID = {OID.get('name')}: {oid}")
  +
get_method = OID.get("get_oid_method", get_oid_data)
  +
  +
try:
  +
oid_value = get_method(OID.get("object_key"))
  +
except TypeError:
  +
oid_value = get_method()
  +
  +
oid_type = OID.get("type", "string")
  +
custom_multiplier = OID.get("custom_multiplier", 1)
  +
logger.debug(f"[value_for_oid] custom_multiplier: {custom_multiplier}")
  +
if custom_multiplier != 1:
  +
try:
  +
oid_value_digit = float(oid_value)
  +
oid_value = oid_value_digit * custom_multiplier
  +
  +
except Exception as e:
  +
logger.debug(f"[value_for_oid] Error: {e}, ignoring. Original value: {oid_value}")
  +
  +
# ингда приходят странные данные которые я хочу игнорировать
  +
try:
  +
oid_value_digit = float(oid_value)
  +
logger.debug(f"[value_for_oid] Check min/max value for OID {oid}")
  +
max_value = OID.get("max_value", oid_value_digit)
  +
min_value = OID.get("min_value", oid_value_digit)
  +
logger.debug(f"[value_for_oid] MAX value for OID {oid} is {max_value}")
  +
logger.debug(f"[value_for_oid] MIN value for OID {oid} is {min_value}")
  +
if oid_value_digit > max_value:
  +
oid_value = max_value
  +
  +
if oid_value_digit < min_value:
  +
oid_value = min_value
  +
  +
except Exception as e:
  +
logger.debug(f"[value_for_oid] Error (not float data): {e}, ignoring. Original value: {oid_value}")
  +
  +
logger.debug(f"OID Data: {oid} {oid_type} {oid_value}")
  +
  +
  +
return (oid_type, str(oid_value))
  +
  +
logger.debug(f"[value_for_oid] OID is not in the list of known OIDs")
  +
return (None, None)
  +
  +
  +
def handle_get(oid: str):
  +
logger.debug(f"handle GET: oid: {oid}")
  +
t, v = value_for_oid(oid)
  +
if t is None:
  +
logger.debug(f"handle GET: type: None")
  +
# Ничего не печатаем -> NoSuchInstance
  +
return
  +
  +
logger.debug(f"handle GET: oid: {oid} type: {t} value: {v}")
  +
logger.debug("Data printed to stdout 1")
  +
  +
print(f".{oid}")
  +
print(f"{t}")
  +
print(f"{v}")
  +
logger.debug("Data printed to stdout")
  +
  +
  +
  +
  +
def handle_getnext(request_oid: str):
  +
# Преобразовать строковый OID в tuple
  +
req_key = oid_key(request_oid)
  +
logger.debug(f"[handle_getnext] {request_oid} {req_key}")
  +
  +
# Сортировка по ключу tuple
  +
SORTED_OIDS = sorted(OIDS.keys(), key=oid_key)
  +
  +
# сначала пробуем найти точное совпадение
  +
try:
  +
# так как ищем след от текущего то находим индекс текущего
  +
# если он не последний -- if idx + 1 < len(SORTED_OIDS)
  +
idx = SORTED_OIDS.index(request_oid)
  +
logger.debug(f"[handle_getnext] {request_oid} has index {idx}")
  +
next_oid = SORTED_OIDS[idx + 1] if idx + 1 < len(SORTED_OIDS) else None
  +
logger.debug(f"[handle_getnext] Next OID {next_oid}")
  +
except ValueError:
  +
# если точного совпадения нет — ищем первый > request_oid
  +
next_oid = None
  +
for candidate in SORTED_OIDS:
  +
#
  +
if oid_key(candidate) > req_key:
  +
next_oid = candidate
  +
logger.debug(f"[handle_getnext] Next OID {next_oid}")
  +
break
  +
  +
if not next_oid:
  +
logger.debug(f"[handle_getnext] Next OID ont found")
  +
return # NoSuchInstance (ничего не печатаем)
  +
  +
oid_type, oid_value = value_for_oid(next_oid)
  +
  +
logger.debug(f"handle GET: oid: {next_oid} type: {oid_type} value: {oid_value}")
  +
logger.debug("Data printed to stdout")
  +
print(f".{next_oid}")
  +
print(f"{oid_type}")
  +
print(f"{oid_value}")
  +
logger.debug("Data printed to stdout")
  +
  +
  +
def main():
  +
logger.debug(f"sys.argv: {sys.argv}")
  +
if len(sys.argv) < 3:
  +
logger.debug(f"sys.argv should be 3 arguments, nothing to do, exiting")
  +
return
  +
  +
cmd = sys.argv[1]
  +
# Remove leading dot if any
  +
oid = sys.argv[2]
  +
oid = oid.lstrip('.')
  +
logger.debug(f"cmd: {cmd}. OID: {oid}")
  +
  +
if cmd == "-g":
  +
logger.debug("Handle get")
  +
handle_get(oid)
  +
elif cmd == "-n":
  +
logger.debug("Handle get next")
  +
handle_getnext(oid)
  +
# SET не поддерживаем, ничего не печатаем
  +
else:
  +
logger.debug("Handle is not configured")
  +
  +
if __name__ == "__main__":
  +
logger.info("Start")
  +
main()
  +
</PRE>
  +
  +
}}
  +
=Zabbix Template=
  +
Максимально просто, никаких дискавери, все элемент просто получаются по OID
  +
{{#spoiler:show=template.yaml|
  +
<PRE>
  +
zabbix_export:
  +
version: '7.0'
  +
template_groups:
  +
- uuid: 3dcd5bbe90534f9e8eb5c2d53756af63
  +
name: Templates/Power
  +
templates:
  +
- uuid: 6044b86a15594724ab3ed309627776eb
  +
template: 'Template DALY BMS by SNMP'
  +
name: 'Template DALY BMS by SNMP'
  +
groups:
  +
- name: Templates/Power
  +
items:
  +
- uuid: cbe5ae7ef5064a3789d59212d284648e
  +
name: cell_voltages_1
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.6.1
  +
key: cell_voltages_1
  +
history: 365d
  +
value_type: FLOAT
  +
units: V
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: bd2b5a652688438482d824e57febca0e
  +
name: cell_voltages_2
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.6.2
  +
key: cell_voltages_2
  +
history: 365d
  +
value_type: FLOAT
  +
units: V
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: ccdd99bd03e34afaa9f566fd903ab2e6
  +
name: cell_voltages_3
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.6.3
  +
key: cell_voltages_3
  +
history: 365d
  +
value_type: FLOAT
  +
units: V
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: ea62e350c5e14fa3b349a4f232f9ce94
  +
name: cell_voltages_4
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.6.4
  +
key: cell_voltages_4
  +
history: 365d
  +
value_type: FLOAT
  +
units: V
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: aecac8b9da0847b7b81a04cf486b47f9
  +
name: cell_voltages_5
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.6.5
  +
key: cell_voltages_5
  +
history: 365d
  +
value_type: FLOAT
  +
units: V
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 1f7e3b69c5054187b1b0ad20eb527db3
  +
name: cell_voltages_6
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.6.6
  +
key: cell_voltages_6
  +
history: 365d
  +
value_type: FLOAT
  +
units: V
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 6f86549b7c2b4a4b90af311f39b0fc7c
  +
name: cell_voltages_7
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.6.7
  +
key: cell_voltages_7
  +
history: 365d
  +
value_type: FLOAT
  +
units: V
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: d5a7c8ea041a48a1899608c0abc27664
  +
name: cell_voltages_8
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.6.8
  +
key: cell_voltages_8
  +
history: 365d
  +
value_type: FLOAT
  +
units: V
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 594d43cdce694ac894b12e9b25e2218d
  +
name: cell_voltages_9
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.6.9
  +
key: cell_voltages_9
  +
history: 365d
  +
value_type: FLOAT
  +
units: V
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: f23a34a1a6684001be0d79907820ee0e
  +
name: cell_voltages_10
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.6.10
  +
key: cell_voltages_10
  +
history: 365d
  +
value_type: FLOAT
  +
units: V
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: c4ce669ac14a4d4393ec82c573e7e51d
  +
name: cell_voltages_11
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.6.11
  +
key: cell_voltages_11
  +
history: 365d
  +
value_type: FLOAT
  +
units: V
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: c1a245d1bf9e4abdb57f74471fea0247
  +
name: cell_voltages_12
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.6.12
  +
key: cell_voltages_12
  +
history: 365d
  +
value_type: FLOAT
  +
units: V
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 6ed6ef135b65454eb08822d495bb9a5e
  +
name: cell_voltages_13
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.6.13
  +
key: cell_voltages_13
  +
history: 365d
  +
value_type: FLOAT
  +
units: V
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 4ecc6516e79444eda478c2d69978978c
  +
name: cell_voltages_14
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.6.14
  +
key: cell_voltages_14
  +
history: 365d
  +
value_type: FLOAT
  +
units: V
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 9d546a8decda4fa58938daf3d004ba70
  +
name: cell_voltages_15
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.6.15
  +
key: cell_voltages_15
  +
history: 365d
  +
value_type: FLOAT
  +
units: V
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 8e17e4caa0bf4f168a40414826b6f76f
  +
name: cell_voltages_16
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.6.16
  +
key: cell_voltages_16
  +
history: 365d
  +
value_type: FLOAT
  +
units: V
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: a929ffda17dd43fd9ec9fe181ffbfa23
  +
name: cell_voltage_range_highest_cell
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.2.2
  +
key: cell_voltage_range_highest_cell
  +
history: 365d
  +
value_type: FLOAT
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 5305259c5f084a1fa7d22a224c304734
  +
name: cell_voltage_range_highest_voltage
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.2.1
  +
key: cell_voltage_range_highest_voltage
  +
history: 365d
  +
value_type: FLOAT
  +
units: V
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 7ad75f03d7334606a9ed130f0e51ae56
  +
name: cell_voltage_range_lowest_cell
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.2.4
  +
key: cell_voltage_range_lowest_cell
  +
history: 365d
  +
value_type: FLOAT
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: b861dd43f76b4b4c8d5f780f761c7c1c
  +
name: cell_voltage_range_lowest_voltage
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.2.3
  +
key: cell_voltage_range_lowest_voltage
  +
history: 365d
  +
value_type: FLOAT
  +
units: V
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 3d1c490069994842853e8f9606352cbd
  +
name: mosfet_status_capacity_ah
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.4.4
  +
key: mosfet_status_capacity_ah
  +
history: 365d
  +
value_type: FLOAT
  +
units: 'A*H'
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 6ccca7e31baa4965aed35572664ed167
  +
name: mosfet_status_charging_mosfet
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.4.2
  +
key: mosfet_status_charging_mosfet
  +
history: 365d
  +
value_type: FLOAT
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 3ee90a36692c483c992eae93b12a7108
  +
name: mosfet_status_discharging_mosfet
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.4.3
  +
key: mosfet_status_discharging_mosfet
  +
history: 365d
  +
value_type: FLOAT
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: fe31f1f091ca4daeb777d99e90ab0d83
  +
name: mosfet_status_mode
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.4.1
  +
key: mosfet_status_mode
  +
history: 365d
  +
value_type: FLOAT
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 56f94235dff545f99a63a70b8acdfe61
  +
name: soc_current
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.1.2
  +
key: soc_current
  +
history: 365d
  +
value_type: FLOAT
  +
units: A
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 172212b88fef4cbebec583d11dc5b5cd
  +
name: soc_soc_percent
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.1.3
  +
key: soc_soc_percent
  +
history: 365d
  +
value_type: FLOAT
  +
units: '%'
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 95eeef199f8f40a9a18caaa9a9665378
  +
name: soc_total_voltage
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.1.1
  +
key: soc_total_voltage
  +
history: 365d
  +
value_type: FLOAT
  +
units: V
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 4571efd987634eeb9ab5ace33fe5997a
  +
name: status_cells
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.5.1.0
  +
key: status_cells
  +
history: 365d
  +
value_type: FLOAT
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 996ed11a787c45c981b9fad4316976a1
  +
name: status_charger_running
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.5.3.0
  +
key: status_charger_running
  +
history: 365d
  +
value_type: FLOAT
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 08569b139e404c07b93ecc9fe8c0fd55
  +
name: status_cycles
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.5.6.0
  +
key: status_cycles
  +
history: 365d
  +
value_type: FLOAT
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: a16015a367d14db49a59e0e62eafae68
  +
name: status_load_running
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.5.4.0
  +
key: status_load_running
  +
history: 365d
  +
value_type: FLOAT
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 89d8714254214a0fb720608fb1c5bc06
  +
name: status_states_DI1
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.5.5.0
  +
key: status_states_DI1
  +
history: 365d
  +
value_type: FLOAT
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 830947cb28f64816a60ecb6a2a47c8c6
  +
name: status_temperature_sensors
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.5.2.0
  +
key: status_temperature_sensors
  +
history: 365d
  +
value_type: FLOAT
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 62aee0d7f2f945d38a1160647b58729e
  +
name: temperatures_1
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.7.1
  +
key: temperatures_1
  +
history: 365d
  +
value_type: FLOAT
  +
units: C
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: e9223f34756c4ceabbf1f71f6e162d15
  +
name: temperatures_2
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.7.2
  +
key: temperatures_2
  +
history: 365d
  +
value_type: FLOAT
  +
units: C
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 5ad90b295e9e4fc7b17981cd986bdf8d
  +
name: temperature_range_highest_sensor
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.3.2
  +
key: temperature_range_highest_sensor
  +
history: 365d
  +
value_type: FLOAT
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: b51f6da831bf45409c6043a995a0d262
  +
name: temperature_range_highest_temperature
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.3.1
  +
key: temperature_range_highest_temperature
  +
history: 365d
  +
value_type: FLOAT
  +
units: C
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 15ea5da6198440b382bb0042481ffafd
  +
name: temperature_range_lowest_sensor
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.3.4
  +
key: temperature_range_lowest_sensor
  +
history: 365d
  +
value_type: FLOAT
  +
units: C
  +
tags:
  +
- tag: component
  +
value: power
  +
- uuid: 9ebe055204224cee82bd4c56aff4708f
  +
name: temperature_range_lowest_temperature
  +
type: SNMP_AGENT
  +
snmp_oid: 1.3.6.1.4.1.418.3.3
  +
key: temperature_range_lowest_temperature
  +
history: 365d
  +
value_type: FLOAT
  +
units: C
  +
tags:
  +
- tag: component
  +
value: power
  +
tags:
  +
- tag: class
  +
value: power
  +
- tag: target
  +
value: BMS
  +
- tag: target
  +
value: DALY
  +
dashboards:
  +
- uuid: bc012219291246a990a28971eb210477
  +
name: 'Daly BMS'
  +
display_period: '120'
  +
pages:
  +
- widgets:
  +
- type: svggraph
  +
name: 'BMS Voltage / Percent'
  +
width: '72'
  +
height: '5'
  +
fields:
  +
- type: STRING
  +
name: ds.0.color
  +
value: FF465C
  +
- type: STRING
  +
name: ds.0.items.0
  +
value: soc_total_voltage
  +
- type: INTEGER
  +
name: ds.1.axisy
  +
value: '1'
  +
- type: STRING
  +
name: ds.1.color
  +
value: FFD54F
  +
- type: STRING
  +
name: ds.1.items.0
  +
value: soc_soc_percent
  +
- type: STRING
  +
name: reference
  +
value: PHJOY
  +
- type: svggraph
  +
name: 'BMS Cells Voltage'
  +
'y': '5'
  +
width: '72'
  +
height: '5'
  +
fields:
  +
- type: STRING
  +
name: ds.0.color
  +
value: 4000FF
  +
- type: INTEGER
  +
name: ds.0.fill
  +
value: '0'
  +
- type: STRING
  +
name: ds.0.items.0
  +
value: cell_voltages_1
  +
- type: STRING
  +
name: ds.0.items.1
  +
value: cell_voltages_2
  +
- type: STRING
  +
name: ds.0.items.2
  +
value: cell_voltages_3
  +
- type: STRING
  +
name: ds.0.items.3
  +
value: cell_voltages_4
  +
- type: STRING
  +
name: ds.0.items.4
  +
value: cell_voltages_5
  +
- type: STRING
  +
name: ds.0.items.5
  +
value: cell_voltages_6
  +
- type: STRING
  +
name: ds.0.items.6
  +
value: cell_voltages_7
  +
- type: STRING
  +
name: ds.0.items.7
  +
value: cell_voltages_8
  +
- type: STRING
  +
name: ds.0.items.8
  +
value: cell_voltages_9
  +
- type: STRING
  +
name: ds.0.items.9
  +
value: cell_voltages_10
  +
- type: STRING
  +
name: ds.0.items.10
  +
value: cell_voltages_11
  +
- type: STRING
  +
name: ds.0.items.11
  +
value: cell_voltages_12
  +
- type: STRING
  +
name: ds.0.items.12
  +
value: cell_voltages_13
  +
- type: STRING
  +
name: ds.0.items.13
  +
value: cell_voltages_14
  +
- type: STRING
  +
name: ds.0.items.14
  +
value: cell_voltages_15
  +
- type: STRING
  +
name: ds.0.items.15
  +
value: cell_voltages_16
  +
- type: INTEGER
  +
name: ds.1.axisy
  +
value: '1'
  +
- type: STRING
  +
name: ds.1.color
  +
value: FF4000
  +
- type: STRING
  +
name: ds.1.items.0
  +
value: cell_voltage_range_highest_voltage
  +
- type: INTEGER
  +
name: ds.1.type
  +
value: '1'
  +
- type: INTEGER
  +
name: ds.2.axisy
  +
value: '1'
  +
- type: STRING
  +
name: ds.2.color
  +
value: 00897B
  +
- type: STRING
  +
name: ds.2.items.0
  +
value: cell_voltage_range_lowest_voltage
  +
- type: INTEGER
  +
name: ds.2.type
  +
value: '1'
  +
- type: STRING
  +
name: lefty_max
  +
value: '3.8'
  +
- type: STRING
  +
name: lefty_min
  +
value: '2.7'
  +
- type: INTEGER
  +
name: legend_lines
  +
value: '10'
  +
- type: INTEGER
  +
name: legend_lines_mode
  +
value: '1'
  +
- type: STRING
  +
name: reference
  +
value: ZATVX
  +
- type: STRING
  +
name: righty_max
  +
value: '3.8'
  +
- type: STRING
  +
name: righty_min
  +
value: '2.7'
  +
- type: svggraph
  +
name: 'SOC current'
  +
'y': '10'
  +
width: '72'
  +
height: '5'
  +
fields:
  +
- type: STRING
  +
name: ds.0.color
  +
value: FF465C
  +
- type: STRING
  +
name: ds.0.items.0
  +
value: soc_current
  +
- type: STRING
  +
name: lefty_max
  +
value: '80'
  +
- type: STRING
  +
name: lefty_min
  +
value: '-80'
  +
- type: STRING
  +
name: reference
  +
value: BVHUJ
  +
- type: INTEGER
  +
name: righty
  +
value: '0'
  +
- type: svggraph
  +
name: mosfet_status_capacity_ah
  +
'y': '15'
  +
width: '72'
  +
height: '5'
  +
fields:
  +
- type: STRING
  +
name: ds.0.color
  +
value: FF465C
  +
- type: STRING
  +
name: ds.0.items.0
  +
value: mosfet_status_capacity_ah
  +
- type: STRING
  +
name: lefty_max
  +
value: '300'
  +
- type: STRING
  +
name: lefty_min
  +
value: '0'
  +
- type: STRING
  +
name: reference
  +
value: QSQWU
  +
- type: INTEGER
  +
name: righty
  +
value: '0'
  +
- type: svggraph
  +
name: mosfet_status_charging_mosfet
  +
'y': '20'
  +
width: '72'
  +
height: '5'
  +
fields:
  +
- type: STRING
  +
name: ds.0.color
  +
value: FF465C
  +
- type: STRING
  +
name: ds.0.items.0
  +
value: mosfet_status_charging_mosfet
  +
- type: STRING
  +
name: ds.0.items.1
  +
value: mosfet_status_discharging_mosfet
  +
- type: STRING
  +
name: ds.0.items.2
  +
value: mosfet_status_mode
  +
- type: STRING
  +
name: reference
  +
value: DYIIC
  +
- type: INTEGER
  +
name: righty
  +
value: '0'
  +
- type: svggraph
  +
name: Temperature
  +
'y': '25'
  +
width: '71'
  +
height: '5'
  +
fields:
  +
- type: STRING
  +
name: ds.0.color
  +
value: FF465C
  +
- type: STRING
  +
name: ds.0.items.0
  +
value: temperature_range_highest_temperature
  +
- type: STRING
  +
name: ds.0.items.1
  +
value: temperature_range_lowest_temperature
  +
- type: STRING
  +
name: ds.1.color
  +
value: FFD54F
  +
- type: STRING
  +
name: ds.1.items.0
  +
value: temperatures_1
  +
- type: STRING
  +
name: ds.1.items.1
  +
value: temperatures_2
  +
- type: STRING
  +
name: lefty_max
  +
value: '35'
  +
- type: STRING
  +
name: lefty_min
  +
value: '0'
  +
- type: STRING
  +
name: reference
  +
value: XQRWM
  +
- type: INTEGER
  +
name: righty
  +
value: '0'
  +
graphs:
  +
- uuid: 2e63e3e1831a45e48a1ae46b434ec79d
  +
name: 'Battery Total SOC Voltage'
  +
graph_items:
  +
- color: 1A7C11
  +
calc_fnc: ALL
  +
item:
  +
host: 'Template DALY BMS by SNMP'
  +
key: soc_total_voltage
  +
- uuid: f1e954331c50430780493379b967be65
  +
name: 'Cell Voltages'
  +
yaxismax: '0'
  +
show_work_period: 'NO'
  +
show_triggers: 'NO'
  +
type: PIE
  +
graph_items:
  +
- color: '274482'
  +
calc_fnc: MIN
  +
item:
  +
host: 'Template DALY BMS by SNMP'
  +
key: cell_voltages_1
  +
- sortorder: '1'
  +
color: 1A7C11
  +
calc_fnc: MIN
  +
item:
  +
host: 'Template DALY BMS by SNMP'
  +
key: cell_voltages_2
  +
- sortorder: '2'
  +
color: F63100
  +
calc_fnc: MIN
  +
item:
  +
host: 'Template DALY BMS by SNMP'
  +
key: cell_voltages_3
  +
- sortorder: '3'
  +
color: 2774A4
  +
calc_fnc: MIN
  +
item:
  +
host: 'Template DALY BMS by SNMP'
  +
key: cell_voltages_4
  +
- sortorder: '4'
  +
color: A54F10
  +
calc_fnc: MIN
  +
item:
  +
host: 'Template DALY BMS by SNMP'
  +
key: cell_voltages_5
  +
- sortorder: '5'
  +
color: FC6EA3
  +
calc_fnc: MIN
  +
item:
  +
host: 'Template DALY BMS by SNMP'
  +
key: cell_voltages_6
  +
- sortorder: '6'
  +
color: 6C59DC
  +
calc_fnc: MIN
  +
item:
  +
host: 'Template DALY BMS by SNMP'
  +
key: cell_voltages_7
  +
- sortorder: '7'
  +
color: AC8C14
  +
calc_fnc: MIN
  +
item:
  +
host: 'Template DALY BMS by SNMP'
  +
key: cell_voltages_8
  +
- sortorder: '8'
  +
color: 611F27
  +
calc_fnc: MIN
  +
item:
  +
host: 'Template DALY BMS by SNMP'
  +
key: cell_voltages_9
  +
- sortorder: '9'
  +
color: F230E0
  +
calc_fnc: MIN
  +
item:
  +
host: 'Template DALY BMS by SNMP'
  +
key: cell_voltages_10
  +
- sortorder: '10'
  +
color: 5CCD18
  +
calc_fnc: MIN
  +
item:
  +
host: 'Template DALY BMS by SNMP'
  +
key: cell_voltages_11
  +
- sortorder: '11'
  +
color: BB2A02
  +
calc_fnc: MIN
  +
item:
  +
host: 'Template DALY BMS by SNMP'
  +
key: cell_voltages_12
  +
- sortorder: '12'
  +
color: 5A2B57
  +
calc_fnc: MIN
  +
item:
  +
host: 'Template DALY BMS by SNMP'
  +
key: cell_voltages_13
  +
- sortorder: '13'
  +
color: 89ABF8
  +
calc_fnc: MIN
  +
item:
  +
host: 'Template DALY BMS by SNMP'
  +
key: cell_voltages_14
  +
- sortorder: '14'
  +
color: 7EC25C
  +
calc_fnc: MIN
  +
item:
  +
host: 'Template DALY BMS by SNMP'
  +
key: cell_voltages_15
  +
- sortorder: '15'
  +
color: 2B5429
  +
calc_fnc: MIN
  +
item:
  +
host: 'Template DALY BMS by SNMP'
  +
key: cell_voltages_16
  +
</PRE>
  +
}}

Текущая версия на 17:54, 15 января 2026

Daly BMS

Идея а том что бы снимать данные и складывать в заббикс

  • дернуть скрипт кроном раз в минуту batt-dale-snmp.py, результат работы сохранить в файл (/var/lib/snmp/daly.json)
  • отдать результат через SNMP pass

Прежде чем начать

У меня сгорел "родной" переходник на котором был распаян разъем (фото нет, и я не знаю как он называется - и нигде не смог найти такой!)
Для замены использовал такой переходник:
Daly BMS 1.JPG

Icon-caution.gif

У меня напряжение было 3.3В на пинах RX/TX со стороны BMC - отсюда я сделал вывод что надо переключить UART-конвертер в 3.3V (джампер)


Daly BMS 2.JPG

Фото BMS в шакальем качестве

Daly BMS 3.JPG

Dalybms на python.

В консоли устанавливаем python-pip

sudo apt install python3-pip

Далее создать virtualenv и устанавливаем dalybms

pip3 install dalybms

для работы с uat портом и mqtt сервером ставим соответствующие пакеты

pip3 install pyserial

Модуль для MQTT по желанию (мне не был нужен)

pip3 install paho-mqtt

необходимо так же установить mqtt сервер если он ещё не установлен и нужен <ЗКУ> sudo apt install mosquitto

на этом установка завершена подключаем нашу BMS к uart порту либо через usb-uart адаптер либо через uart разъем на одноплатнике (необходимо включить порт в настройках), далее будет рассмотрено подключение через usb-uart Подключаем следующим образом:

BMS — UART
GND — GND
RX — TX
TX — RX

После подключения usb-uart адаптера смотрим имя адаптера введя команду

ls -n /dev/ttyU*

должен показать устройства

crw-rw—- 1 0 20 188, 0 Feb 24 21:12 /dev/ttyUSB0
crw-rw—-+ 1 0 20 188, 0 Feb 24 19:57 /dev/ttyUSB1

где /dev/ttyUSB0 и /dev/ttyUSB1 это наши USB устройства, у меня их 2 и с этим могут быть проблемы поскольку при перезагрузки они могут иметь имена наоборот и после перезагрузки устройства не будут работать. Для того чтобы это исключить мы будем обращаться к устройства по ID, получаем id наших устройств, вводим команду:

ls -n /dev/serial/by-id/*

получаем список

lrwxrwxrwx 1 0 0 13 Sep 8 09:58 /dev/serial/by-id/usb-ITead_Sonoff_Zigbee_3.0_USB_Dongle_Plus_12967c31b312ec11b6da21c7bd930c07-if00-port0 -> ../../ttyUSB0
lrwxrwxrwx 1 0 0 13 Feb 24 22:18 /dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0 -> ../../ttyUSB1
ls -n /dev/serial/by-id/*
lrwxrwxrwx 1 0 0 13 Jan 12 15:29 /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A5XK3RJT-if00-port0 -> ../../ttyUSB0

синим это наши устройства, в дальнейшем в конфигах и командах можно использовать как /dev/ttyUSB0 так и полный путь к id устройству. У меня как видно Sonoff Zigbee USB стик и USB-UART адаптер на чипе CP2102 (USB-UART адаптеры бывают на разных чипах) Теперь проверим соединение с нашей BMS.

daly-bms-cli -d /dev/ttyUSB0 --all

или можно по id,

daly-bms-cli -d /dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0 --all

мы получим все параметры. Если данные не получены то возможно Ваша BMS сделана на другом чипе, для этого надо добавить флаг —sinowealth

daly-bms-cli -d /dev/ttyUSB0 --all --sinowealth

Теперь есть несколько вариантов просмотра данных, не зависимо от того какую систему домашней автоматизации Вы используете мы будем передавать данные в систему домашней автоматизации по популярному протоколу mqtt, команда которую мы написали выше будет иметь вид:

daly-bms-cli -d /dev/ttyUSB0 --all --mqtt


collect_batt_status.sh

Запускаю из крона (/etc/cron.d/batt_dale_status):

*/3 * * * * root /etc/nut/collect_batt_status.sh

Конечный результат в файле /var/lib/snmp/daly.json (который разбираем для SNMP)

#!/usr/bin/env bash


DEV="/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A5XK3RJT-if00-port0"

sudo -u nut \
    /usr/local/virtualenvs/daly-bms-cli/bin/python3 \
         /usr/local/virtualenvs/daly-bms-cli/bin/daly-bms-cli -d ${DEV} --all > /tmp/daly.json 2>>/var/lib/snmp/daly.err && \
    mv /tmp/daly.json /var/lib/snmp/daly.json

SNMP

Для того что бы дергать скрипт на пайтоне через SNMP и отдавать данные заббиксу делаю так

pass .1.3.6.1.4.1.418 /etc/nut/batt-dale-snmp.py

batt-dale-snmp.py

Zabbix Template

Максимально просто, никаких дискавери, все элемент просто получаются по OID