Codec Decoder for zelsius C5 IUF

Hi, we have over 100 Zenner C5 IUF heatmeters and C5 IUW watermeters in use.
This is our payload for the heatmeters, but it doesn’t include everything.
I hope it works for you.

// Decode decodes an array of bytes into an object.
//  - fPort contains the LoRaWAN fPort number
//  - bytes is an array of bytes, e.g. [225, 230, 255, 0]
//  - variables contains the device variables e.g. {"calibration": "3.5"} (both the key / value are of type string)
// The function must return an object, e.g. {"temperature": 22.5}

//Zenner Zelsius C5
// v0.1
// v0.2 Hz - fcvalue slice() fehler angepasst
/*
noch nicht komplett !!!!
*/

/*
2 Transmission szenarios
  TS1: SP6 / SP7 / SP8 / SP9.1 / SP9.2 / SP9.3
  TS2: SP5 / SP8 / SP9.1 / SP9.2 / SP9.3
SP0.1 -diagnostic mode
SP5 - Daily
SP6 - monthly (beginning month)
SP7 - monthly (second half of month)
SP8 - monthly -- only after reaching key date 
SP9.1 - once per month
SP9.2 - after first activation, then every 6 month
SP9.3 - after first activation, then every 6 month
*/

function fcvalue(bytes, length){
  //bytes[i++] << 32 | bytes[i++] << 24 | bytes[i++] << 16 | bytes[i++] << 8 | bytes[i++],
  switch (length){
    case 2:
      return bytes[1] << 8 | bytes[0];
    case 3:
      return bytes[2] << 16 | bytes[1] << 8 | bytes[0];
    case 4:
      return bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];
  }
}
function fcvaluetemp(bytes, type){
  switch(type){
    case 'avg':
      var avg = bytes[1] & 0x0f << 8 | bytes[0];
      if (avg >= 2048){
        avg = 4096-avg}
      return avg;
    case 'max':
      var max = (bytes[1] >> 4) | (bytes[2] << 4) ;
      if (max >= 2048){
        max = 4096-max}
      return max ;
  }
  
  
 /* var avg = bytes[1] & 0x0f << 8 | bytes[0];
  var max = bytes[0];
  //max = max >> 4;
  console.log(avg)
  console.log(max)
  return [avg, max];*/
}

function decodeUplink(input) {
	var data ={};
  var packet_type = input.bytes[0] >> 4;
  var packet_subtype = input.bytes[0] & 0x0F;
  var packet = packet_type + "." + packet_subtype;
  //  var packet = `${packet_subtype}.${packet_type}`;
  data.packettype = packet;
  var avg;

    
    switch (true){
      case packet=='0.1':
        data.energy = {
          value: fcvalue(input.bytes.slice(1, 5), 4) / 1000,
          unit: 'MWh'
        };
        data.cooling = {
          value: fcvalue(input.bytes.slice(5, 9), 4) / 1000,
          unit: 'MWh'
        };
        data.volume = {
          value: fcvalue(input.bytes.slice(9, 13), 4) / 1000,
          unit: 'm3'
        };
        data.avgtemp = {
          value: fcvaluetemp(input.bytes.slice(13),'avg') / 10,
          unit: '°C'
        };
        data.maxtemp = {
          value: fcvaluetemp(input.bytes.slice(13),'max') / 10,
          unit: '°C'
        };
        
        break;
      case packet=='5.1':
        data.energy = {
          value: fcvalue(input.bytes.slice(1, 5), 4) / 1000,
          unit: 'MWh'
        };
        break;

      case packet=='9.1':
      case packet=='9.2':
      case packet=='9.3':
        break;

    }


    return {
      data: data,
      warnings: [],
      errors:[]
    };
}