From 4afe68c8089a74be71337e41c082acaec5e667c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberto=20Penas=20D=C3=ADaz?= Date: Thu, 16 Apr 2026 12:22:29 +0200 Subject: [PATCH 1/5] Create Changelog for milesight-iot-em320-tilt --- milesight-iot-em320-tilt/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 milesight-iot-em320-tilt/CHANGELOG.md diff --git a/milesight-iot-em320-tilt/CHANGELOG.md b/milesight-iot-em320-tilt/CHANGELOG.md new file mode 100644 index 000000000..57140b7b5 --- /dev/null +++ b/milesight-iot-em320-tilt/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## 1.0.0 - 2026-04-16 + +- First version of plugin \ No newline at end of file From 93cd5d90d57268fca0d7adb89ec76c0087e6248a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberto=20Penas=20D=C3=ADaz?= Date: Thu, 16 Apr 2026 12:22:29 +0200 Subject: [PATCH 2/5] Create LICENSE for milesight-iot-em320-tilt --- milesight-iot-em320-tilt/LICENSE.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 milesight-iot-em320-tilt/LICENSE.md diff --git a/milesight-iot-em320-tilt/LICENSE.md b/milesight-iot-em320-tilt/LICENSE.md new file mode 100644 index 000000000..bffeef341 --- /dev/null +++ b/milesight-iot-em320-tilt/LICENSE.md @@ -0,0 +1,7 @@ +Copyright 2026 Thinger.io + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file From b889d4eedba95b4f0985b6af0e99eb0a5b974406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberto=20Penas=20D=C3=ADaz?= Date: Thu, 16 Apr 2026 12:22:52 +0200 Subject: [PATCH 3/5] Upload image milesight-iot-em320-tilt --- milesight-iot-em320-tilt/assets/em320-tilt.png | Bin 0 -> 32096 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 milesight-iot-em320-tilt/assets/em320-tilt.png diff --git a/milesight-iot-em320-tilt/assets/em320-tilt.png b/milesight-iot-em320-tilt/assets/em320-tilt.png new file mode 100644 index 0000000000000000000000000000000000000000..49a453069d3fe028bd8a7be01029bd140c5ec892 GIT binary patch literal 32096 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 literal 0 HcmV?d00001 From 96b1a70a09308f79be6616bedc21d37e99dcbc4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberto=20Penas=20D=C3=ADaz?= Date: Thu, 16 Apr 2026 12:24:17 +0200 Subject: [PATCH 4/5] Create README for milesight-iot-em320-tilt --- milesight-iot-em320-tilt/README.md | 59 ++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 milesight-iot-em320-tilt/README.md diff --git a/milesight-iot-em320-tilt/README.md b/milesight-iot-em320-tilt/README.md new file mode 100644 index 000000000..6575e32fc --- /dev/null +++ b/milesight-iot-em320-tilt/README.md @@ -0,0 +1,59 @@ +# EM320-TILT - Tilt Sensor + +The EM320-TILT is an LoRaWAN® tilt sensor mainly for angle measurement and asset movement detection. With its compact size and 3-axis accelerometer, the device provides high-precision tilt monitoring for various applications. It features a wide measurement range of -90° to +90° with an ultra-high resolution of 0.01° and accuracy of ±1°, making it suitable for monitoring the inclination of objects and detecting movement based on angle changes. + +## Features + +- **3-Axis Accelerometer**: Precise angle measurement on X, Y, and Z axes +- **Wide Measurement Range**: -90° to +90° tilt detection +- **High Precision**: 0.01° resolution with ±1° accuracy +- **Flexible Configuration**: Up to 36 configurable triggers for customized monitoring +- **LoRaWAN Connectivity**: Long-range wireless communication with low power consumption +- **Compact Design**: Small form factor (58 x 18 x 85 mm) for easy installation +- **IP67 Enclosure**: Weather-resistant and dustproof for outdoor applications +- **Wide Operating Temperature**: -30°C to +60°C +- **Built-in Sensors**: Battery monitoring, tilt, and accelerometer + +## Use Cases + +- Angle measurement of machinery, equipment, and structures +- Asset movement and tampering detection +- Structural monitoring and safety applications +- Industrial equipment positioning and alignment +- Geotechnical monitoring +- Tower and pole inclination monitoring + +## Thinger.io Integration + +## Requirements + +A LoRaWAN server is required to communicate the EM320-TILT into Thinger.io, some options are: + +- [The Things Stack](https://www.thethingsindustries.com/stack/) +- [LORIOT](https://loriot.io/) +- [ChirpStack](https://www.chirpstack.io/) + +Alongside, the corresponding plugin for the selected LoRaWAN server needs to be installed in your Thinger.io instance. + +## Get Started + +### Installation + +Look for the plugin in the [Thinger.io Plugin Store](https://marketplace.thinger.io/) and install it in your Thinger.io instance. Once the plugin is installed a new Product will be created for this device. + +### Configuration + +The Product is already preconfigured, check that the auto provision prefix matches the one selected in your LoRaWAN server plugin in Thinger.io, or change it to your desire. + +### Usage + +Start sending uplinks for autoprovisioning devices and buckets. +This product also provides a predefined dashboard and downlinks. + +## Additional Resources + +Milesight resources can be found at: + +- [Product Page](https://www.milesight.com/iot/product/lorawan-sensor/em320-tilt) +- [User Guide](https://resource.milesight.com/milesight/iot/document/em320-tilt-user-guide-en.pdf) +- [Thinger docs](https://docs.thinger.io) \ No newline at end of file From 72f4d860da6b98f0b1db3e253ff8f36a1095df7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberto=20Penas=20D=C3=ADaz?= Date: Thu, 16 Apr 2026 12:27:39 +0200 Subject: [PATCH 5/5] Create plugin.json for milesight-iot-em320-tilt --- milesight-iot-em320-tilt/plugin.json | 672 +++++++++++++++++++++++++++ 1 file changed, 672 insertions(+) create mode 100644 milesight-iot-em320-tilt/plugin.json diff --git a/milesight-iot-em320-tilt/plugin.json b/milesight-iot-em320-tilt/plugin.json new file mode 100644 index 000000000..5d59a5738 --- /dev/null +++ b/milesight-iot-em320-tilt/plugin.json @@ -0,0 +1,672 @@ +{ + "name": "milesight_iot_em320_tilt", + "version": "1.0.0", + "description": "EM320-TILT is an LoRaWAN® tilt sensor mainly for angle measurementand asset movement detection", + "author": "Thinger.io", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/thinger-io/plugins.git", + "directory": "milesight-iot-em320-tilt" + }, + "metadata": { + "name": "Milesight-Iot EM320-TILT", + "description": "EM320-TILT is an LoRaWAN® tilt sensor mainly for angle measurementand asset movement detection", + "image": "assets/em320-tilt.png", + "category": "devices", + "vendor": "milesight-iot" + }, + "resources": { + "products": [ + { + "description": "EM320-TILT is an LoRaWAN® tilt sensor mainly for angle measurementand asset movement detection", + "enabled": true, + "name": "Milesight-Iot EM320-TILT", + "product": "milesight_iot_em320_tilt", + "profile": { + "api": { + "downlink": { + "enabled": true, + "handle_connectivity": false, + "request": { + "data": { + "path": "/downlink", + "payload": "{\r\n \"data\" : \"{{payload.data=\"\"}}\",\r\n \"port\" : {{payload.port=2}},\r\n \"priority\": {{payload.priority=3}},\r\n \"confirmed\" : {{payload.confirmed=false}},\r\n \"uplink\" : {{property.uplink}} \r\n}", + "payload_function": "", + "payload_type": "", + "plugin": "{{property.uplink.source}}", + "target": "plugin_endpoint" + } + }, + "response": { + "data": { + "source": "request_response" + } + } + }, + "uplink": { + "enabled": true, + "handle_connectivity": true, + "request": { + "data": { + "payload": "{{payload}}", + "payload_function": "", + "payload_type": "source_payload", + "resource_stream": "uplink", + "target": "resource_stream" + } + }, + "response": { + "data": { + "source": "request_response" + } + } + } + }, + "autoprovisions": { + "device_autoprovisioning": { + "config": { + "mode": "pattern", + "pattern": "em320_tilt_.*" + }, + "enabled": true + } + }, + "buckets": { + "milesight_em320_tilt_data": { + "backend": "mongodb", + "data": { + "payload": "{{payload}}", + "payload_function": "", + "payload_type": "source_payload", + "resource_stream": "uplink_decoded", + "target": "resource_stream" + }, + "enabled": true, + "retention": { + "period": 3, + "unit": "months" + }, + "tags": [] + } + }, + "code": { + "code": "function decodeThingerUplink(thingerData) {\n // 0. If data has already been decoded, we will return it\n if (thingerData.decodedPayload) return thingerData.decodedPayload;\n \n // 1. Extract and Validate Input\n // We need 'payload' (hex string) and 'fPort' (integer)\n const hexPayload = thingerData.payload || \"\";\n const port = thingerData.fPort || 1;\n\n // 2. Convert Hex String to Byte Array\n const bytes = [];\n for (let i = 0; i < hexPayload.length; i += 2) {\n bytes.push(parseInt(hexPayload.substr(i, 2), 16));\n }\n\n // 3. Dynamic Function Detection and Execution\n \n // CASE A: (The Things Stack v3)\n if (typeof decodeUplink === 'function') {\n try {\n const input = {\n bytes: bytes,\n fPort: port\n };\n var result = decodeUplink(input);\n \n if (result.data) return result.data;\n\n return result; \n } catch (e) {\n console.error(\"Error inside decodeUplink:\", e);\n throw e;\n }\n }\n\n // CASE B: Legacy TTN (v2)\n else if (typeof Decoder === 'function') {\n try {\n return Decoder(bytes, port);\n } catch (e) {\n console.error(\"Error inside Decoder:\", e);\n throw e;\n }\n }\n\n // CASE C: No decoder found\n else {\n throw new Error(\"No compatible TTN decoder function (decodeUplink or Decoder) found in scope.\");\n }\n}\n\n\n// TTN decoder\nfunction decodeUplink(input) {\n var res = Decoder(input.bytes, input.fPort);\n if (res.error) {\n return {\n errors: [res.error],\n };\n }\n return {\n data: res,\n };\n}\n/**\n * Payload Decoder for The Things Network\n *\n * Copyright 2023 Milesight IoT\n *\n * @product EM320-TILT\n */\nfunction Decoder(bytes, port) {\n return milesight(bytes);\n}\n\nfunction milesight(bytes) {\n var decoded = {};\n\n for (var i = 0; i < bytes.length;) {\n var channel_id = bytes[i++];\n var channel_type = bytes[i++];\n\n // BATTERY\n if (channel_id === 0x01 && channel_type === 0x75) {\n decoded.battery = bytes[i];\n i += 1;\n }\n // ANGLE\n else if (channel_id === 0x03 && channel_type === 0xd4) {\n decoded.angle_x = (readInt16LE(bytes.slice(i, i + 2)) >> 1) / 100;\n decoded.angle_y = (readInt16LE(bytes.slice(i + 2, i + 4)) >> 1) / 100;\n decoded.angle_z = (readInt16LE(bytes.slice(i + 4, i + 6)) >> 1) / 100;\n decoded.threshold_x = (bytes[i] & 0x01) === 0x01 ? \"trigger\" : \"normal\";\n decoded.threshold_y = (bytes[i + 2] & 0x01) === 0x01 ? \"trigger\" : \"normal\";\n decoded.threshold_z = (bytes[i + 4] & 0x01) === 0x01 ? \"trigger\" : \"normal\";\n i += 6;\n } else {\n break;\n }\n }\n\n return decoded;\n}\n\n/* ******************************************\n * bytes to number\n ********************************************/\nfunction readUInt16LE(bytes) {\n var value = (bytes[1] << 8) + bytes[0];\n return value & 0xffff;\n}\n\nfunction readInt16LE(bytes) {\n var ref = readUInt16LE(bytes);\n return ref > 0x7fff ? ref - 0x10000 : ref;\n}\n", + "environment": "javascript", + "storage": "", + "version": "1.0" + }, + "flows": { + "milesight_em320_tilt_decoder": { + "data": { + "payload": "{{payload}}", + "payload_function": "decodeThingerUplink", + "payload_type": "source_payload", + "resource": "uplink", + "source": "resource", + "update": "events" + }, + "enabled": true, + "sink": { + "payload": "{{payload}}", + "payload_function": "", + "payload_type": "source_payload", + "resource_stream": "uplink_decoded", + "target": "resource_stream" + }, + "split_data": false + } + }, + "properties": { + "uplink": { + "data": { + "payload": "{{payload}}", + "payload_function": "", + "payload_type": "source_payload", + "resource": "uplink", + "source": "resource", + "update": "events" + }, + "default": { + "source": "value" + }, + "enabled": true + } + } + }, + "_resources": { + "properties": [ + { + "property": "dashboard", + "value": { + "tabs": [ + { + "name": "EM320-TILT", + "widgets": [ + { + "layout": { + "col": 0, + "row": 0, + "sizeX": 2, + "sizeY": 5 + }, + "panel": { + "color": "#ffffff", + "currentColor": "#ffffff", + "showOffline": { + "type": "none" + }, + "title": "Angle X" + }, + "properties": { + "decimalPlaces": 2, + "enableExtraTextColor": false, + "enableIconColor": false, + "enableIconSize": false, + "extraText": "", + "extraTextColor": "#1E313E", + "extraTextColorConditions": [], + "extraTextConditions": [], + "extraTextPosition": "above-value", + "extraTextSize": "20px", + "extraTextWeight": "font-light", + "icon": "", + "iconColor": "#1E313E", + "iconColorConditions": [], + "iconConditions": [], + "iconGap": "8px", + "iconPosition": "before-value", + "iconSize": "75px", + "iconVerticalOffset": "0px", + "link": "", + "textAlign": "center", + "textColor": "#1E313E", + "textColorConditions": [], + "textSize": "60px", + "textWeight": "font-light", + "unit": "°", + "unitSize": "20px" + }, + "sources": [ + { + "bucket": { + "backend": "mongodb", + "id": "milesight_em320_tilt_data", + "mapping": "angle_x", + "tags": { + "device": [], + "group": [] + } + }, + "color": "#1abc9c", + "name": "Source 1", + "source": "bucket", + "timespan": { + "mode": "latest" + } + } + ], + "type": "text" + }, + { + "layout": { + "col": 2, + "row": 0, + "sizeX": 2, + "sizeY": 5 + }, + "panel": { + "color": "#ffffff", + "currentColor": "#ffffff", + "showOffline": { + "type": "none" + }, + "title": "Angle Y" + }, + "properties": { + "decimalPlaces": 2, + "enableExtraTextColor": false, + "enableIconColor": false, + "enableIconSize": false, + "extraText": "", + "extraTextColor": "#1E313E", + "extraTextColorConditions": [], + "extraTextConditions": [], + "extraTextPosition": "above-value", + "extraTextSize": "20px", + "extraTextWeight": "font-light", + "icon": "", + "iconColor": "#1E313E", + "iconColorConditions": [], + "iconConditions": [], + "iconGap": "8px", + "iconPosition": "before-value", + "iconSize": "75px", + "iconVerticalOffset": "0px", + "link": "", + "textAlign": "center", + "textColor": "#1E313E", + "textColorConditions": [], + "textSize": "60px", + "textWeight": "font-light", + "unit": "°", + "unitSize": "20px" + }, + "sources": [ + { + "bucket": { + "backend": "mongodb", + "id": "milesight_em320_tilt_data", + "mapping": "angle_y", + "tags": { + "device": [], + "group": [] + } + }, + "color": "#1abc9c", + "name": "Source 1", + "source": "bucket", + "timespan": { + "mode": "latest" + } + } + ], + "type": "text" + }, + { + "layout": { + "col": 4, + "row": 0, + "sizeX": 2, + "sizeY": 5 + }, + "panel": { + "color": "#ffffff", + "currentColor": "#ffffff", + "showOffline": { + "type": "none" + }, + "title": "Angle Z" + }, + "properties": { + "decimalPlaces": 2, + "enableExtraTextColor": false, + "enableIconColor": false, + "enableIconSize": false, + "extraText": "", + "extraTextColor": "#1E313E", + "extraTextColorConditions": [], + "extraTextConditions": [], + "extraTextPosition": "above-value", + "extraTextSize": "20px", + "extraTextWeight": "font-light", + "icon": "", + "iconColor": "#1E313E", + "iconColorConditions": [], + "iconConditions": [], + "iconGap": "8px", + "iconPosition": "before-value", + "iconSize": "75px", + "iconVerticalOffset": "0px", + "link": "", + "textAlign": "center", + "textColor": "#1E313E", + "textColorConditions": [], + "textSize": "60px", + "textWeight": "font-light", + "unit": "°", + "unitSize": "20px" + }, + "sources": [ + { + "bucket": { + "backend": "mongodb", + "id": "milesight_em320_tilt_data", + "mapping": "angle_z", + "tags": { + "device": [], + "group": [] + } + }, + "color": "#1abc9c", + "name": "Source 1", + "source": "bucket", + "timespan": { + "mode": "latest" + } + } + ], + "type": "text" + }, + { + "layout": { + "col": 0, + "row": 5, + "sizeX": 6, + "sizeY": 10 + }, + "panel": { + "color": "#ffffff", + "currentColor": "#ffffff", + "showOffline": { + "type": "none" + }, + "title": "Tilt Angles (24h)" + }, + "properties": { + "alignTimeSeries": false, + "dataAppend": false, + "options": "var options = {\n chart: {\n type: 'line',\n stacked: false\n },\n dataLabels: {\n enabled: false\n },\n stroke: {\n curve: 'smooth',\n width: 2\n },\n xaxis: {\n type: 'datetime',\n labels: {\n datetimeUTC: false\n },\n tooltip: {\n enabled: false\n }\n },\n yaxis: {\n title: {\n text: 'Angle (°)'\n },\n labels: {\n formatter: function (val) {\n if ( val !== null && typeof val !== 'undefined' )\n return val.toFixed(2);\n }\n }\n },\n tooltip: {\n x: {\n format: 'dd/MM/yyyy HH:mm:ss'\n }\n }\n};\n", + "realTimeUpdate": true + }, + "sources": [ + { + "aggregation": {}, + "bucket": { + "backend": "mongodb", + "id": "milesight_em320_tilt_data", + "mapping": "angle_x", + "tags": { + "device": [], + "group": [] + } + }, + "color": "#d1311f", + "name": "Angle X", + "source": "bucket", + "timespan": { + "magnitude": "hour", + "mode": "relative", + "period": "latest", + "value": 24 + } + }, + { + "aggregation": {}, + "bucket": { + "backend": "mongodb", + "id": "milesight_em320_tilt_data", + "mapping": "angle_y", + "tags": { + "device": [], + "group": [] + } + }, + "color": "#2ebd59", + "name": "Angle Y", + "source": "bucket", + "timespan": { + "magnitude": "hour", + "mode": "relative", + "period": "latest", + "value": 24 + } + }, + { + "aggregation": {}, + "bucket": { + "backend": "mongodb", + "id": "milesight_em320_tilt_data", + "mapping": "angle_z", + "tags": { + "device": [], + "group": [] + } + }, + "color": "#329fcd", + "name": "Angle Z", + "source": "bucket", + "timespan": { + "magnitude": "hour", + "mode": "relative", + "period": "latest", + "value": 24 + } + } + ], + "type": "apex_charts" + }, + { + "layout": { + "col": 0, + "row": 15, + "sizeX": 2, + "sizeY": 5 + }, + "panel": { + "color": "#ffffff", + "currentColor": "#ffffff", + "showOffline": { + "type": "none" + }, + "title": "Battery" + }, + "properties": { + "color": "#2ebd59", + "gradient": false, + "max": 100, + "min": 0, + "unit": "%" + }, + "sources": [ + { + "bucket": { + "backend": "mongodb", + "id": "milesight_em320_tilt_data", + "mapping": "battery", + "tags": { + "device": [], + "group": [] + } + }, + "color": "#1abc9c", + "name": "Source 1", + "source": "bucket", + "timespan": { + "mode": "latest" + } + } + ], + "type": "gauge" + }, + { + "layout": { + "col": 2, + "row": 15, + "sizeX": 4, + "sizeY": 5 + }, + "panel": { + "color": "#ffffff", + "currentColor": "#ffffff", + "showOffline": { + "type": "none" + }, + "title": "Threshold Status" + }, + "type": "group_widget", + "widgets": [ + { + "layout": { + "col": 0, + "row": 0, + "sizeX": 2, + "sizeY": 5 + }, + "panel": { + "color": "#ffffff", + "currentColor": "#ffffff", + "showOffline": { + "type": "none" + }, + "title": "Threshold X" + }, + "properties": { + "color": "#2ebd59", + "colors": [ + { + "blink": false, + "color": "#2ecc71", + "max": 0, + "min": 0 + }, + { + "blink": true, + "color": "#e74c3c", + "max": 1, + "min": 1 + } + ], + "size": "50px" + }, + "sources": [ + { + "bucket": { + "backend": "mongodb", + "id": "milesight_em320_tilt_data", + "mapping": "threshold_x", + "tags": { + "device": [], + "group": [] + } + }, + "color": "#1abc9c", + "name": "Source 1", + "processing": { + "input": "thresholdToCode" + }, + "source": "bucket", + "timespan": { + "mode": "latest" + } + } + ], + "type": "led" + }, + { + "layout": { + "col": 2, + "row": 0, + "sizeX": 2, + "sizeY": 5 + }, + "panel": { + "color": "#ffffff", + "currentColor": "#ffffff", + "showOffline": { + "type": "none" + }, + "title": "Threshold Y" + }, + "properties": { + "color": "#2ebd59", + "colors": [ + { + "blink": false, + "color": "#2ecc71", + "max": 0, + "min": 0 + }, + { + "blink": true, + "color": "#e74c3c", + "max": 1, + "min": 1 + } + ], + "size": "50px" + }, + "sources": [ + { + "bucket": { + "backend": "mongodb", + "id": "milesight_em320_tilt_data", + "mapping": "threshold_y", + "tags": { + "device": [], + "group": [] + } + }, + "color": "#1abc9c", + "name": "Source 1", + "processing": { + "input": "thresholdToCode" + }, + "source": "bucket", + "timespan": { + "mode": "latest" + } + } + ], + "type": "led" + }, + { + "layout": { + "col": 4, + "row": 0, + "sizeX": 2, + "sizeY": 5 + }, + "panel": { + "color": "#ffffff", + "currentColor": "#ffffff", + "showOffline": { + "type": "none" + }, + "title": "Threshold Z" + }, + "properties": { + "color": "#2ebd59", + "colors": [ + { + "blink": false, + "color": "#2ecc71", + "max": 0, + "min": 0 + }, + { + "blink": true, + "color": "#e74c3c", + "max": 1, + "min": 1 + } + ], + "size": "50px" + }, + "sources": [ + { + "bucket": { + "backend": "mongodb", + "id": "milesight_em320_tilt_data", + "mapping": "threshold_z", + "tags": { + "device": [], + "group": [] + } + }, + "color": "#1abc9c", + "name": "Source 1", + "processing": { + "input": "thresholdToCode" + }, + "source": "bucket", + "timespan": { + "mode": "latest" + } + } + ], + "type": "led" + } + ] + } + ] + } + ] + } + } + ] + } + } + ] + } +} \ No newline at end of file