Created
September 13, 2023 05:06
-
-
Save kyawswarthwin/e4bd3d9956a2266ad8481e3c598073c5 to your computer and use it in GitHub Desktop.
China LiFePO4 Battery QR Code Decoder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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