Plugin file
Plugin configuration file
{
"name": "loraboatmonitor",
"version": "1.0.0",
"description": "The LoRa boat monitor is used to monitor the boat when you are away. Various measured values such as battery voltage, GPS position, humidity, temperature, air pressure, filling levels, bilge and door contact are continuously forwarded to the LoRaWAN.",
"author": "Thinger.io",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/thinger-io/plugins.git",
"directory": "loraboatmonitor"
},
"metadata": {
"name": "LORABOATMONITOR",
"description": "The LoRa boat monitor is used to monitor the boat when you are away. Various measured values such as battery voltage, GPS position, humidity, temperature, air pressure, filling levels, bilge and door contact are continuously forwarded to the LoRaWAN.",
"image": "assets/LoraBoat_Monitor.png",
"category": "devices",
"vendor": "open-boat-projects"
},
"resources": {
"products": [
{
"config": {
"icons": []
},
"description": "The LoRa boat monitor is used to monitor the boat when you are away. Various measured values such as battery voltage, GPS position, humidity, temperature, air pressure, filling levels, bilge and door contact are continuously forwarded to the LoRaWAN.",
"enabled": true,
"name": "LORABOATMONITOR",
"product": "loraboatmonitor",
"profile": {
"api": {
"downlink": {
"enabled": true,
"handle_connectivity": false,
"request": {
"data": {
"path": "/downlink",
"payload": "{\n \"data\" : \"{{payload.data=\"\"}}\",\n \"port\" : {{payload.port=85}},\n \"priority\": {{payload.priority=3}},\n \"confirmed\" : {{payload.confirmed=false}},\n \"uplink\" : {{property.uplink}} \n}",
"payload_function": "",
"payload_type": "",
"plugin": "{{property.uplink.source}}",
"target": "plugin_endpoint"
}
}
},
"uplink": {
"device_id_resolver": "getId",
"enabled": true,
"handle_connectivity": true,
"request": {
"data": {
"payload": "{{payload}}",
"payload_function": "",
"payload_type": "source_payload",
"resource_stream": "uplink",
"target": "resource_stream"
}
}
}
},
"autoprovisions": {
"device_autoprovisioning": {
"config": {
"mode": "pattern",
"pattern": "loraboat-.*"
},
"enabled": true
}
},
"buckets": {
"loraboatmonitor_data": {
"backend": "mongodb",
"data": {
"payload": "{{payload}}",
"payload_function": "decodeThingerUplink",
"payload_type": "source_payload",
"resource": "uplink",
"source": "resource",
"update": "events"
},
"enabled": true,
"retention": {
"period": 6,
"unit": "months"
},
"tags": [
"telemetry",
"boat",
"environmental",
"gps"
]
}
},
"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\n/*\nPayload smaple: 0A00541FE027770B9517D6043F1AA702751AFF133D0F0000000001\n\nDecode result:\n\n{\n \"alarm1\": 1,\n \"altitude\": 1,\n \"counter\": 10,\n \"device\": 123456789,\n \"dewpoint\": 10.4,\n \"hdop\": 1.1,\n \"humidity\": 29.35,\n \"latitude\": 51.193901,\n \"level1\": 0,\n \"level2\": 0,\n \"longitude\": 6.796773,\n \"position\": {\n \"context\": {\n \"lat\": 51.193901,\n \"lng\": 6.796773\n },\n \"value\": 0\n },\n \"pressure\": 1020.8,\n \"relay\": 0,\n \"tempbattery\": 17.2,\n \"temperature\": 20.1,\n \"voltage\": 12.38\n}\n\n*/\n\nfunction decodeUplink(input) {\n var data = {};\n var events = {\n 1: \"setup\",\n 2: \"interval\",\n 3: \"motion\",\n 4: \"button\"\n };\n// data.event = events[input.fPort];\n\n var voffset = 0; // Voltage offset\n var toffset = 0; // Temperature offset for BME280\n var poffset = 0; // pressure offset for altitude\n\n data.device = 123456789;\n data.counter = ((input.bytes[1] << 8) | input.bytes[0]);\n var temperature = (((input.bytes[3] << 8) | input.bytes[2]) / 100) - 50 + toffset;\n data.temperature = Math.round(temperature * 10) / 10;\n data.pressure = ((input.bytes[5] << 8) | input.bytes[4]) / 10 + poffset;\n data.humidity = ((input.bytes[7] << 8) | input.bytes[6]) / 100;\n var dewpoint = (((input.bytes[9] << 8) | input.bytes[8]) / 100) - 50;\n data.dewpoint = Math.round(dewpoint * 10) / 10;\n var voltage = ((input.bytes[11] << 8) | input.bytes[10]) / 1000 + voffset;\n data.voltage = Math.round(voltage * 1000) / 1000;\n var tempbattery = (((input.bytes[13] << 8) | input.bytes[12]) / 100) - 50;\n data.tempbattery = Math.round(tempbattery * 10) / 10;\n var longitude = ((input.bytes[15] << 8) | input.bytes[14]) / 100 + ((input.bytes[17] << 8) | input.bytes[16]) / 1000000;\n data.longitude = longitude;\n var latitude = ((input.bytes[19] << 8) | input.bytes[18]) / 100 + ((input.bytes[21] << 8) | input.bytes[20]) / 1000000;\n data.latitude = latitude;\n data.altitude = 1;\n data.hdop = 1.1;\n data.position = {\"value\": 0, context:{\"lat\": latitude, \"lng\": longitude}};\n data.level1 = ((input.bytes[23] << 8) | input.bytes[22]) / 100;\n data.level2 = ((input.bytes[25] << 8) | input.bytes[24]) / 100;\n data.alarm1 = input.bytes[26] & 0x01;\n data.relay = (input.bytes[26] & 0x10) / 0x10;\n\n var warnings = [];\n if (data.voltage < 10) {\n warnings.push(\"Battery undervoltage\");\n }\n if (data.voltage > 14.7) {\n warnings.push(\"Battery overload\");\n }\n return {\n data: data,\n warnings: warnings\n };\n}\n",
"environment": "javascript",
"storage": "",
"version": "1.0"
},
"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": "Overview",
"widgets": [
{
"layout": {
"col": 4,
"row": 6,
"sizeX": 2,
"sizeY": 6
},
"panel": {
"color": "#ffffff",
"currentColor": "#ffffff",
"showOffline": {
"type": "none"
},
"title": "Battery Voltage"
},
"properties": {
"color": "#f0e924",
"max": 15,
"min": 10,
"unit": "V"
},
"sources": [
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "voltage",
"tags": {
"device": [],
"group": []
}
},
"color": "#f39c12",
"name": "Battery Voltage",
"source": "bucket",
"timespan": {
"mode": "latest"
}
}
],
"type": "donutchart"
},
{
"layout": {
"col": 3,
"row": 6,
"sizeX": 1,
"sizeY": 6
},
"panel": {
"color": "#ffffff",
"currentColor": "#ffffff",
"showOffline": {
"type": "none"
},
"title": "Temperature"
},
"properties": {
"color": "#ff0000",
"max": 50,
"min": -20,
"unit": "°C"
},
"sources": [
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "temperature",
"tags": {
"device": [],
"group": []
}
},
"color": "#e74c3c",
"name": "Temperature",
"source": "bucket",
"timespan": {
"mode": "latest"
}
}
],
"type": "donutchart"
},
{
"layout": {
"col": 3,
"row": 0,
"sizeX": 1,
"sizeY": 6
},
"panel": {
"color": "#ffffff",
"currentColor": "#ffffff",
"showOffline": {
"type": "none"
},
"title": "Humidity"
},
"properties": {
"color": "#0000ff",
"max": 100,
"min": 0,
"unit": "%RH"
},
"sources": [
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "humidity",
"tags": {
"device": [],
"group": []
}
},
"color": "#3498db",
"name": "Humidity",
"source": "bucket",
"timespan": {
"mode": "latest"
}
}
],
"type": "donutchart"
},
{
"layout": {
"col": 0,
"row": 12,
"sizeX": 3,
"sizeY": 6
},
"panel": {
"color": "#ffffff",
"currentColor": "#ffffff",
"showOffline": {
"type": "none"
},
"title": "Pressure"
},
"properties": {
"color": "#95a5a6",
"max": 1100,
"min": 950,
"unit": "hPa"
},
"sources": [
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "pressure",
"tags": {
"device": [],
"group": []
}
},
"color": "#95a5a6",
"name": "Pressure",
"source": "bucket",
"timespan": {
"mode": "latest"
}
}
],
"type": "donutchart"
},
{
"layout": {
"col": 3,
"row": 12,
"sizeX": 3,
"sizeY": 6
},
"panel": {
"color": "#ffffff",
"currentColor": "#ffffff",
"showOffline": {
"type": "none"
},
"title": "Dew Point"
},
"properties": {
"color": "#1abc9c",
"max": 30,
"min": -10,
"unit": "°C"
},
"sources": [
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "dewpoint",
"tags": {
"device": [],
"group": []
}
},
"color": "#16a085",
"name": "Dew Point",
"source": "bucket",
"timespan": {
"mode": "latest"
}
}
],
"type": "donutchart"
},
{
"layout": {
"col": 4,
"row": 0,
"sizeX": 2,
"sizeY": 6
},
"panel": {
"color": "#ffffff",
"currentColor": "#ffffff",
"showOffline": {
"type": "none"
},
"title": "Battery Temperature"
},
"properties": {
"color": "#e67e22",
"max": 50,
"min": -20,
"unit": "°C"
},
"sources": [
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "tempbattery",
"tags": {
"device": [],
"group": []
}
},
"color": "#d35400",
"name": "Battery Temp",
"source": "bucket",
"timespan": {
"mode": "latest"
}
}
],
"type": "donutchart"
},
{
"layout": {
"col": 0,
"row": 0,
"sizeX": 3,
"sizeY": 12
},
"panel": {
"color": "#ffffff",
"currentColor": "#ffffff",
"showOffline": {
"type": "none"
},
"title": "GPS Location"
},
"properties": {
"center": {
"latitude": 51.193901,
"longitude": 6.796773
},
"zoom": 10
},
"sources": [
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "position",
"tags": {
"device": [],
"group": []
}
},
"color": "#e74c3c",
"name": "Boat Position",
"source": "bucket",
"timespan": {
"mode": "latest"
}
}
],
"type": "map"
}
]
},
{
"name": "Historical Trends",
"widgets": [
{
"layout": {
"col": 0,
"row": 0,
"sizeX": 3,
"sizeY": 10
},
"panel": {
"color": "#ffffff",
"currentColor": "#ffffff",
"showOffline": {
"type": "none"
},
"title": "Temperature & Humidity Trends"
},
"properties": {
"axis": true,
"fill": false,
"legend": true,
"multiple_axes": true
},
"sources": [
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "temperature",
"tags": {
"device": [],
"group": []
}
},
"color": "#e74c3c",
"name": "Temperature (°C)",
"source": "bucket",
"timespan": {
"magnitude": "day",
"mode": "relative",
"period": "latest",
"value": 7
}
},
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "humidity",
"tags": {
"device": [],
"group": []
}
},
"color": "#3498db",
"name": "Humidity (%RH)",
"source": "bucket",
"timespan": {
"magnitude": "day",
"mode": "relative",
"period": "latest",
"value": 7
}
}
],
"type": "chart"
},
{
"layout": {
"col": 3,
"row": 0,
"sizeX": 3,
"sizeY": 10
},
"panel": {
"color": "#ffffff",
"currentColor": "#ffffff",
"showOffline": {
"type": "none"
},
"title": "Battery Voltage History"
},
"properties": {
"axis": true,
"fill": false,
"legend": true,
"multiple_axes": false
},
"sources": [
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "voltage",
"tags": {
"device": [],
"group": []
}
},
"color": "#f39c12",
"name": "Battery Voltage (V)",
"source": "bucket",
"timespan": {
"magnitude": "day",
"mode": "relative",
"period": "latest",
"value": 7
}
}
],
"type": "chart"
},
{
"layout": {
"col": 0,
"row": 10,
"sizeX": 3,
"sizeY": 10
},
"panel": {
"color": "#ffffff",
"currentColor": "#ffffff",
"showOffline": {
"type": "none"
},
"title": "Pressure & Dew Point"
},
"properties": {
"axis": true,
"fill": false,
"legend": true,
"multiple_axes": true
},
"sources": [
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "pressure",
"tags": {
"device": [],
"group": []
}
},
"color": "#95a5a6",
"name": "Pressure (hPa)",
"source": "bucket",
"timespan": {
"magnitude": "day",
"mode": "relative",
"period": "latest",
"value": 7
}
},
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "dewpoint",
"tags": {
"device": [],
"group": []
}
},
"color": "#16a085",
"name": "Dew Point (°C)",
"source": "bucket",
"timespan": {
"magnitude": "day",
"mode": "relative",
"period": "latest",
"value": 7
}
}
],
"type": "chart"
},
{
"layout": {
"col": 3,
"row": 10,
"sizeX": 3,
"sizeY": 10
},
"panel": {
"color": "#ffffff",
"currentColor": "#ffffff",
"showOffline": {
"type": "none"
},
"title": "Liquid Levels"
},
"properties": {
"axis": true,
"fill": false,
"legend": true,
"multiple_axes": false
},
"sources": [
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "level1",
"tags": {
"device": [],
"group": []
}
},
"color": "#9b59b6",
"name": "Level 1 (%)",
"source": "bucket",
"timespan": {
"magnitude": "day",
"mode": "relative",
"period": "latest",
"value": 7
}
},
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "level2",
"tags": {
"device": [],
"group": []
}
},
"color": "#8e44ad",
"name": "Level 2 (%)",
"source": "bucket",
"timespan": {
"magnitude": "day",
"mode": "relative",
"period": "latest",
"value": 7
}
}
],
"type": "chart"
}
]
},
{
"name": "Alarms & Status",
"widgets": [
{
"layout": {
"col": 0,
"row": 0,
"sizeX": 2,
"sizeY": 8
},
"panel": {
"color": "#ffffff",
"currentColor": "#ffffff",
"showOffline": {
"type": "none"
},
"title": "Alarm Status"
},
"properties": {
"source": "code",
"template": "<div style=\"width:100%; height:100%; display:flex; align-items:center; justify-content:center; flex-direction:column;\">\r\n <div ng-repeat=\"entry in value | limitTo:1\" style=\"text-align:center;\">\r\n <div ng-if=\"entry.alarm1 == 1\" style=\"font-size:72px; color:#e74c3c;\">\r\n <i class=\"fa fa-exclamation-triangle\"></i>\r\n </div>\r\n <div ng-if=\"entry.alarm1 == 0\" style=\"font-size:72px; color:#27ae60;\">\r\n <i class=\"fa fa-check-circle\"></i>\r\n </div>\r\n <h2 ng-if=\"entry.alarm1 == 1\" style=\"color:#e74c3c; margin-top:20px;\">ALARM ACTIVE</h2>\r\n <h2 ng-if=\"entry.alarm1 == 0\" style=\"color:#27ae60; margin-top:20px;\">ALL CLEAR</h2>\r\n </div>\r\n</div>\r\n"
},
"sources": [
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "alarm1",
"tags": {
"device": [],
"group": []
}
},
"name": "alarm1",
"source": "bucket",
"timespan": {
"mode": "latest"
}
}
],
"type": "html_time"
},
{
"layout": {
"col": 2,
"row": 0,
"sizeX": 2,
"sizeY": 8
},
"panel": {
"color": "#ffffff",
"currentColor": "#ffffff",
"showOffline": {
"type": "none"
},
"title": "Relay Status"
},
"properties": {
"source": "code",
"template": "<div style=\"width:100%; height:100%; display:flex; align-items:center; justify-content:center; flex-direction:column;\">\r\n <div ng-repeat=\"entry in value | limitTo:1\" style=\"text-align:center;\">\r\n <div ng-if=\"entry.relay == 1\" style=\"font-size:72px; color:#27ae60;\">\r\n <i class=\"fa fa-power-off\"></i>\r\n </div>\r\n <div ng-if=\"entry.relay == 0\" style=\"font-size:72px; color:#95a5a6;\">\r\n <i class=\"fa fa-power-off\"></i>\r\n </div>\r\n <h2 ng-if=\"entry.relay == 1\" style=\"color:#27ae60; margin-top:20px;\">RELAY ON</h2>\r\n <h2 ng-if=\"entry.relay == 0\" style=\"color:#95a5a6; margin-top:20px;\">RELAY OFF</h2>\r\n </div>\r\n</div>\r\n"
},
"sources": [
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "relay",
"tags": {
"device": [],
"group": []
}
},
"name": "relay",
"source": "bucket",
"timespan": {
"mode": "latest"
}
}
],
"type": "html_time"
},
{
"layout": {
"col": 4,
"row": 0,
"sizeX": 2,
"sizeY": 8
},
"panel": {
"color": "#ffffff",
"currentColor": "#ffffff",
"showOffline": {
"type": "none"
},
"title": "Battery Health"
},
"properties": {
"source": "code",
"template": "<div style=\"width:100%; height:100%; display:flex; align-items:center; justify-content:center; flex-direction:column; padding:20px;\">\r\n <div ng-repeat=\"entry in value | limitTo:1\" style=\"text-align:center; width:100%;\">\r\n <div ng-if=\"entry.voltage >= 12.0 && entry.voltage <= 14.7\" style=\"font-size:48px; color:#27ae60;\">\r\n <i class=\"fa fa-battery-full\"></i>\r\n </div>\r\n <div ng-if=\"entry.voltage < 12.0\" style=\"font-size:48px; color:#e74c3c;\">\r\n <i class=\"fa fa-battery-empty\"></i>\r\n </div>\r\n <div ng-if=\"entry.voltage > 14.7\" style=\"font-size:48px; color:#f39c12;\">\r\n <i class=\"fa fa-exclamation-triangle\"></i>\r\n </div>\r\n <h3 style=\"margin-top:20px;\">{{ entry.voltage }} V</h3>\r\n <p ng-if=\"entry.voltage >= 12.0 && entry.voltage <= 14.7\" style=\"color:#27ae60;\"><strong>Normal</strong></p>\r\n <p ng-if=\"entry.voltage < 12.0\" style=\"color:#e74c3c;\"><strong>Undervoltage Warning</strong></p>\r\n <p ng-if=\"entry.voltage > 14.7\" style=\"color:#f39c12;\"><strong>Overload Warning</strong></p>\r\n </div>\r\n</div>\r\n"
},
"sources": [
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "voltage",
"tags": {
"device": [],
"group": []
}
},
"name": "voltage",
"source": "bucket",
"timespan": {
"mode": "latest"
}
}
],
"type": "html_time"
},
{
"layout": {
"col": 0,
"row": 8,
"sizeX": 6,
"sizeY": 12
},
"panel": {
"color": "#ffffff",
"currentColor": "#ffffff",
"showOffline": {
"type": "none"
},
"title": "Event History"
},
"properties": {
"source": "code",
"template": "<div style=\"width:100%; height:100%; overflow-y:auto\">\r\n <table class=\"table table-striped table-condensed\">\r\n <thead>\r\n <tr>\r\n <th>Timestamp</th>\r\n <th>Alarm</th>\r\n <th>Relay</th>\r\n <th>Voltage (V)</th>\r\n <th>Level 1 (%)</th>\r\n <th>Level 2 (%)</th>\r\n <th>Temp (°C)</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr ng-repeat=\"entry in value\">\r\n <td>{{ entry.ts | date:'short' }}</td>\r\n <td><span ng-class=\"{'label label-danger': entry.alarm1 == 1, 'label label-success': entry.alarm1 == 0}\">{{ entry.alarm1 == 1 ? 'ACTIVE' : 'OK' }}</span></td>\r\n <td><span ng-class=\"{'label label-success': entry.relay == 1, 'label label-default': entry.relay == 0}\">{{ entry.relay == 1 ? 'ON' : 'OFF' }}</span></td>\r\n <td>{{ entry.voltage }}</td>\r\n <td>{{ entry.level1 }}</td>\r\n <td>{{ entry.level2 }}</td>\r\n <td>{{ entry.temperature }}</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n</div>\r\n"
},
"sources": [
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "ts",
"tags": {
"device": [],
"group": []
}
},
"name": "ts",
"source": "bucket",
"timespan": {
"magnitude": "day",
"mode": "relative",
"period": "latest",
"value": 7
}
},
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "alarm1",
"tags": {
"device": [],
"group": []
}
},
"name": "alarm1",
"source": "bucket",
"timespan": {
"magnitude": "day",
"mode": "relative",
"period": "latest",
"value": 7
}
},
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "relay",
"tags": {
"device": [],
"group": []
}
},
"name": "relay",
"source": "bucket",
"timespan": {
"magnitude": "day",
"mode": "relative",
"period": "latest",
"value": 7
}
},
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "voltage",
"tags": {
"device": [],
"group": []
}
},
"name": "voltage",
"source": "bucket",
"timespan": {
"magnitude": "day",
"mode": "relative",
"period": "latest",
"value": 7
}
},
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "level1",
"tags": {
"device": [],
"group": []
}
},
"name": "level1",
"source": "bucket",
"timespan": {
"magnitude": "day",
"mode": "relative",
"period": "latest",
"value": 7
}
},
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "level2",
"tags": {
"device": [],
"group": []
}
},
"name": "level2",
"source": "bucket",
"timespan": {
"magnitude": "day",
"mode": "relative",
"period": "latest",
"value": 7
}
},
{
"bucket": {
"backend": "mongodb",
"id": "loraboatmonitor_data",
"mapping": "temperature",
"tags": {
"device": [],
"group": []
}
},
"name": "temperature",
"source": "bucket",
"timespan": {
"magnitude": "day",
"mode": "relative",
"period": "latest",
"value": 7
}
}
],
"type": "html_time"
}
]
}
]
}
}
]
}
}
]
}
}