Versions Compared

Key

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

...

Code Block
languagejs
// Encode downlink function.
//
// Input is an object with the following fields:
// - output = Object representing the payload that must be encoded.
// - variables = Object containing the configured device variables.
//
// Output must be an object with the following fields:
// - bytes = Byte array containing the downlink payload.
function encodeDownlink(input) {
  let mode = input.data.userMode; // "Ambient_Temperature" or "Valve_Position"
  let safetyMode = input.data.safetyMode; // "Ambient_Temperature" or "Valve_Position"
  let setValue = input.data.setValue; // 0-40 for Ambient_Temperature, 0-100 for Valve_Position
  let roomTemperature = input.data.roomTemperature; // 0-40
  let safetyValue = input.data.safetyValue; // 0-40 for Ambient_Temperature, 0-100 for Valve_Position
  let radioInterval = input.data.radioInterval; // 5, 10, 60, 120, 480
  let doReferenceRunNow = input.data.doReferenceRunNow; // 0 or 1

  let 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");
  }

  // Byte 2: Room temperature (0-40)
  if (roomTemperature < 0 || roomTemperature > 40) {
    throw new Error("Room temperature out of range");
  }
  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");
  }

  // Byte 4: Radio interval, user mode, safety mode
  let 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");
  }

  let userModeBits;
  if (mode === "Ambient_Temperature") {
      userModeBits = 2 << 2; // User mode "Ambient_Temperature" in bits 3 and 4
  } else {
      userModeBits = 0 << 2; // User mode "Valve_Position" in bits 3 and 4
  }

  let safetyModeBits;
  if (safetyMode === "Ambient_Temperature") {
      safetyModeBits = 0 << 0; // Safety mode "Ambient_Temperature" in bits 1 and 2
  } else {
      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");
  bytes[5] = doReferenceRunNow << 7;

  return {
      "bytes": bytes
  };
}

...