{
  "name": "ChirpStack downlink converter for TA692FC-L-5",
  "type": "DOWNLINK",
  "debugMode": true,
  "configuration": {
    "scriptLang": "JS",
    "decoder": null,
    "tbelDecoder": null,
    "encoder": "// Avantec Manufacturing Limited\n// https://www.avantec.com.hk/\n// for TA692FC-L-5\n// T.C. Liang\n// v1.0.0-2023-06-15\n\n// Encode downlink data from incoming Rule Engine message\n\n// msg - JSON message payload downlink message json\n// msgType - type of message, for ex. 'ATTRIBUTES_UPDATED', 'POST_TELEMETRY_REQUEST', etc.\n// metadata - list of key-value pairs with additional data about the message\n// integrationMetadata - list of key-value pairs with additional data defined in Integration executing this converter\n\n/** Encoder **/\n\nvar data = {};\n\nvar fPort;\nvar content;\nvar contentBase64;\n//var length = 0;\n\n// Process data from incoming message and metadata\nvar remoteSetSetTemperature = msg.remoteSetSetTemperature;\nvar remoteSetFanMode = msg.remoteSetFanMode;\nvar remoteSetThreshold = msg.remoteSetThreshold;\nvar remoteSetSystemMode = msg.remoteSetSystemMode;\nvar remoteSetCoolPBand = msg.remoteSetCoolPBand;\nvar remoteSetCoolITime = msg.remoteSetCoolITime;\nvar remoteSetKFactor = msg.remoteSetKFactor;\n\n\nif (remoteSetSetTemperature && (\n        typeof remoteSetSetTemperature === \"number\")) {\n    fPort = 91;\n    //length = 2;\n    content = Math.round(remoteSetSetTemperature * 10);\n    contentBase64 = Uint16ToBase64(content);\n} else if (remoteSetFanMode && (typeof remoteSetFanMode ===\n        \"string\")) {\n    fPort = 92;\n    //length = 1;\n    if (remoteSetFanMode == \"OFF\") {\n        content = 0;\n        contentBase64 = Uint8ToBase64(content);\n    } else if (remoteSetFanMode == \"LOW\") {\n        content = 1;\n        contentBase64 = Uint8ToBase64(content);\n    } else if (remoteSetFanMode == \"MED\") {\n        content = 2;\n        contentBase64 = Uint8ToBase64(content);\n    } else if (remoteSetFanMode == \"HIGH\") {\n        content = 3;\n        contentBase64 = Uint8ToBase64(content);\n    } else if (remoteSetFanMode == \"AUTO\") {\n        content = 4;\n        contentBase64 = Uint8ToBase64(content);\n    }\n} else if (remoteSetThreshold && (\n        typeof remoteSetThreshold === \"number\")) {\n    fPort = 93;\n    //length = 1;\n    content = Math.round(remoteSetThreshold * 10);\n    contentBase64 = Uint8ToBase64(content);\n} else if (remoteSetSystemMode && (\n        typeof remoteSetSystemMode === \"string\")) {\n    fPort = 94;\n    //length = 1;\n    if (remoteSetSystemMode == \"OFF\") {\n        content = 0;\n        contentBase64 = Uint8ToBase64(content);\n    } else if (remoteSetSystemMode == \"COOL\") {\n        content = 1;\n        contentBase64 = Uint8ToBase64(content);\n    } else if (remoteSetSystemMode == \"FAN-ONLY\") {\n        content = 2;\n        contentBase64 = Uint8ToBase64(content);\n    }\n} else if (remoteSetCoolPBand && (\n        typeof remoteSetCoolPBand === \"number\")) {\n    fPort = 95;\n    //length = 1;\n    content = Math.round(remoteSetCoolPBand * 10);\n    contentBase64 = Uint8ToBase64(content);\n} else if (remoteSetCoolITime && (\n        typeof remoteSetCoolITime === \"number\")) {\n    fPort = 96;\n    //length = 2;\n    content = Math.round(remoteSetCoolITime);\n    contentBase64 = Uint16ToBase64(content);\n} else if (remoteSetKFactor && (typeof remoteSetKFactor ===\n        \"number\")) {\n    fPort = 97;\n    //length = 1;\n    content = Math.round(remoteSetKFactor);\n    contentBase64 = Uint8ToBase64(content);\n}\n\nif (content == null) {\n    data.content = \"nil\";\n} else {\n    data.content = content;\n}\n\nif (contentBase64 !== null) {\n    data.contentBase64 = contentBase64;\n}\n\n//data.remoteSetSystemModexxx = typeof remoteSetSystemMode;\n\n\n\n// Result object with encoded downlink payload\nvar result = {\n    // downlink data content type: JSON, TEXT or BINARY (base64 format)\n    contentType: \"TEXT\",\n\n    // downlink data\n    data: contentBase64, //JSON.stringify(data),\n\n    // object: {...},   //ChirpStack v4 // decoded object (when application coded has been configured)\n    // Optional metadata object presented in key/value format\n    metadata: {\n        DevEUI: metadata.cs_devEUI, //ChirpStack v3\n        fPort: fPort //ChirpStack v3\n    }\n};\n\nfunction Uint16ToBase64(value) {\n    var myArr = new Uint8Array(2);\n    myArr[0] = value >> 8; // High byte\n    myArr[1] = value >> 0; // Low byte\n\n    var myStr = Uint8ArrayToString(myArr);\n    return btoa(myStr);\n}\n\nfunction Uint8ToBase64(value) {\n    var myArr = new Uint8Array(1);\n    myArr[0] = value >> 0;\n\n    var myStr = Uint8ArrayToString(myArr);\n    return btoa(myStr);\n}\n\nfunction Uint8ArrayToString(fileData) {\n    var dataString = \"\";\n    for (var i = 0; i < fileData.length; i++) {\n        dataString += String.fromCharCode(fileData[i]);\n    }\n\n    return dataString;\n}\n\nreturn result;\n\n/* debug atob() & btoa()\nvar base64 = \"AOUA12QCAwIBKAAeAw==\";\nvar raw = atob(base64);\ndata.raw = raw;\ndata.rawType = typeof raw;\ndata.rawLength = raw.length;\ndata.decode = base64ToHex(base64);\n//data.base64 = btoa(raw);\n\nfunction base64ToHex(str) {\n  var raw = atob(str);\n  var res = \"\";\n  for (var i = 0; i < raw.length; i++) {\n    var hex = raw.charCodeAt(i).toString(16);\n    res += (hex.length === 2 ? hex : '0' + hex);\n  }\n  return res.toUpperCase();\n}\n\nconst myArr = new Uint8Array(13);\nmyArr[0] = 0x00;\nmyArr[1] = 0xE5;\nmyArr[2] = 0x00;\nmyArr[3] = 0xD7;\nmyArr[4] = 0x64;\nmyArr[5] = 0x02;\nmyArr[6] = 0x03;\nmyArr[7] = 0x02;\nmyArr[8] = 0x01;\nmyArr[9] = 0x28;\nmyArr[10] = 0x00;\nmyArr[11] = 0x1E;\nmyArr[12] = 0x03;\n//let myStr = Buffer.from(myArr.buffer).toString();\nlet myStr  = Uint8ArrayToString(myArr);\ndata.base64 = btoa(myStr);\n*/",
    "tbelEncoder": "// Encode downlink data from incoming Rule Engine message\n\n// msg - JSON message payload downlink message json\n// msgType - type of message, for ex. 'ATTRIBUTES_UPDATED', 'POST_TELEMETRY_REQUEST', etc.\n// metadata - list of key-value pairs with additional data about the message\n// integrationMetadata - list of key-value pairs with additional data defined in Integration executing this converter\n\n/** Encoder **/\n\nvar data = {};\n\n// Process data from incoming message and metadata\n\ndata.tempFreq = msg.temperatureUploadFrequency;\ndata.humFreq = msg.humidityUploadFrequency;\n\ndata.devSerialNumber = metadata['ss_serialNumber'];\n\n// Result object with encoded downlink payload\nvar result = {\n\n    // downlink data content type: JSON, TEXT or BINARY (base64 format)\n    contentType: \"JSON\",\n\n    // downlink data\n    data: JSON.stringify(data),\n\n    // Optional metadata object presented in key/value format\n    metadata: {\n            topic: metadata['deviceType']+'/'+metadata['deviceName']+'/upload'\n    }\n\n};\n\nreturn result;"
  },
  "additionalInfo": {
    "description": "Avantec, v1.0.0, 2023-06-15"
  },
  "edgeTemplate": false,
  "externalId": null
}