Answer to me! but not finished
/*
* Code pour decoder le TIC du compteur PMEPMI
*/
// ----------------------------------------------------------------
// ----------------------- FUNCTIONS PART -------------------------
// ----------------------------------------------------------------
function UintToInt(Uint, Size) {
if (Size === 2) {
if ((Uint & 0x8000) > 0) {
Uint = Uint - 0x10000;
}
}
if (Size === 3) {
if ((Uint & 0x800000) > 0) {
Uint = Uint - 0x1000000;
}
}
if (Size === 4) {
if ((Uint & 0x80000000) > 0) {
Uint = Uint - 0x100000000;
}
}
return Uint;
}
function toHexString(byteArray) {
var s = '';
byteArray.forEach(function(byte) {
s += ('0' + (byte & 0xFF).toString(16)).slice(-2);
});
return s;
}
function decimalToHex(d, padding) {
var hex = Number(d).toString(16).toUpperCase();
padding = typeof (padding) === "undefined" || padding === null ? padding = 2 : padding;
while (hex.length < padding) {
hex = "0" + hex;
}
return "0x" + hex;
}
function hex_to_ascii(str1)
{
var hex = str1.toString();
var str = '';
for (var n = 0; n < hex.length; n += 2) {
str += String.fromCharCode(parseInt(hex.substr(n, 2), 16));
}
return str;
}
function dec2String(array) {
var result = "";
for (var i = 0; i < array.length; i++)
{
result += String.fromCharCode(array[i]);
}
return result;
}
function Bytes2Float32(bytes) {
var sign = (bytes & 0x80000000) ? -1 : 1;
var exponent = ((bytes >> 23) & 0xFF) - 127;
var significand = (bytes & ~(-1 << 23));
if (exponent == 128)
return sign * ((significand) ? Number.NaN : Number.POSITIVE_INFINITY);
if (exponent == -127) {
if (significand == 0) return sign * 0.0;
exponent = -126;
significand /= (1 << 22);
} else significand = (significand | (1 << 23)) / (1 << 23);
return sign * significand * Math.pow(2, exponent);
}
function parseHexString(str) {
var result = [];
while (str.length >= 2) {
result.push(parseInt(str.substring(0, 2), 16));
str = str.substring(2, str.length);
}
return result;
}
function Decoder( bytes, fPort) {
// Decode an uplink message from a buffer
// (array) of bytes to an object of fields.
// la ligne du dessous est pour la compatibilité avec Lora-server
var byte_array = bytes;
// recuperer le numero de port
var port_nb = parseInt(fPort, 10);
var decoded = {};
decoded.lora = {};
decoded.lora.port = port_nb;
// Get raw payload
var bytes_len_ = byte_array.length;
var temp_hex_str = ""
decoded.lora.payload = "";
for( var j = 0; j < bytes_len_; j++ )
{
temp_hex_str = byte_array[j].toString( 16 ).toUpperCase( );
if( temp_hex_str.length == 1 )
{
temp_hex_str = "0" + temp_hex_str;
}
decoded.lora.payload += temp_hex_str;
var date = new Date();
decoded.lora.date = date.toISOString();
}
// ici on a le payload et la date du message
// Nke utilise toujours le port 125, sinon c'est pas du Nke
if (port_nb === 125)
{
//On verifie si c'est un message de type batch ou une trame standard
batch = !(byte_array[0] & 0x01);
//On traite la trame standard
if (batch === false)
{
// On va decoder le header de la trame standard
decoded.zclheader = {};
decoded.zclheader.report = "standard";
attributID = -1;
cmdID = -1;
clusterdID = -1;
//endpoint
decoded.zclheader.endpoint = ((byte_array[0]&0xE0)>>5) | ((byte_array[0]&0x06)<<2);
//command ID
cmdID = byte_array[1]; decoded.zclheader.cmdID = decimalToHex(cmdID,2);
//Cluster ID
clusterdID = byte_array[2]*256 + byte_array[3]; decoded.zclheader.clusterdID = decimalToHex(clusterdID,4);
// decode report and read attribut response
if((cmdID === 0x0a)|(cmdID === 0x8a)|(cmdID === 0x01))
{
decoded.data = {};
//Attribut ID
attributID = byte_array[4]*256 + byte_array[5];decoded.zclheader.attributID = decimalToHex(attributID,4);
// TIC PMEPMI est le Cluster 0057, attributID à 00 car on gère que le cas courant
if ((clusterdID === 0x0057) & (attributID === 0x0000))
{
// le zcldatatype donne la facon d'encoder le nombre d'octets à suivre: ie sur 1 octet(0x41) ou 2 octets(0x43)
decoded.zclheader.zcldatatype = decimalToHex(byte_array[6],2);
decoded.zclheader.nboctet = byte_array[7]; // parce que byte_array[6]=0x41
//decoded.zclheader.nboctet = byte_array[7]*256 + byte_array[8]; // parce que byte_array[6]=0x43 et dans ce cas on décale tout les bytes dans la suite
// on va la TICFieldsList
decoded.TICFieldsList = {};
decoded.TICFieldsList.TICFieldsSelector={};
decoded.TICFieldsList.TICFieldsSelector.DescHeader={};
// en premier decodage de l'entete
decoded.TICFieldsList.TICFieldsSelector.DescHeader.b7=(byte_array[8]& parseInt('10000000', 2)) >>7;
decoded.TICFieldsList.TICFieldsSelector.DescHeader.b6=(byte_array[8]& parseInt('01000000', 2)) >>6;
decoded.TICFieldsList.TICFieldsSelector.DescHeader.b5=(byte_array[8]& parseInt('00100000', 2)) >>5;
decoded.TICFieldsList.TICFieldsSelector.DescHeader.size=byte_array[8]& parseInt('00011111', 2); //0x1F=11111
// le bit 7 pour l'etat du TIC
if(decoded.TICFieldsList.TICFieldsSelector.DescHeader.b7 === 0)
{
decoded.TICFieldsList.TICFieldsSelector.DescHeader.signalTIC = "TIC OK";
}
else{
decoded.TICFieldsList.TICFieldsSelector.DescHeader.signalTIC = "Obsolete";
}
// le Bit 6 pour la validité du rapport
if(decoded.TICFieldsList.TICFieldsSelector.DescHeader.b6 === 0)
{
decoded.TICFieldsList.TICFieldsSelector.DescHeader.report = "Report standard";
}
else{
decoded.TICFieldsList.TICFieldsSelector.DescHeader.report = "Report decalé";
}
// Le bit 5 pour le codage de la suite -> notre compteur envoi du descvarIndexes
if(decoded.TICFieldsList.TICFieldsSelector.DescHeader.b5 === 0)
{
decoded.TICFieldsList.TICFieldsSelector.DescHeader.descvarbitfield = "oui";
decoded.TICFieldsList.TICFieldsSelector.DescHeader.descvarIndexes = "non";
// code non réalisé
}
else
{
decoded.TICFieldsList.TICFieldsSelector.DescHeader.descvarbitfield = "non";
decoded.TICFieldsList.TICFieldsSelector.DescHeader.descvarIndexes = "oui";
var selectiondechamps=[];
var emplacement=0;
for (n=1+8 ;n<=decoded.TICFieldsList.TICFieldsSelector.DescHeader.size-1+8;n++)
{
selectiondechamps[emplacement++]=byte_array[n];
}
//verification des champs trouvé
console.log (selectiondechamps);
var nbchamps= decoded.TICFieldsList.TICFieldsSelector.DescHeader.size-1+8;
var bytesplace = decoded.TICFieldsList.TICFieldsSelector.DescHeader.size-1+8+1;
decoded.FieldsList = {};
// on decode chacun des champs, il faudrait en faire 75
for (n=0; n<= nbchamps; n++)
{
if (selectiondechamps[n] === 0)
{
decoded.FieldsList.TRAME= byte_array[bytesplace]; //test
bytesplace=bytesplace+1;
}
// numero du compteur
if (selectiondechamps[n] === 1)
{
var adssize= byte_array[bytesplace++];
decoded.FieldsList.ADS= toHexString(byte_array.slice(bytesplace, bytesplace+adssize));
bytesplace=bytesplace+adssize;
}
// Traitement tarifaire
if (selectiondechamps[n] === 2)
{
var MESURES1= byte_array[bytesplace++] ;
if (((MESURES1& parseInt('10000000', 2)) >>7 ) ===0)
{
console.log ("0");
var enumere = MESURES1& parseInt('01111111', 2);
if (enumere === 3)
{
decoded.FieldsList.MESURES1 = "BT 4 SUP 36" ;
}
if (enumere === 4)
{
decoded.FieldsList.MESURES1 = "BT 5 SUP 36" ;
}
if (enumere === 5)
{
decoded.FieldsList.MESURES1 = "HTA 5" ;
}
if (enumere === 6)
{
decoded.FieldsList.MESURES1 = "HTA 8" ;
}
if (enumere === 7)
{
decoded.FieldsList.MESURES1 = "TJ EJP" ;
}
if (enumere === 8)
{
decoded.FieldsList.MESURES1 = "TJ EJP-HH" ;
}
if (enumere === 9)
{
decoded.FieldsList.MESURES1 = "TJ EJP-PM" ;
}
if (enumere === 10)
{
decoded.FieldsList.MESURES1 = "TJ EJP-SD" ;
}
if (enumere === 11)
{
decoded.FieldsList.MESURES1 = "TJ LU" ;
}
if (enumere === 12)
{
decoded.FieldsList.MESURES1 = "TJ LU-CH" ;
}
if (enumere === 13)
{
decoded.FieldsList.MESURES1 = "TJ LU-P" ;
}
if (enumere === 14)
{
decoded.FieldsList.MESURES1 = "TJ LU-PH" ;
}
if (enumere === 15)
{
decoded.FieldsList.MESURES1 = "TJ LU-SD" ;
}
if (enumere === 16)
{
decoded.FieldsList.MESURES1 = "TJ MU" ;
}
if (enumere === 17)
{
decoded.FieldsList.MESURES1 = "TJ A5 BASE" ;
}
if (enumere === 18)
{
decoded.FieldsList.MESURES1 = "TJ A8 BASE" ;
}
}
if (((MESURES1& parseInt('10000000', 2)) >>7 )===1)
{
var nbcaractere = MESURES1& parseInt('01111111', 2);
var tabdedonne = byte_array.slice(bytesplace, bytesplace+nbcaractere);
decoded.FieldsList.MESURES1 =dec2String(tabdedonne);
bytesplace=bytesplace+nbcaractere;
}
}
// Date et heure courante DMYhms
if (selectiondechamps[n] === 3)
{
var date= new Date (2000+byte_array[bytesplace+2], byte_array[bytesplace+1]-1, byte_array[bytesplace], byte_array[bytesplace+3],byte_array[bytesplace+4],byte_array[bytesplace+5])
decoded.FieldsList.DATE= date.toString();
bytesplace=bytesplace+6;
}
// à traiter: 4 à 11
if (selectiondechamps[n] === 12)
{
var PTCOUR1= byte_array[bytesplace++] ;
if (((PTCOUR1& parseInt('10000000', 2)) >>7 ) ===0)
{
var enumere = PTCOUR1& parseInt('01111111', 2);
if (enumere === 3)
{
decoded.FieldsList.PTCOUR1 = " ? " ;
}
if (enumere === 4)
{
decoded.FieldsList.PTCOUR1 = "000" ;
}
if (enumere === 5)
{
decoded.FieldsList.PTCOUR1 = "HC" ;
}
if (enumere === 6)
{
decoded.FieldsList.PTCOUR1 = "HCD" ;
}
if (enumere === 7)
{
decoded.FieldsList.PTCOUR1 = "HCE" ;
}
if (enumere === 8)
{
decoded.FieldsList.PTCOUR1 = "HCH" ;
}
if (enumere === 9)
{
decoded.FieldsList.PTCOUR1 = "HH" ;
}
if (enumere === 10)
{
decoded.FieldsList.PTCOUR1 = "HH " ;
}
if (enumere === 11)
{
decoded.FieldsList.PTCOUR1 = "HP" ;
}
if (enumere === 12)
{
decoded.FieldsList.PTCOUR1 = "HP " ;
}
if (enumere === 13)
{
decoded.FieldsList.PTCOUR1 = "HPD" ;
}
if (enumere === 14)
{
decoded.FieldsList.PTCOUR1 = "HPE" ;
}
if (enumere === 15)
{
decoded.FieldsList.PTCOUR1 = "HPH" ;
}
if (enumere === 16)
{
decoded.FieldsList.PTCOUR1 = "JA" ;
}
if (enumere === 17)
{
decoded.FieldsList.PTCOUR1 = "JA " ;
}
if (enumere === 18)
{
decoded.FieldsList.PTCOUR1 = "P" ;
}
if (enumere === 19)
{
decoded.FieldsList.PTCOUR1 = "P " ;
}
if (enumere === 20)
{
decoded.FieldsList.PTCOUR1 = "PM" ;
}
if (enumere === 21)
{
decoded.FieldsList.PTCOUR1 = "PM " ;
}
if (enumere === 22)
{
decoded.FieldsList.PTCOUR1 = "XXX" ;
}
}
if (((PTCOUR1& parseInt('10000000', 2)) >>7 )===1)
{
var nbcaractere = PTCOUR1& parseInt('01111111', 2);
var tabdedonne = byte_array.slice(bytesplace, bytesplace+nbcaractere);
decoded.FieldsList.PTCOUR1 =dec2String(tabdedonne);
bytesplace=bytesplace+nbcaractere;
}
}
// à traiter: 13 à 39
if (selectiondechamps[n] === 40) //tsDMYhms
{
var Timestampdebp = byte_array[bytesplace++]<<24 |byte_array[bytesplace++]<<16 | byte_array[bytesplace++]<<8 |byte_array[bytesplace++];
var Timestampdebpdate= new Date ( Timestampdebp*1000);
Timestampdebpdate.setFullYear(Timestampdebpdate.getFullYear()+30);
decoded.FieldsList.DebP= Timestampdebpdate.toString() ;
}
if (selectiondechamps[n] === 41)
{
decoded.FieldsList.EAP_s= byte_array[bytesplace++]<<16 |byte_array[bytesplace++]<<8 |byte_array[bytesplace++]
}
// à traiter: 42 à 54
if (selectiondechamps[n] === 55)
{
//decoded.FieldsList.PS=toHexString(byte_array.slice(bytesplace, bytesplace+4));
decoded.FieldsList.PS= byte_array[bytesplace++]<<16 |byte_array[bytesplace++]<<8 |byte_array[bytesplace++] ;
var PSunit= byte_array[bytesplace++] ;
if (((PSunit& parseInt('10000000', 2)) >>7 ) ===0)
{
var enumere = PSunit& parseInt('01111111', 2);
if (enumere === 3)
{
decoded.FieldsList.PSunit = " ACTIF" ;
}
if (enumere === 4)
{
decoded.FieldsList.PSunit = "ACTIF" ;
}
if (enumere === 5)
{
decoded.FieldsList.PSunit = "CONSO" ;
}
if (enumere === 6)
{
decoded.FieldsList.PSunit = "CONTROLE" ;
}
if (enumere === 7)
{
decoded.FieldsList.PSunit = "DEP" ;
}
if (enumere === 8)
{
decoded.FieldsList.PSunit = "INACTIF" ;
}
if (enumere === 9)
{
decoded.FieldsList.PSunit = "PROD" ;
}
if (enumere === 10)
{
decoded.FieldsList.PSunit = "TEST" ;
}
if (enumere === 11)
{
decoded.FieldsList.PSunit = "kVA" ;
}
if (enumere === 12)
{
decoded.FieldsList.PSunit = "kW" ;
}
}
if (((PSunit& parseInt('10000000', 2)) >>7 )===1)
{
var nbcaractere = PSunit& parseInt('01111111', 2);
var tabdedonne = byte_array.slice(bytesplace, bytesplace+nbcaractere);
decoded.FieldsList.PSunit =dec2String(tabdedonne);
bytesplace=bytesplace+nbcaractere;
}
decoded.FieldsList.PS=decoded.FieldsList.PS + " " + decoded.FieldsList.PSunit;
}
// à traiter: 56 à 75
}
}
}
}
//decode configuration response
if(cmdID === 0x07)
{
}
//decode read configuration response
if(cmdID === 0x09)
{
}
}
else
{
decoded.batch = {};
decoded.batch.report = "batch";
}
}
return decoded;
}