diff --git a/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/converter.json b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/converter.json new file mode 100644 index 0000000..e925431 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/converter.json @@ -0,0 +1,35 @@ +{ + "name": "ChirpStack uplink converter for Milesight AT101/103", + "type": "UPLINK", + "debugMode": true, + "configuration": { + "scriptLang": "TBEL", + "decoder": null, + "tbelDecoder": "var data = decodeToJson(payload);\nvar deviceName = \"CT101/CT103 \" + data.deviceInfo.deviceName;\nvar deviceType = \"CT101/CT103\";\nvar groupName = null; // If groupName is not null - created device will be added to the entity group with such name.\nvar customerName = null; // If customerName is not null - created devices will be assigned to customer with such name. \n\n// use assetName and assetType instead of deviceName and deviceType\n// to automatically create assets instead of devices.\n// var assetName = 'Asset A';\n// var assetType = 'building';\n\n// If you want to parse incoming data somehow, you can add your code to this function.\n// input: bytes\n// expected output:\n// {\n// \"attributes\": {\"attributeKey\": \"attributeValue\"},\n// \"telemetry\": [{\"ts\": 1...1, \"values\": {\"telemetryKey\":\"telemetryValue\"}, {\"ts\": 1...2, \"values\": {\"telemetryKey\":\"telemetryValue\"}}]\n// }\n\nfunction decodePayload(input) {\n var output = {\n attributes: {},\n telemetry: []\n };\n \n // --- Decoding code --- //\n var decoded = {};\n for (var i = 0; i < input.length - 2;) {\n var channel_id = input[i++] & 0xff;\n var channel_type = input[i++] & 0xff;\n \n // POWER STATE\n if (channel_id === 0xff && channel_type === 0x0b) {\n decoded.power = \"on\";\n i += 1;\n }\n // IPSO VERSION\n if (channel_id === 0xff && channel_type === 0x01) {\n decoded.ipso_version = readProtocolVersion(input[i]);\n i += 1;\n }\n // PRODUCT SERIAL NUMBER\n if (channel_id === 0xff && channel_type === 0x16) {\n decoded.sn = bytesToHex(java.util.Arrays.copyOfRange(input, i, i + 8));\n i += 8;\n }\n // HARDWARE VERSION\n if (channel_id === 0xff && channel_type === 0x09) {\n decoded.hardware_version = readHardwareVersion(java.util.Arrays.copyOfRange(input, i, i + 2));\n i += 2;\n }\n // FIRMWARE VERSION\n if (channel_id === 0xff && channel_type === 0x0a) {\n decoded.firmware_version = readFirmwareVersion(java.util.Arrays.copyOfRange(input, i, i + 2));\n i += 2;\n }\n // TOTAL CURRENT\n if (channel_id === 0x03 && channel_type === 0x97) {\n decoded.total_current = parseBytesToInt(input, i, 4, false) / 100;\n i += 4;\n }\n // CURRENT\n if (channel_id === 0x04 && channel_type === 0x98) {\n var value = parseBytesToInt(input, i, 2, false);\n if (value === 0xffff) {\n decoded.alarm = \"read failed\";\n } else {\n decoded.current = value / 100;\n }\n i += 2;\n }\n // TEMPERATURE\n if (channel_id === 0x09 && channel_type === 0x67) {\n var temperature_value = parseBytesToInt(input, i, 2, false);\n if (temperature_value === 0xfffd) {\n decoded.temperature_exception = \"over range alarm\";\n } else if (temperature_value === 0xffff) {\n decoded.temperature_exception = \"read failed\";\n } else {\n decoded.temperature = parseBytesToInt(input, i, 2, false) / 10;\n }\n i += 2;\n }\n // CURRENT ALARM\n if (channel_id === 0x84 && channel_type === 0x98) {\n decoded.current_max = parseBytesToInt(input, i, 2, false) / 100;\n decoded.current_min = parseBytesToInt(input, i + 2, 2, false) / 100;\n decoded.current = parseBytesToInt(input, i + 4, 2, false) / 100;\n decoded.alarm = readCurrentAlarm(input[i + 6]);\n i += 7;\n }\n // TEMPERATURE ALARM\n if (channel_id === 0x89 && channel_type === 0x67) {\n decoded.temperature = parseBytesToInt(input, i, 2, false) / 10;\n decoded.temperature_alarm = readTemperatureAlarm(input[i + 2]);\n i += 3;\n }\n }\n\n output.telemetry = [{\n ts: timestamp,\n values: decoded\n }];\n \n // --- Decoding code --- //\n return output;\n}\n\n// --- attributes and telemetry objects ---\nvar telemetry = [];\nvar attributes = {};\n// --- attributes and telemetry objects ---\n\n// --- Timestamp parsing\nvar dateString = data.time;\ntimestamp = parseDateToTimestamp(dateString);\n// --- Timestamp parsing\n\n// Passing incoming bytes to decodePayload function, to get custom decoding\nvar customDecoding = decodePayload(base64ToBytes(data\n.data));\n\n\nattributes.eui = data.deviceInfo.devEui;\n\n// Collecting data to result\nif (customDecoding.?telemetry.size() > 0) {\n if (customDecoding.telemetry instanceof java.util.ArrayList) {\n foreach(telemetryObj: customDecoding.telemetry) {\n if (telemetryObj.ts != null && telemetryObj.values != null) {\n telemetry.add(telemetryObj);\n }\n }\n } else {\n telemetry.putAll(customDecoding.telemetry);\n }\n}\n\nif (customDecoding.?attributes.size() > 0) {\n attributes.putAll(customDecoding.attributes);\n}\n\n// You can add some keys manually to attributes or telemetry\nattributes.eui = data.deviceInfo.?devEui;\nattributes.devAddr = data.devAddr;\nattributes.fPort = data.fPort;\nattributes.applicationId = data.deviceInfo.?applicationId;\nattributes.applicationName = data.deviceInfo.?applicationName;\nattributes.tenantId = data.deviceInfo.?tenantId;\nattributes.tenantName = data.deviceInfo.?tenantName;\nattributes.deviceProfileId = data.deviceInfo.?deviceProfileId;\nattributes.deviceProfileName = data.deviceInfo.?deviceProfileName;\nattributes.frequency = data.txInfo.?frequency;\nattributes.bandwidth = data.txInfo.?modulation.?lora.?bandwidth;\nattributes.spreadingFactor = data.txInfo.?modulation.?lora.?spreadingFactor;\nattributes.codeRate = data.txInfo.?modulation.?lora.?codeRate;\n\nvar gatewayInfo = getGatewayInfo();\nvar addDataToTelemetry = {};\naddDataToTelemetry.snr = gatewayInfo.snr;\naddDataToTelemetry.rssi = gatewayInfo.rssi;\naddDataToTelemetry.channel = gatewayInfo.channel;\naddDataToTelemetry.rfChain = gatewayInfo.rfChain;\naddDataToTelemetry.fCnt = data.fCnt;\n\nvar isIncludeGatewayInfo = metadata[\"includeGatewayInfo\"];\nif(isIncludeGatewayInfo == true) {\n telemetry = processTelemetryData(telemetry, addDataToTelemetry);\n}\n\nvar result = {\n deviceName: deviceName,\n deviceType: deviceType,\n // assetName: assetName,\n // assetType: assetType,\n attributes: attributes,\n telemetry: telemetry\n};\n\naddAdditionalInfoForDeviceMsg(result, customerName, groupName);\n\nreturn result;\n\nfunction addAdditionalInfoForDeviceMsg(deviceInfo, customerName, groupName) {\n if (customerName != null) {\n deviceInfo.customerName = customerName;\n }\n if (groupName != null) {\n deviceInfo.groupName = groupName;\n }\n}\n\nfunction parseDateToTimestamp(dateString) {\n var timestamp = -1;\n if (dateString != null) {\n timestamp = new Date(dateString).getTime();\n if (timestamp == -1) {\n var secondsSeparatorIndex = dateString.lastIndexOf(\n '.') + 1;\n var millisecondsEndIndex = dateString.lastIndexOf(\n '+');\n if (millisecondsEndIndex == -1) {\n millisecondsEndIndex = dateString.lastIndexOf(\n 'Z');\n }\n if (millisecondsEndIndex == -1) {\n millisecondsEndIndex = dateString.lastIndexOf(\n '-');\n }\n if (millisecondsEndIndex == -1) {\n if (dateString.length >= secondsSeparatorIndex +\n 3) {\n dateString = dateString.substring(0,\n secondsSeparatorIndex + 3);\n }\n } else {\n dateString = dateString.substring(0,\n secondsSeparatorIndex + 3) +\n dateString.substring(millisecondsEndIndex,\n dateString.length);\n }\n timestamp = new Date(dateString).getTime();\n }\n }\n // If we cannot parse timestamp - we will use the current timestamp\n if (timestamp == -1) {\n timestamp = Date.now();\n }\n \n return timestamp;\n}\n\nfunction getGatewayInfo() {\n var gatewayList = data.rxInfo;\n var maxRssi = Integer. MIN_VALUE;\n var gatewayInfo = {};\n \n foreach (gateway : gatewayList) {\n if(gateway.rssi > maxRssi) {\n maxRssi = gateway.rssi;\n gatewayInfo = gateway;\n }\n }\n \n return gatewayInfo;\n}\n\nfunction processTelemetryData(telemetry, addDataToTelemetry) {\n if (telemetry.size > 1) {\n telemetry = addDataToMultipleTelemetries(telemetry, addDataToTelemetry);\n }\n else if (telemetry.size == 1) {\n telemetry = addDataToSingleTelemetry(telemetry, addDataToTelemetry);\n }\n else {\n telemetry.add(addDataToTelemetry);\n }\n \n return telemetry;\n}\n\nfunction addDataToMultipleTelemetries(telemetry, addDataToTelemetry) {\n foreach(element : addDataToTelemetry.entrySet()) {\n if(!telemetry[0][\"values\"].keys.contains(element.key)) {\n telemetry[0][\"values\"][element.key] = element.value;\n }\n if (!telemetry[1][\"values\"].keys.contains(element.key)) {\n telemetry[1][\"values\"][element.key] = element.value;\n }\n }\n \n return telemetry;\n}\n\nfunction addDataToSingleTelemetry(telemetry, addDataToTelemetry) {\n foreach(element : addDataToTelemetry.entrySet()) {\n if(!telemetry[0][\"values\"].keys.contains(element.key)) {\n telemetry[0][\"values\"][element.key] = element.value;\n }\n }\n \n return telemetry;\n}\n\nfunction readProtocolVersion(bytes) {\n var major = (bytes & 0xf0) >> 4;\n var minor = bytes & 0x0f;\n return \"v\" + major + \".\" + minor;\n}\n\nfunction readHardwareVersion(bytes) {\n var major = bytes[0] & 0xff;\n var minor = (bytes[1] & 0xff) >> 4;\n return \"v\" + major + \".\" + minor;\n}\n\nfunction readFirmwareVersion(bytes) {\n var major = bytes[0] & 0xff;\n var minor = bytes[1] & 0xff;\n return \"v\" + major + \".\" + minor;\n}\n\nfunction readCurrentAlarm(type) {\n var alarm = [];\n if ((type >> 0 & 0x01) != 0) {\n alarm.add(\"threshold alarm\");\n }\n if ((type >> 1 & 0x01) != 0) {\n alarm.add(\"threshold alarm release\");\n }\n if ((type >> 2 & 0x01) != 0) {\n alarm.add(\"over range alarm\");\n }\n if ((type >> 3 & 0x01) != 0) {\n alarm.add(\"over range alarm release\");\n }\n \n return alarm;\n}\n\nfunction readTemperatureAlarm(type) {\n var alarms = [];\n \n if ((type & 0x01) != 0) {\n alarms.add(\"Threshold alarm\");\n }\n if ((type & 0x02) != 0) {\n alarms.add(\"Threshold alarm dismiss\");\n }\n\n return alarms;\n}", + "encoder": null, + "tbelEncoder": null, + "updateOnlyKeys": [ + "tenantId", + "tenantName", + "applicationId", + "applicationName", + "deviceProfileId", + "deviceProfileName", + "devAddr", + "fPort", + "frequency", + "bandwidth", + "spreadingFactor", + "codeRate", + "battery", + "channel", + "rfChain", + "eui", + "beep" + ] + }, + "additionalInfo": { + "description": "" + }, + "edgeTemplate": false +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/metadata.json b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/metadata.json new file mode 100644 index 0000000..1f9359b --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/metadata.json @@ -0,0 +1,4 @@ +{ + "integrationName": "ChirpStack integration", + "includeGatewayInfo": false +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/payload_1.json b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/payload_1.json new file mode 100644 index 0000000..3ac8370 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/payload_1.json @@ -0,0 +1,48 @@ +{ + "deduplicationId": "57433366-50a6-4dc2-8145-2df1bbc70d9e", + "time": "2023-05-22T07:47:05.404859+00:00", + "deviceInfo": { + "tenantId": "52f14cd4-c6f1-4fbd-8f87-4025e1d49242", + "tenantName": "ChirpStack", + "applicationId": "ca739e26-7b67-4f14-b69e-d568c22a5a75", + "applicationName": "Chirpstack application", + "deviceProfileId": "605d08d4-65f5-4d2c-8a5a-3d2457662f79", + "deviceProfileName": "Chirpstack default device profile", + "deviceName": "Device name", + "devEui": "1000000000000001", + "tags": {} + }, + "devAddr": "20000001", + "adr": true, + "dr": 5, + "fCnt": 4, + "fPort": 85, + "confirmed": false, + "data": "/wv//wEB/xZnRtOIAlgAAP8JAQD/CgEB/w8A", + "rxInfo": [{ + "gatewayId": "6a7e111a10000000", + "uplinkId": 24022, + "time": "2023-05-22T07:47:05.404859+00:00", + "rssi": -35, + "snr": 11.5, + "channel": 2, + "rfChain": 1, + "location": {}, + "context": "EFwMtA==", + "metadata": { + "region_common_name": "EU868", + "region_config_id": "eu868" + }, + "crcStatus": "CRC_OK" + }], + "txInfo": { + "frequency": 868500000, + "modulation": { + "lora": { + "bandwidth": 125000, + "spreadingFactor": 7, + "codeRate": "CR_4_5" + } + } + } +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/payload_2.json b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/payload_2.json new file mode 100644 index 0000000..935af88 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/payload_2.json @@ -0,0 +1,48 @@ +{ + "deduplicationId": "57433366-50a6-4dc2-8145-2df1bbc70d9e", + "time": "2023-05-22T07:47:05.404859+00:00", + "deviceInfo": { + "tenantId": "52f14cd4-c6f1-4fbd-8f87-4025e1d49242", + "tenantName": "ChirpStack", + "applicationId": "ca739e26-7b67-4f14-b69e-d568c22a5a75", + "applicationName": "Chirpstack application", + "deviceProfileId": "605d08d4-65f5-4d2c-8a5a-3d2457662f79", + "deviceProfileName": "Chirpstack default device profile", + "deviceName": "Device name", + "devEui": "1000000000000001", + "tags": {} + }, + "devAddr": "20000001", + "adr": true, + "dr": 5, + "fCnt": 4, + "fPort": 85, + "confirmed": false, + "data": "A5cQJwAA", + "rxInfo": [{ + "gatewayId": "6a7e111a10000000", + "uplinkId": 24022, + "time": "2023-05-22T07:47:05.404859+00:00", + "rssi": -35, + "snr": 11.5, + "channel": 2, + "rfChain": 1, + "location": {}, + "context": "EFwMtA==", + "metadata": { + "region_common_name": "EU868", + "region_config_id": "eu868" + }, + "crcStatus": "CRC_OK" + }], + "txInfo": { + "frequency": 868500000, + "modulation": { + "lora": { + "bandwidth": 125000, + "spreadingFactor": 7, + "codeRate": "CR_4_5" + } + } + } +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/payload_3.json b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/payload_3.json new file mode 100644 index 0000000..faf3415 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/payload_3.json @@ -0,0 +1,48 @@ +{ + "deduplicationId": "57433366-50a6-4dc2-8145-2df1bbc70d9e", + "time": "2023-05-22T07:47:05.404859+00:00", + "deviceInfo": { + "tenantId": "52f14cd4-c6f1-4fbd-8f87-4025e1d49242", + "tenantName": "ChirpStack", + "applicationId": "ca739e26-7b67-4f14-b69e-d568c22a5a75", + "applicationName": "Chirpstack application", + "deviceProfileId": "605d08d4-65f5-4d2c-8a5a-3d2457662f79", + "deviceProfileName": "Chirpstack default device profile", + "deviceName": "Device name", + "devEui": "1000000000000001", + "tags": {} + }, + "devAddr": "20000001", + "adr": true, + "dr": 5, + "fCnt": 4, + "fPort": 85, + "confirmed": false, + "data": "BJi4CwAAAAA=", + "rxInfo": [{ + "gatewayId": "6a7e111a10000000", + "uplinkId": 24022, + "time": "2023-05-22T07:47:05.404859+00:00", + "rssi": -35, + "snr": 11.5, + "channel": 2, + "rfChain": 1, + "location": {}, + "context": "EFwMtA==", + "metadata": { + "region_common_name": "EU868", + "region_config_id": "eu868" + }, + "crcStatus": "CRC_OK" + }], + "txInfo": { + "frequency": 868500000, + "modulation": { + "lora": { + "bandwidth": 125000, + "spreadingFactor": 7, + "codeRate": "CR_4_5" + } + } + } +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/payload_4.json b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/payload_4.json new file mode 100644 index 0000000..6c692f7 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/payload_4.json @@ -0,0 +1,48 @@ +{ + "deduplicationId": "57433366-50a6-4dc2-8145-2df1bbc70d9e", + "time": "2023-05-22T07:47:05.404859+00:00", + "deviceInfo": { + "tenantId": "52f14cd4-c6f1-4fbd-8f87-4025e1d49242", + "tenantName": "ChirpStack", + "applicationId": "ca739e26-7b67-4f14-b69e-d568c22a5a75", + "applicationName": "Chirpstack application", + "deviceProfileId": "605d08d4-65f5-4d2c-8a5a-3d2457662f79", + "deviceProfileName": "Chirpstack default device profile", + "deviceName": "Device name", + "devEui": "1000000000000001", + "tags": {} + }, + "devAddr": "20000001", + "adr": true, + "dr": 5, + "fCnt": 4, + "fPort": 85, + "confirmed": false, + "data": "BJj//w==", + "rxInfo": [{ + "gatewayId": "6a7e111a10000000", + "uplinkId": 24022, + "time": "2023-05-22T07:47:05.404859+00:00", + "rssi": -35, + "snr": 11.5, + "channel": 2, + "rfChain": 1, + "location": {}, + "context": "EFwMtA==", + "metadata": { + "region_common_name": "EU868", + "region_config_id": "eu868" + }, + "crcStatus": "CRC_OK" + }], + "txInfo": { + "frequency": 868500000, + "modulation": { + "lora": { + "bandwidth": 125000, + "spreadingFactor": 7, + "codeRate": "CR_4_5" + } + } + } +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/payload_5.json b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/payload_5.json new file mode 100644 index 0000000..591fd14 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/payload_5.json @@ -0,0 +1,48 @@ +{ + "deduplicationId": "57433366-50a6-4dc2-8145-2df1bbc70d9e", + "time": "2023-05-22T07:47:05.404859+00:00", + "deviceInfo": { + "tenantId": "52f14cd4-c6f1-4fbd-8f87-4025e1d49242", + "tenantName": "ChirpStack", + "applicationId": "ca739e26-7b67-4f14-b69e-d568c22a5a75", + "applicationName": "Chirpstack application", + "deviceProfileId": "605d08d4-65f5-4d2c-8a5a-3d2457662f79", + "deviceProfileName": "Chirpstack default device profile", + "deviceName": "Device name", + "devEui": "1000000000000001", + "tags": {} + }, + "devAddr": "20000001", + "adr": true, + "dr": 5, + "fCnt": 4, + "fPort": 85, + "confirmed": false, + "data": "hJi4C9AHxAkF", + "rxInfo": [{ + "gatewayId": "6a7e111a10000000", + "uplinkId": 24022, + "time": "2023-05-22T07:47:05.404859+00:00", + "rssi": -35, + "snr": 11.5, + "channel": 2, + "rfChain": 1, + "location": {}, + "context": "EFwMtA==", + "metadata": { + "region_common_name": "EU868", + "region_config_id": "eu868" + }, + "crcStatus": "CRC_OK" + }], + "txInfo": { + "frequency": 868500000, + "modulation": { + "lora": { + "bandwidth": 125000, + "spreadingFactor": 7, + "codeRate": "CR_4_5" + } + } + } +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/result_1.json b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/result_1.json new file mode 100644 index 0000000..3b06e06 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/result_1.json @@ -0,0 +1,29 @@ +{ + "deviceName": "CT101/CT103 Device name", + "deviceType": "CT101/CT103", + "attributes": { + "eui": "1000000000000001", + "devAddr": "20000001", + "fPort": 85, + "applicationId": "ca739e26-7b67-4f14-b69e-d568c22a5a75", + "applicationName": "Chirpstack application", + "tenantId": "52f14cd4-c6f1-4fbd-8f87-4025e1d49242", + "tenantName": "ChirpStack", + "deviceProfileId": "605d08d4-65f5-4d2c-8a5a-3d2457662f79", + "deviceProfileName": "Chirpstack default device profile", + "frequency": 868500000, + "bandwidth": 125000, + "spreadingFactor": 7, + "codeRate": "CR_4_5" + }, + "telemetry": [{ + "ts": 1684741625404, + "values": { + "power": "on", + "ipso_version": "v0.1", + "sn": "6746D38802580000", + "hardware_version": "v1.0", + "firmware_version": "v1.1" + } + }] +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/result_2.json b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/result_2.json new file mode 100644 index 0000000..bd14e7c --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/result_2.json @@ -0,0 +1,25 @@ +{ + "deviceName": "CT101/CT103 Device name", + "deviceType": "CT101/CT103", + "attributes": { + "eui": "1000000000000001", + "devAddr": "20000001", + "fPort": 85, + "applicationId": "ca739e26-7b67-4f14-b69e-d568c22a5a75", + "applicationName": "Chirpstack application", + "tenantId": "52f14cd4-c6f1-4fbd-8f87-4025e1d49242", + "tenantName": "ChirpStack", + "deviceProfileId": "605d08d4-65f5-4d2c-8a5a-3d2457662f79", + "deviceProfileName": "Chirpstack default device profile", + "frequency": 868500000, + "bandwidth": 125000, + "spreadingFactor": 7, + "codeRate": "CR_4_5" + }, + "telemetry": [{ + "ts": 1684741625404, + "values": { + "total_current": 100.0 + } + }] +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/result_3.json b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/result_3.json new file mode 100644 index 0000000..fcba59e --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/result_3.json @@ -0,0 +1,25 @@ +{ + "deviceName": "CT101/CT103 Device name", + "deviceType": "CT101/CT103", + "attributes": { + "eui": "1000000000000001", + "devAddr": "20000001", + "fPort": 85, + "applicationId": "ca739e26-7b67-4f14-b69e-d568c22a5a75", + "applicationName": "Chirpstack application", + "tenantId": "52f14cd4-c6f1-4fbd-8f87-4025e1d49242", + "tenantName": "ChirpStack", + "deviceProfileId": "605d08d4-65f5-4d2c-8a5a-3d2457662f79", + "deviceProfileName": "Chirpstack default device profile", + "frequency": 868500000, + "bandwidth": 125000, + "spreadingFactor": 7, + "codeRate": "CR_4_5" + }, + "telemetry": [{ + "ts": 1684741625404, + "values": { + "current": 30.0 + } + }] +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/result_4.json b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/result_4.json new file mode 100644 index 0000000..da6a20b --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/result_4.json @@ -0,0 +1,25 @@ +{ + "deviceName": "CT101/CT103 Device name", + "deviceType": "CT101/CT103", + "attributes": { + "eui": "1000000000000001", + "devAddr": "20000001", + "fPort": 85, + "applicationId": "ca739e26-7b67-4f14-b69e-d568c22a5a75", + "applicationName": "Chirpstack application", + "tenantId": "52f14cd4-c6f1-4fbd-8f87-4025e1d49242", + "tenantName": "ChirpStack", + "deviceProfileId": "605d08d4-65f5-4d2c-8a5a-3d2457662f79", + "deviceProfileName": "Chirpstack default device profile", + "frequency": 868500000, + "bandwidth": 125000, + "spreadingFactor": 7, + "codeRate": "CR_4_5" + }, + "telemetry": [{ + "ts": 1684741625404, + "values": { + "alarm": "read failed" + } + }] +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/result_5.json b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/result_5.json new file mode 100644 index 0000000..b6b232d --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ChirpStack/uplink/result_5.json @@ -0,0 +1,28 @@ +{ + "deviceName": "CT101/CT103 Device name", + "deviceType": "CT101/CT103", + "attributes": { + "eui": "1000000000000001", + "devAddr": "20000001", + "fPort": 85, + "applicationId": "ca739e26-7b67-4f14-b69e-d568c22a5a75", + "applicationName": "Chirpstack application", + "tenantId": "52f14cd4-c6f1-4fbd-8f87-4025e1d49242", + "tenantName": "ChirpStack", + "deviceProfileId": "605d08d4-65f5-4d2c-8a5a-3d2457662f79", + "deviceProfileName": "Chirpstack default device profile", + "frequency": 868500000, + "bandwidth": 125000, + "spreadingFactor": 7, + "codeRate": "CR_4_5" + }, + "telemetry": [{ + "ts": 1684741625404, + "values": { + "current_max": 30.0, + "current_min": 20.0, + "current": 25.0, + "alarm": ["threshold alarm", "over range alarm"] + } + }] +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/Loriot/uplink/converter.json b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/converter.json new file mode 100644 index 0000000..c9ce64f --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/converter.json @@ -0,0 +1,25 @@ +{ + "name": "Uplink data converter for Loriot integration СТ101/СТ103", + "type": "UPLINK", + "debugMode": true, + "configuration": { + "scriptLang": "TBEL", + "decoder": "// Decode an uplink message from a buffer\n// payload - array of bytes\n// metadata - key/value object\n\n/** Decoder **/\n\n// decode payload to string\nvar payloadStr = decodeToString(payload);\n\n// decode payload to JSON\n// var data = decodeToJson(payload);\n\nvar deviceName = 'Device A';\nvar deviceType = 'thermostat';\nvar customerName = 'Customer C';\nvar groupName = 'thermostat devices';\nvar manufacturer = 'Example corporation';\n// use assetName and assetType instead of deviceName and deviceType\n// to automatically create assets instead of devices.\n// var assetName = 'Asset A';\n// var assetType = 'building';\n\n// Result object with device/asset attributes/telemetry data\nvar result = {\n// Use deviceName and deviceType or assetName and assetType, but not both.\n deviceName: deviceName,\n deviceType: deviceType,\n// assetName: assetName,\n// assetType: assetType,\n// customerName: customerName,\n groupName: groupName,\n attributes: {\n model: 'Model A',\n serialNumber: 'SN111',\n integrationName: metadata['integrationName'],\n manufacturer: manufacturer\n },\n telemetry: {\n temperature: 42,\n humidity: 80,\n rawData: payloadStr\n }\n};\n\n/** Helper functions **/\n\nfunction decodeToString(payload) {\n return String.fromCharCode.apply(String, payload);\n}\n\nfunction decodeToJson(payload) {\n // covert payload to string.\n var str = decodeToString(payload);\n\n // parse string to JSON\n var data = JSON.parse(str);\n return data;\n}\n\nreturn result;", + "tbelDecoder": "var data = decodeToJson(payload);\nvar deviceName = \"CT101/CT103 \" + data.EUI;\nvar deviceType = \"CT101/CT103\";\nvar groupName = null; // If groupName is not null - created device will be added to the entity group with such name.\nvar customerName = null; // If customerName is not null - created devices will be assigned to customer with such name. \n\n// use assetName and assetType instead of deviceName and deviceType\n// to automatically create assets instead of devices.\n// var assetName = 'Asset A';\n// var assetType = 'building';\n\n// If you want to parse incoming data somehow, you can add your code to this function.\n// input: bytes\n// expected output:\n// {\n// \"attributes\": {\"attributeKey\": \"attributeValue\"},\n// \"telemetry\": {\"telemetryKey\": \"telemetryValue\"}\n// }\n\nfunction decodePayload(input) {\n var output = { attributes: {}, telemetry: []};\n \n // --- Decoding code --- //\n var decoded = {};\n for (var i = 0; i < input.length - 2; ) {\n var channel_id = input[i++] & 0xff;\n var channel_type = input[i++] & 0xff;\n \n // POWER STATE\n if (channel_id === 0xff && channel_type === 0x0b) {\n decoded.power = \"on\";\n i += 1;\n }\n // IPSO VERSION\n if (channel_id === 0xff && channel_type === 0x01) {\n decoded.ipso_version = readProtocolVersion(input[i]);\n i += 1;\n }\n // PRODUCT SERIAL NUMBER\n if (channel_id === 0xff && channel_type === 0x16) {\n decoded.sn = bytesToHex(input.slice(i, i + 8));\n i += 8;\n }\n // HARDWARE VERSION\n if (channel_id === 0xff && channel_type === 0x09) {\n decoded.hardware_version = readHardwareVersion(input.slice(i, i + 2));\n i += 2;\n }\n // FIRMWARE VERSION\n if (channel_id === 0xff && channel_type === 0x0a) {\n decoded.firmware_version = readFirmwareVersion(input.slice(i, i + 2));\n i += 2;\n }\n // TOTAL CURRENT\n if (channel_id === 0x03 && channel_type === 0x97) {\n decoded.total_current = parseBytesToInt(input, i, 4, false) / 100;\n i += 4;\n }\n // CURRENT\n if (channel_id === 0x04 && channel_type === 0x98) {\n var value = parseBytesToInt(input, i, 2, false);\n if (value === 0xffff) {\n decoded.alarm = \"read failed\";\n } else {\n decoded.current = value / 100;\n }\n i += 2;\n }\n // TEMPERATURE\n if (channel_id === 0x09 && channel_type === 0x67) {\n var temperature_value = parseBytesToInt(input, i, 2, false);\n if (temperature_value === 0xfffd) {\n decoded.temperature_exception = \"over range alarm\";\n } else if (temperature_value === 0xffff) {\n decoded.temperature_exception = \"read failed\";\n } else {\n decoded.temperature = parseBytesToInt(input, i, 2, false) / 10;\n }\n i += 2;\n }\n // CURRENT ALARM\n if (channel_id === 0x84 && channel_type === 0x98) {\n decoded.current_max = parseBytesToInt(input, i, 2, false) / 100;\n decoded.current_min = parseBytesToInt(input, i+2, 2, false) / 100;\n decoded.current = parseBytesToInt(input, i+4, 2, false) / 100;\n decoded.alarm = readCurrentAlarm(input[i + 6]);\n i += 7;\n }\n // TEMPERATURE ALARM\n if (channel_id === 0x89 && channel_type === 0x67) {\n decoded.temperature = parseBytesToInt(input, i, 2, false) / 10;\n decoded.temperature_alarm = readTemperatureAlarm(input[i + 2]);\n i += 3;\n }\n }\n \n output.telemetry = [{\n ts: timestamp,\n values: decoded\n }];\n\n // --- Decoding code --- //\n return output;\n}\n\n// --- attributes and telemetry objects ---\nvar telemetry = [];\nvar attributes = {};\n// --- attributes and telemetry objects ---\n\n// --- Timestamp parsing\ntimestamp = data.ts;\n// --- Timestamp parsing\n\n// Message parsing\n// To avoid paths in the decoded objects we passing false value to function as \"pathInKey\" argument.\n// Warning: pathInKey can cause already found fields to be overwritten with the last value found.\n\nvar uplinkDataList = [];\n\n// Passing incoming bytes to decodePayload function, to get custom decoding\nvar customDecoding = decodePayload(hexToBytes(data.data));\n\n// Collecting data to result\nif (customDecoding.?telemetry.size() > 0) {\n if (customDecoding.telemetry instanceof java.util.ArrayList) {\n foreach(telemetryObj: customDecoding.telemetry) {\n if (telemetryObj.ts != null && telemetryObj.values != null) {\n telemetry.add(telemetryObj);\n }\n }\n } else {\n telemetry.putAll(customDecoding.telemetry);\n }\n}\n\nif (customDecoding.?attributes.size() > 0) {\n attributes.putAll(customDecoding.attributes);\n}\n\n// You can add some keys manually to attributes or telemetry\nattributes.eui = data.EUI;\nattributes.fPort = data.port;\nattributes.frequency = data.freq;\n\nvar addDataToTelemetry = {};\naddDataToTelemetry.rssi = data.rssi;\naddDataToTelemetry.seqno = data.seqno;\naddDataToTelemetry.snr = data.snr;\naddDataToTelemetry.ack = data.ack;\naddDataToTelemetry.toa = data.toa;\naddDataToTelemetry.fCnt = data.fcnt;\n\nvar isIncludeGatewayInfo = metadata[\"includeGatewayInfo\"];\nif(isIncludeGatewayInfo == true) {\n telemetry = processTelemetryData(telemetry, addDataToTelemetry);\n}\n\nvar deviceInfo = {\n deviceName: deviceName,\n deviceType: deviceType,\n// assetName: assetName,\n// assetType: assetType,\n attributes: attributes,\n telemetry: telemetry, \n};\n\naddAdditionalInfoForDeviceMsg(deviceInfo, customerName, groupName);\n\nuplinkDataList.add(deviceInfo);\n\nvar includeGatewayInfo = [\"ts\", \"gweui\", \"rssi\"];\n\nvar gatewayDeviceNamePrefix = \"Gateway \";\nvar gatewayDeviceType = \"Lora gateway\";\nvar gatewayGroupName = null; // If gatewayGroupName is not null - created device will be added to the entity group with such name.\n\nif (data.cmd == \"gw\") {\n foreach( gatewayInfo : data.gws ) {\n var gatewayInfoMsg = {\n deviceName: gatewayDeviceNamePrefix + gatewayInfo.gweui,\n deviceType: gatewayDeviceType,\n telemetry: [{\n \"ts\": parseDateToTimestamp(gatewayInfo.ts),\n \"values\": getDataList(gatewayInfo, includeGatewayInfo)\n }],\n attributes: {\n eui: gatewayInfo.gweui\n }\n };\n addAdditionalInfoForDeviceMsg(gatewayInfoMsg, customerName, gatewayGroupName);\n uplinkDataList.add(gatewayInfoMsg);\n }\n}\n\nreturn uplinkDataList;\n\nfunction addAdditionalInfoForDeviceMsg(deviceInfo, customerName, groupName) {\n if (customerName != null) {\n deviceInfo.customerName = customerName;\n }\n if (groupName != null) {\n deviceInfo.groupName = groupName;\n }\n}\n\nfunction parseDateToTimestamp(dateString) {\n var timestamp = -1;\n if (dateString != null) {\n \n timestamp = new Date(dateString).getTime();\n if (timestamp == -1) {\n var secondsSeparatorIndex = dateString.lastIndexOf('.') + 1;\n var millisecondsEndIndex = dateString.lastIndexOf('+');\n if (millisecondsEndIndex == -1) {\n millisecondsEndIndex = dateString.lastIndexOf('Z');\n }\n if (millisecondsEndIndex == -1) {\n millisecondsEndIndex = dateString.lastIndexOf('-');\n }\n if (millisecondsEndIndex == -1) {\n if (dateString.length >= secondsSeparatorIndex + 3) {\n dateString = dateString.substring(0, secondsSeparatorIndex + 3);\n }\n } else {\n dateString = dateString.substring(0, secondsSeparatorIndex + 3) +\n dateString.substring(millisecondsEndIndex, dateString.length);\n }\n \n timestamp = new Date(dateString).getTime();\n }\n }\n // If we cannot parse timestamp - we will use the current timestamp\n if (timestamp == -1) {\n timestamp = Date.now();\n }\n \n return timestamp;\n}\n\nfunction processTelemetryData(telemetry, addDataToTelemetry) {\n if (telemetry.size > 1) {\n telemetry = addDataToMultipleTelemetries(telemetry, addDataToTelemetry);\n }\n else if (telemetry.size == 1) {\n telemetry = addDataToSingleTelemetry(telemetry, addDataToTelemetry);\n }\n else {\n telemetry.add(addDataToTelemetry);\n }\n \n return telemetry;\n}\n\nfunction addDataToMultipleTelemetries(telemetry, addDataToTelemetry) {\n foreach(element : addDataToTelemetry.entrySet()) {\n if(!telemetry[0][\"values\"].keys.contains(element.key)) {\n telemetry[0][\"values\"][element.key] = element.value;\n }\n if (!telemetry[1][\"values\"].keys.contains(element.key)) {\n telemetry[1][\"values\"][element.key] = element.value;\n }\n }\n \n return telemetry;\n}\n\nfunction addDataToSingleTelemetry(telemetry, addDataToTelemetry) {\n foreach(element : addDataToTelemetry.entrySet()) {\n if(!telemetry[0][\"values\"].keys.contains(element.key)) {\n telemetry[0][\"values\"][element.key] = element.value;\n }\n }\n \n return telemetry;\n}\n\nfunction readProtocolVersion(bytes) {\n var major = (bytes & 0xf0) >> 4;\n var minor = bytes & 0x0f;\n return \"v\" + major + \".\" + minor;\n}\n\nfunction readHardwareVersion(bytes) {\n var major = bytes[0] & 0xff;\n var minor = (bytes[1] & 0xff) >> 4;\n return \"v\" + major + \".\" + minor;\n}\n\nfunction readFirmwareVersion(bytes) {\n var major = bytes[0] & 0xff;\n var minor = bytes[1] & 0xff;\n return \"v\" + major + \".\" + minor;\n}\n\nfunction readCurrentAlarm(type) {\n var alarm = [];\n if ((type >> 0 & 0x01) != 0) {\n alarm.add(\"threshold alarm\");\n }\n if ((type >> 1 & 0x01) != 0) {\n alarm.add(\"threshold alarm release\");\n }\n if ((type >> 2 & 0x01) != 0) {\n alarm.add(\"over range alarm\");\n }\n if ((type >> 3 & 0x01) != 0) {\n alarm.add(\"over range alarm release\");\n }\n \n return alarm;\n}\n\nfunction readTemperatureAlarm(type) {\n var alarms = [];\n \n if ((type & 0x01) != 0) {\n alarms.add(\"Threshold alarm\");\n }\n if ((type & 0x02) != 0) {\n alarms.add(\"Threshold alarm dismiss\");\n }\n\n return alarms;\n}", + "encoder": null, + "tbelEncoder": null, + "updateOnlyKeys": [ + "fPort", + "battery", + "ack", + "beep", + "eui", + "frequency", + "dr" + ] + }, + "additionalInfo": { + "description": "" + }, + "edgeTemplate": false +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/Loriot/uplink/metadata.json b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/metadata.json new file mode 100644 index 0000000..d991a3c --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/metadata.json @@ -0,0 +1,4 @@ +{ + "integrationName": "Loriot integration", + "includeGatewayInfo": false +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/Loriot/uplink/payload_1.json b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/payload_1.json new file mode 100644 index 0000000..fbf3d55 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/payload_1.json @@ -0,0 +1,17 @@ +{ + "cmd": "rx", + "seqno": 3040, + "EUI": "1000000000000001", + "ts": 1684478801936, + "fcnt": 2, + "port": 85, + "freq": 867500000, + "rssi": -21, + "snr": 10, + "toa": 206, + "dr": "SF9 BW125 4/5", + "ack": false, + "bat": 94, + "offline": false, + "data": "FF0BFFFF0101FF166746D38802580000FF090100FF0A0101FF0F00" +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/Loriot/uplink/payload_2.json b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/payload_2.json new file mode 100644 index 0000000..0186e63 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/payload_2.json @@ -0,0 +1,17 @@ +{ + "cmd": "rx", + "seqno": 3040, + "EUI": "1000000000000001", + "ts": 1684478801936, + "fcnt": 2, + "port": 85, + "freq": 867500000, + "rssi": -21, + "snr": 10, + "toa": 206, + "dr": "SF9 BW125 4/5", + "ack": false, + "bat": 94, + "offline": false, + "data": "039710270000" +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/Loriot/uplink/payload_3.json b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/payload_3.json new file mode 100644 index 0000000..75d5326 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/payload_3.json @@ -0,0 +1,17 @@ +{ + "cmd": "rx", + "seqno": 3040, + "EUI": "1000000000000001", + "ts": 1684478801936, + "fcnt": 2, + "port": 85, + "freq": 867500000, + "rssi": -21, + "snr": 10, + "toa": 206, + "dr": "SF9 BW125 4/5", + "ack": false, + "bat": 94, + "offline": false, + "data": "0498B80B00000000" +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/Loriot/uplink/payload_4.json b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/payload_4.json new file mode 100644 index 0000000..b9c8733 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/payload_4.json @@ -0,0 +1,17 @@ +{ + "cmd": "rx", + "seqno": 3040, + "EUI": "1000000000000001", + "ts": 1684478801936, + "fcnt": 2, + "port": 85, + "freq": 867500000, + "rssi": -21, + "snr": 10, + "toa": 206, + "dr": "SF9 BW125 4/5", + "ack": false, + "bat": 94, + "offline": false, + "data": "0498FFFF" +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/Loriot/uplink/payload_5.json b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/payload_5.json new file mode 100644 index 0000000..977e280 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/payload_5.json @@ -0,0 +1,17 @@ +{ + "cmd": "rx", + "seqno": 3040, + "EUI": "1000000000000001", + "ts": 1684478801936, + "fcnt": 2, + "port": 85, + "freq": 867500000, + "rssi": -21, + "snr": 10, + "toa": 206, + "dr": "SF9 BW125 4/5", + "ack": false, + "bat": 94, + "offline": false, + "data": "8498B80BD007C40905" +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/Loriot/uplink/result_1.json b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/result_1.json new file mode 100644 index 0000000..d80f27a --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/result_1.json @@ -0,0 +1,19 @@ +[{ + "deviceName": "CT101/CT103 1000000000000001", + "deviceType": "CT101/CT103", + "attributes": { + "eui": "1000000000000001", + "fPort": 85, + "frequency": 867500000 + }, + "telemetry": [{ + "ts": 1684478801936, + "values": { + "power": "on", + "ipso_version": "v0.1", + "sn": "6746D38802580000", + "hardware_version": "v1.0", + "firmware_version": "v1.1" + } + }] +}] \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/Loriot/uplink/result_2.json b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/result_2.json new file mode 100644 index 0000000..c6c5509 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/result_2.json @@ -0,0 +1,15 @@ +[{ + "deviceName": "CT101/CT103 1000000000000001", + "deviceType": "CT101/CT103", + "attributes": { + "eui": "1000000000000001", + "fPort": 85, + "frequency": 867500000 + }, + "telemetry": [{ + "ts": 1684478801936, + "values": { + "total_current": 100.0 + } + }] +}] \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/Loriot/uplink/result_3.json b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/result_3.json new file mode 100644 index 0000000..ab0d949 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/result_3.json @@ -0,0 +1,15 @@ +[{ + "deviceName": "CT101/CT103 1000000000000001", + "deviceType": "CT101/CT103", + "attributes": { + "eui": "1000000000000001", + "fPort": 85, + "frequency": 867500000 + }, + "telemetry": [{ + "ts": 1684478801936, + "values": { + "current": 30.0 + } + }] +}] \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/Loriot/uplink/result_4.json b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/result_4.json new file mode 100644 index 0000000..023b348 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/result_4.json @@ -0,0 +1,15 @@ +[{ + "deviceName": "CT101/CT103 1000000000000001", + "deviceType": "CT101/CT103", + "attributes": { + "eui": "1000000000000001", + "fPort": 85, + "frequency": 867500000 + }, + "telemetry": [{ + "ts": 1684478801936, + "values": { + "alarm": "read failed" + } + }] +}] \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/Loriot/uplink/result_5.json b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/result_5.json new file mode 100644 index 0000000..3ed946f --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/Loriot/uplink/result_5.json @@ -0,0 +1,18 @@ +[{ + "deviceName": "CT101/CT103 1000000000000001", + "deviceType": "CT101/CT103", + "attributes": { + "eui": "1000000000000001", + "fPort": 85, + "frequency": 867500000 + }, + "telemetry": [{ + "ts": 1684478801936, + "values": { + "current_max": 30.0, + "current_min": 20.0, + "current": 25.0, + "alarm": ["threshold alarm", "over range alarm"] + } + }] +}] \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/converter.json b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/converter.json new file mode 100644 index 0000000..1507971 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/converter.json @@ -0,0 +1,35 @@ +{ + "name": "Uplink data converter for The Things Stack Community integration CT101/CT103", + "type": "UPLINK", + "debugMode": true, + "configuration": { + "scriptLang": "TBEL", + "decoder": null, + "tbelDecoder": "var data = decodeToJson(payload);\n\nvar deviceName = \"CT101/CT103 \" + data.end_device_ids.device_id;\nvar deviceType = \"CT101/CT103\";\nvar groupName = null; // If groupName is not null - created device will be added to the entity group with such name.\nvar customerName = null; // If customerName is not null - created devices will be assigned to customer with such name. \n\n// use assetName and assetType instead of deviceName and deviceType\n// to automatically create assets instead of devices.\n// var assetName = 'Asset A';\n// var assetType = 'building';\n\n// If you want to parse incoming data somehow, you can add your code to this function.\n// input: bytes\n// expected output:\n// {\n// \"attributes\": {\"attributeKey\": \"attributeValue\"},\n// \"telemetry\": [{\"ts\": 1...1, \"values\": {\"telemetryKey\":\"telemetryValue\"}, {\"ts\": 1...2, \"values\": {\"telemetryKey\":\"telemetryValue\"}}]\n// }\n\nfunction decodeFrmPayload(input) {\n var output = {\n attributes: {}, telemetry: {}\n };\n \n // --- Decoding code --- //\n var decoded = {};\n for (var i = 0; i < input.length - 2; ) {\n var channel_id = input[i++] & 0xff;\n var channel_type = input[i++] & 0xff;\n \n // POWER STATE\n if (channel_id === 0xff && channel_type === 0x0b) {\n decoded.power = \"on\";\n i += 1;\n }\n // IPSO VERSION\n if (channel_id === 0xff && channel_type === 0x01) {\n decoded.ipso_version = readProtocolVersion(input[i]);\n i += 1;\n }\n // PRODUCT SERIAL NUMBER\n if (channel_id === 0xff && channel_type === 0x16) {\n decoded.sn = bytesToHex(java.util.Arrays.copyOfRange(input, i, i + 8));\n i += 8;\n }\n // HARDWARE VERSION\n if (channel_id === 0xff && channel_type === 0x09) {\n decoded.hardware_version = readHardwareVersion(java.util.Arrays.copyOfRange(input, i, i + 2));\n i += 2;\n }\n // FIRMWARE VERSION\n if (channel_id === 0xff && channel_type === 0x0a) {\n decoded.firmware_version = readFirmwareVersion(java.util.Arrays.copyOfRange(input, i, i + 2));\n i += 2;\n }\n // TOTAL CURRENT\n if (channel_id === 0x03 && channel_type === 0x97) {\n decoded.total_current = parseBytesToInt(input, i, 4, false) / 100;\n i += 4;\n }\n // CURRENT\n if (channel_id === 0x04 && channel_type === 0x98) {\n var value = parseBytesToInt(input, i, 2, false);\n if (value === 0xffff) {\n decoded.alarm = \"read failed\";\n } else {\n decoded.current = value / 100;\n }\n i += 2;\n }\n // TEMPERATURE\n if (channel_id === 0x09 && channel_type === 0x67) {\n var temperature_value = parseBytesToInt(input, i, 2, false);\n if (temperature_value === 0xfffd) {\n decoded.temperature_exception = \"over range alarm\";\n } else if (temperature_value === 0xffff) {\n decoded.temperature_exception = \"read failed\";\n } else {\n decoded.temperature = parseBytesToInt(input, i, 2, false) / 10;\n }\n i += 2;\n }\n // CURRENT ALARM\n if (channel_id === 0x84 && channel_type === 0x98) {\n decoded.current_max = parseBytesToInt(input, i, 2, false) / 100;\n decoded.current_min = parseBytesToInt(input, i + 2, 2, false) / 100;\n decoded.current = parseBytesToInt(input, i + 4, 2, false) / 100;\n decoded.alarm = readCurrentAlarm(input[i + 6]);\n i += 7;\n }\n // TEMPERATURE ALARM\n if (channel_id === 0x89 && channel_type === 0x67) {\n decoded.temperature = parseBytesToInt(input, i, 2, false) / 10;\n decoded.temperature_alarm = readTemperatureAlarm(input[i + 2]);\n i += 3;\n }\n }\n \n output.telemetry = [{\n ts: timestamp,\n values: decoded\n }];\n \n // --- Decoding code --- //\n return output;\n}\n\n\n// --- attributes and telemetry objects ---\nvar telemetry = [];\nvar attributes = {};\n// --- attributes and telemetry objects ---\n\n// --- Timestamp parsing\nvar dateString = data.uplink_message.received_at;\n// If data is simulated or device doesn't send his own date string - we will use date from upcoming message, set by network server\nif ((data.simulated != null && data.simulated) || dateString == null) {\n dateString = data.received_at;\n}\ntimestamp = parseDateToTimestamp(dateString);\n// --- Timestamp parsing\n\n// Message parsing\n// To avoid paths in the decoded objects we passing false value to function as \"pathInKey\" argument.\n// Warning: pathInKey can cause already found fields to be overwritten with the last value found, e.g. receive_at from uplink_message will be written receive_at in the root.\n\n// Passing incoming bytes to decodeFrmPayload function, to get custom decoding\nvar customDecoding = {};\nif (data.uplink_message.get(\"frm_payload\") != null) {\n customDecoding = decodeFrmPayload(base64ToBytes(data.uplink_message.frm_payload));\n}\n\n// Collecting data to result\nif (customDecoding.?telemetry.size() > 0) {\n if (customDecoding.telemetry instanceof java.util.ArrayList) {\n foreach(telemetryObj: customDecoding.telemetry) {\n if (telemetryObj.ts != null && telemetryObj.values != null) {\n telemetry.add(telemetryObj);\n }\n }\n } else {\n telemetry.putAll(customDecoding.telemetry);\n }\n}\n\nif (customDecoding.?attributes.size() > 0) {\n attributes.putAll(customDecoding.attributes);\n}\n\n// You can add some keys manually to attributes or telemetry\nvar applicationId = data.end_device_ids.?application_ids.?application_id;\nvar devAddr = data.end_device_ids.?dev_addr;\nvar spreadingFactor = data.uplink_message.?settings.?data_rate.?lora.?spreading_factor;\nvar codeRate = data.uplink_message.?settings.?data_rate.?lora.?coding_rate;\nvar tenantId = data.uplink_message.?network_ids.?tenant_id;\nattributes.eui = data.end_device_ids.dev_eui;\nattributes.fPort = data.uplink_message.f_port;\nattributes.applicationId = applicationId;\nattributes.devAddr = devAddr;\nattributes.spreadingFactor = spreadingFactor;\nattributes.codeRate = codeRate;\nattributes.tenantId = tenantId;\nattributes.device_id = data.end_device_ids.?device_id;\nattributes.join_eui = data.end_device_ids.?join_eui;\nattributes.net_id = data.uplink_message.?network_ids.?net_id;\nattributes.cluster_id = data.uplink_message.?network_ids.?cluster_id;\nattributes.cluster_adress = data.uplink_message.?network_ids.?cluster_address;\nattributes.bandwidth = data.uplink_message.?settings.?data_rate.?lora.?bandwidth;\nattributes.frequency = data.uplink_message.?settings.?frequency;\n\n\nvar gatewayInfo = getGatewayInfo();\nvar addDataToTelemetry = {};\naddDataToTelemetry.snr = gatewayInfo.snr;\naddDataToTelemetry.rssi = gatewayInfo.rssi;\naddDataToTelemetry.channel = gatewayInfo.channel_index;\naddDataToTelemetry.consumed_airtime = data.uplink_message.?consumed_airtime;\naddDataToTelemetry.fCnt = data.uplink_message.?f_cnt;\n\nvar isIncludeGatewayInfo = metadata[\"includeGatewayInfo\"];\nif(isIncludeGatewayInfo == true) {\n telemetry = processTelemetryData(telemetry, addDataToTelemetry);\n}\n\nvar result = {\n deviceName: deviceName,\n deviceType: deviceType,\n// assetName: assetName,\n// assetType: assetType,\n attributes: attributes,\n telemetry: telemetry\n};\n\naddAdditionalInfoForDeviceMsg(result, customerName, groupName);\n\nreturn result;\n\n\nfunction addAdditionalInfoForDeviceMsg(deviceInfo, customerName, groupName) {\n if (customerName != null) {\n deviceInfo.customerName = customerName;\n }\n if (groupName != null) {\n deviceInfo.groupName = groupName;\n }\n}\n\nfunction parseDateToTimestamp(dateString) {\n var timestamp = new Date(dateString).getTime();\n var timestamp = -1;\n if (dateString != null) {\n timestamp = new Date(dateString).getTime();\n if (timestamp == -1) {\n var secondsSeparatorIndex = dateString.lastIndexOf('.') + 1;\n var millisecondsEndIndex = dateString.lastIndexOf('+');\n if (millisecondsEndIndex == -1) {\n millisecondsEndIndex = dateString.lastIndexOf('Z');\n }\n if (millisecondsEndIndex == -1) {\n millisecondsEndIndex = dateString.lastIndexOf('-');\n }\n if (millisecondsEndIndex == -1) {\n if (dateString.length >= secondsSeparatorIndex + 3) {\n dateString = dateString.substring(0, secondsSeparatorIndex + 3);\n }\n } else {\n dateString = dateString.substring(0, secondsSeparatorIndex + 3) +\n dateString.substring(millisecondsEndIndex, dateString.length);\n }\n timestamp = new Date(dateString).getTime();\n }\n }\n // If we cannot parse timestamp - we will use the current timestamp\n if (timestamp == -1) {\n timestamp = Date.now();\n }\n \n return timestamp;\n}\n\nfunction getGatewayInfo() {\n var gatewayList = data.uplink_message.?rx_metadata;\n var maxRssi = Integer. MIN_VALUE;\n var gatewayInfo = {};\n \n foreach (gateway : gatewayList) {\n if(gateway.rssi > maxRssi) {\n maxRssi = gateway.rssi;\n gatewayInfo = gateway;\n }\n }\n \n return gatewayInfo;\n}\n\nfunction processTelemetryData(telemetry, addDataToTelemetry) {\n if (telemetry.size > 1) {\n telemetry = addDataToMultipleTelemetries(telemetry, addDataToTelemetry);\n }\n else if (telemetry.size == 1) {\n telemetry = addDataToSingleTelemetry(telemetry, addDataToTelemetry);\n }\n else {\n telemetry.add(addDataToTelemetry);\n }\n \n return telemetry;\n}\n\nfunction addDataToMultipleTelemetries(telemetry, addDataToTelemetry) {\n foreach(element : addDataToTelemetry.entrySet()) {\n if(!telemetry[0][\"values\"].keys.contains(element.key)) {\n telemetry[0][\"values\"][element.key] = element.value;\n }\n if (!telemetry[1][\"values\"].keys.contains(element.key)) {\n telemetry[1][\"values\"][element.key] = element.value;\n }\n }\n \n return telemetry;\n}\n\nfunction addDataToSingleTelemetry(telemetry, addDataToTelemetry) {\n foreach(element : addDataToTelemetry.entrySet()) {\n if(!telemetry[0][\"values\"].keys.contains(element.key)) {\n telemetry[0][\"values\"][element.key] = element.value;\n }\n }\n \n return telemetry;\n}\n\nfunction readProtocolVersion(bytes) {\n var major = (bytes & 0xf0) >> 4;\n var minor = bytes & 0x0f;\n return \"v\" + major + \".\" + minor;\n}\n\nfunction readHardwareVersion(bytes) {\n var major = bytes[0] & 0xff;\n var minor = (bytes[1] & 0xff) >> 4;\n return \"v\" + major + \".\" + minor;\n}\n\nfunction readFirmwareVersion(bytes) {\n var major = bytes[0] & 0xff;\n var minor = bytes[1] & 0xff;\n return \"v\" + major + \".\" + minor;\n}\n\nfunction readCurrentAlarm(type) {\n var alarm = [];\n if ((type >> 0 & 0x01) != 0) {\n alarm.add(\"threshold alarm\");\n }\n if ((type >> 1 & 0x01) != 0) {\n alarm.add(\"threshold alarm release\");\n }\n if ((type >> 2 & 0x01) != 0) {\n alarm.add(\"over range alarm\");\n }\n if ((type >> 3 & 0x01) != 0) {\n alarm.add(\"over range alarm release\");\n }\n \n return alarm;\n}\n\nfunction readTemperatureAlarm(type) {\n var alarms = [];\n \n if ((type & 0x01) != 0) {\n alarms.add(\"Threshold alarm\");\n }\n if ((type & 0x02) != 0) {\n alarms.add(\"Threshold alarm dismiss\");\n }\n\n return alarms;\n}", + "encoder": null, + "tbelEncoder": null, + "updateOnlyKeys": [ + "fPort", + "bandwidth", + "frequency", + "net_id", + "cluster_id", + "cluster_address", + "device_id", + "join_eui", + "battery", + "eui", + "beep", + "channel", + "applicationId", + "devAddr", + "spreadingFactor", + "codeRate", + "tenantId" + ] + }, + "additionalInfo": { + "description": "" + }, + "edgeTemplate": false +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/metadata.json b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/metadata.json new file mode 100644 index 0000000..ccdda72 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/metadata.json @@ -0,0 +1,4 @@ +{ + "integrationName": "The Things Stack Community integration", + "includeGatewayInfo": false +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/payload_1.json b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/payload_1.json new file mode 100644 index 0000000..fa0a12a --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/payload_1.json @@ -0,0 +1,54 @@ +{ + "end_device_ids": { + "device_id": "eui-1000000000000001", + "application_ids": { + "application_id": "application-tts-name" + }, + "dev_eui": "1000000000000001", + "join_eui": "2000000000000001", + "dev_addr": "20000001" + }, + "correlation_ids": ["as:up:01H0S7ZJQ9MQPMVY49FT3SE07M", "gs:conn:01H03BQZ9342X3Y86DJ2P704E5", "gs:up:host:01H03BQZ99EGAM52KK1300GFKN", "gs:uplink:01H0S7ZJGS6D9TJSKJN8XNTMAV", "ns:uplink:01H0S7ZJGS9KKD4HTTPKFEMWCV", "rpc:/ttn.lorawan.v3.GsNs/HandleUplink:01H0S7ZJGSF3M38ZRZVTM38DEC", "rpc:/ttn.lorawan.v3.NsAs/HandleUplink:01H0S7ZJQ8R2EH5AA269AKM8DX"], + "received_at": "2023-05-19T05:33:35.848446463Z", + "uplink_message": { + "session_key_id": "AYfqmb0pc/1uRZv9xUydgQ==", + "f_port": 85, + "f_cnt": 10335, + "frm_payload": "/wv//wEB/xZnRtOIAlgAAP8JAQD/CgEB/w8A", + "rx_metadata": [{ + "gateway_ids": { + "gateway_id": "eui-6a7e111a10000000", + "eui": "6A7E111A10000000" + }, + "time": "2023-05-19T05:33:35.608982Z", + "timestamp": 3893546133, + "rssi": -35, + "channel_rssi": -35, + "snr": 13.2, + "frequency_offset": "69", + "uplink_token": "CiIKIAoUZXVpLTZhN2UxMTFhMTAwMDAwMDASCCThJP/+9k6eEJWZy8AOGgwIr5ScowYQvNbUsQIgiMy8y6jwpwE=", + "channel_index": 3, + "received_at": "2023-05-19T05:33:35.607383681Z" + }], + "settings": { + "data_rate": { + "lora": { + "bandwidth": 125000, + "spreading_factor": 7, + "coding_rate": "4/5" + } + }, + "frequency": "867100000", + "timestamp": 3893546133, + "time": "2023-05-19T05:33:35.608982Z" + }, + "received_at": "2023-05-19T05:33:35.641841782Z", + "consumed_airtime": "0.056576s", + "network_ids": { + "net_id": "000013", + "tenant_id": "ttn", + "cluster_id": "eu1", + "cluster_address": "eu1.cloud.thethings.network" + } + } +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/payload_2.json b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/payload_2.json new file mode 100644 index 0000000..60c8281 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/payload_2.json @@ -0,0 +1,54 @@ +{ + "end_device_ids": { + "device_id": "eui-1000000000000001", + "application_ids": { + "application_id": "application-tts-name" + }, + "dev_eui": "1000000000000001", + "join_eui": "2000000000000001", + "dev_addr": "20000001" + }, + "correlation_ids": ["as:up:01H0S7ZJQ9MQPMVY49FT3SE07M", "gs:conn:01H03BQZ9342X3Y86DJ2P704E5", "gs:up:host:01H03BQZ99EGAM52KK1300GFKN", "gs:uplink:01H0S7ZJGS6D9TJSKJN8XNTMAV", "ns:uplink:01H0S7ZJGS9KKD4HTTPKFEMWCV", "rpc:/ttn.lorawan.v3.GsNs/HandleUplink:01H0S7ZJGSF3M38ZRZVTM38DEC", "rpc:/ttn.lorawan.v3.NsAs/HandleUplink:01H0S7ZJQ8R2EH5AA269AKM8DX"], + "received_at": "2023-05-19T05:33:35.848446463Z", + "uplink_message": { + "session_key_id": "AYfqmb0pc/1uRZv9xUydgQ==", + "f_port": 85, + "f_cnt": 10335, + "frm_payload": "A5cQJwAA", + "rx_metadata": [{ + "gateway_ids": { + "gateway_id": "eui-6a7e111a10000000", + "eui": "6A7E111A10000000" + }, + "time": "2023-05-19T05:33:35.608982Z", + "timestamp": 3893546133, + "rssi": -35, + "channel_rssi": -35, + "snr": 13.2, + "frequency_offset": "69", + "uplink_token": "CiIKIAoUZXVpLTZhN2UxMTFhMTAwMDAwMDASCCThJP/+9k6eEJWZy8AOGgwIr5ScowYQvNbUsQIgiMy8y6jwpwE=", + "channel_index": 3, + "received_at": "2023-05-19T05:33:35.607383681Z" + }], + "settings": { + "data_rate": { + "lora": { + "bandwidth": 125000, + "spreading_factor": 7, + "coding_rate": "4/5" + } + }, + "frequency": "867100000", + "timestamp": 3893546133, + "time": "2023-05-19T05:33:35.608982Z" + }, + "received_at": "2023-05-19T05:33:35.641841782Z", + "consumed_airtime": "0.056576s", + "network_ids": { + "net_id": "000013", + "tenant_id": "ttn", + "cluster_id": "eu1", + "cluster_address": "eu1.cloud.thethings.network" + } + } +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/payload_3.json b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/payload_3.json new file mode 100644 index 0000000..193b530 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/payload_3.json @@ -0,0 +1,54 @@ +{ + "end_device_ids": { + "device_id": "eui-1000000000000001", + "application_ids": { + "application_id": "application-tts-name" + }, + "dev_eui": "1000000000000001", + "join_eui": "2000000000000001", + "dev_addr": "20000001" + }, + "correlation_ids": ["as:up:01H0S7ZJQ9MQPMVY49FT3SE07M", "gs:conn:01H03BQZ9342X3Y86DJ2P704E5", "gs:up:host:01H03BQZ99EGAM52KK1300GFKN", "gs:uplink:01H0S7ZJGS6D9TJSKJN8XNTMAV", "ns:uplink:01H0S7ZJGS9KKD4HTTPKFEMWCV", "rpc:/ttn.lorawan.v3.GsNs/HandleUplink:01H0S7ZJGSF3M38ZRZVTM38DEC", "rpc:/ttn.lorawan.v3.NsAs/HandleUplink:01H0S7ZJQ8R2EH5AA269AKM8DX"], + "received_at": "2023-05-19T05:33:35.848446463Z", + "uplink_message": { + "session_key_id": "AYfqmb0pc/1uRZv9xUydgQ==", + "f_port": 85, + "f_cnt": 10335, + "frm_payload": "BJi4CwAAAAA=", + "rx_metadata": [{ + "gateway_ids": { + "gateway_id": "eui-6a7e111a10000000", + "eui": "6A7E111A10000000" + }, + "time": "2023-05-19T05:33:35.608982Z", + "timestamp": 3893546133, + "rssi": -35, + "channel_rssi": -35, + "snr": 13.2, + "frequency_offset": "69", + "uplink_token": "CiIKIAoUZXVpLTZhN2UxMTFhMTAwMDAwMDASCCThJP/+9k6eEJWZy8AOGgwIr5ScowYQvNbUsQIgiMy8y6jwpwE=", + "channel_index": 3, + "received_at": "2023-05-19T05:33:35.607383681Z" + }], + "settings": { + "data_rate": { + "lora": { + "bandwidth": 125000, + "spreading_factor": 7, + "coding_rate": "4/5" + } + }, + "frequency": "867100000", + "timestamp": 3893546133, + "time": "2023-05-19T05:33:35.608982Z" + }, + "received_at": "2023-05-19T05:33:35.641841782Z", + "consumed_airtime": "0.056576s", + "network_ids": { + "net_id": "000013", + "tenant_id": "ttn", + "cluster_id": "eu1", + "cluster_address": "eu1.cloud.thethings.network" + } + } +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/payload_4.json b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/payload_4.json new file mode 100644 index 0000000..14179a5 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/payload_4.json @@ -0,0 +1,54 @@ +{ + "end_device_ids": { + "device_id": "eui-1000000000000001", + "application_ids": { + "application_id": "application-tts-name" + }, + "dev_eui": "1000000000000001", + "join_eui": "2000000000000001", + "dev_addr": "20000001" + }, + "correlation_ids": ["as:up:01H0S7ZJQ9MQPMVY49FT3SE07M", "gs:conn:01H03BQZ9342X3Y86DJ2P704E5", "gs:up:host:01H03BQZ99EGAM52KK1300GFKN", "gs:uplink:01H0S7ZJGS6D9TJSKJN8XNTMAV", "ns:uplink:01H0S7ZJGS9KKD4HTTPKFEMWCV", "rpc:/ttn.lorawan.v3.GsNs/HandleUplink:01H0S7ZJGSF3M38ZRZVTM38DEC", "rpc:/ttn.lorawan.v3.NsAs/HandleUplink:01H0S7ZJQ8R2EH5AA269AKM8DX"], + "received_at": "2023-05-19T05:33:35.848446463Z", + "uplink_message": { + "session_key_id": "AYfqmb0pc/1uRZv9xUydgQ==", + "f_port": 85, + "f_cnt": 10335, + "frm_payload": "BJj//w==", + "rx_metadata": [{ + "gateway_ids": { + "gateway_id": "eui-6a7e111a10000000", + "eui": "6A7E111A10000000" + }, + "time": "2023-05-19T05:33:35.608982Z", + "timestamp": 3893546133, + "rssi": -35, + "channel_rssi": -35, + "snr": 13.2, + "frequency_offset": "69", + "uplink_token": "CiIKIAoUZXVpLTZhN2UxMTFhMTAwMDAwMDASCCThJP/+9k6eEJWZy8AOGgwIr5ScowYQvNbUsQIgiMy8y6jwpwE=", + "channel_index": 3, + "received_at": "2023-05-19T05:33:35.607383681Z" + }], + "settings": { + "data_rate": { + "lora": { + "bandwidth": 125000, + "spreading_factor": 7, + "coding_rate": "4/5" + } + }, + "frequency": "867100000", + "timestamp": 3893546133, + "time": "2023-05-19T05:33:35.608982Z" + }, + "received_at": "2023-05-19T05:33:35.641841782Z", + "consumed_airtime": "0.056576s", + "network_ids": { + "net_id": "000013", + "tenant_id": "ttn", + "cluster_id": "eu1", + "cluster_address": "eu1.cloud.thethings.network" + } + } +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/payload_5.json b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/payload_5.json new file mode 100644 index 0000000..09539d3 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/payload_5.json @@ -0,0 +1,54 @@ +{ + "end_device_ids": { + "device_id": "eui-1000000000000001", + "application_ids": { + "application_id": "application-tts-name" + }, + "dev_eui": "1000000000000001", + "join_eui": "2000000000000001", + "dev_addr": "20000001" + }, + "correlation_ids": ["as:up:01H0S7ZJQ9MQPMVY49FT3SE07M", "gs:conn:01H03BQZ9342X3Y86DJ2P704E5", "gs:up:host:01H03BQZ99EGAM52KK1300GFKN", "gs:uplink:01H0S7ZJGS6D9TJSKJN8XNTMAV", "ns:uplink:01H0S7ZJGS9KKD4HTTPKFEMWCV", "rpc:/ttn.lorawan.v3.GsNs/HandleUplink:01H0S7ZJGSF3M38ZRZVTM38DEC", "rpc:/ttn.lorawan.v3.NsAs/HandleUplink:01H0S7ZJQ8R2EH5AA269AKM8DX"], + "received_at": "2023-05-19T05:33:35.848446463Z", + "uplink_message": { + "session_key_id": "AYfqmb0pc/1uRZv9xUydgQ==", + "f_port": 85, + "f_cnt": 10335, + "frm_payload": "hJi4C9AHxAkF", + "rx_metadata": [{ + "gateway_ids": { + "gateway_id": "eui-6a7e111a10000000", + "eui": "6A7E111A10000000" + }, + "time": "2023-05-19T05:33:35.608982Z", + "timestamp": 3893546133, + "rssi": -35, + "channel_rssi": -35, + "snr": 13.2, + "frequency_offset": "69", + "uplink_token": "CiIKIAoUZXVpLTZhN2UxMTFhMTAwMDAwMDASCCThJP/+9k6eEJWZy8AOGgwIr5ScowYQvNbUsQIgiMy8y6jwpwE=", + "channel_index": 3, + "received_at": "2023-05-19T05:33:35.607383681Z" + }], + "settings": { + "data_rate": { + "lora": { + "bandwidth": 125000, + "spreading_factor": 7, + "coding_rate": "4/5" + } + }, + "frequency": "867100000", + "timestamp": 3893546133, + "time": "2023-05-19T05:33:35.608982Z" + }, + "received_at": "2023-05-19T05:33:35.641841782Z", + "consumed_airtime": "0.056576s", + "network_ids": { + "net_id": "000013", + "tenant_id": "ttn", + "cluster_id": "eu1", + "cluster_address": "eu1.cloud.thethings.network" + } + } +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/result_1.json b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/result_1.json new file mode 100644 index 0000000..08b436f --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/result_1.json @@ -0,0 +1,30 @@ +{ + "deviceName": "CT101/CT103 eui-1000000000000001", + "deviceType": "CT101/CT103", + "attributes": { + "eui": "1000000000000001", + "fPort": 85, + "applicationId": "application-tts-name", + "devAddr": "20000001", + "spreadingFactor": 7, + "codeRate": "4/5", + "tenantId": "ttn", + "device_id": "eui-1000000000000001", + "join_eui": "2000000000000001", + "net_id": "000013", + "cluster_id": "eu1", + "cluster_adress": "eu1.cloud.thethings.network", + "bandwidth": 125000, + "frequency": "867100000" + }, + "telemetry": [{ + "ts": 1684474415641, + "values": { + "power": "on", + "ipso_version": "v0.1", + "sn": "6746D38802580000", + "hardware_version": "v1.0", + "firmware_version": "v1.1" + } + }] +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/result_2.json b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/result_2.json new file mode 100644 index 0000000..6b630f1 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/result_2.json @@ -0,0 +1,26 @@ +{ + "deviceName": "CT101/CT103 eui-1000000000000001", + "deviceType": "CT101/CT103", + "attributes": { + "eui": "1000000000000001", + "fPort": 85, + "applicationId": "application-tts-name", + "devAddr": "20000001", + "spreadingFactor": 7, + "codeRate": "4/5", + "tenantId": "ttn", + "device_id": "eui-1000000000000001", + "join_eui": "2000000000000001", + "net_id": "000013", + "cluster_id": "eu1", + "cluster_adress": "eu1.cloud.thethings.network", + "bandwidth": 125000, + "frequency": "867100000" + }, + "telemetry": [{ + "ts": 1684474415641, + "values": { + "total_current": 100.0 + } + }] +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/result_3.json b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/result_3.json new file mode 100644 index 0000000..abdc338 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/result_3.json @@ -0,0 +1,26 @@ +{ + "deviceName": "CT101/CT103 eui-1000000000000001", + "deviceType": "CT101/CT103", + "attributes": { + "eui": "1000000000000001", + "fPort": 85, + "applicationId": "application-tts-name", + "devAddr": "20000001", + "spreadingFactor": 7, + "codeRate": "4/5", + "tenantId": "ttn", + "device_id": "eui-1000000000000001", + "join_eui": "2000000000000001", + "net_id": "000013", + "cluster_id": "eu1", + "cluster_adress": "eu1.cloud.thethings.network", + "bandwidth": 125000, + "frequency": "867100000" + }, + "telemetry": [{ + "ts": 1684474415641, + "values": { + "current": 30.0 + } + }] +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/result_4.json b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/result_4.json new file mode 100644 index 0000000..b0cde3d --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/result_4.json @@ -0,0 +1,26 @@ +{ + "deviceName": "CT101/CT103 eui-1000000000000001", + "deviceType": "CT101/CT103", + "attributes": { + "eui": "1000000000000001", + "fPort": 85, + "applicationId": "application-tts-name", + "devAddr": "20000001", + "spreadingFactor": 7, + "codeRate": "4/5", + "tenantId": "ttn", + "device_id": "eui-1000000000000001", + "join_eui": "2000000000000001", + "net_id": "000013", + "cluster_id": "eu1", + "cluster_adress": "eu1.cloud.thethings.network", + "bandwidth": 125000, + "frequency": "867100000" + }, + "telemetry": [{ + "ts": 1684474415641, + "values": { + "alarm": "read failed" + } + }] +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/result_5.json b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/result_5.json new file mode 100644 index 0000000..b61a001 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackCommunity/uplink/result_5.json @@ -0,0 +1,29 @@ +{ + "deviceName": "CT101/CT103 eui-1000000000000001", + "deviceType": "CT101/CT103", + "attributes": { + "eui": "1000000000000001", + "fPort": 85, + "applicationId": "application-tts-name", + "devAddr": "20000001", + "spreadingFactor": 7, + "codeRate": "4/5", + "tenantId": "ttn", + "device_id": "eui-1000000000000001", + "join_eui": "2000000000000001", + "net_id": "000013", + "cluster_id": "eu1", + "cluster_adress": "eu1.cloud.thethings.network", + "bandwidth": 125000, + "frequency": "867100000" + }, + "telemetry": [{ + "ts": 1684474415641, + "values": { + "current_max": 30.0, + "current_min": 20.0, + "current": 25.0, + "alarm": ["threshold alarm", "over range alarm"] + } + }] +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/converter.json b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/converter.json new file mode 100644 index 0000000..0e7679c --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/converter.json @@ -0,0 +1,36 @@ +{ + "name": "Uplink data converter for The Things Stack Industries integration CT101/CT103", + "type": "UPLINK", + "debugMode": true, + "configuration": { + "scriptLang": "TBEL", + "decoder": null, + "tbelDecoder": "var data = decodeToJson(payload);\n\nvar deviceName = \"CT101/CT103 \" + data.end_device_ids.device_id;\nvar deviceType = \"CT101/CT103\";\nvar groupName = null; // If groupName is not null - created device will be added to the entity group with such name.\nvar customerName = null; // If customerName is not null - created devices will be assigned to customer with such name. \n\n// use assetName and assetType instead of deviceName and deviceType\n// to automatically create assets instead of devices.\n// var assetName = 'Asset A';\n// var assetType = 'building';\n\n// If you want to parse incoming data somehow, you can add your code to this function.\n// input: bytes\n// expected output:\n// {\n// \"attributes\": {\"attributeKey\": \"attributeValue\"},\n// \"telemetry\": [{\"ts\": 1...1, \"values\": {\"telemetryKey\":\"telemetryValue\"}, {\"ts\": 1...2, \"values\": {\"telemetryKey\":\"telemetryValue\"}}]\n// }\n\nfunction decodeFrmPayload(input) {\n var output = { attributes: {}, telemetry: []};\n \n // --- Timestamp parsing\n var decoded = {};\n for (var i = 0; i < input.length - 2; ) {\n var channel_id = input[i++] & 0xff;\n var channel_type = input[i++] & 0xff;\n\n // POWER STATE\n if (channel_id === 0xff && channel_type === 0x0b) {\n decoded.power = \"on\";\n i += 1;\n }\n // IPSO VERSION\n if (channel_id === 0xff && channel_type === 0x01) {\n decoded.ipso_version = readProtocolVersion(input[i]);\n i += 1;\n }\n // PRODUCT SERIAL NUMBER\n if (channel_id === 0xff && channel_type === 0x16) {\n decoded.sn = bytesToHex(java.util.Arrays.copyOfRange(input, i, i + 8));\n i += 8;\n }\n // HARDWARE VERSION\n if (channel_id === 0xff && channel_type === 0x09) {\n decoded.hardware_version = readHardwareVersion(java.util.Arrays.copyOfRange(input, i, i + 2));\n i += 2;\n }\n // FIRMWARE VERSION\n if (channel_id === 0xff && channel_type === 0x0a) {\n decoded.firmware_version = readFirmwareVersion(java.util.Arrays.copyOfRange(input, i, i + 2));\n i += 2;\n }\n // TOTAL CURRENT\n if (channel_id === 0x03 && channel_type === 0x97) {\n decoded.total_current = parseBytesToInt(input, i, 4, false) / 100;\n i += 4;\n }\n // CURRENT\n if (channel_id === 0x04 && channel_type === 0x98) {\n var value = parseBytesToInt(input, i, 2, false);\n if (value === 0xffff) {\n decoded.alarm = \"read failed\";\n } else {\n decoded.current = value / 100;\n }\n i += 2;\n }\n // TEMPERATURE\n if (channel_id === 0x09 && channel_type === 0x67) {\n var temperature_value = parseBytesToInt(input, i, 2, false);\n if (temperature_value === 0xfffd) {\n decoded.temperature_exception = \"over range alarm\";\n } else if (temperature_value === 0xffff) {\n decoded.temperature_exception = \"read failed\";\n } else {\n decoded.temperature = parseBytesToInt(input, i, 2, false) / 10;\n }\n i += 2;\n }\n // CURRENT ALARM\n if (channel_id === 0x84 && channel_type === 0x98) {\n decoded.current_max = parseBytesToInt(input, i, 2, false) / 100;\n decoded.current_min = parseBytesToInt(input, i + 2, 2, false) / 100;\n decoded.current = parseBytesToInt(input, i + 4, 2, false) / 100;\n decoded.alarm = readCurrentAlarm(input[i + 6]);\n i += 7;\n }\n // TEMPERATURE ALARM\n if (channel_id === 0x89 && channel_type === 0x67) {\n decoded.temperature = parseBytesToInt(input, i, 2, false) / 10;\n decoded.temperature_alarm = readTemperatureAlarm(input[i + 2]);\n i += 3;\n }\n }\n \n output.telemetry = [{\n ts: timestamp,\n values: decoded\n }];\n\n // --- Decoding code --- //\n return output;\n}\n\n// --- attributes and telemetry objects ---\nvar telemetry = [];\nvar attributes = {};\n// --- attributes and telemetry objects ---\n\n// --- Timestamp parsing\nvar dateString = data.uplink_message.received_at;\n\nif ((data.simulated != null && data.simulated) || dateString == null) {\n dateString = data.received_at;\n}\n\ntimestamp = parseDateToTimestamp(dateString);\n// --- Timestamp parsing\n\n// Message parsing\n// To avoid paths in the decoded objects we passing false value to function as \"pathInKey\" argument.\n// Warning: pathInKey can cause already found fields to be overwritten with the last value found, e.g. receive_at from uplink_message will be written receive_at in the root.\n\n// Passing incoming bytes to decodeFrmPayload function, to get custom decoding\nvar customDecoding = {};\nif (data.uplink_message.get(\"frm_payload\") != null) {\n customDecoding = decodeFrmPayload(base64ToBytes(data.uplink_message.frm_payload));\n}\n\n// Collecting data to result\nif (customDecoding.?telemetry.size() > 0) {\n if (customDecoding.telemetry instanceof java.util.ArrayList) {\n foreach(telemetryObj: customDecoding.telemetry) {\n if (telemetryObj.ts != null && telemetryObj.values != null) {\n telemetry.add(telemetryObj);\n }\n }\n } else {\n telemetry.putAll(customDecoding.telemetry);\n }\n}\n\nif (customDecoding.?attributes.size() > 0) {\n attributes.putAll(customDecoding.attributes);\n}\n\n// You can add some keys manually to attributes or telemetry\nvar applicationId = data.end_device_ids.?application_ids.?application_id;\nvar devAddr = data.end_device_ids.?dev_addr;\nvar spreadingFactor = data.uplink_message.?settings.?data_rate.?lora.?spreading_factor;\nvar codeRate = data.uplink_message.?settings.?data_rate.?lora.?coding_rate;\nvar tenantId = data.uplink_message.?network_ids.?tenant_id;\nattributes.eui = data.end_device_ids.dev_eui;\nattributes.fPort = data.uplink_message.f_port;\nattributes.applicationId = applicationId;\nattributes.devAddr = devAddr;\nattributes.spreadingFactor = spreadingFactor;\nattributes.codeRate = codeRate;\nattributes.tenantId = tenantId;\nattributes.device_id = data.end_device_ids.?device_id;\nattributes.join_eui = data.end_device_ids.?join_eui;\nattributes.net_id = data.uplink_message.?network_ids.?net_id;\nattributes.cluster_id = data.uplink_message.?network_ids.?cluster_id;\nattributes.cluster_adress = data.uplink_message.?network_ids.?cluster_address;\nattributes.bandwidth = data.uplink_message.?settings.?data_rate.?lora.?bandwidth;\nattributes.frequency = data.uplink_message.?settings.?frequency;\n\nvar gatewayInfo = getGatewayInfo();\nvar addDataToTelemetry = {};\naddDataToTelemetry.snr = gatewayInfo.snr;\naddDataToTelemetry.rssi = gatewayInfo.rssi;\naddDataToTelemetry.channel = gatewayInfo.channel_index;\naddDataToTelemetry.consumed_airtime = data.uplink_message.?consumed_airtime;\naddDataToTelemetry.fCnt = data.uplink_message.?f_cnt;\n\nvar isIncludeGatewayInfo = metadata[\"includeGatewayInfo\"];\nif(isIncludeGatewayInfo == true) {\n telemetry = processTelemetryData(telemetry, addDataToTelemetry);\n}\n\nvar result = {\n deviceName: deviceName,\n deviceType: deviceType,\n // assetName: assetName,\n // assetType: assetType,\n attributes: attributes,\n telemetry: telemetry\n};\n\naddAdditionalInfoForDeviceMsg(result, customerName, groupName);\n\nreturn result;\n\nfunction addAdditionalInfoForDeviceMsg(deviceInfo, customerName, groupName) {\n if (customerName != null) {\n deviceInfo.customerName = customerName;\n }\n if (groupName != null) {\n deviceInfo.groupName = groupName;\n }\n}\n\nfunction parseDateToTimestamp(dateString) {\n var timestamp = new Date(dateString).getTime();\n var timestamp = -1;\n if (dateString != null) {\n timestamp = new Date(dateString).getTime();\n if (timestamp == -1) {\n var secondsSeparatorIndex = dateString.lastIndexOf('.') + 1;\n var millisecondsEndIndex = dateString.lastIndexOf('+');\n if (millisecondsEndIndex == -1) {\n millisecondsEndIndex = dateString.lastIndexOf('Z');\n }\n if (millisecondsEndIndex == -1) {\n millisecondsEndIndex = dateString.lastIndexOf('-');\n }\n if (millisecondsEndIndex == -1) {\n if (dateString.length >= secondsSeparatorIndex + 3) {\n dateString = dateString.substring(0, secondsSeparatorIndex + 3);\n }\n } else {\n dateString = dateString.substring(0, secondsSeparatorIndex + 3) +\n dateString.substring(millisecondsEndIndex, dateString.length);\n }\n timestamp = new Date(dateString).getTime();\n }\n }\n // If we cannot parse timestamp - we will use the current timestamp\n if (timestamp == -1) {\n timestamp = Date.now();\n }\n \n return timestamp;\n}\n\nfunction getGatewayInfo() {\n var gatewayList = data.uplink_message.?rx_metadata;\n var maxRssi = Integer. MIN_VALUE;\n var gatewayInfo = {};\n \n foreach (gateway : gatewayList) {\n if(gateway.rssi > maxRssi) {\n maxRssi = gateway.rssi;\n gatewayInfo = gateway;\n }\n }\n \n return gatewayInfo;\n}\n\nfunction processTelemetryData(telemetry, addDataToTelemetry) {\n if (telemetry.size > 1) {\n telemetry = addDataToMultipleTelemetries(telemetry, addDataToTelemetry);\n }\n else if (telemetry.size == 1) {\n telemetry = addDataToSingleTelemetry(telemetry, addDataToTelemetry);\n }\n else {\n telemetry.add(addDataToTelemetry);\n }\n \n return telemetry;\n}\n\nfunction addDataToMultipleTelemetries(telemetry, addDataToTelemetry) {\n foreach(element : addDataToTelemetry.entrySet()) {\n if(!telemetry[0][\"values\"].keys.contains(element.key)) {\n telemetry[0][\"values\"][element.key] = element.value;\n }\n if (!telemetry[1][\"values\"].keys.contains(element.key)) {\n telemetry[1][\"values\"][element.key] = element.value;\n }\n }\n \n return telemetry;\n}\n\nfunction addDataToSingleTelemetry(telemetry, addDataToTelemetry) {\n foreach(element : addDataToTelemetry.entrySet()) {\n if(!telemetry[0][\"values\"].keys.contains(element.key)) {\n telemetry[0][\"values\"][element.key] = element.value;\n }\n }\n \n return telemetry;\n}\n\nfunction readProtocolVersion(bytes) {\n var major = (bytes & 0xf0) >> 4;\n var minor = bytes & 0x0f;\n return \"v\" + major + \".\" + minor;\n}\n\nfunction readHardwareVersion(bytes) {\n var major = bytes[0] & 0xff;\n var minor = (bytes[1] & 0xff) >> 4;\n return \"v\" + major + \".\" + minor;\n}\n\nfunction readFirmwareVersion(bytes) {\n var major = bytes[0] & 0xff;\n var minor = bytes[1] & 0xff;\n return \"v\" + major + \".\" + minor;\n}\n\nfunction readCurrentAlarm(type) {\n var alarm = [];\n if ((type >> 0 & 0x01) != 0) {\n alarm.add(\"threshold alarm\");\n }\n if ((type >> 1 & 0x01) != 0) {\n alarm.add(\"threshold alarm release\");\n }\n if ((type >> 2 & 0x01) != 0) {\n alarm.add(\"over range alarm\");\n }\n if ((type >> 3 & 0x01) != 0) {\n alarm.add(\"over range alarm release\");\n }\n \n return alarm;\n}\n\nfunction readTemperatureAlarm(type) {\n var alarms = [];\n \n if ((type & 0x01) != 0) {\n alarms.add(\"Threshold alarm\");\n }\n if ((type & 0x02) != 0) {\n alarms.add(\"Threshold alarm dismiss\");\n }\n\n return alarms;\n}", + "encoder": null, + "tbelEncoder": null, + "updateOnlyKeys": [ + "fPort", + "bandwidth", + "frequency", + "net_id", + "cluster_id", + "cluster_address", + "tenant_address", + "device_id", + "join_eui", + "battery", + "eui", + "beep", + "channel", + "devAddr", + "spreadingFactor", + "codeRate", + "tenantId", + "applicationId" + ] + }, + "additionalInfo": { + "description": "" + }, + "edgeTemplate": false +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/metadata.json b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/metadata.json new file mode 100644 index 0000000..074bdab --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/metadata.json @@ -0,0 +1,4 @@ +{ + "integrationName": "The Things Stack Industries integration new", + "includeGatewayInfo": false +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/payload_1.json b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/payload_1.json new file mode 100644 index 0000000..7fbdd33 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/payload_1.json @@ -0,0 +1,77 @@ +{ + "end_device_ids": { + "device_id": "eui-1000000000000001", + "application_ids": { + "application_id": "application-tti-name" + }, + "dev_eui": "1000000000000001", + "join_eui": "2000000000000001", + "dev_addr": "20000001" + }, + "correlation_ids": ["as:up:01H0PZDGB1NW6NAPD815NGHPF6", "gs:conn:01H0FJRSXSYT7VKNYXJ89F95XT", "gs:up:host:01H0FJRSY3MZMGPPFBQ4FZV4T8", "gs:uplink:01H0PZDG4HHGFRTXRTXD4PFTH7", "ns:uplink:01H0PZDG4JZ3BM0K6J89EQK1J7", "rpc:/ttn.lorawan.v3.GsNs/HandleUplink:01H0PZDG4J02F85RYFPCNSNXCR", "rpc:/ttn.lorawan.v3.NsAs/HandleUplink:01H0PZDGB081PMP806BJHNHX1A"], + "received_at": "2023-05-18T08:25:26.112483370Z", + "uplink_message": { + "session_key_id": "AYfg8rhha5n+FWx0ZaAprA==", + "f_port": 85, + "f_cnt": 5017, + "frm_payload": "/wv//wEB/xZnRtOIAlgAAP8JAQD/CgEB/w8A", + "rx_metadata": [{ + "gateway_ids": { + "gateway_id": "eui-6A7E111A10000000", + "eui": "6A7E111A10000000" + }, + "time": "2023-05-18T08:25:25.885310Z", + "timestamp": 818273765, + "rssi": -24, + "channel_rssi": -24, + "snr": 12, + "frequency_offset": "671", + "uplink_token": "CiIKIAoUZXVpLTZBN0UxMTFBMTAwMDAwMDASCCThJP/+9k6eEOW7l4YDGgwI9cGXowYQ5KPhrwMgiI2rp+jpOA=", + "channel_index": 2, + "received_at": "2023-05-18T08:25:25.869324983Z" + }, { + "gateway_ids": { + "gateway_id": "packetbroker" + }, + "packet_broker": { + "message_id": "01H0PZDG4MF9AYSMNY44MAVTDH", + "forwarder_net_id": "000013", + "forwarder_tenant_id": "ttn", + "forwarder_cluster_id": "eu1.cloud.thethings.network", + "forwarder_gateway_eui": "6A7E111A10000000", + "forwarder_gateway_id": "eui-6a7e111a10000000", + "home_network_net_id": "000013", + "home_network_tenant_id": "tenant", + "home_network_cluster_id": "eu1.cloud.thethings.industries" + }, + "time": "2023-05-18T08:25:25.885310Z", + "rssi": -24, + "channel_rssi": -24, + "snr": 12, + "frequency_offset": "671", + "uplink_token": "eyJnIjoiWlhsS2FHSkhZMmxQYVVwQ1RWUkpORkl3VGs1VE1XTnBURU5LYkdKdFRXbFBhVXBDVFZSSk5GSXdUazVKYVhkcFlWaFphVTlwU201a01uaGhWVlJvZDFSWFVuRmlSM1JtVFcxT2RVbHBkMmxrUjBadVNXcHZhV05ZY0RKT1IyeExaREpSZVZwR1pIUmpNRXBLVlVoR2RFNVZkR3BWVTBvNUxua3paVVJTWVRaM1lXOU1kbTQwVm5sdmIyWmlPWGN1ZUhCZmVrcElaa3hIWlZadGRVUlFVeTVuYlRaVlZXRXdkakpHV0VKMGJUUjZaMjVXUkVoeGVHRjRaMlJKTlVkS1VsbERhemc1VDNCbk5rVk1iM1JDUkVZM1VWbHdZbEJDTkdOblNqWjBlbkphYUV4MFRVMHhZMVZFTTFac01XdExURUo0YURaMFExTnhhMVJsWWw4eE5FdHlVVXcyZUhsRWFFbEhlakJITXpoTE0xaFdlRzR5VUVjMk4wNUViME5WTkhoTmRrazFZVk5oWkUwd2FXVnFjR294VGtoMFduZHlZMDFxVlVGNmRsbERUazlNY2s5eFdVeFpWMk5XTG1WVFFYVkpNVkptT1U5NWRqUTNhSEoxTUZoalYxRT0iLCJhIjp7ImZuaWQiOiIwMDAwMTMiLCJmdGlkIjoidHRuIiwiZmNpZCI6ImV1MS5jbG91ZC50aGV0aGluZ3MubmV0d29yayJ9fQ==", + "received_at": "2023-05-18T08:25:25.906038642Z" + }], + "settings": { + "data_rate": { + "lora": { + "bandwidth": 125000, + "spreading_factor": 7, + "coding_rate": "4/5" + } + }, + "frequency": "868500000", + "timestamp": 818273765, + "time": "2023-05-18T08:25:25.885310Z" + }, + "received_at": "2023-05-18T08:25:25.906399073Z", + "consumed_airtime": "0.097536s", + "network_ids": { + "net_id": "000013", + "tenant_id": "tenant", + "cluster_id": "eu1", + "cluster_address": "eu1.cloud.thethings.industries", + "tenant_address": "tenant.eu1.cloud.thethings.industries" + } + } +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/payload_2.json b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/payload_2.json new file mode 100644 index 0000000..ce08936 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/payload_2.json @@ -0,0 +1,77 @@ +{ + "end_device_ids": { + "device_id": "eui-1000000000000001", + "application_ids": { + "application_id": "application-tti-name" + }, + "dev_eui": "1000000000000001", + "join_eui": "2000000000000001", + "dev_addr": "20000001" + }, + "correlation_ids": ["as:up:01H0PZDGB1NW6NAPD815NGHPF6", "gs:conn:01H0FJRSXSYT7VKNYXJ89F95XT", "gs:up:host:01H0FJRSY3MZMGPPFBQ4FZV4T8", "gs:uplink:01H0PZDG4HHGFRTXRTXD4PFTH7", "ns:uplink:01H0PZDG4JZ3BM0K6J89EQK1J7", "rpc:/ttn.lorawan.v3.GsNs/HandleUplink:01H0PZDG4J02F85RYFPCNSNXCR", "rpc:/ttn.lorawan.v3.NsAs/HandleUplink:01H0PZDGB081PMP806BJHNHX1A"], + "received_at": "2023-05-18T08:25:26.112483370Z", + "uplink_message": { + "session_key_id": "AYfg8rhha5n+FWx0ZaAprA==", + "f_port": 85, + "f_cnt": 5017, + "frm_payload": "A5cQJwAA", + "rx_metadata": [{ + "gateway_ids": { + "gateway_id": "eui-6A7E111A10000000", + "eui": "6A7E111A10000000" + }, + "time": "2023-05-18T08:25:25.885310Z", + "timestamp": 818273765, + "rssi": -24, + "channel_rssi": -24, + "snr": 12, + "frequency_offset": "671", + "uplink_token": "CiIKIAoUZXVpLTZBN0UxMTFBMTAwMDAwMDASCCThJP/+9k6eEOW7l4YDGgwI9cGXowYQ5KPhrwMgiI2rp+jpOA=", + "channel_index": 2, + "received_at": "2023-05-18T08:25:25.869324983Z" + }, { + "gateway_ids": { + "gateway_id": "packetbroker" + }, + "packet_broker": { + "message_id": "01H0PZDG4MF9AYSMNY44MAVTDH", + "forwarder_net_id": "000013", + "forwarder_tenant_id": "ttn", + "forwarder_cluster_id": "eu1.cloud.thethings.network", + "forwarder_gateway_eui": "6A7E111A10000000", + "forwarder_gateway_id": "eui-6a7e111a10000000", + "home_network_net_id": "000013", + "home_network_tenant_id": "tenant", + "home_network_cluster_id": "eu1.cloud.thethings.industries" + }, + "time": "2023-05-18T08:25:25.885310Z", + "rssi": -24, + "channel_rssi": -24, + "snr": 12, + "frequency_offset": "671", + "uplink_token": "eyJnIjoiWlhsS2FHSkhZMmxQYVVwQ1RWUkpORkl3VGs1VE1XTnBURU5LYkdKdFRXbFBhVXBDVFZSSk5GSXdUazVKYVhkcFlWaFphVTlwU201a01uaGhWVlJvZDFSWFVuRmlSM1JtVFcxT2RVbHBkMmxrUjBadVNXcHZhV05ZY0RKT1IyeExaREpSZVZwR1pIUmpNRXBLVlVoR2RFNVZkR3BWVTBvNUxua3paVVJTWVRaM1lXOU1kbTQwVm5sdmIyWmlPWGN1ZUhCZmVrcElaa3hIWlZadGRVUlFVeTVuYlRaVlZXRXdkakpHV0VKMGJUUjZaMjVXUkVoeGVHRjRaMlJKTlVkS1VsbERhemc1VDNCbk5rVk1iM1JDUkVZM1VWbHdZbEJDTkdOblNqWjBlbkphYUV4MFRVMHhZMVZFTTFac01XdExURUo0YURaMFExTnhhMVJsWWw4eE5FdHlVVXcyZUhsRWFFbEhlakJITXpoTE0xaFdlRzR5VUVjMk4wNUViME5WTkhoTmRrazFZVk5oWkUwd2FXVnFjR294VGtoMFduZHlZMDFxVlVGNmRsbERUazlNY2s5eFdVeFpWMk5XTG1WVFFYVkpNVkptT1U5NWRqUTNhSEoxTUZoalYxRT0iLCJhIjp7ImZuaWQiOiIwMDAwMTMiLCJmdGlkIjoidHRuIiwiZmNpZCI6ImV1MS5jbG91ZC50aGV0aGluZ3MubmV0d29yayJ9fQ==", + "received_at": "2023-05-18T08:25:25.906038642Z" + }], + "settings": { + "data_rate": { + "lora": { + "bandwidth": 125000, + "spreading_factor": 7, + "coding_rate": "4/5" + } + }, + "frequency": "868500000", + "timestamp": 818273765, + "time": "2023-05-18T08:25:25.885310Z" + }, + "received_at": "2023-05-18T08:25:25.906399073Z", + "consumed_airtime": "0.097536s", + "network_ids": { + "net_id": "000013", + "tenant_id": "tenant", + "cluster_id": "eu1", + "cluster_address": "eu1.cloud.thethings.industries", + "tenant_address": "tenant.eu1.cloud.thethings.industries" + } + } +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/payload_3.json b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/payload_3.json new file mode 100644 index 0000000..d6d1017 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/payload_3.json @@ -0,0 +1,77 @@ +{ + "end_device_ids": { + "device_id": "eui-1000000000000001", + "application_ids": { + "application_id": "application-tti-name" + }, + "dev_eui": "1000000000000001", + "join_eui": "2000000000000001", + "dev_addr": "20000001" + }, + "correlation_ids": ["as:up:01H0PZDGB1NW6NAPD815NGHPF6", "gs:conn:01H0FJRSXSYT7VKNYXJ89F95XT", "gs:up:host:01H0FJRSY3MZMGPPFBQ4FZV4T8", "gs:uplink:01H0PZDG4HHGFRTXRTXD4PFTH7", "ns:uplink:01H0PZDG4JZ3BM0K6J89EQK1J7", "rpc:/ttn.lorawan.v3.GsNs/HandleUplink:01H0PZDG4J02F85RYFPCNSNXCR", "rpc:/ttn.lorawan.v3.NsAs/HandleUplink:01H0PZDGB081PMP806BJHNHX1A"], + "received_at": "2023-05-18T08:25:26.112483370Z", + "uplink_message": { + "session_key_id": "AYfg8rhha5n+FWx0ZaAprA==", + "f_port": 85, + "f_cnt": 5017, + "frm_payload": "BJi4CwAAAAA=", + "rx_metadata": [{ + "gateway_ids": { + "gateway_id": "eui-6A7E111A10000000", + "eui": "6A7E111A10000000" + }, + "time": "2023-05-18T08:25:25.885310Z", + "timestamp": 818273765, + "rssi": -24, + "channel_rssi": -24, + "snr": 12, + "frequency_offset": "671", + "uplink_token": "CiIKIAoUZXVpLTZBN0UxMTFBMTAwMDAwMDASCCThJP/+9k6eEOW7l4YDGgwI9cGXowYQ5KPhrwMgiI2rp+jpOA=", + "channel_index": 2, + "received_at": "2023-05-18T08:25:25.869324983Z" + }, { + "gateway_ids": { + "gateway_id": "packetbroker" + }, + "packet_broker": { + "message_id": "01H0PZDG4MF9AYSMNY44MAVTDH", + "forwarder_net_id": "000013", + "forwarder_tenant_id": "ttn", + "forwarder_cluster_id": "eu1.cloud.thethings.network", + "forwarder_gateway_eui": "6A7E111A10000000", + "forwarder_gateway_id": "eui-6a7e111a10000000", + "home_network_net_id": "000013", + "home_network_tenant_id": "tenant", + "home_network_cluster_id": "eu1.cloud.thethings.industries" + }, + "time": "2023-05-18T08:25:25.885310Z", + "rssi": -24, + "channel_rssi": -24, + "snr": 12, + "frequency_offset": "671", + "uplink_token": "eyJnIjoiWlhsS2FHSkhZMmxQYVVwQ1RWUkpORkl3VGs1VE1XTnBURU5LYkdKdFRXbFBhVXBDVFZSSk5GSXdUazVKYVhkcFlWaFphVTlwU201a01uaGhWVlJvZDFSWFVuRmlSM1JtVFcxT2RVbHBkMmxrUjBadVNXcHZhV05ZY0RKT1IyeExaREpSZVZwR1pIUmpNRXBLVlVoR2RFNVZkR3BWVTBvNUxua3paVVJTWVRaM1lXOU1kbTQwVm5sdmIyWmlPWGN1ZUhCZmVrcElaa3hIWlZadGRVUlFVeTVuYlRaVlZXRXdkakpHV0VKMGJUUjZaMjVXUkVoeGVHRjRaMlJKTlVkS1VsbERhemc1VDNCbk5rVk1iM1JDUkVZM1VWbHdZbEJDTkdOblNqWjBlbkphYUV4MFRVMHhZMVZFTTFac01XdExURUo0YURaMFExTnhhMVJsWWw4eE5FdHlVVXcyZUhsRWFFbEhlakJITXpoTE0xaFdlRzR5VUVjMk4wNUViME5WTkhoTmRrazFZVk5oWkUwd2FXVnFjR294VGtoMFduZHlZMDFxVlVGNmRsbERUazlNY2s5eFdVeFpWMk5XTG1WVFFYVkpNVkptT1U5NWRqUTNhSEoxTUZoalYxRT0iLCJhIjp7ImZuaWQiOiIwMDAwMTMiLCJmdGlkIjoidHRuIiwiZmNpZCI6ImV1MS5jbG91ZC50aGV0aGluZ3MubmV0d29yayJ9fQ==", + "received_at": "2023-05-18T08:25:25.906038642Z" + }], + "settings": { + "data_rate": { + "lora": { + "bandwidth": 125000, + "spreading_factor": 7, + "coding_rate": "4/5" + } + }, + "frequency": "868500000", + "timestamp": 818273765, + "time": "2023-05-18T08:25:25.885310Z" + }, + "received_at": "2023-05-18T08:25:25.906399073Z", + "consumed_airtime": "0.097536s", + "network_ids": { + "net_id": "000013", + "tenant_id": "tenant", + "cluster_id": "eu1", + "cluster_address": "eu1.cloud.thethings.industries", + "tenant_address": "tenant.eu1.cloud.thethings.industries" + } + } +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/payload_4.json b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/payload_4.json new file mode 100644 index 0000000..c0054aa --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/payload_4.json @@ -0,0 +1,77 @@ +{ + "end_device_ids": { + "device_id": "eui-1000000000000001", + "application_ids": { + "application_id": "application-tti-name" + }, + "dev_eui": "1000000000000001", + "join_eui": "2000000000000001", + "dev_addr": "20000001" + }, + "correlation_ids": ["as:up:01H0PZDGB1NW6NAPD815NGHPF6", "gs:conn:01H0FJRSXSYT7VKNYXJ89F95XT", "gs:up:host:01H0FJRSY3MZMGPPFBQ4FZV4T8", "gs:uplink:01H0PZDG4HHGFRTXRTXD4PFTH7", "ns:uplink:01H0PZDG4JZ3BM0K6J89EQK1J7", "rpc:/ttn.lorawan.v3.GsNs/HandleUplink:01H0PZDG4J02F85RYFPCNSNXCR", "rpc:/ttn.lorawan.v3.NsAs/HandleUplink:01H0PZDGB081PMP806BJHNHX1A"], + "received_at": "2023-05-18T08:25:26.112483370Z", + "uplink_message": { + "session_key_id": "AYfg8rhha5n+FWx0ZaAprA==", + "f_port": 85, + "f_cnt": 5017, + "frm_payload": "BJj//w==", + "rx_metadata": [{ + "gateway_ids": { + "gateway_id": "eui-6A7E111A10000000", + "eui": "6A7E111A10000000" + }, + "time": "2023-05-18T08:25:25.885310Z", + "timestamp": 818273765, + "rssi": -24, + "channel_rssi": -24, + "snr": 12, + "frequency_offset": "671", + "uplink_token": "CiIKIAoUZXVpLTZBN0UxMTFBMTAwMDAwMDASCCThJP/+9k6eEOW7l4YDGgwI9cGXowYQ5KPhrwMgiI2rp+jpOA=", + "channel_index": 2, + "received_at": "2023-05-18T08:25:25.869324983Z" + }, { + "gateway_ids": { + "gateway_id": "packetbroker" + }, + "packet_broker": { + "message_id": "01H0PZDG4MF9AYSMNY44MAVTDH", + "forwarder_net_id": "000013", + "forwarder_tenant_id": "ttn", + "forwarder_cluster_id": "eu1.cloud.thethings.network", + "forwarder_gateway_eui": "6A7E111A10000000", + "forwarder_gateway_id": "eui-6a7e111a10000000", + "home_network_net_id": "000013", + "home_network_tenant_id": "tenant", + "home_network_cluster_id": "eu1.cloud.thethings.industries" + }, + "time": "2023-05-18T08:25:25.885310Z", + "rssi": -24, + "channel_rssi": -24, + "snr": 12, + "frequency_offset": "671", + "uplink_token": "eyJnIjoiWlhsS2FHSkhZMmxQYVVwQ1RWUkpORkl3VGs1VE1XTnBURU5LYkdKdFRXbFBhVXBDVFZSSk5GSXdUazVKYVhkcFlWaFphVTlwU201a01uaGhWVlJvZDFSWFVuRmlSM1JtVFcxT2RVbHBkMmxrUjBadVNXcHZhV05ZY0RKT1IyeExaREpSZVZwR1pIUmpNRXBLVlVoR2RFNVZkR3BWVTBvNUxua3paVVJTWVRaM1lXOU1kbTQwVm5sdmIyWmlPWGN1ZUhCZmVrcElaa3hIWlZadGRVUlFVeTVuYlRaVlZXRXdkakpHV0VKMGJUUjZaMjVXUkVoeGVHRjRaMlJKTlVkS1VsbERhemc1VDNCbk5rVk1iM1JDUkVZM1VWbHdZbEJDTkdOblNqWjBlbkphYUV4MFRVMHhZMVZFTTFac01XdExURUo0YURaMFExTnhhMVJsWWw4eE5FdHlVVXcyZUhsRWFFbEhlakJITXpoTE0xaFdlRzR5VUVjMk4wNUViME5WTkhoTmRrazFZVk5oWkUwd2FXVnFjR294VGtoMFduZHlZMDFxVlVGNmRsbERUazlNY2s5eFdVeFpWMk5XTG1WVFFYVkpNVkptT1U5NWRqUTNhSEoxTUZoalYxRT0iLCJhIjp7ImZuaWQiOiIwMDAwMTMiLCJmdGlkIjoidHRuIiwiZmNpZCI6ImV1MS5jbG91ZC50aGV0aGluZ3MubmV0d29yayJ9fQ==", + "received_at": "2023-05-18T08:25:25.906038642Z" + }], + "settings": { + "data_rate": { + "lora": { + "bandwidth": 125000, + "spreading_factor": 7, + "coding_rate": "4/5" + } + }, + "frequency": "868500000", + "timestamp": 818273765, + "time": "2023-05-18T08:25:25.885310Z" + }, + "received_at": "2023-05-18T08:25:25.906399073Z", + "consumed_airtime": "0.097536s", + "network_ids": { + "net_id": "000013", + "tenant_id": "tenant", + "cluster_id": "eu1", + "cluster_address": "eu1.cloud.thethings.industries", + "tenant_address": "tenant.eu1.cloud.thethings.industries" + } + } +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/payload_5.json b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/payload_5.json new file mode 100644 index 0000000..d2a02b9 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/payload_5.json @@ -0,0 +1,77 @@ +{ + "end_device_ids": { + "device_id": "eui-1000000000000001", + "application_ids": { + "application_id": "application-tti-name" + }, + "dev_eui": "1000000000000001", + "join_eui": "2000000000000001", + "dev_addr": "20000001" + }, + "correlation_ids": ["as:up:01H0PZDGB1NW6NAPD815NGHPF6", "gs:conn:01H0FJRSXSYT7VKNYXJ89F95XT", "gs:up:host:01H0FJRSY3MZMGPPFBQ4FZV4T8", "gs:uplink:01H0PZDG4HHGFRTXRTXD4PFTH7", "ns:uplink:01H0PZDG4JZ3BM0K6J89EQK1J7", "rpc:/ttn.lorawan.v3.GsNs/HandleUplink:01H0PZDG4J02F85RYFPCNSNXCR", "rpc:/ttn.lorawan.v3.NsAs/HandleUplink:01H0PZDGB081PMP806BJHNHX1A"], + "received_at": "2023-05-18T08:25:26.112483370Z", + "uplink_message": { + "session_key_id": "AYfg8rhha5n+FWx0ZaAprA==", + "f_port": 85, + "f_cnt": 5017, + "frm_payload": "hJi4C9AHxAkF", + "rx_metadata": [{ + "gateway_ids": { + "gateway_id": "eui-6A7E111A10000000", + "eui": "6A7E111A10000000" + }, + "time": "2023-05-18T08:25:25.885310Z", + "timestamp": 818273765, + "rssi": -24, + "channel_rssi": -24, + "snr": 12, + "frequency_offset": "671", + "uplink_token": "CiIKIAoUZXVpLTZBN0UxMTFBMTAwMDAwMDASCCThJP/+9k6eEOW7l4YDGgwI9cGXowYQ5KPhrwMgiI2rp+jpOA=", + "channel_index": 2, + "received_at": "2023-05-18T08:25:25.869324983Z" + }, { + "gateway_ids": { + "gateway_id": "packetbroker" + }, + "packet_broker": { + "message_id": "01H0PZDG4MF9AYSMNY44MAVTDH", + "forwarder_net_id": "000013", + "forwarder_tenant_id": "ttn", + "forwarder_cluster_id": "eu1.cloud.thethings.network", + "forwarder_gateway_eui": "6A7E111A10000000", + "forwarder_gateway_id": "eui-6a7e111a10000000", + "home_network_net_id": "000013", + "home_network_tenant_id": "tenant", + "home_network_cluster_id": "eu1.cloud.thethings.industries" + }, + "time": "2023-05-18T08:25:25.885310Z", + "rssi": -24, + "channel_rssi": -24, + "snr": 12, + "frequency_offset": "671", + "uplink_token": "eyJnIjoiWlhsS2FHSkhZMmxQYVVwQ1RWUkpORkl3VGs1VE1XTnBURU5LYkdKdFRXbFBhVXBDVFZSSk5GSXdUazVKYVhkcFlWaFphVTlwU201a01uaGhWVlJvZDFSWFVuRmlSM1JtVFcxT2RVbHBkMmxrUjBadVNXcHZhV05ZY0RKT1IyeExaREpSZVZwR1pIUmpNRXBLVlVoR2RFNVZkR3BWVTBvNUxua3paVVJTWVRaM1lXOU1kbTQwVm5sdmIyWmlPWGN1ZUhCZmVrcElaa3hIWlZadGRVUlFVeTVuYlRaVlZXRXdkakpHV0VKMGJUUjZaMjVXUkVoeGVHRjRaMlJKTlVkS1VsbERhemc1VDNCbk5rVk1iM1JDUkVZM1VWbHdZbEJDTkdOblNqWjBlbkphYUV4MFRVMHhZMVZFTTFac01XdExURUo0YURaMFExTnhhMVJsWWw4eE5FdHlVVXcyZUhsRWFFbEhlakJITXpoTE0xaFdlRzR5VUVjMk4wNUViME5WTkhoTmRrazFZVk5oWkUwd2FXVnFjR294VGtoMFduZHlZMDFxVlVGNmRsbERUazlNY2s5eFdVeFpWMk5XTG1WVFFYVkpNVkptT1U5NWRqUTNhSEoxTUZoalYxRT0iLCJhIjp7ImZuaWQiOiIwMDAwMTMiLCJmdGlkIjoidHRuIiwiZmNpZCI6ImV1MS5jbG91ZC50aGV0aGluZ3MubmV0d29yayJ9fQ==", + "received_at": "2023-05-18T08:25:25.906038642Z" + }], + "settings": { + "data_rate": { + "lora": { + "bandwidth": 125000, + "spreading_factor": 7, + "coding_rate": "4/5" + } + }, + "frequency": "868500000", + "timestamp": 818273765, + "time": "2023-05-18T08:25:25.885310Z" + }, + "received_at": "2023-05-18T08:25:25.906399073Z", + "consumed_airtime": "0.097536s", + "network_ids": { + "net_id": "000013", + "tenant_id": "tenant", + "cluster_id": "eu1", + "cluster_address": "eu1.cloud.thethings.industries", + "tenant_address": "tenant.eu1.cloud.thethings.industries" + } + } +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/result_1.json b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/result_1.json new file mode 100644 index 0000000..e372dd9 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/result_1.json @@ -0,0 +1,30 @@ +{ + "deviceName": "CT101/CT103 eui-1000000000000001", + "deviceType": "CT101/CT103", + "attributes": { + "eui": "1000000000000001", + "fPort": 85, + "applicationId": "application-tti-name", + "devAddr": "20000001", + "spreadingFactor": 7, + "codeRate": "4/5", + "tenantId": "tenant", + "device_id": "eui-1000000000000001", + "join_eui": "2000000000000001", + "net_id": "000013", + "cluster_id": "eu1", + "cluster_adress": "eu1.cloud.thethings.industries", + "bandwidth": 125000, + "frequency": "868500000" + }, + "telemetry": [{ + "ts": 1684398325906, + "values": { + "power": "on", + "ipso_version": "v0.1", + "sn": "6746D38802580000", + "hardware_version": "v1.0", + "firmware_version": "v1.1" + } + }] +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/result_2.json b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/result_2.json new file mode 100644 index 0000000..3750146 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/result_2.json @@ -0,0 +1,26 @@ +{ + "deviceName": "CT101/CT103 eui-1000000000000001", + "deviceType": "CT101/CT103", + "attributes": { + "eui": "1000000000000001", + "fPort": 85, + "applicationId": "application-tti-name", + "devAddr": "20000001", + "spreadingFactor": 7, + "codeRate": "4/5", + "tenantId": "tenant", + "device_id": "eui-1000000000000001", + "join_eui": "2000000000000001", + "net_id": "000013", + "cluster_id": "eu1", + "cluster_adress": "eu1.cloud.thethings.industries", + "bandwidth": 125000, + "frequency": "868500000" + }, + "telemetry": [{ + "ts": 1684398325906, + "values": { + "total_current": 100.0 + } + }] +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/result_3.json b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/result_3.json new file mode 100644 index 0000000..c587563 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/result_3.json @@ -0,0 +1,26 @@ +{ + "deviceName": "CT101/CT103 eui-1000000000000001", + "deviceType": "CT101/CT103", + "attributes": { + "eui": "1000000000000001", + "fPort": 85, + "applicationId": "application-tti-name", + "devAddr": "20000001", + "spreadingFactor": 7, + "codeRate": "4/5", + "tenantId": "tenant", + "device_id": "eui-1000000000000001", + "join_eui": "2000000000000001", + "net_id": "000013", + "cluster_id": "eu1", + "cluster_adress": "eu1.cloud.thethings.industries", + "bandwidth": 125000, + "frequency": "868500000" + }, + "telemetry": [{ + "ts": 1684398325906, + "values": { + "current": 30.0 + } + }] +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/result_4.json b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/result_4.json new file mode 100644 index 0000000..f73b7c9 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/result_4.json @@ -0,0 +1,26 @@ +{ + "deviceName": "CT101/CT103 eui-1000000000000001", + "deviceType": "CT101/CT103", + "attributes": { + "eui": "1000000000000001", + "fPort": 85, + "applicationId": "application-tti-name", + "devAddr": "20000001", + "spreadingFactor": 7, + "codeRate": "4/5", + "tenantId": "tenant", + "device_id": "eui-1000000000000001", + "join_eui": "2000000000000001", + "net_id": "000013", + "cluster_id": "eu1", + "cluster_adress": "eu1.cloud.thethings.industries", + "bandwidth": 125000, + "frequency": "868500000" + }, + "telemetry": [{ + "ts": 1684398325906, + "values": { + "alarm": "read failed" + } + }] +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/result_5.json b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/result_5.json new file mode 100644 index 0000000..e20f0a2 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/ThingsStackIndustries/uplink/result_5.json @@ -0,0 +1,29 @@ +{ + "deviceName": "CT101/CT103 eui-1000000000000001", + "deviceType": "CT101/CT103", + "attributes": { + "eui": "1000000000000001", + "fPort": 85, + "applicationId": "application-tti-name", + "devAddr": "20000001", + "spreadingFactor": 7, + "codeRate": "4/5", + "tenantId": "tenant", + "device_id": "eui-1000000000000001", + "join_eui": "2000000000000001", + "net_id": "000013", + "cluster_id": "eu1", + "cluster_adress": "eu1.cloud.thethings.industries", + "bandwidth": 125000, + "frequency": "868500000" + }, + "telemetry": [{ + "ts": 1684398325906, + "values": { + "current_max": 30.0, + "current_min": 20.0, + "current": 25.0, + "alarm": ["threshold alarm", "over range alarm"] + } + }] +} \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/guide.md b/VENDORS/Milesight/CT101-CT103/guide.md new file mode 100644 index 0000000..7c3b8c9 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/guide.md @@ -0,0 +1,53 @@ +## Payload Definition + +| CHANNEL | ID | TYPE | LENGTH | DESCRIPTION | +| :---------------: | :--: | :--: | :----: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Protocol Version | 0xFF | 0x01 | 1 | protocol_version(1B) | +| Power Status | 0xFF | 0x0B | 1 | power(1B) | +| Serial Number | 0xFF | 0x16 | 8 | sn(8B) | +| Hardware Version | 0xFF | 0x09 | 2 | hardware_version(8B) | +| Firmware Version | 0xFF | 0x0A | 2 | firmware_version(8B) | +| Total Current | 0x03 | 0x97 | 4 | total_ah(4B)
total_ah, read: uint32/100, unit: Ah | +| Current | 0x04 | 0x98 | 2 | current(2B)
current, read: uint16/100, unit: A | +| Temperature | 0x09 | 0x67 | 2 | temperature(2B)
temperature, read: int16/10, unit: ℃ | | +| Current Alarm | 0x84 | 0x98 | 7 | current_max(2B) + current_min(2B) + current(2B) + alarm(1B)
alarm, values: (0: threshold alarm, 1: threshold alarm release, 2: over range alarm, 3: over range alarm release) | +| Temperature Alarm | 0x89 | 0x67 | 3 | temperature(2B) + temperature_alarm(1B)
temperature, read: int16/10, unit: ℃
temperature_alarm, values: (0: threshold alarm release, 1: threshold alarm) | + +## Example + +```json +// FF0BFF FF0101 FF166746D38802580000 FF090100 FF0A0101 FF0F00 +{ + "firmware_version": "v1.1", + "hardware_version": "v1.0", + "ipso_version": "v0.1", + "power": "on", + "sn": "6746d38802580000" +} + +// 039710270000 +{ + "total_current": 100 +} + +// 0498B80B00000000 +{ + "current": 30 +} + +// 0498FFFF +{ + "alarm": "read failed" +} + +// 8498B80BD007C40905 +{ + "alarm": [ + "threshold alarm", + "over range alarm" + ], + "current": 25, + "current_max": 30, + "current_min": 20 +} +``` \ No newline at end of file diff --git a/VENDORS/Milesight/CT101-CT103/info.json b/VENDORS/Milesight/CT101-CT103/info.json new file mode 100644 index 0000000..9ef62a5 --- /dev/null +++ b/VENDORS/Milesight/CT101-CT103/info.json @@ -0,0 +1,5 @@ +{ + "url": "https://www.milesight.com/iot/product/lorawan-sensor/ct10x", + "label": "CT10x: LoRaWAN® Smart Current Transformer", + "description": "The CT10x is a LoRaWAN® current transformer designed for remote energy monitoring and consumption analysis. Offering various current options and threshold alarms, the CT10x features a compact, detachable clamp design for easy, safe indoor installation without requiring power shutdown. Compatible with Milesight LoRaWAN® gateways and IoT Cloud, it supports remote monitoring via web or mobile app. Ideal for energy tracking in smart buildings, machine failure detection, and preventive maintenance." +} diff --git a/VENDORS/Milesight/CT101-CT103/photo.png b/VENDORS/Milesight/CT101-CT103/photo.png new file mode 100644 index 0000000..395688d Binary files /dev/null and b/VENDORS/Milesight/CT101-CT103/photo.png differ