Skip to content

Instantly share code, notes, and snippets.

@kyawswarthwin
Created September 13, 2023 05:06
Show Gist options
  • Save kyawswarthwin/e4bd3d9956a2266ad8481e3c598073c5 to your computer and use it in GitHub Desktop.
Save kyawswarthwin/e4bd3d9956a2266ad8481e3c598073c5 to your computer and use it in GitHub Desktop.
China LiFePO4 Battery QR Code Decoder
function formatError(code, message) {
return {
code,
message,
};
}
function handleResponse(response) {
const formatResponse = ({ ok, status, statusText }, data) => {
const responseData = {
success: ok,
status,
statusText,
data,
};
if (!response.ok) {
return Promise.reject(responseData);
}
return responseData;
};
const contentType = response.headers.get('content-type');
if (contentType?.indexOf('application/json') !== -1) {
return response.json().then((data) => formatResponse(response, data));
}
return response.text().then((data) => formatResponse(response, data));
}
export { formatError, handleResponse };
import { formatError } from './helper.util';
function decode(qrCode) {
if (!qrCode?.length) {
return Promise.reject(formatError(400, 'Bad Request'));
}
qrCode = qrCode.toUpperCase();
const manufacturerCode = qrCode.substring(0, 3);
const productTypeCode = qrCode.substring(3, 4);
const batteryTypeCode = qrCode.substring(4, 5);
const productionDateCode = qrCode.substring(14, 17);
const [manufacturer, manufacturerWebsite] = getManufacturer(manufacturerCode);
const productType = getProductType(productTypeCode);
const [batteryType, nominalVoltage] = getBatteryType(batteryTypeCode);
const [modelNumber, nominalCapacity] = getSpecification(manufacturer, qrCode);
const productionDate = getProductionDate(productionDateCode);
const qrCodeLength = qrCode.length;
const isValidLength =
qrCodeLength === 19 || qrCodeLength === 24 || qrCodeLength === 26;
const isValid =
isValidLength && productType !== 'Unknown' && batteryType !== 'Unknown';
if (!isValid) {
return Promise.reject(formatError(400, 'Invalid QR Code'));
}
const result = {
manufacturer,
manufacturerWebsite: manufacturerWebsite ? manufacturerWebsite : 'Unknown',
productType,
batteryType,
modelNumber,
nominalVoltage: nominalVoltage ? `${nominalVoltage}V` : 'Unknown',
nominalCapacity: nominalCapacity ? `${nominalCapacity}Ah` : 'Unknown',
productionDate,
};
return Promise.resolve(result);
}
function getManufacturer(manufacturerCode) {
const manufacturers = {
'001': ['CATL', 'https://www.catl.com'],
'02Y': ['EVE', 'https://www.evebattery.com'],
'04Q': ['EVE Power', 'https://www.evebattery.com'],
'02K': ['Great Power', 'http://www.greatpower.net'],
'069': ['GREE Altairnano/Yinlong'],
'081': ['REPT', 'https://www.chinarept.com'],
'08I': ['REPT', 'https://www.chinarept.com'],
'08B': ['Lishen', 'http://www.lishen.com.cn'],
'02C': ['Lishen', 'http://www.lishen.com.cn'],
'0AL': ['Ganfeng', 'http://www.ganfenglithium.com'],
'0B5': ['CALB', 'http://www.calb-tech.com'],
OB5: ['CALB', 'http://www.calb-tech.com'],
'09U': ['SVOLT'],
'0F4': ['BYD'],
'07H': ['Higee', 'http://www.ihigee.com'],
'04U': ['Narada Power'],
'00P': ['Sunwoda'],
'0H9': ['Tafel'],
'01Y': ['Narada'],
'03H': ['Gotion', 'https://www.gotion.com.cn'],
};
return manufacturers[manufacturerCode] || ['Unknown'];
}
function getProductType(productTypeCode) {
const productTypes = {
C: 'Battery Cell',
P: 'Battery Pack',
M: 'Battery Module',
};
return productTypes[productTypeCode] || 'Unknown';
}
function getBatteryType(batteryTypeCode) {
const batteryTypes = {
A: ['NiMH', 1.2],
B: ['LiFePO4', 3.2],
C: ['LiMnO2', 3.0],
D: ['LiCoO2', 3.7],
E: ['Ternary', 3.7],
F: ['Supercapacitor'],
G: ['LTO', 2.3],
Z: ['Other'],
};
return batteryTypes[batteryTypeCode] || ['Unknown'];
}
function getSpecification(manufacturer, qrCode) {
let specifications;
let specificationCode = qrCode.substring(5, 7);
if (manufacturer === 'Gotion') {
specifications = {
14: ['52', 52],
'0R': ['52', 52],
16: ['GT102', 102],
'09': ['105', 105],
'1B': ['150', 150],
23: ['GT-340', 340],
'0Y': ['INP2714897A', 50],
};
specificationCode = qrCode.substring(6, 8);
} else if (manufacturer === 'GREE Altairnano/Yinlong') {
specifications = {
A2: ['66160', 40],
A3: ['66160', 45],
A4: ['32140', 9],
};
} else if (manufacturer === 'SVOLT') {
specifications = {
20: ['CL01', 184],
10: ['CE01', 104],
};
} else if (manufacturer === 'BYD') {
specifications = {
A3: ['102', 102],
};
} else if (manufacturer === 'REPT') {
specifications = {
'05': ['205', 205],
O5: ['205', 205],
26: ['CB71173200EA', 280],
29: ['230', 230],
40: ['CB71173204EB', 280],
25: ['135', 135],
54: ['142', 142],
'03': ['CB3914895EA-50A', 50],
'09': ['155', 155],
};
} else {
specifications = {
20: ['202', 202],
'2O': ['202', 202],
21: ['71H3L7', 280],
22: ['173', 173],
24: ['302AH', 302],
'2W': ['71H3L7', 280],
31: ['280', 280],
'3I': ['280', 280],
32: ['125', 125],
52: ['114', 114],
ER: ['234', 234],
43: ['117', 117],
46: ['136', 136],
15: ['50', 50],
64: ['LF90K', 90],
65: ['LF105', 105],
66: ['LF280', 280],
68: ['LF50', 50],
'6C': ['LF100L', 100],
'6D': ['LF100MA', 100],
71: ['LF280N', 280],
'7I': ['LF280N', 280],
72: ['LF230', 230],
73: ['LF304', 304],
75: ['LF173', 173],
76: ['LF280K', 280],
83: ['INP114E', 114],
89: ['INP20P', 20],
E6: ['LF22k', 22],
35: ['4680 sample trial cell', 31],
EJ: ['100', 100],
FE: ['GSP34135214F', 100],
F6: ['GSP27135250F', 100],
FD: ['GSP42173166', 135],
FI: ['50', 50],
'03': ['FE100A', 100],
PB: ['LP71173207', 272],
PE: ['LP54173207', 190],
NA: ['202', 202],
PF: ['LP54173207', 202],
A0: ['48173125', 100],
A3: ['48173125', 100],
AO: ['48173125', 100],
S0: ['50', 50],
SO: ['50', 50],
37: ['L173F230', 230],
C0: ['L160F100B', 100],
CO: ['L160F100B', 100],
'2C': ['L148F88', 88],
G2: ['L194F130A', 130],
BE: ['L300F187', 187],
'3B': ['L173F280', 280],
'2A': ['L148N58A', 58],
'4C': ['L221N169A', 169],
B9: ['l300f177a', 177],
50: ['I50', 50],
G4: ['106', 106],
A1: ['75', 75],
A6: ['142', 142],
C1: ['120Ah', 120],
C5: ['150Ah?', 150],
};
}
return specifications[specificationCode] || ['Unknown'];
}
function getProductionDate(productionDateCode) {
const yearCode = productionDateCode.substring(0, 1);
const monthCode = productionDateCode.substring(1, 2);
const dayCode = productionDateCode.substring(2, 3);
let year;
if (isNaN(yearCode)) {
const code = yearCode.charCodeAt(0);
if (code > 64 && code < 91) {
year = 2020 + (code - 65);
}
} else if (Number(yearCode) > 0) {
year = 2010 + Number(yearCode);
}
let month;
if (isNaN(monthCode)) {
const code = monthCode.charCodeAt(0);
if (code > 64 && code < 68) {
month = 10 + (code - 65);
}
} else if (Number(monthCode) > 0) {
month = Number(monthCode);
}
let day;
if (isNaN(dayCode)) {
const code = dayCode.charCodeAt(0);
if (code > 64 && code < 87) {
day = 10 + (code - 65);
}
} else if (Number(dayCode) > 0) {
day = Number(dayCode);
}
return new Date(year, month && month - 1, day).toLocaleDateString('en-GB', {
year: 'numeric',
month: 'short',
day: 'numeric',
});
}
export default { decode };
@rbur004
Copy link

rbur004 commented Apr 10, 2025

Got some second hand electric truck lifepo4 batteries, with manufacturers code 070.
Traced it to Shenzhen Hongsen Feida Electronics Co., Ltd
Seller claims it is a 90Ah 3.2V Lifepo4 cell. Haven't verified that.
070CB05EGECDN1B5N2E12061

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment