Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Milesight Codec Uplink Decoder

Code Block
languagejs
function Decode(fPort, bytes) {
  switch (fPort) {
    case 1:
      {
        var output = {};
        var decoded = {};

        decoded.DEV_EUI = LoRaObject.devEUI;
        decoded.RSSI = LoRaObject.rxInfo[0].rssi;
        decoded.SNR = LoRaObject.rxInfo[0].loRaSNR;
        decoded.Data = LoRaObject.data;
        decoded.ADR = LoRaObject.txInfo.adr;
        decoded.coderate = LoRaObject.txInfo.codeRate;
        decoded.FCnt = LoRaObject.fCnt;
        decoded.Port = LoRaObject.fPort;
        decoded.Frequency = LoRaObject.txInfo.frequency;
        decoded.Modulation = LoRaObject.txInfo.dataRate.modulation;
        decoded.Bandwidth = LoRaObject.txInfo.dataRate.bandwidth;
        decoded.SpreadingFactor = LoRaObject.txInfo.dataRate.spreadFactor;

        output.Current_Valve_Position = bytes[0];
        output.Flow_Sensor_Raw = bytes[1] * 0.5;
        output.Flow_Temperature = bytes[2] * 0.5;
        output.Ambient_Sensor_Raw = bytes[3] * 0.25;
        output.Ambient_Temperature = bytes[4] * 0.25;
        output.Energy_Storage = bytes[5] >> 6 & 0x01;
        output.Harvesting_Active = bytes[5] >> 5 & 0x01;
        output.Ambient_Sensor_Failure = bytes[5] >> 4 & 0x01;
        output.Flow_Sensor_Failure = bytes[5] >> 3 & 0x01;
        output.Radio_Communication_Error = bytes[5] >> 2 & 0x01;
        output.Received_Signal_Strength = bytes[5] >> 1 & 0x01;
        output.Motor_Error = bytes[5] >> 0 & 0x01;
        output.Storage_Voltage = Number((bytes[6] * 0.02).toFixed(2));
        output.Average_Current_Consumed = bytes[7] * 10;
        output.Average_Current_Generated = bytes[8] * 10;
        output.Reference_Completed = bytes[9] >> 4 & 0x01;
        output.Operating_Mode = bytes[9] >> 7 & 0x01;
        output.Storage_Fully_Charged = bytes[9] >> 6 & 0x01;

        if (bytes.length === 11) {
          var um = bytes[9] & 0x03;
          var uv = (um === 0) ? bytes[10] : bytes[10] * 0.5;
          output.User_Mode = um;
          output.User_Value = uv;
        }

        return {status: decoded, uplink_decoded: output};
      }
    default:
      return {
        errors: ['unknown FPort'],
      };
  }
}

Milesight Codec Downlink Encoder

Code Block
/*
Possible values:

"UserMode":"Set_Point_Ambient_Temperature", "Valve_Position"
"SafetyMode":"Set_Point_Ambient_Temperature", "Valve_Position"
"Radio_Communication_Interval": 5,10,60,120,480
"Do_Reference_Run_Now": 0,1
"P_Controller_Gain": 1,2,3,4
"FSOC": "+1","+2","+3","+4","+5","+6","+7","-1","-2","-3","-4","-5","-6","-7","-8"

Example Downlink Object
{
"UserMode":"Set_Point_Ambient_Temperature",
"UserValue":20,

"SafetyMode":"Set_Point_Ambient_Temperature",
"SafetyValue":20,

"Room_Temperature_from_RCU":0,

"Radio_Communication_Interval":10,

"FSOC":"+3",

"Do_Reference_Run_Now":0,
"P_Controller_Gain":1
}
*/

function get_set_point_value(mode, value) {
  if (mode === "undefined") {
    throw "Enter Mode";
  }
  else if (value === "undefined") {
    throw "Enter Value";
  }
  else {
    switch (mode) {
      case "Set_Point_Ambient_Temperature":
        return value*2.0;
      case "Valve_Position":
        return value;
      default:
        throw "Invalid UserMode";
    }
  }
}

function get_room_temperature_from_rcu(obj) {
  if (typeof obj.Room_Temperature_from_RCU === "undefined") {
    throw "Check Room_Temperature_from_RCU";
  }
  else {
    return obj.Room_Temperature_from_RCU;
  }
}

function prepare_radio_communication_interval(obj) {
  if (typeof obj.Radio_Communication_Interval === "undefined") {
    throw "Enter Radio Communication Interval";
  }
  else {
    switch (obj.Radio_Communication_Interval) {
      case 10:
        return "0000";
      case 5:
        return "0001";
      case 60:
        return "0010";
      case 120:
        return "0011";
      case 480:
        return "0100";
      default:
        throw "Invalid Radio Communication Interval";
    }
  }  
}

function prepare_set_point_mode(obj) {
  if (typeof obj === "undefined") {
    throw "Enter Mode";
  } else {
    switch (obj) {
      case "Set_Point_Ambient_Temperature":
        return "10";
      case "Valve_Position":
        return "00";
      default:
        throw "Invalid Mode";
    }
  }  
}

function get_byte_3(obj) {
  var rci_value = prepare_radio_communication_interval(obj);
  var user_mode_value = prepare_set_point_mode(obj.UserMode);
  var safety_mode_value = prepare_set_point_mode(obj.SafetyMode);
  
  var byte_3 = rci_value
             + user_mode_value
             + safety_mode_value;

  var byte_3_converted = parseInt(byte_3, 2);

  return byte_3_converted;
}

function get_flow_sensor_offset_compensation(obj) {
  if (typeof obj.FSOC == "undefined") {
    throw "Enter FSOC";
  } else {
    switch (obj.FSOC) {
      case "+3":
        return parseInt("0000"+"0000", 2);
      case "+1":
        return parseInt("0001"+"0000", 2);
      case "+2":
        return parseInt("0010"+"0000", 2);
      case "+3":
        return parseInt("0011"+"0000", 2);
      case "+4":
        return parseInt("0100"+"0000", 2);
      case "+6":
        return parseInt("0110"+"0000", 2);
      case "+7":
        return parseInt("0111"+"0000", 2);
      case "-8":
        return parseInt("1000"+"0000", 2);
      case "-7":
        return parseInt("1001"+"0000", 2);
      case "-6":
        return parseInt("1010"+"0000", 2);
      case "-5":
        return parseInt("1011"+"0000", 2);
      case "-4":
        return parseInt("1100"+"0000", 2);
      case "-3":
        return parseInt("1101"+"0000", 2);
      case "-2":
        return parseInt("1110"+"0000", 2);
      case "-1":
        return parseInt("1111"+"0000", 2);                
      default:
        throw "Invalid FSOC";
    }
  }  
}

function get_reference_run_bits(obj) {
  if (typeof obj.Do_Reference_Run_Now === "undefined") {
    throw "Enter Do_Reference_Run_Now Bit";
  } else {
    switch (obj.Do_Reference_Run_Now) {
      case 1:
        return "1";
      case 0:
        return "0";
      default:
        throw "Invalid Do_Reference_Run_Now Bit";
    }
  }    
}

function get_p_gain_bits(obj) {
  if (typeof obj.P_Controller_Gain === "undefined") {
    throw "Enter P_Controller_Gain";
  } else {
    switch (obj.P_Controller_Gain) {
      case 1:
        return "10";
      case 2:
        return "11";
      case 3:
        return "00";
      case 4:
        return "01";
      default:
        throw "Invalid P_Controller_Gain";
    }
  }    
}

function get_byte_5(obj) {
  var ref_bit = get_reference_run_bits(obj);
  var p_gain_bit = get_p_gain_bits(obj);

  var byte_5 = ref_bit + p_gain_bit + "00000";

  return (parseInt(byte_5, 2));
}

function Encode(fPort, obj) {
    var encoded = [];

    encoded[0] = get_set_point_value(obj.UserMode, obj.UserValue);
    encoded[1] = get_room_temperature_from_rcu(obj);
    encoded[2] = get_set_point_value(obj.SafetyMode, obj.SafetyValue);
    encoded[3] = get_byte_3(obj);
    encoded[4] = get_flow_sensor_offset_compensation(obj);
    encoded[5] = get_byte_5(obj);

    return encoded;
}