...
Code Block | ||
---|---|---|
| ||
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);
if (bytes.length == 12) {
utmp = bytes[11] * 0.25;
output.Used_Temperature = utmp;
}
}
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;
} |
...
Code Block | ||
---|---|---|
| ||
// Possible Optionsparameters: // userMode : "Ambient_Temperature" or "Valve_Position" // setValue : 0 to 40 (0.5° resolution) for "Ambient_Temperature" // setValue : 0 to 100 (1% resolution) for "Valve_Position" // safetyMode : "Ambient_Temperature" or "Valve_Position" // safetyValue : 0 to 40 (0.5° resolution) for "Ambient_Temperature" // safetyValue : 0 to 100 (1% resolution) for "Valve_Position" // roomTemperature : 0 (Internal Ambient Estimate) or Temperature from External Sensor (0.25° resolution) // radioInterval : 5 or 10 or 60 or 120 or 480 (minutes) // doReferenceRunNow : 0 or 1 (0-False; 1-True) /* IMPORTANT: All function Encode(fPort,of the parameters in obj) is {NOT required for the encoder varto modework = obj.userMode; // "Ambient_Temperature" or "Valve_Position" var safetyMode = obj.safetyMode; Eg. Only the "roomTemperature" parameter can be added and For the remaining parameters, the defaults will be applied */ var DEFAULT_USER_MODE_BITS = 2 << 2; // "Ambient Temperature" var DEFAULT_SET_VALUE = 38; // 19° Ambient Temperature" var DEFAULT_SAFETY_MODE_BITS = 0 << 0; // "Ambient Temperature" var DEFAULT_SAFETY_MODE_VALUE = 38; // 19° Ambient Temperature" var DEFAULT_RADIO_INTERVAL_BITS = 0 << 4; // 10 minutes var DEFAULT_ROOM_TEMPERATURE_VALUE = 0; // Use Internal Ambient Estimate var DEFAULT_DO_REFERENCE_RUN_NOW_BIT = 0; // 0- No Reference Run function Encode(fPort, obj) { var mode = obj.userMode; // "Ambient_Temperature" or "Valve_Position" var safetyMode = obj.safetyMode; // "Ambient_Temperature" or "Valve_Position" var setValue = obj.setValue; // 0-40 for Ambient_Temperature, 0-100 for Valve_Position var roomTemperature = obj.roomTemperature; // 0-40 var safetyValue = obj.safetyValue; // 0-40 for Ambient_Temperature, 0-100 for Valve_Position var radioInterval = obj.radioInterval; // 5, 10, 60, 120, 480 var doReferenceRunNow = obj.doReferenceRunNow; // 0 or 1 var bytes = [0, 0, 0, 0, 0, 0]; // Byte 1: Set value if (mode === "Ambient_Temperature") { if (setValue < 0 || setValue > 40) { throw new Error("Set value out of range for ambient mode"); } else { bytes[0] = setValue *2; } } else if (mode === "Valve_Position") { if (setValue < 0 || setValue > 100) { throw new Error("Set value out of range for valve mode"); } else { bytes[0] = setValue; } } else { throw new Error("Invalid user mode") bytes[0] = DEFAULT_SET_VALUE; } // Byte 2: Room temperature (0-40) if (roomTemperature < 0 || roomTemperature > 40 || roomTemperature > 40) { throw new Error("Room temperature out of range"); } else if (typeof roomTemperature === "undefined") { throw new Error("Room temperature out of range") bytes[1] = DEFAULT_ROOM_TEMPERATURE_VALUE; } else { bytes[1] = roomTemperature * 4; } // Byte 3: Safety value if (safetyMode === "Ambient_Temperature") { if (safetyValue < 0 || safetyValue > 40) { throw new Error("Safety value out of range for ambient mode"); } else { bytes[2] = safetyValue * 2; } } else if (safetyMode === "Valve_Position") { if (safetyValue < 0 || safetyValue > 100) { throw new Error("Safety value out of range for valve mode"); } else { bytes[2] = safetyValue; } } else { throw new Error("Invalid safety mode")bytes[2] = DEFAULT_SAFETY_MODE_VALUE; } // Byte 4: Radio interval, user mode, safety mode var radioBits; switch (radioInterval) { case 5: radioBits = 1 << 4; // Radio interval 5 minutes break; case 10: radioBits = 0 << 4; // Radio interval 10 minutes break; case 60: radioBits = 2 << 4; // Radio interval 60 minutes break; case 120: radioBits = 3 << 4; // Radio interval 120 minutes break; case 480: radioBits = 4 << 4; // Radio interval 480 minutes break; default: throw new Error("Invalid radio interval")radioBits = DEFAULT_RADIO_INTERVAL_BITS; } var userModeBits; if (mode === "Ambient_Temperature") { userModeBits = 2 << 2; // User mode "Ambient_Temperature" in bits 3 and 4 } else 4 } else if (typeof mode === "undefined") { userModeBits = DEFAULT_USER_MODE_BITS; } else if (mode === "Valve_Position") { userModeBits = 0 << 2; // User mode "Valve_Position" in bits 3 and 4 } var safetyModeBits; if (safetyMode === "Ambient_Temperature") { safetyModeBits = 0 << 0; // Safety mode "Ambient_Temperature" in bits 1 and 2 } else if (typeof safetyMode === "undefined") { safetyModeBits = DEFAULT_SAFETY_MODE_BITS; } else if (safetyMode } else=== "Valve_Position") { safetyModeBits = 2 << 0; // Safety mode "Valve_Position" in bits 1 and 2 } bytes[3] = radioBits | userModeBits | safetyModeBits; // Byte 5: Reserved (set to 0) bytes[4] = 0; // Byte 6: doReferenceRunNow bit (bit 8) if (doReferenceRunNow < 0 || doReferenceRunNow > 1) { throw new Error("Invalid doReferenceRunNow value"); } else if (typeof doReferenceRunNow === "undefined") { bytes[5] = DEFAULT_DO_REFERENCE_RUN_NOW_BIT; } else { bytes[5] = doReferenceRunNow << 7; } return bytes; } |
Downlink example
Code Block | ||
---|---|---|
| ||
// Example 1 { "userMode": "Valve_Position", "setValue": 42, "roomTemperature": 0, "safetyMode": "Ambient_Temperature", "safetyValue": 19, "radioInterval": 5, "doReferenceRunNow": 1 } // Example 2 { "userMode": "Ambient_Temperature", "setValue": 21.5, "roomTemperature": 24, "safetyMode": "Valve_Position", "safetyValue": 0, "radioInterval": 60, "doReferenceRunNow": 0 } // Example 3 { "userMode": "Valve_Position", "setValue": 36, "roomTemperature": 0, "safetyMode": "Valve_Position", "safetyValue": 21, "radioInterval": 5, "doReferenceRunNow": 1 } // Example 4 { "userMode": "Ambient_Temperature", "setValue": 20.5, "roomTemperature": 23.75, "safetyMode": "Ambient_Temperature", "safetyValue": 18, "radioInterval": 10, "doReferenceRunNow": 0 } |
...