Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added HTTP integration for Milesight devices #189

Merged
merged 3 commits into from
Dec 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions VENDORS/Milesight/AM102/HTTP/uplink/converter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "HTTP Uplink integration for AM102",
"type": "UPLINK",
"debugMode": false,
"debugSettings": {
"failuresEnabled": true,
"allEnabled": false,
"allEnabledUntil": 1735560006385
},
"configuration": {
"scriptLang": "TBEL",
"decoder": null,
"tbelDecoder": "var data = decodeToJson(payload);\nvar deviceName = \"AM102 \" + data.devEUI;\nvar deviceType = \"AM102\";\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 var fPort = data.fPort;\n var historyDataList = [];\n if(fPort == 85) {\n for (var i = 0; i < input.length - 2;) {\n var channel_id = input[i++] & 0xff;\n var channel_type = input[i++] & 0xff;\n // BATTERY\n if (channel_id === 0x01 && channel_type === 0x75) {\n decoded.battery = input[i];\n i += 1;\n }\n // TEMPERATURE\n if (channel_id === 0x03 && channel_type === 0x67) {\n // ℃\n decoded.temperature = parseBytesToInt(input, i,\n 2, false) / 10;\n i += 2;\n // ℉\n // decoded.temperature = parseBytesToInt(input, i, 2, false) / 10 * 1.8 + 32;\n // i +=2;\n }\n // HUMIDITY\n if (channel_id === 0x04 && channel_type === 0x68) {\n decoded.humidity = parseBytesToInt(input, i, 1, false) / 2;\n i += 1;\n }\n // HISTORY DATA\n if (channel_id === 0x20 && channel_type === 0xCE) {\n var historyData = {\n ts: parseBytesToInt(input, i, 4, false) * 1000,\n values: {\n temperature: parseBytesToInt(input, i + 4, 2, false) / 10,\n humidity: parseBytesToInt(input, i + 6, 1, false) / 2,\n }\n };\n \n historyDataList.add(historyData);\n \n i += 7;\n }\n }\n }\n\n output.telemetry = [{\n ts: timestamp,\n values: decoded\n }];\n \n output.telemetry.addAll(historyDataList);\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.data));\n\n// Collecting data to result\nif (customDecoding.?telemetry.size() > 0) {\n foreach(telemetryObj: customDecoding.telemetry) {\n if (telemetryObj.ts != null && telemetryObj.values != null) {\n telemetry.add(telemetryObj);\n }\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.?devEui;\nattributes.fPort = data.fPort;\nattributes.applicationId = data.?applicationId;\nattributes.applicationName = data.?applicationName;\nattributes.frequency = data.txInfo.?frequency;\nattributes.bandwidth = data.txInfo.?dataRate.?bandwidth;\nattributes.spreadingFactor = data.txInfo.?dataRate.?spreadFactor;\nattributes.codeRate = data.txInfo.?codeRate;\n\nif(Boolean.parseBoolean(metadata[\"includeGatewayInfo\"])) {\n var gatewayInfo = getGatewayInfo();\n var addDataToTelemetry = {};\n addDataToTelemetry.snr = gatewayInfo.?loRaSNR;\n addDataToTelemetry.rssi = gatewayInfo.rssi;\n addDataToTelemetry.fCnt = data.fCnt;\n \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 dateString = dateString.replaceFirst(\"(\\\\d{4}-\\\\d{2})(\\\\d{2})\", \"$1-$2\");\n dateString = dateString.replaceFirst(\"\\\\.(\\\\d{3})\\\\d+Z\", \".$1Z\");\n dateString = dateString.replace(\"Z\", \"+0000\");\n var date = new Date(dateString);\n var timestamp = date.getTime();\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 = addDataToTelemetries(telemetry, addDataToTelemetry);\n }\n else {\n telemetry.add(addDataToTelemetry);\n }\n \n return telemetry;\n}\n\nfunction addDataToTelemetries(telemetries, addDataToTelemetry) {\n foreach(telemetry : telemetries) {\n foreach(element : addDataToTelemetry.entrySet()) {\n if(!telemetry[\"values\"].keys.contains(element.key)) {\n telemetry[\"values\"][element.key] = element.value;\n }\n } \n }\n \n return telemetries;\n}",
"encoder": null,
"tbelEncoder": null,
"updateOnlyKeys": [
"fPort",
"applicationName",
"frequency",
"bandwidth",
"spreadingFactor",
"codeRate"
]
},
"additionalInfo": {
"description": ""
},
"edgeTemplate": false
}
4 changes: 4 additions & 0 deletions VENDORS/Milesight/AM102/HTTP/uplink/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"integrationName": "HTTP integration",
"includeGatewayInfo": "false"
}
31 changes: 31 additions & 0 deletions VENDORS/Milesight/AM102/HTTP/uplink/payload.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"applicationID": 1,
"applicationName": "cloud",
"deviceName": "24e1641092176759",
"devEUI": "24e1641092176759",
"time": "2020-0327T12:39:05.547336Z",
"rxInfo": [
{
"mac": "24e124fffef021be",
"rssi": -57,
"loRaSNR": 10,
"name": "local_gateway",
"latitude": 0,
"longitude": 0,
"altitude": 0
}
],
"txInfo": {
"frequency": 868300000,
"dataRate": {
"modulation": "LORA",
"bandwidth": 125,
"spreadFactor": 7
},
"adr": false,
"codeRate": "4/5"
},
"fCnt": 0,
"fPort": 85,
"data": "AXVkA2cYAQRobQ=="
}
20 changes: 20 additions & 0 deletions VENDORS/Milesight/AM102/HTTP/uplink/result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"deviceName": "AM102 24e1641092176759",
"deviceType": "AM102",
"attributes": {
"fPort": 85,
"applicationName": "cloud",
"frequency": 868300000,
"bandwidth": 125,
"spreadingFactor": 7,
"codeRate": "4/5"
},
"telemetry": [{
"ts": 1585312745547,
"values": {
"battery": 100,
"temperature": 28.0,
"humidity": 54.5
}
}]
}
43 changes: 43 additions & 0 deletions VENDORS/Milesight/AM102/LORIOT/uplink/result_2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
[{
"deviceName": "AM102 0102030405060708",
"deviceType": "AM102",
"attributes": {
"eui": "0102030405060708",
"fPort": 207,
"frequency": 868300000
},
"telemetry": [{
"ts": 1690901260493,
"values": {
"battery": 100,
"temperature": 28.0,
"humidity": 54.5
}
}]
}, {
"deviceName": "Gateway 1020304080706050",
"deviceType": "Lora gateway",
"telemetry": [{
"ts": 1690901260493,
"values": {
"rssi": -38,
"snr": 8.5
}
}],
"attributes": {
"eui": "1020304080706050"
}
}, {
"deviceName": "Gateway 1020304081716151",
"deviceType": "Lora gateway",
"telemetry": [{
"ts": 1690901260495,
"values": {
"rssi": -42,
"snr": 8.8
}
}],
"attributes": {
"eui": "1020304081716151"
}
}]
Empty file.
29 changes: 29 additions & 0 deletions VENDORS/Milesight/AM102L/HTTP/uplink/converter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "HTTP Uplink integration for AM102L",
"type": "UPLINK",
"debugMode": false,
"debugSettings": {
"failuresEnabled": true,
"allEnabled": false,
"allEnabledUntil": 1735560006385
},
"configuration": {
"scriptLang": "TBEL",
"decoder": null,
"tbelDecoder": "var data = decodeToJson(payload);\nvar deviceName = \"AM102L \" + data.devEUI;\nvar deviceType = \"AM102L\";\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 var fPort = data.fPort;\n var historyDataList = [];\n if(fPort == 85) {\n for (var i = 0; i < input.length - 2;) {\n var channel_id = input[i++] & 0xff;\n var channel_type = input[i++] & 0xff;\n // BATTERY\n if (channel_id === 0x01 && channel_type === 0x75) {\n decoded.battery = input[i];\n i += 1;\n }\n // TEMPERATURE\n if (channel_id === 0x03 && channel_type === 0x67) {\n // ℃\n decoded.temperature = parseBytesToInt(input, i,\n 2, false) / 10;\n i += 2;\n // ℉\n // decoded.temperature = parseBytesToInt(input, i, 2, false) / 10 * 1.8 + 32;\n // i +=2;\n }\n // HUMIDITY\n if (channel_id === 0x04 && channel_type === 0x68) {\n decoded.humidity = parseBytesToInt(input, i, 1, false) / 2;\n i += 1;\n }\n // HISTORY DATA\n if (channel_id === 0x20 && channel_type === 0xCE) {\n var historyData = {\n ts: parseBytesToInt(input, i, 4, false) * 1000,\n values: {\n temperature: parseBytesToInt(input, i + 4, 2, false) / 10,\n humidity: parseBytesToInt(input, i + 6, 1, false) / 2,\n }\n };\n \n historyDataList.add(historyData);\n \n i += 7;\n }\n }\n }\n\n output.telemetry = [{\n ts: timestamp,\n values: decoded\n }];\n \n output.telemetry.addAll(historyDataList);\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.data));\n\n// Collecting data to result\nif (customDecoding.?telemetry.size() > 0) {\n foreach(telemetryObj: customDecoding.telemetry) {\n if (telemetryObj.ts != null && telemetryObj.values != null) {\n telemetry.add(telemetryObj);\n }\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.?devEui;\nattributes.fPort = data.fPort;\nattributes.applicationId = data.?applicationId;\nattributes.applicationName = data.?applicationName;\nattributes.frequency = data.txInfo.?frequency;\nattributes.bandwidth = data.txInfo.?dataRate.?bandwidth;\nattributes.spreadingFactor = data.txInfo.?dataRate.?spreadFactor;\nattributes.codeRate = data.txInfo.?codeRate;\n\nif(Boolean.parseBoolean(metadata[\"includeGatewayInfo\"])) {\n var gatewayInfo = getGatewayInfo();\n var addDataToTelemetry = {};\n addDataToTelemetry.snr = gatewayInfo.?loRaSNR;\n addDataToTelemetry.rssi = gatewayInfo.rssi;\n addDataToTelemetry.fCnt = data.fCnt;\n \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 dateString = dateString.replaceFirst(\"(\\\\d{4}-\\\\d{2})(\\\\d{2})\", \"$1-$2\");\n dateString = dateString.replaceFirst(\"\\\\.(\\\\d{3})\\\\d+Z\", \".$1Z\");\n dateString = dateString.replace(\"Z\", \"+0000\");\n var date = new Date(dateString);\n var timestamp = date.getTime();\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 = addDataToTelemetries(telemetry, addDataToTelemetry);\n }\n else {\n telemetry.add(addDataToTelemetry);\n }\n \n return telemetry;\n}\n\nfunction addDataToTelemetries(telemetries, addDataToTelemetry) {\n foreach(telemetry : telemetries) {\n foreach(element : addDataToTelemetry.entrySet()) {\n if(!telemetry[\"values\"].keys.contains(element.key)) {\n telemetry[\"values\"][element.key] = element.value;\n }\n } \n }\n \n return telemetries;\n}",
"encoder": null,
"tbelEncoder": null,
"updateOnlyKeys": [
"fPort",
"applicationName",
"frequency",
"bandwidth",
"spreadingFactor",
"codeRate"
]
},
"additionalInfo": {
"description": ""
},
"edgeTemplate": false
}
4 changes: 4 additions & 0 deletions VENDORS/Milesight/AM102L/HTTP/uplink/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"integrationName": "HTTP integration",
"includeGatewayInfo": "false"
}
31 changes: 31 additions & 0 deletions VENDORS/Milesight/AM102L/HTTP/uplink/payload.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"applicationID": 1,
"applicationName": "cloud",
"deviceName": "24e1641092176759",
"devEUI": "24e1641092176759",
"time": "2020-0327T12:39:05.547336Z",
"rxInfo": [
{
"mac": "24e124fffef021be",
"rssi": -57,
"loRaSNR": 10,
"name": "local_gateway",
"latitude": 0,
"longitude": 0,
"altitude": 0
}
],
"txInfo": {
"frequency": 868300000,
"dataRate": {
"modulation": "LORA",
"bandwidth": 125,
"spreadFactor": 7
},
"adr": false,
"codeRate": "4/5"
},
"fCnt": 0,
"fPort": 85,
"data": "AXVkA2cYAQRobQ=="
}
20 changes: 20 additions & 0 deletions VENDORS/Milesight/AM102L/HTTP/uplink/result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"deviceName": "AM102L 24e1641092176759",
"deviceType": "AM102L",
"attributes": {
"fPort": 85,
"applicationName": "cloud",
"frequency": 868300000,
"bandwidth": 125,
"spreadingFactor": 7,
"codeRate": "4/5"
},
"telemetry": [{
"ts": 1585312745547,
"values": {
"battery": 100,
"temperature": 28.0,
"humidity": 54.5
}
}]
}
Loading