use "48V_LIFEPO4_BATTERY ", one space character at the end!hello, can you please confirm the password since it doesn't work?
many thanks
use "48V_LIFEPO4_BATTERY ", one space character at the end!hello, can you please confirm the password since it doesn't work?
many thanks
Yes... THX.Is this Node-Red? Looks amazing!
[{"id":"e8741fa499dd6155","type":"tab","label":"Batteries From China","disabled":false,"info":"","env":[]},{"id":"b80ca6efc679cf53","type":"function","z":"e8741fa499dd6155","name":"request","func":"/*\nSAMPLE\n 1: ~ SOI\n 2: 22 VER\n 3: 01 ADR\n 4: 4A CID1 \n 5: 42 CID2 Get analaog values\n 6: E0 LEN1 Length checksum = E\n 7: 02 LEN2 Length 2 hex bytes\n 8: 01 INFO Get pack 1 data\n 9: FD CHKSUM\n10: 28 CHKSUM\n11: CR EOI \n*/\nvar cmd = []\n\ncmd[0] = \"~22\" // SOI, VER\ncmd[1] = msg.addr // ADDR: \"01\" or \"02\"\ncmd[2] = \"4A42\" // CID1, CID2\ncmd[3] = \"E002\" // LEN\ncmd[4] = \"01\"\n\nvar cmdstr = cmd.join('');\nvar C = 0;\nfor (let index = 1; index < cmdstr.length; index++) {\n const c = cmdstr.charCodeAt(index);\n C += c;\n}\nC = (~C & 0xffff) + 1\n \nmsg.payload = cmdstr + C.toString(16).toUpperCase() + \"\\x0d\"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":360,"wires":[["67f3703dd92df2ef"]]},{"id":"a79405afce98bcd2","type":"inject","z":"e8741fa499dd6155","name":"5s","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"5","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":70,"y":360,"wires":[["084f2bcfa9d4ad43"]]},{"id":"67f3703dd92df2ef","type":"serial request","z":"e8741fa499dd6155","name":"","serial":"91d1aae3823e1ef2","x":530,"y":360,"wires":[["e9e6b0f2ad058063","b42e1447116f89e2","d42f8c64bea41df4"]]},{"id":"e9e6b0f2ad058063","type":"function","z":"e8741fa499dd6155","name":"extract","func":"/*\n ~ = SOI\n 01 22 = Ver = 22\n 03 01 = ADDR\n 05 4A = CID1\n 07 00\n 09 E0C6 = Length + length checksum\n 13 00\n 15 2704 = SOC 99.88 (/100)\n 19 1533 = Pack voltage 54.27V (/100)\n 23 10 = 16 cells\n 25 0D44 = cell voltages, 3396mV\n 29 0D57 = 3415 mV\n 0D2D\n 0D14\n 0D11\n 0D13\n 0D6F\n 0D22\n 0D70\n 0D70\n 0D6D\n 0D34\n 0D33\n 0D0F\n 0D5C\n 0D55 = cell 16 voltage\n 010E = 27 deg C (/10)\n 00FA = 25 deg C (/10)\n 010E = 27 deg C (/10)\n 101 04\n 103 0104\n 107 0104\n 111 0104\n 115 00FA\n 119 0000 = Current ?\n 0000\n 0064\n 01\n 30D4 = 125 Ahr total capacity\n 30C6 = 124.86 Ahr available\n 0005 = 5 cycles\n 0000\n 0000\n 0000\n 0000\n 0023 = 35\n 0000000000000000000000000000000000000000000000\nD563 = checksum\n*/\nif (msg.status != \"OK\") return; // no data\n// check RTN code for valid (==\"00\")\nif (msg.payload.substr(7, 2) != \"00\") return; // no data\nmsg.D = msg.payload // save original data\n\n/* it appears that sometimes we get results for different battery, maybe\n because of a timeout on previous call? Either way, we can use the data\n as long as it is valid\n*/\n\nmsg.addr = msg.D.substr(3, 2)\n\n// Checksum validation\nvar C = 0;\nfor (let index = 1; index < msg.D.length-5; index++) {\n const c = msg.D.charCodeAt(index);\n C += c;\n}\nC = (~C & 0xffff) + 1\n\nvar rxC = parseInt(msg.D.substr(msg.D.length-5, 4), 16)\nmsg.valid = (C == rxC)\nif (!msg.valid) return; // return with no data if invalid\n\nmsg.payload = {}\n\nmsg.payload.soc = parseInt(msg.D.substr(15, 4), 16) / 100\nmsg.payload.voltage = parseInt(msg.D.substr(19, 4), 16) / 100\n// Parse current\nvar a = parseInt(msg.D.substr(119, 4), 16)\nif ((a & 0x8000) > 0) a = a - 0x10000; // need to handle negative hex number for current\nmsg.payload.current = a/100;\n//\nmsg.payload.cellcount = parseInt(msg.D.substr(23,2),16)\nmsg.payload.cellvoltage = []\nfor (let index = 0; index < msg.payload.cellcount; index++) \n{\n msg.payload.cellvoltage[index] = parseInt(msg.D.substr(25+4*index, 4), 16) \n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":520,"y":280,"wires":[["b08a5271bceeaa98","0842c048ba4040fd"]]},{"id":"54a14510753a8c7f","type":"mqtt out","z":"e8741fa499dd6155","name":"Publish","topic":"","qos":"1","retain":"true","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"9cb0be1e.1c82a","x":960,"y":210,"wires":[]},{"id":"b08a5271bceeaa98","type":"split","z":"e8741fa499dd6155","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"key","x":650,"y":280,"wires":[["439a6141cc9dad27"]]},{"id":"cd8a4e22f0d435dc","type":"debug","z":"e8741fa499dd6155","name":"debug 12","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":950,"y":280,"wires":[]},{"id":"439a6141cc9dad27","type":"function","z":"e8741fa499dd6155","name":"make key","func":"msg.topic = \"NRED/Power/battery/china/\" + msg.addr + \"/\" + msg.key\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":790,"y":280,"wires":[["cd8a4e22f0d435dc","da41da0092a687b6"]]},{"id":"da41da0092a687b6","type":"rbe","z":"e8741fa499dd6155","name":"","func":"rbe","gap":"","start":"","inout":"out","septopics":true,"property":"payload","topi":"topic","x":820,"y":210,"wires":[["54a14510753a8c7f"]]},{"id":"b42e1447116f89e2","type":"debug","z":"e8741fa499dd6155","name":"debug 13","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":800,"y":360,"wires":[]},{"id":"d42f8c64bea41df4","type":"switch","z":"e8741fa499dd6155","name":"addr==01?","property":"addr","propertyType":"msg","rules":[{"t":"eq","v":"01","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":480,"y":500,"wires":[["7ccdb8358f62bed5"]]},{"id":"7ccdb8358f62bed5","type":"change","z":"e8741fa499dd6155","name":"addr=02","rules":[{"t":"set","p":"addr","pt":"msg","to":"02","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":630,"y":500,"wires":[["20be21bf678fd47d"]]},{"id":"084f2bcfa9d4ad43","type":"change","z":"e8741fa499dd6155","name":"addr=01","rules":[{"t":"set","p":"addr","pt":"msg","to":"01","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":210,"y":360,"wires":[["b80ca6efc679cf53"]]},{"id":"f561167b68f27b78","type":"link in","z":"e8741fa499dd6155","name":"B-again","links":["20be21bf678fd47d"],"x":195,"y":260,"wires":[["b80ca6efc679cf53"]]},{"id":"20be21bf678fd47d","type":"link out","z":"e8741fa499dd6155","name":"link out 1","mode":"link","links":["f561167b68f27b78"],"x":725,"y":500,"wires":[]},{"id":"2ccc611d35c3595e","type":"comment","z":"e8741fa499dd6155","name":"loop for 2nd battery","info":"","x":650,"y":460,"wires":[]},{"id":"0842c048ba4040fd","type":"debug","z":"e8741fa499dd6155","name":"debug 14","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":620,"y":200,"wires":[]},{"id":"91d1aae3823e1ef2","type":"serial-port","serialport":"/dev/ttyUSB2","serialbaud":"19200","databits":"8","parity":"none","stopbits":"1","waitfor":"","dtr":"none","rts":"none","cts":"none","dsr":"none","newline":"300","bin":"false","out":"interbyte","addchar":"","responsetimeout":"2000"},{"id":"9cb0be1e.1c82a","type":"mqtt-broker","name":"MQTT_R1","broker":"192.168.7.101","port":"1883","clientid":"nodered_client1","usetls":false,"compatmode":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"sessionExpiry":""}]
Ahoj, doufám, že to pomůže.
pokud potřebujete kód pro Node Red, dejte mi zpětnou vazbu.
PW: 48V_LIFEPO4_BATTERY
pozdravy
Hi,
Hi,since it is new to me and to understand it better:
So it is as you said? I have to convert the buffer to ASCII which then contains hex values which I have to decode to 16bit numbers? (well, it might contain status bits somewhere, too, no idea yet)
I think I made some progress, 2 data packages:
~22014A00E0C6002
71014E510
0D13 cell01 3347V
0D07 cell02 3335V
0D08 cell03 3336V
0D0A cell04 3338V
0D08 cell05 3336V
0D0E cell06 3342V
0D07 cell07 3335V
0D0C cell08 3340V
0D18 cell09 3352V
0D1A cell10 3354V
0D09 cell11 3337V
0D08 cell12 3336V
0D07 cell13 3335V
0D08 cell14 3336V
0D28 cell15 3368V
0D23 cell16 3363V
012C temp 30.0
0122 temp 29.0
012C temp 30.0
0401
2C012C012201220000
000000640128CA
28CA SoC/Capacity 104.42Ah
0006000000000000000000230000000000000000000000000000000000000000000000D56C
~22014A00E0C6002
39A150D10
0D27 cell01 3367V
0D29 cell02 3369V
0D2B cell03 3371V
0D29 cell04 3369V
0D28 cell05 3368V
0D29 cell06 3369V
0D2A cell07 3370V
0D28 cell08 3368V
0D28 cell09 3368V
0D29 cell10 3369V
0D28 cell11 3368V
0D2A cell12 3370V
0D29 cell13 3369V
0D2A cell14 3370V
0D28 cell15 3368V
0D26 cell16 3366V
0118 temp 28.0
010E temp 27.0
0118 temp 28.0
0401
0E010E010E010E0285
000000640128CA
252D SoC/Capacity 95.17Ah
0006000000010000000000230000000000000000000000000000000000000000000000D520
That means I have to work with substrings after decoding to ASCII, I guess.
Hi,The PW from my BMS is 666666. But be carefully with changes.
I am searching for a solution to readout the Parameters. I test the "solaranzeige.de" with a Pylontech Batterie Protokoll but the protocols are not compatible.
After i put the PW i became more Informations in the menu "Help":
View attachment 115507
And know the big question: If i change the protocol to pylon1363 then maybe then the "solaranzeige.de" software can read the parameters. If that is the case, then it will be possible to read the data via the MQTT server from solaranzeige.de
On the other hand i am afraid that it will be not more possible to have a communication with the own software to change the parameters of the BMS.
I will inform you if i have some news ...
Many Regards
mohon password file extraxnya, terima kasihHai, saya harap ini membantu.
jika Anda memerlukan Kode untuk Node Red, beri saya umpan balik.
PW: 48V_LIFEPO4_BATTERY
Salam
Hello,hello,
i am new to this forum, too.
i am using iobroker, not node red.
i have the usb-rs485 cable.
in windows i am able to communicate with the software to the BMS.
But how could i get the information in Linux ?
Which program ?
Really appreciate your help.
# BMS communication script
import serial
import time
import datetime
import syslog
import ftplib
import os
def chksum_data(str) :
result=0;
for znak in str:
result = result + ord(znak);
result = result ^ 0xFFFF;
return result + 1;
def Lchksum(value) :
value = value & 0x0FFF;
n1=value & 0xF;
n2=(value >> 4) & 0xF;
n3=(value >> 8) & 0xF;
chksum=((n1 + n2 + n3) & 0xF) ^ 0xF;
chksum = chksum + 1;
return value + ( chksum << 12 );
def CID2_decode(CID2):
match CID2:
case '00':
# print ('CID2 response ok.');
return 0;
case '01':
syslog.syslog ('VER error.');
case '02':
syslog.syslog ('CHKSUM error.');
case '03':
syslog.syslog ('LCHKSUM error.');
case '04':
syslog.syslog ('CID2 invalid.');
case '05':
syslog.syslog ('Command format error.');
case '06':
syslog.syslog ('INFO data invalid.');
case '90':
syslog.syslog ('ADR error.');
case '91':
syslog.syslog ('Battery communication error.');
# print ('CID2 error response code: ', CID2);
return -1;
syslog.syslog('Starting solar control.');
BOJLER_OFF = 1;
BOJLER_ON = 0
SOLAR_OFF = 0;
SOLAR_ON = 1;
BOJLER_PIN = 198;
SOLAR_PIN = 199;
bojler = BOJLER_OFF;
solar = SOLAR_ON;
sent=b'~22014A42E00201FD28\r';
ser = serial.Serial('/dev/ttyUSB0', 9600);
while True:
rcv = '';
ser.write(sent);
# print('Request sent:', datetime.datetime.now());
time.sleep(4);
while ser.inWaiting() > 0:
try:
chr = ser.read();
rcv+=chr.decode();
if chr == b'\r':
break;
except:
# syslog.syslog('Invalid character from serial port.');
pass;
valid_data = 1;
try:
CID2 = rcv[7:9];
if CID2_decode(CID2) == -1:
valid_data = -1;
except:
valid_data = -1;
try:
LENID = int(rcv[9:13], base=16);
length = LENID & 0x0FFF;
if Lchksum(length) == LENID:
pass;
# print('LEN_ID ok.');
else:
# print('LEN_ID error.');
valid_data = -1;
except:
valid_data = -1;
try:
chksum = int(rcv[len(rcv)-5:], base=16);
if chksum_data(rcv[1:len(rcv)-5]) == chksum:
# print('CHKSUM ok.')
valid_data = 1;
else:
# print('CHKSUM error.');
valid_data = -1;
except:
valid_data = -1;
# syslog.syslog("Invalid data from the battery.");
if valid_data == 1:
# Data z baterky jsou OK
data = rcv[13:len(rcv)-5]
SOC = int(data[2:6], base=16) / 100;
# print('SOC: ',SOC, '%');
napeti = int(data[6:10], base=16) /100;
# print('Napětí: ', napeti, 'V');
proud = int(data[106:110], base=16);
if proud > 32767:
proud = -(32768-(proud - 32768));
proud /=100;
# print('Proud: ', proud, 'A');
# print('--------------------------------\n');
if (time.localtime().tm_min in [0, 15, 30, 45]) & (time.localtime().tm_sec < 5):
syslog.syslog('INFO: ' + str(napeti) + 'V ' + str(proud) + 'A ' + str(SOC)+'% BOJLER: ' + ('OFF' if bojler == 1 else 'ON'));
##################################################################################################
if (bojler == BOJLER_OFF) & (proud > 30) & (SOC > 80):
bojler = BOJLER_ON;
syslog.syslog('BOJLER ON: ' + str(napeti) + 'V ' + str(proud) + 'A ' + str(SOC) + '%');
if (bojler == BOJLER_ON) & (proud < -10) & (SOC < 90):
bojler = BOJLER_OFF;
syslog.syslog('BOJLER OFF: ' + str(napeti) + 'V ' + str(proud) + 'A ' + str(SOC) + '%');
if (solar == SOLAR_ON) & (SOC > 99):
solar = SOLAR_OFF;
syslog.syslog('SOLAR OFF: ' + str(napeti) + 'V ' + str(proud) + 'A ' + str(SOC) + '%');
if (solar == SOLAR_OFF) & (SOC < 90):
solar = SOLAR_ON;
syslog.syslog('SOLAR ON: ' + str(napeti) + 'V ' + str(proud) + 'A ' + str(SOC) + '%');
if (bojler == BOJLER_OFF) & (SOC > 95):
bojler = BOJLER_ON;
syslog.syslog('BOJLER ON: ' + str(napeti) + 'V ' + str(proud) + 'A ' + str(SOC) + '%');
##################################################################################################
o = open("/sys/class/gpio/gpio198/value", "w"); o.write(str(bojler)); o.close();
o = open("/sys/class/gpio/gpio199/value", "w"); o.write(str(solar)); o.close();
else:
# print('Invalid data.\n----------------------\n');
# syslog.syslog("Invalid data from the battery.");
pass;
ser.close();
time.sleep(120);
os.system('reboot');