BLE to MQTT application for Pycom boards
This application is designed to turn your pycom board into a functioning BLE gateway. It creates a topic that is specific to each tag for ease of subscribing and using the data.
This application shoud be able to work on most Pycom boards with it tested on:
- WiPy3
- SiPy
With the SiPy having much less memory then the WiPy3 no performance issue have been noticed on the SiPy.
This applications allows for the decoding of some BLE data. Meaning once received the data can be easily pushed into a database.
In the published message the format type is send as "f". The following types of data can be decoded:
- Format 0 - Any BLE data that is not decoded by the application.
- Format 1 - Eddystone TLM data.
- Format 3 - Ruuvi RAWv1
- Format 5 - Ruuvi RAWv2
These topics send data and cannot receive it. This application supports publishing these advertisements over MQTT.
-
Topic1/boardMAC/topic2/BLEMAC Example: home/3C71BF877D48/beacon/E20B1593499E
Publishing a mesasges like:
{"x": 0.024, "z": 1.008, "f": 5, "temp": 26.14, "ts": "2019-11-17T02:39:31.261467Z", "Mac": "E20B1593499E", "edgeMAC": "3C71BF877D48", "battery": 2.025, "rssi": -86, "y": 0.012, "tAcc": 1.008357, "pressure": 1018.39, "tx": -6, "humidity": 57.1375, "Data": "0201061BFF990405146C5947CA7F0018000C03F0A4B4B02D06E20B1593499E03190000020A000D09436F72655461675F3439396500000000000000000000"}
-
Topic1/boardMAC/topic2/heartbeat Example: home/3C71BF877D48/beacon/device/heartbeat Publishing a message like:
{"uptime": 147434.0, "ts": "2019-11-17T02:40:48.766209Z", "edgeMAC": "3C71BF877D48", "memFree": 2538688, "board": "WiPy"}
The application has the ability to subscribe to a topic and receive message if sent to the board. However performance is limited to the reliabilty of the MQTT connection which is a limitation of the at the moment.
At this stage this is not used, but can be tested to print a message if wanted.
The configuration file is located in the main directory being named config.py. It contains all of the different configuration options.
Multiple configurations can be entered and called upon in the main application on line 12. By replacing "CONFIGhome" with the name of your config.
Example:
CONFIGhome = {
"broker" : "0.0.0.0",
"ssl" : False,
"port" : 1883,
"usr" : True,
"mqttuser" : "username",
"mqttpass" : "password",
"topic1" : "home",
"topic2" : "beacon",
"ssid" : "ssid",
"wifiPass" : "wifipassword",
"wifiExt" : False,
"ntp_server" : "time.google.com",
"rssiEn" : False,
"rssi" : -127,
"macFilterEn" : False,
"macFilter" : [ "c0bb722a568e", "aabbccddeeff", "aabbccddeef1", "aabbccddeef2"],
"btExt" : False
}
- broker = The IP address of your MQTT broker.
- ssl = If wanting to use a SSL conenction to you broker.
- port = 1883 is the standard MQTT port, if using SSL 8883 is standard
- usr = Enable this if your broker requires a username and password to connect
- mqttuser = Username required for broker conenction
- mqttpass = Password required for broker connection
- topic1 = can be used to identifiy each gateway further. For example "kitchen"
- topic2 = used to publish ble Data
- ssid = WiFi SSID
- wifiPass = WiFi password
- wifiExt = Enable this is wanting to use external WiFi antenna
- ntp_server = Default checks time with google NTP server
- rssiEn = Enable if RSSI filtering is wanted
- rssi = Set the RSSI filter for example -40 would be almost touching the board
- macFilterEn = Enable this if you want to only send data on specific BLE beacons
- macFilter = The list of ble beacons to send data for
- btExt = Enable this if you want to use the external antenna for BLE
Software needed:
- MQTT broker (mosquitto on a RPI)
- Node-RED
- Grafana (I am using v6.3.6)
- InfluxDB (I am using V1.7.8)
I created 3 databases in influxDB. Those are:
- unknownBeacons
- TLM
- Ruuvi
The below flows will pass all received data into their corresponding databases.
[{"id":"e184de2d.f9883","type":"tab","label":"BLE2MQTT2INFLUX","disabled":false,"info":""},{"id":"211dbd92.7c49e2","type":"function","z":"e184de2d.f9883","name":"TLM","func":"var tokens = msg.topic.split(\"/\");\nmsg.topic =tokens[3]; //get device name from topic level 3 /v1.6/devices/tokens[3]\nvar dest = tokens[tokens.length-1];\ninputjson =JSON.parse(msg.payload);\nvar _fields = {};\nfor(var item in inputjson){\n if (item.includes('Data') || item.includes(\"ts\")){}\n else\n {\n _fields[item] = inputjson[item];}\n}\n\nvar tags = {\n Mac: inputjson['Mac'],\n esgeMAC: inputjson['edgeMAC']\n } ;\n\nmsg.payload = [ \n { //device name as measurement\n measurement: \"TLM_Data\",\n tags,\n fields: _fields\n }\n ];\n \nreturn msg;","outputs":1,"noerr":0,"x":870,"y":160,"wires":[["8acb47f4.5155d8"]]},{"id":"4b425dc7.05fe24","type":"switch","z":"e184de2d.f9883","name":"","property":"payload.f","propertyType":"msg","rules":[{"t":"eq","v":"0","vt":"str"},{"t":"eq","v":"1","vt":"str"},{"t":"eq","v":"3","vt":"str"},{"t":"eq","v":"5","vt":"str"}],"checkall":"true","repair":false,"outputs":4,"x":505,"y":156,"wires":[["4672a641.6e33b8"],["42b4cd3a.5b1b64"],["c37f1e0d.fe8bf"],["c37f1e0d.fe8bf"]]},{"id":"953817ff.3a4d08","type":"json","z":"e184de2d.f9883","name":"","property":"payload","action":"","pretty":false,"x":335,"y":156,"wires":[["4b425dc7.05fe24"]]},{"id":"42b4cd3a.5b1b64","type":"json","z":"e184de2d.f9883","name":"","property":"payload","action":"","pretty":false,"x":710,"y":160,"wires":[["211dbd92.7c49e2"]]},{"id":"fe884652.0b6638","type":"function","z":"e184de2d.f9883","name":"Ruuvi","func":"var tokens = msg.topic.split(\"/\");\nmsg.topic =tokens[3]; //get device name from topic level 3 /v1.6/devices/tokens[3]\nvar dest = tokens[tokens.length-1];\ninputjson =JSON.parse(msg.payload);\nvar _fields = {};\nfor(var item in inputjson){\n if (item.includes('Data') || item.includes(\"ts\")){}\n else\n {\n _fields[item] = inputjson[item];}\n}\n\nvar tags = {\n Mac: inputjson['Mac'],\n edgeMAC: inputjson['edgeMAC']\n } ;\n\nmsg.payload = [ \n {\n measurement: \"Ruuvi_Data\" ,\n tags, //device name as measurement\n fields: _fields\n },\n ];\n \nreturn msg;","outputs":1,"noerr":0,"x":875,"y":196,"wires":[["955726d0.7886b8"]]},{"id":"c37f1e0d.fe8bf","type":"json","z":"e184de2d.f9883","name":"","property":"payload","action":"","pretty":false,"x":715,"y":196,"wires":[["fe884652.0b6638"]]},{"id":"14d5955a.a27f1b","type":"mqtt in","z":"e184de2d.f9883","name":"","topic":"home/+/beacon/#","qos":"0","datatype":"auto","broker":"20502e04.4f7d22","x":125,"y":156,"wires":[["24bbe690.ee84fa","953817ff.3a4d08"]]},{"id":"24bbe690.ee84fa","type":"debug","z":"e184de2d.f9883","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":150,"y":200,"wires":[]},{"id":"429320e6.b803","type":"comment","z":"e184de2d.f9883","name":"MQTT2Influx","info":"","x":125,"y":56,"wires":[]},{"id":"4672a641.6e33b8","type":"json","z":"e184de2d.f9883","name":"","property":"payload","action":"","pretty":false,"x":705,"y":116,"wires":[["911eb92c.6d5d18"]]},{"id":"911eb92c.6d5d18","type":"function","z":"e184de2d.f9883","name":"Unknown","func":"var tokens = msg.topic.split(\"/\");\nmsg.topic =tokens[3]; //get device name from topic level 3 /v1.6/devices/tokens[3]\nvar dest = tokens[tokens.length-1];\ninputjson =JSON.parse(msg.payload);\nvar _fields = {};\nfor(var item in inputjson){\n if (item.includes('Data') || item.includes(\"ts\")){}\n else\n {\n _fields[item] = inputjson[item];}\n}\n\nvar tags = {\n Mac: inputjson['Mac'],\n esgeMAC: inputjson['edgeMAC']\n } ;\n\nmsg.payload = [ \n { //device name as measurement\n measurement: \"Unknown_Beacon\",\n tags,\n fields: _fields\n }\n ];\n \nreturn msg;","outputs":1,"noerr":0,"x":875,"y":116,"wires":[["709f3350.75f02c"]]},{"id":"955726d0.7886b8","type":"influxdb batch","z":"e184de2d.f9883","influxdb":"c598a3ff.40fa6","precision":"","retentionPolicy":"","name":"","x":1005,"y":196,"wires":[]},{"id":"8acb47f4.5155d8","type":"influxdb batch","z":"e184de2d.f9883","influxdb":"52d8d338.02671c","precision":"","retentionPolicy":"","name":"TLM","x":1025,"y":156,"wires":[]},{"id":"709f3350.75f02c","type":"influxdb batch","z":"e184de2d.f9883","influxdb":"6e88ee26.41e24","precision":"","retentionPolicy":"","name":"","x":1105,"y":96,"wires":[]},{"id":"3369677a.74aeb8","type":"tab","label":"Pycom Board Health","disabled":false,"info":""},{"id":"d5f9617.9a83aa","type":"mqtt in","z":"3369677a.74aeb8","name":"","topic":"home/240AC4024A6C/beacon/device/heartbeat","qos":"0","datatype":"auto","broker":"20502e04.4f7d22","x":300,"y":140,"wires":[["838beac4.749028"]]},{"id":"159c5a5b.88b086","type":"mqtt in","z":"3369677a.74aeb8","name":"","topic":"home/240AC400DE4C/beacon/device/heartbeat","qos":"0","datatype":"auto","broker":"20502e04.4f7d22","x":302,"y":108,"wires":[["838beac4.749028"]]},{"id":"57bb169f.99f248","type":"mqtt in","z":"3369677a.74aeb8","name":"","topic":"home/3C71BF877D24/beacon/device/heartbeat","qos":"0","datatype":"auto","broker":"20502e04.4f7d22","x":301,"y":223,"wires":[[]]},{"id":"efa28f5b.1c22a","type":"comment","z":"3369677a.74aeb8","name":"SiPy's","info":"","x":160,"y":79,"wires":[]},{"id":"fd6e9c8a.f1445","type":"function","z":"3369677a.74aeb8","name":"","func":"var tokens = msg.topic.split(\"/\");\nmsg.topic =tokens[3]; //get device name from topic level 3 /v1.6/devices/tokens[3]\nvar dest = tokens[tokens.length-1];\ninputjson =JSON.parse(msg.payload);\nvar _fields = {};\nfor(var item in inputjson){\n if (item.includes('Data') || item.includes(\"ts\")){}\n else\n {\n _fields[item] = inputjson[item];}\n}\n\nvar tags = {\n edgeMac: inputjson['edgeMAC'],\n boardType: inputjson['board']\n } ;\n\nmsg.payload = [ \n {\n measurement: \"PycomHealth\",\n tags, //device name as measurement\n fields: _fields\n },\n ];\n \nreturn msg;","outputs":1,"noerr":0,"x":670,"y":340,"wires":[["29862159.36d95e"]]},{"id":"78d8d0d4.b0bbe","type":"mqtt in","z":"3369677a.74aeb8","name":"","topic":"home/3C71BF877D48/beacon/device/heartbeat","qos":"0","datatype":"auto","broker":"20502e04.4f7d22","x":299,"y":256,"wires":[[]]},{"id":"376672cd.39f14e","type":"comment","z":"3369677a.74aeb8","name":"WiPy's","info":"","x":158,"y":194,"wires":[]},{"id":"6959ecf0.0a0614","type":"debug","z":"3369677a.74aeb8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":690,"y":260,"wires":[]},{"id":"838beac4.749028","type":"debug","z":"3369677a.74aeb8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":630,"y":100,"wires":[]},{"id":"9590589.0e58ea8","type":"mqtt in","z":"3369677a.74aeb8","name":"","topic":"home/+/beacon/device/heartbeat","qos":"0","datatype":"auto","broker":"20502e04.4f7d22","x":260,"y":340,"wires":[["6959ecf0.0a0614","fd6e9c8a.f1445"]]},{"id":"29862159.36d95e","type":"influxdb batch","z":"3369677a.74aeb8","influxdb":"140e195f.cd0b67","precision":"","retentionPolicy":"","name":"","x":840,"y":340,"wires":[]},{"id":"20502e04.4f7d22","type":"mqtt-broker","z":"","name":"Pi","broker":"192.168.69.2","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"c598a3ff.40fa6","type":"influxdb","z":"","hostname":"192.168.69.4","port":"8086","protocol":"http","database":"Ruuvi","name":"Ruuvi","usetls":false,"tls":"c01d971f.348e88"},{"id":"52d8d338.02671c","type":"influxdb","z":"","hostname":"192.168.69.4","port":"8086","protocol":"http","database":"TLM","name":"","usetls":false,"tls":"c01d971f.348e88"},{"id":"6e88ee26.41e24","type":"influxdb","z":"","hostname":"192.168.69.4","port":"8086","protocol":"http","database":"unknownBeacons","name":"UnknownBeacons","usetls":false,"tls":"c01d971f.348e88"},{"id":"140e195f.cd0b67","type":"influxdb","z":"","hostname":"192.168.69.4","port":"8086","protocol":"http","database":"Pycom","name":"Pycom","usetls":false,"tls":"c01d971f.348e88"},{"id":"c01d971f.348e88","type":"tls-config","z":"","name":"local-tls","cert":"","key":"","ca":"","certname":"","keyname":"","caname":"","verifyservercert":false}]
Before importing the dashboard the databases need to be added as a datasource. Instruction: https://grafana.com/docs/features/datasources/influxdb/
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"id": 3,
"links": [],
"panels": [
{
"cacheTimeout": null,
"datasource": "Pycom",
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 0
},
"id": 2,
"links": [],
"options": {
"displayMode": "basic",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"mappings": [],
"max": 250000,
"min": 0,
"thresholds": [
{
"color": "green",
"value": null
},
{
"color": "#EAB839",
"value": 23000
},
{
"color": "red",
"value": 25000
}
],
"unit": "bytes"
},
"override": {},
"values": false
},
"orientation": "vertical"
},
"pluginVersion": "6.3.6",
"targets": [
{
"alias": "MAC: $tag_edgeMac",
"groupBy": [
{
"params": [
"$__interval"
],
"type": "time"
},
{
"params": [
"edgeMac"
],
"type": "tag"
},
{
"params": [
"linear"
],
"type": "fill"
}
],
"measurement": "PycomHealth",
"orderByTime": "ASC",
"policy": "default",
"refId": "A",
"resultFormat": "time_series",
"select": [
[
{
"params": [
"memFree"
],
"type": "field"
},
{
"params": [],
"type": "mean"
}
]
],
"tags": []
}
],
"timeFrom": null,
"timeShift": null,
"title": "Mem Free",
"type": "bargauge"
},
{
"cacheTimeout": null,
"datasource": "Pycom",
"gridPos": {
"h": 9,
"w": 12,
"x": 12,
"y": 0
},
"id": 3,
"links": [],
"options": {
"displayMode": "basic",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"mappings": [],
"max": 2419200,
"min": 0,
"thresholds": [
{
"color": "dark-orange",
"value": null
},
{
"color": "light-orange",
"value": 302400
},
{
"color": "super-light-green",
"value": 604800
},
{
"color": "light-green",
"value": 1209600
},
{
"color": "semi-dark-green",
"value": 1814400
},
{
"color": "dark-green",
"value": 2419200
}
],
"unit": "s"
},
"override": {},
"values": false
},
"orientation": "vertical"
},
"pluginVersion": "6.3.6",
"targets": [
{
"alias": "Mac: $tag_edgeMac",
"groupBy": [
{
"params": [
"$__interval"
],
"type": "time"
},
{
"params": [
"edgeMac"
],
"type": "tag"
},
{
"params": [
"linear"
],
"type": "fill"
}
],
"measurement": "PycomHealth",
"orderByTime": "ASC",
"policy": "default",
"refId": "A",
"resultFormat": "time_series",
"select": [
[
{
"params": [
"uptime"
],
"type": "field"
},
{
"params": [],
"type": "mean"
}
]
],
"tags": []
}
],
"timeFrom": null,
"timeShift": null,
"title": "Uptime",
"type": "bargauge"
},
{
"aliasColors": {},
"bars": false,
"cacheTimeout": null,
"dashLength": 10,
"dashes": false,
"datasource": "Pycom",
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 9
},
"id": 4,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pluginVersion": "6.3.6",
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "MAC: $tag_edgeMac",
"groupBy": [
{
"params": [
"$__interval"
],
"type": "time"
},
{
"params": [
"edgeMac"
],
"type": "tag"
},
{
"params": [
"linear"
],
"type": "fill"
}
],
"measurement": "PycomHealth",
"orderByTime": "ASC",
"policy": "default",
"refId": "A",
"resultFormat": "time_series",
"select": [
[
{
"params": [
"memFree"
],
"type": "field"
},
{
"params": [],
"type": "mean"
}
]
],
"tags": []
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Mem Free",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
"bars": false,
"cacheTimeout": null,
"dashLength": 10,
"dashes": false,
"datasource": "Pycom",
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 9,
"w": 12,
"x": 12,
"y": 9
},
"id": 5,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pluginVersion": "6.3.6",
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "Mac: $tag_edgeMac",
"groupBy": [
{
"params": [
"$__interval"
],
"type": "time"
},
{
"params": [
"edgeMac"
],
"type": "tag"
},
{
"params": [
"null"
],
"type": "fill"
}
],
"measurement": "PycomHealth",
"orderByTime": "ASC",
"policy": "default",
"refId": "A",
"resultFormat": "time_series",
"select": [
[
{
"params": [
"uptime"
],
"type": "field"
},
{
"params": [],
"type": "mean"
}
]
],
"tags": []
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Uptime",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
}
],
"schemaVersion": 19,
"style": "dark",
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
]
},
"timezone": "",
"title": "Pycom Boards",
"uid": "4IvnakhWk",
"version": 9
}
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"id": 1,
"links": [],
"panels": [
{
"datasource": "Ruuvi",
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 0
},
"id": 2,
"options": {
"displayMode": "gradient",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"decimals": 2,
"mappings": [],
"max": 60,
"min": 0,
"thresholds": [
{
"color": "blue",
"value": null
},
{
"color": "green",
"value": 17.5
},
{
"color": "yellow",
"value": 35
},
{
"color": "red",
"value": 45
}
],
"unit": "celsius"
},
"override": {},
"values": false
},
"orientation": "vertical"
},
"pluginVersion": "6.3.6",
"targets": [
{
"alias": "Mac: $tag_Mac",
"groupBy": [
{
"params": [
"$__interval"
],
"type": "time"
},
{
"params": [
"Mac"
],
"type": "tag"
},
{
"params": [
"null"
],
"type": "fill"
}
],
"measurement": "Ruuvi_Data",
"orderByTime": "ASC",
"policy": "autogen",
"refId": "A",
"resultFormat": "time_series",
"select": [
[
{
"params": [
"temp"
],
"type": "field"
},
{
"params": [],
"type": "mean"
}
]
],
"tags": [
{
"key": "Mac",
"operator": "!=",
"value": "0117C53953DD"
}
]
}
],
"timeFrom": null,
"timeShift": null,
"title": "Ruuvi Temp",
"transparent": true,
"type": "bargauge"
},
{
"datasource": "Ruuvi",
"gridPos": {
"h": 9,
"w": 12,
"x": 12,
"y": 0
},
"id": 6,
"options": {
"displayMode": "gradient",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"decimals": 2,
"mappings": [],
"max": 4,
"min": 0,
"thresholds": [
{
"color": "red",
"value": null
},
{
"color": "green",
"value": 1.8
}
],
"unit": "mvolt"
},
"override": {},
"values": false
},
"orientation": "vertical"
},
"pluginVersion": "6.3.6",
"targets": [
{
"alias": "Mac: $tag_Mac",
"groupBy": [
{
"params": [
"$__interval"
],
"type": "time"
},
{
"params": [
"Mac"
],
"type": "tag"
},
{
"params": [
"null"
],
"type": "fill"
}
],
"measurement": "Ruuvi_Data",
"orderByTime": "ASC",
"policy": "autogen",
"refId": "A",
"resultFormat": "time_series",
"select": [
[
{
"params": [
"battery"
],
"type": "field"
},
{
"params": [],
"type": "mean"
}
]
],
"tags": [
{
"key": "Mac",
"operator": "!=",
"value": "0117C53953DD"
}
]
}
],
"timeFrom": null,
"timeShift": null,
"title": "Ruuvi Battery",
"transparent": true,
"type": "bargauge"
},
{
"datasource": "Ruuvi",
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 9
},
"id": 3,
"options": {
"displayMode": "gradient",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "red",
"value": null
},
{
"color": "#EF843C",
"value": 20
},
{
"color": "#EAB839",
"value": 40
},
{
"color": "light-green",
"value": 60
},
{
"color": "dark-green",
"value": 70
},
{
"color": "light-blue",
"value": 80
},
{
"color": "dark-blue",
"value": 100
}
],
"unit": "humidity"
},
"override": {},
"values": false
},
"orientation": "vertical"
},
"pluginVersion": "6.3.6",
"targets": [
{
"alias": "Mac: $tag_Mac",
"groupBy": [
{
"params": [
"$__interval"
],
"type": "time"
},
{
"params": [
"Mac"
],
"type": "tag"
},
{
"params": [
"null"
],
"type": "fill"
}
],
"measurement": "Ruuvi_Data",
"orderByTime": "ASC",
"policy": "autogen",
"refId": "A",
"resultFormat": "time_series",
"select": [
[
{
"params": [
"humidity"
],
"type": "field"
},
{
"params": [],
"type": "mean"
}
]
],
"tags": [
{
"key": "Mac",
"operator": "!=",
"value": "0117C53953DD"
}
]
}
],
"timeFrom": null,
"timeShift": null,
"title": "Ruuvi Humidity",
"transparent": true,
"type": "bargauge"
},
{
"datasource": "Ruuvi",
"gridPos": {
"h": 9,
"w": 12,
"x": 12,
"y": 9
},
"id": 4,
"options": {
"displayMode": "gradient",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"decimals": 2,
"mappings": [],
"max": 1100,
"min": 800,
"thresholds": [
{
"color": "green",
"value": null
},
{
"color": "#E24D42",
"value": 275
},
{
"color": "#1F78C1",
"value": 412.5
},
{
"color": "#EAB839",
"value": 550
},
{
"color": "#BA43A9",
"value": 687.5
},
{
"color": "#6ED0E0",
"value": 825
},
{
"color": "#EF843C",
"value": 962.5
},
{
"color": "red",
"value": 1100
}
],
"unit": "pressurehpa"
},
"override": {},
"values": false
},
"orientation": "vertical"
},
"pluginVersion": "6.3.6",
"targets": [
{
"alias": "Mac: $tag_Mac",
"groupBy": [
{
"params": [
"$__interval"
],
"type": "time"
},
{
"params": [
"Mac"
],
"type": "tag"
},
{
"params": [
"null"
],
"type": "fill"
}
],
"measurement": "Ruuvi_Data",
"orderByTime": "ASC",
"policy": "autogen",
"refId": "A",
"resultFormat": "time_series",
"select": [
[
{
"params": [
"pressure"
],
"type": "field"
},
{
"params": [],
"type": "mean"
}
]
],
"tags": [
{
"key": "Mac",
"operator": "!=",
"value": "0117C53953DD"
}
]
}
],
"timeFrom": null,
"timeShift": null,
"title": "Ruuvi Pressure",
"transparent": true,
"type": "bargauge"
},
{
"aliasColors": {},
"bars": false,
"cacheTimeout": null,
"dashLength": 10,
"dashes": false,
"datasource": "Ruuvi",
"fill": 0,
"fillGradient": 0,
"gridPos": {
"h": 11,
"w": 24,
"x": 0,
"y": 18
},
"id": 5,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pluginVersion": "6.3.6",
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "Mac: $tag_Mac",
"groupBy": [
{
"params": [
"$__interval"
],
"type": "time"
},
{
"params": [
"Mac"
],
"type": "tag"
},
{
"params": [
"linear"
],
"type": "fill"
}
],
"measurement": "Ruuvi_Data",
"orderByTime": "ASC",
"policy": "autogen",
"refId": "A",
"resultFormat": "time_series",
"select": [
[
{
"params": [
"tAcc"
],
"type": "field"
},
{
"params": [],
"type": "mean"
}
]
],
"tags": []
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Ruuvi Total Acceleration",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"transparent": true,
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
"bars": false,
"cacheTimeout": null,
"dashLength": 10,
"dashes": false,
"datasource": "Ruuvi",
"fill": 0,
"fillGradient": 0,
"gridPos": {
"h": 11,
"w": 24,
"x": 0,
"y": 29
},
"id": 7,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pluginVersion": "6.3.6",
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "Mac: $tag_Mac",
"groupBy": [
{
"params": [
"$__interval"
],
"type": "time"
},
{
"params": [
"Mac"
],
"type": "tag"
},
{
"params": [
"linear"
],
"type": "fill"
}
],
"measurement": "Ruuvi_Data",
"orderByTime": "ASC",
"policy": "autogen",
"refId": "A",
"resultFormat": "time_series",
"select": [
[
{
"params": [
"rssi"
],
"type": "field"
},
{
"params": [],
"type": "mean"
}
]
],
"tags": []
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Ruuvi RSSI",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"transparent": true,
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
"bars": false,
"cacheTimeout": null,
"dashLength": 10,
"dashes": false,
"datasource": "Ruuvi",
"fill": 0,
"fillGradient": 0,
"gridPos": {
"h": 11,
"w": 24,
"x": 0,
"y": 40
},
"id": 8,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pluginVersion": "6.3.6",
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "Mac: $tag_Mac",
"groupBy": [
{
"params": [
"$__interval"
],
"type": "time"
},
{
"params": [
"Mac"
],
"type": "tag"
},
{
"params": [
"linear"
],
"type": "fill"
}
],
"measurement": "Ruuvi_Data",
"orderByTime": "ASC",
"policy": "autogen",
"refId": "A",
"resultFormat": "time_series",
"select": [
[
{
"params": [
"temp"
],
"type": "field"
},
{
"params": [],
"type": "mean"
}
]
],
"tags": []
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Ruuvi Temp",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"transparent": true,
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
}
],
"refresh": "5s",
"schemaVersion": 19,
"style": "dark",
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
]
},
"timezone": "",
"title": "Ruuvi Tags",
"uid": "FfAH1zhWz",
"version": 27
}
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"id": 2,
"links": [],
"panels": [
{
"datasource": "TLM",
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 0
},
"id": 2,
"options": {
"displayMode": "gradient",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"decimals": 2,
"mappings": [],
"max": 60,
"min": -25,
"thresholds": [
{
"color": "super-light-blue",
"value": null
},
{
"color": "light-blue",
"value": 0
},
{
"color": "semi-dark-blue",
"value": 10
},
{
"color": "dark-green",
"value": 20
},
{
"color": "light-green",
"value": 30
},
{
"color": "super-light-red",
"value": 40
},
{
"color": "dark-red",
"value": 50
}
],
"unit": "celsius"
},
"override": {},
"values": false
},
"orientation": "vertical"
},
"pluginVersion": "6.3.6",
"targets": [
{
"alias": "Mac: $tag_Mac",
"groupBy": [
{
"params": [
"$__interval"
],
"type": "time"
},
{
"params": [
"Mac"
],
"type": "tag"
},
{
"params": [
"null"
],
"type": "fill"
}
],
"measurement": "TLM_Data",
"orderByTime": "ASC",
"policy": "autogen",
"refId": "A",
"resultFormat": "time_series",
"select": [
[
{
"params": [
"temp"
],
"type": "field"
},
{
"params": [],
"type": "mean"
}
]
],
"tags": []
}
],
"timeFrom": null,
"timeShift": null,
"title": "TLM Temp",
"transparent": true,
"type": "bargauge"
},
{
"datasource": "TLM",
"gridPos": {
"h": 9,
"w": 12,
"x": 12,
"y": 0
},
"id": 4,
"options": {
"displayMode": "gradient",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"decimals": 2,
"mappings": [],
"max": 4,
"min": 0,
"thresholds": [
{
"color": "red",
"value": null
},
{
"color": "green",
"value": 1.8
}
],
"unit": "mvolt"
},
"override": {},
"values": false
},
"orientation": "vertical"
},
"pluginVersion": "6.3.6",
"targets": [
{
"alias": "Mac: $tag_Mac",
"groupBy": [
{
"params": [
"$__interval"
],
"type": "time"
},
{
"params": [
"Mac"
],
"type": "tag"
},
{
"params": [
"null"
],
"type": "fill"
}
],
"measurement": "TLM_Data",
"orderByTime": "ASC",
"policy": "autogen",
"refId": "A",
"resultFormat": "time_series",
"select": [
[
{
"params": [
"battery"
],
"type": "field"
},
{
"params": [],
"type": "mean"
}
]
],
"tags": []
}
],
"timeFrom": null,
"timeShift": null,
"title": "Ruuvi Battery",
"transparent": true,
"type": "bargauge"
},
{
"aliasColors": {},
"bars": false,
"cacheTimeout": null,
"dashLength": 10,
"dashes": false,
"datasource": "TLM",
"fill": 0,
"fillGradient": 0,
"gridPos": {
"h": 11,
"w": 24,
"x": 0,
"y": 9
},
"id": 6,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pluginVersion": "6.3.6",
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "Mac: $tag_Mac",
"groupBy": [
{
"params": [
"$__interval"
],
"type": "time"
},
{
"params": [
"Mac"
],
"type": "tag"
},
{
"params": [
"linear"
],
"type": "fill"
}
],
"measurement": "TLM_Data",
"orderByTime": "ASC",
"policy": "autogen",
"refId": "A",
"resultFormat": "time_series",
"select": [
[
{
"params": [
"rssi"
],
"type": "field"
},
{
"params": [],
"type": "mean"
}
]
],
"tags": []
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Ruuvi RSSI",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"transparent": true,
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
}
],
"schemaVersion": 19,
"style": "dark",
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
]
},
"timezone": "",
"title": "TLM",
"uid": "cxcuxkhZk",
"version": 5
}
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"id": 4,
"links": [],
"panels": [
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "unknownBeacons",
"fill": 0,
"fillGradient": 0,
"gridPos": {
"h": 21,
"w": 24,
"x": 0,
"y": 0
},
"id": 2,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "MAC: $tag_Mac",
"groupBy": [
{
"params": [
"$__interval"
],
"type": "time"
},
{
"params": [
"Mac"
],
"type": "tag"
},
{
"params": [
"linear"
],
"type": "fill"
}
],
"measurement": "Unknown_Beacon",
"orderByTime": "ASC",
"policy": "autogen",
"refId": "A",
"resultFormat": "time_series",
"select": [
[
{
"params": [
"rssi"
],
"type": "field"
},
{
"params": [],
"type": "mean"
}
]
],
"tags": []
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "RSSI",
"tooltip": {
"shared": false,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
}
],
"schemaVersion": 19,
"style": "dark",
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
]
},
"timezone": "",
"title": "Unknown Tags",
"uid": "_7o1TmhWk",
"version": 3
}
I have found that the limitations of the application are towards the MQTT implementation on the board itself. With loss of connections to broker happening on occassion. Whilst there is data going through both the BLE and Heartbeat client the conenction seems to be strong however the subscribing to a topic always causes issues.
I have tried using the BLE client which is almost always TX messages to subscribe to the comms topic and issues would still occur after some time.
SSL performance is unreliable and slow