Versions Compared

Key

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

...

Code Block
languagejs
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
languagejs
// 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
languagejson
// 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 
}

...