Milesight Codec Uplink Decoder
function get_user_mode(input) { var user_mode = input[9] & 0x7; switch (user_mode) { case 0: return "Valve_Position"; case 1: return "RESERVED"; case 2: return "SP_Ambient_Temperature"; case 3: return "Detecting_Opening_Point"; case 4: return "Slow_Harvesting"; case 5: return "Temperature_Drop"; case 6: return "Freeze_Protect"; case 7: return "Forced_Heating"; default: return "Unknown Operating Mode"; } } function get_user_value(input) { var user_mode = get_user_mode(input); switch (user_mode) { case "Valve_Position": case "Freeze_Protect": case "Forced_Heating": return input[10]; case "SP_Ambient_Temperature": return input[10] * 0.5; case "Detecting_Opening_Point": case "Slow_Harvesting": return input[10] * 0.25; default: return "Invalid User Mode"; } } function decode_port_1(bytes) { var output = {}; { output.DEV_EUI = LoRaObject.devEUI; output.RSSI = LoRaObject.rxInfo[0].rssi; output.SNR = LoRaObject.rxInfo[0].loRaSNR; output.Data = LoRaObject.data; output.ADR = LoRaObject.txInfo.adr; output.coderate = LoRaObject.txInfo.codeRate; output.FCnt = LoRaObject.fCnt; output.Port = LoRaObject.fPort; output.Frequency = LoRaObject.txInfo.frequency; output.Modulation = LoRaObject.txInfo.dataRate.modulation; output.Bandwidth = LoRaObject.txInfo.dataRate.bandwidth; output.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.Operating_Condition= bytes[9] >> 7 & 0x01, output.Storage_Fully_Charged= bytes[9] >> 6 & 0x01, output.Zero_Error= bytes[9] >> 5 & 0x01, output.Calibration_OK= bytes[9] >> 4 & 0x01, output.User_Mode = get_user_mode(bytes); output.User_Value = get_user_value(bytes); } return output; } function decode_port_2(bytes) { var output = {}; { var REV_Major = (bytes[0] & 0xF).toString(); var REV_Minor = ((bytes[0] >> 4) & 0xF).toString(16); output.REV = REV_Major + "." + REV_Minor; } { var HW_Major = (bytes[1] & 0xF).toString(); var HW_Minor = ((bytes[1] >> 4) & 0xF).toString(); output.HW = HW_Major + "." + HW_Minor; } { var FW_Year = bytes[2].toString(); var FW_Month = bytes[3].toString(); var FW_Day = bytes[4].toString(); var FW_Minor = bytes[5].toString(); output.FW = "20" + FW_Year + "." + FW_Month + "." + FW_Day + "." + FW_Minor; } return output; } function decode_port_3(bytes) { var output = {}; switch (bytes[0]) { case 0: output.motor_range = 2.56048; break; case 7: output.motor_range = 1.456; break; case 8: output.motor_range = 1.664; break; case 9: output.motor_range = 1.872; break; case 10: output.motor_range = 2.080; break; case 11: output.motor_range = 2.288; break; case 12: output.motor_range = 2.496; break; default: output.motor_range = 0; break; } return output; } function Decode(fPort, bytes) { var output = {}; switch (fPort) { case 1: output = decode_port_1(bytes); break; case 2: output = decode_port_2(bytes); break; case 3: output = decode_port_3(bytes); break; default: return { errors: ['unknown FPort'], }; } return output; }
Milesight Codec Downlink Encoder
function Encode(fPort, obj) { var encoded = []; if ("Valve_Position_RCI_10_minutes" in obj) { var new_vp_10min = obj.Valve_Position_RCI_10_minutes; encoded = [new_vp_10min,0x00,0x26,0x00,0x00,0x00]; } if ("Valve_Position_RCI_5_minutes" in obj) { var new_vp_5min = obj.Valve_Position_RCI_5_minutes; encoded = [new_vp_5min,0x00,0x26,0x10,0x00,0x00]; } if ("Set_Point_Ambient_Temperature_RCI_10_Minutes" in obj) { var new_spt_10min = (obj.Set_Point_Ambient_Temperature_RCI_10_Minutes)*2; encoded = [new_spt_10min,0x00,0x26,0x08,0x00,0x00]; } if ("Set_Point_Ambient_Temperature_RCI_5_Minutes" in obj) { var new_spt_5min = (obj.Set_Point_Ambient_Temperature_RCI_5_Minutes)*2; encoded = [new_spt_5min,0x00,0x26,0x18,0x00,0x00]; } return encoded; }
Downlink example
{"Set_Point_Ambient_Temperature_RCI_10_Minutes":22} {"Set_Point_Ambient_Temperature_RCI_5_Minutes":20} {"Valve_Position_RCI_10_minutes":73} {"Valve_Position_RCI_5_minutes":42}