Milesight Codec Uplink Decoder
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 Uplink Decoder
/* 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; }