-
Notifications
You must be signed in to change notification settings - Fork 378
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into browan-devices
- Loading branch information
Showing
34 changed files
with
1,768 additions
and
732 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,67 +1,130 @@ | ||
function decodeUplink(input) { | ||
var decoded = {} | ||
decoded.index = decode_index(toHexString(input.bytes)) | ||
decoded.step = decode_step(toHexString(input.bytes)) | ||
decoded.list_increment = decode_list_increment(toHexString(input.bytes)) | ||
if(decoded.index && decoded.list_increment.length==8 && decoded.step>0){ | ||
return decoded | ||
} | ||
else{ | ||
msg = "The payload has the wrong size !" | ||
return msg | ||
} | ||
} | ||
//return index from T1 payload | ||
function decode_index(payload) { | ||
var index = null; | ||
if (payload.length == 40) { | ||
index = payload.substring(2, 8); | ||
} | ||
return parseInt(index, 16); | ||
const PAYLOAD_TYPE = { | ||
T1_10MN : {header: 0x20, size: 20/*in bytes*/, name: "T1_10MN"}, | ||
T1_15MN : {header: 0x21, size: 20/*in bytes*/, name: "T1_15MN"}, | ||
T1_1H : {header: 0x22, size: 20/*in bytes*/, name: "T1_1H"}, | ||
TT1_MECA : {header: 0x12, size: 37/*in bytes*/, name: "TT1_MECA"}, | ||
TT2_MECA : {header: 0x13, size: 30/*in bytes*/, name: "TT2_MECA"}, | ||
TT1_ELEC : {header: 0x12, size: 19/*in bytes*/, name: "TT1_ELEC"}, | ||
TT2_ELEC : {header: 0x13, size: 11/*in bytes*/, name: "TT2_ELEC"}, | ||
T2 : {header: 0x0e, size: 12/*in bytes*/, name: "T2"}, | ||
START : {header: 0x01, size: 3/*in bytes*/, name: "START"} | ||
} | ||
|
||
//return hexadecimal power list from T1 payload | ||
function payload_to_hex(payload) { | ||
var list_increment_hex = [] | ||
if (payload.length == 40){ | ||
for(i=0;i<16;i++){ | ||
list_increment_hex.push(payload.substring((8+2*i),2+(8+2*i))) | ||
} | ||
//Main function Decoder | ||
function decodeUplink(input){ | ||
var decoded = { | ||
data: { | ||
index : null, | ||
message_type : null, | ||
increments : [], | ||
powers: [], | ||
time_step: null, | ||
meter_type : null, | ||
low_battery : null, | ||
firmware_version: null, | ||
number_of_starts : null, | ||
param_id: null | ||
}, | ||
index: null, | ||
step: null, | ||
list_increment: null, | ||
warnings: [], | ||
errors: [] | ||
} | ||
//Find message type | ||
decoded.data.message_type = find_message_type(input.bytes); | ||
if(decoded.data.message_type == null){ | ||
decoded.errors.push("Invalid payload") | ||
return decoded | ||
} | ||
return list_increment_hex | ||
if(decoded.data.message_type == PAYLOAD_TYPE.T1_10MN.name) decoded.data.time_step = 10; | ||
if(decoded.data.message_type == PAYLOAD_TYPE.T1_15MN.name) decoded.data.time_step = 15; | ||
if(decoded.data.message_type == PAYLOAD_TYPE.T1_1H.name) decoded.data.time_step = 60; | ||
//Decode message | ||
if(decoded.data.message_type == PAYLOAD_TYPE.T1_10MN.name || decoded.data.message_type == PAYLOAD_TYPE.T1_15MN.name | ||
|| decoded.data.message_type == PAYLOAD_TYPE.T1_1H.name){ | ||
var data = decode_T1(input.bytes, decoded.data.time_step); | ||
decoded.data.index = data.index; | ||
decoded.data.increments = data.increments; | ||
decoded.data.powers = data.powers; | ||
}else if(decoded.data.message_type == PAYLOAD_TYPE.TT1_MECA.name || decoded.data.message_type == PAYLOAD_TYPE.TT2_MECA.name){ | ||
decoded.data.meter_type = "Electromechanical (Position A)" | ||
}else if(decoded.data.message_type == PAYLOAD_TYPE.TT1_ELEC.name || decoded.data.message_type == PAYLOAD_TYPE.TT2_ELEC.name){ | ||
decoded.data.meter_type = "Electronic (Position B)" | ||
}else if(decoded.data.message_type == PAYLOAD_TYPE.T2.name){ | ||
var data = decode_T2(input.bytes); | ||
decoded.data.index = data.index; | ||
decoded.data.meter_type = data.meter_type; | ||
decoded.data.low_battery = data.low_battery; | ||
decoded.data.firmware_version = data.firmware_version; | ||
decoded.data.number_of_starts = data.number_of_starts; | ||
decoded.data.param_id = data.param_id; | ||
decoded.data.time_step = data.time_step; | ||
} | ||
//Retrocompatibility | ||
decoded.step = decoded.data.time_step; | ||
decoded.list_increment = decoded.data.increments; | ||
decoded.index = decoded.data.index; | ||
return decoded | ||
} | ||
|
||
//return power list from T1 payload | ||
function decode_list_increment(payload) { | ||
var list_increment = [] | ||
var list_increment_hex = [] | ||
if (payload.length == 40){ | ||
list_increment_hex = payload_to_hex(payload) | ||
//Find message type - return null if nothing found | ||
function find_message_type(payload){ | ||
switch(payload[0]){ | ||
case PAYLOAD_TYPE.T1_10MN.header: | ||
if(payload.length == PAYLOAD_TYPE.T1_10MN.size) return PAYLOAD_TYPE.T1_10MN.name | ||
break; | ||
case PAYLOAD_TYPE.T1_15MN.header: | ||
if(payload.length == PAYLOAD_TYPE.T1_15MN.size) return PAYLOAD_TYPE.T1_15MN.name | ||
break; | ||
case PAYLOAD_TYPE.T1_1H.header: | ||
if(payload.length == PAYLOAD_TYPE.T1_1H.size) return PAYLOAD_TYPE.T1_1H.name | ||
break; | ||
case PAYLOAD_TYPE.TT1_MECA.header: | ||
if(payload.length == PAYLOAD_TYPE.TT1_MECA.size) return PAYLOAD_TYPE.TT1_MECA.name | ||
if(payload.length == PAYLOAD_TYPE.TT1_ELEC.size) return PAYLOAD_TYPE.TT1_ELEC.name | ||
break; | ||
case PAYLOAD_TYPE.TT2_MECA.header: | ||
if(payload.length == PAYLOAD_TYPE.TT2_MECA.size) return PAYLOAD_TYPE.TT2_MECA.name | ||
if(payload.length == PAYLOAD_TYPE.TT2_ELEC.size) return PAYLOAD_TYPE.TT2_ELEC.name | ||
break; | ||
case PAYLOAD_TYPE.T2.header: | ||
if(payload.length == PAYLOAD_TYPE.T2.size) return PAYLOAD_TYPE.T2.name | ||
break; | ||
case PAYLOAD_TYPE.START.header: | ||
if(payload.length == PAYLOAD_TYPE.START.size) return PAYLOAD_TYPE.START.name | ||
break; | ||
} | ||
if(list_increment_hex.length == 16){ | ||
for(i=0;i<8;i++){ | ||
list_increment.push(parseInt(list_increment_hex[i*2]+list_increment_hex[i*2+1], 16)) | ||
} | ||
} | ||
return list_increment | ||
return null | ||
} | ||
|
||
//return step from T1 payload | ||
function decode_step(payload){ | ||
var step = 0 | ||
var header = null | ||
if(payload.length == 40){ | ||
header = parseInt(payload.substring(0, 2), 16) | ||
if(header == 32) step = 10 | ||
if(header == 33) step = 15 | ||
if(header == 34) step = 60 | ||
function decode_T1(payload,time_step){ | ||
var data = {}; | ||
data.index = (payload[1] & 0xFF) << 16 | (payload[2] & 0xFF) << 8 | (payload[3] & 0xFF); | ||
data.increments = [] | ||
data.powers = [] | ||
for(i=0;i<8;i++){ | ||
data.increments.push((payload[4+2*i] & 0xFF) << 8 | (payload[5+2*i] & 0xFF)) | ||
} | ||
for(i=0;i<8;i++){ | ||
data.powers.push(data.increments[i] * 60 / time_step) | ||
} | ||
return step | ||
return data | ||
} | ||
|
||
//Convert uplink payload.bytes to hexString payload | ||
function toHexString(byteArray) { | ||
return Array.from(byteArray, function(byte) { | ||
return ('0' + (byte & 0xFF).toString(16)).slice(-2); | ||
}).join('') | ||
} | ||
function decode_T2(payload){ | ||
var data = {}; | ||
data.number_of_starts = payload[1]; | ||
data.index = (payload[5] & 0xFF) << 24 | (payload[6] & 0xFF) << 16 | (payload[7] & 0xFF) << 8 | (payload[8] & 0xFF); | ||
data.firmware_version = payload[4] >> 2; | ||
data.low_battery = payload[4] & 0x1; | ||
data.meter_type = payload[4] >> 1 & 0x1; | ||
if(data.meter_type == 0) data.meter_type = "Electromechanical (Position A)" | ||
if(data.meter_type == 1) data.meter_type = "Electronic (Position B)" | ||
data.param_id = payload[3]; | ||
data.time_step = payload[11]; | ||
if(data.time_step == 0) data.time_step = 10; | ||
if(data.time_step == 3) data.time_step = 15; | ||
if(data.time_step == 1) data.time_step = 60; | ||
return data; | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,60 +1,91 @@ | ||
const PAYLOAD_TYPE = { | ||
T1 : {header: 0x5b, size: 45/*in bytes*/, name: "T1"}, | ||
TT1_MECA : {header: 0x12, size: 37/*in bytes*/, name: "TT1_MECA"}, | ||
TT2_MECA : {header: 0x13, size: 30/*in bytes*/, name: "TT2_MECA"}, | ||
T2 : {header: 0x51, size: 12/*in bytes*/, name: "T2"}, | ||
START : {header: 0x5f, size: 9/*in bytes*/, name: "START"} | ||
} | ||
|
||
//Main function Decoder | ||
function decodeUplink(input){ | ||
var decoded = {} | ||
decoded.index = decode_index(toHexString(input.bytes)) | ||
decoded.power_list = decode_power_list(toHexString(input.bytes)) | ||
if(decoded.index && decoded.power_list.length==20){ | ||
return { | ||
data:{ | ||
index: decoded.index, | ||
powers: decoded.power_list | ||
|
||
} | ||
} | ||
var decoded = { | ||
data: { | ||
index : null, | ||
message_type : null, | ||
powers : [], | ||
meter_type : null, | ||
low_battery : null, | ||
firmware_version: null, | ||
number_of_starts : null | ||
}, | ||
warnings: [], | ||
errors: [] | ||
} | ||
else{ | ||
msg = "The payload has the wrong size !" | ||
return msg | ||
} | ||
} | ||
//return index from T1 payload | ||
function decode_index(payload) { | ||
var index = null; | ||
if (payload.length == 90) { | ||
index = payload.substring(2, 8); | ||
//Find message type | ||
decoded.data.message_type = find_message_type(input.bytes); | ||
if(decoded.data.message_type == null){ | ||
decoded.errors.push("Invalid payload") | ||
return decoded | ||
} | ||
return parseInt(index, 16); | ||
//Decode message | ||
if(decoded.data.message_type == PAYLOAD_TYPE.T1.name){ | ||
var data = decode_T1(input.bytes); | ||
decoded.data.index = data.index; | ||
decoded.data.powers = data.power_list; | ||
}else if(decoded.data.message_type == PAYLOAD_TYPE.TT1_MECA.name || decoded.data.message_type == PAYLOAD_TYPE.TT2_MECA.name){ | ||
decoded.data.meter_type = "Electromechanical (Position A)" | ||
}else if(decoded.data.message_type == PAYLOAD_TYPE.T2.name){ | ||
var data = decode_T2(input.bytes); | ||
decoded.data.index = data.index; | ||
decoded.data.meter_type = data.meter_type; | ||
decoded.data.low_battery = data.low_battery; | ||
decoded.data.firmware_version = data.firmware_version; | ||
decoded.data.number_of_starts = data.number_of_starts; | ||
} | ||
|
||
return decoded | ||
} | ||
|
||
//return hexadecimal power list from T1 payload | ||
function payload_to_hex(payload) { | ||
var power_list_hex = [] | ||
if (payload.length == 90){ | ||
for(i=0;i<40;i++){ | ||
power_list_hex.push(payload.substring((10+2*i),2+(10+2*i))) | ||
} | ||
//Find message type - return null if nothing found | ||
function find_message_type(payload){ | ||
switch(payload[0]){ | ||
case PAYLOAD_TYPE.T1.header: | ||
if(payload.length == PAYLOAD_TYPE.T1.size) return PAYLOAD_TYPE.T1.name | ||
break; | ||
case PAYLOAD_TYPE.TT1_MECA.header: | ||
if(payload.length == PAYLOAD_TYPE.TT1_MECA.size) return PAYLOAD_TYPE.TT1_MECA.name | ||
break; | ||
case PAYLOAD_TYPE.TT2_MECA.header: | ||
if(payload.length == PAYLOAD_TYPE.TT2_MECA.size) return PAYLOAD_TYPE.TT2_MECA.name | ||
break; | ||
case PAYLOAD_TYPE.T2.header: | ||
if(payload.length == PAYLOAD_TYPE.T2.size) return PAYLOAD_TYPE.T2.name | ||
break; | ||
case PAYLOAD_TYPE.START.header: | ||
if(payload.length == PAYLOAD_TYPE.START.size) return PAYLOAD_TYPE.START.name | ||
break; | ||
} | ||
return power_list_hex | ||
return null | ||
} | ||
|
||
//return power list from T1 payload | ||
function decode_power_list(payload) { | ||
var power_list = [] | ||
var power_list_hex = [] | ||
if (payload.length == 90){ | ||
power_list_hex = payload_to_hex(payload) | ||
function decode_T1(payload){ | ||
var data = {}; | ||
data.index = (payload[1] & 0xFF) << 24 | (payload[2] & 0xFF) << 16 | (payload[3] & 0xFF) << 8 | (payload[4] & 0xFF); | ||
data.power_list = [] | ||
for(i=0;i<20;i++){ | ||
data.power_list.push((payload[5+2*i] & 0xFF) << 8 | (payload[6+2*i] & 0xFF)) | ||
} | ||
if(power_list_hex.length == 40){ | ||
for(i=0;i<20;i++){ | ||
power_list.push(parseInt(power_list_hex[i*2]+power_list_hex[i*2+1], 16)) | ||
} | ||
} | ||
return power_list | ||
return data | ||
} | ||
|
||
//Convert uplink payload.bytes to hexString payload | ||
function toHexString(byteArray) { | ||
return Array.from(byteArray, function(byte) { | ||
return ('0' + (byte & 0xFF).toString(16)).slice(-2); | ||
}).join('') | ||
} | ||
function decode_T2(payload){ | ||
var data = {}; | ||
data.number_of_starts = payload[1]; | ||
data.index = (payload[5] & 0xFF) << 24 | (payload[6] & 0xFF) << 16 | (payload[7] & 0xFF) << 8 | (payload[8] & 0xFF); | ||
data.firmware_version = payload[4] >> 2; | ||
data.low_battery = payload[4] & 0x1; | ||
data.meter_type = payload[4] >> 1 & 0x1; | ||
if(data.meter_type == 0) data.meter_type = "Electromechanical (Position A)" | ||
if(data.meter_type == 1) data.meter_type = "Electronic (Position B)" | ||
return data; | ||
} |
Oops, something went wrong.