aku
Published © GPL3+

Vehicle Health Monitoring System

Vehicles are usually serviced on time basis or distance basis. Why not make this process more intelligent?

IntermediateFull instructions provided20 hours3,233
Vehicle Health Monitoring System

Things used in this project

Hardware components

Rapid IoT Prototyping Kit
NXP Rapid IoT Prototyping Kit
×1
Raspberry Pi Zero Wireless
Raspberry Pi Zero Wireless
×1

Software apps and online services

NXP rapid iot studio
grafana
influxdb

Story

Read more

Code

python code

Python
Run at startup. Make sure influxdb and rapid prototyping kit are both up and running!
import time
import os
import pygatt
import binascii
import struct
import json
from subprocess import check_output
from influxdb import InfluxDBClient
RPK_ADDRESS = "00:00:00:00:00:00" # Change this with your Device's BT Address
CHAR_UUIDS = {
  "accelX":"13eb9b68-b891-4134-b09e-e61554e9929e",
  "accelY":"d9a450ad-1421-486d-a72d-865572419ae6",
  "accelZ":"f837afa7-24bc-406b-86e7-c7a90c3704d4",
  "rotX":"7ffd87ab-d953-4342-a2f0-96f229ffddd5",
  "rotY":"846f131b-5cbd-42ee-85ad-f2d31dc97217",
  "rotZ":"8f1cee1b-86fe-4c25-a261-d0bb3a4f2368",
  "Temp":"a213c47d-a4ad-4e8f-8d97-dc479688363e",
  "Humidity":"4bece079-eb30-40ac-8361-5558eeb6b22f"  
}
CHAR_UUIDS_2 = {
  "tvoc":"feb23eee-fa4f-4e87-aaaf-85a2dac44f29",
  "co2":"e5eb79f4-0bc4-4207-9f2d-b1e00ed95ab4"
  }
def save_prk_values():
  """ Saves BLE sensor values, got using BLE-GATT, to an InfluxDB database """
  adapter = pygatt.GATTToolBackend()
  db_client = InfluxDBClient('000.000.0.00', database="rpk")#IP of the desktop-pc
  try:
      # Connect to the RPK device
      adapter.start()
      conn = adapter.connect(RPK_ADDRESS)
      while(1):
         print("start")
         time_info = int(time.time()*1000000000.0)
         # Get sensor values
         sensor_values = {}
         for sensor in CHAR_UUIDS:
             value = conn.char_read(CHAR_UUIDS[sensor])
             print(sensor)
             [value] = struct.unpack('<f',value)
             print(value)
             sensor_values[sensor] = value
         # Save to DB
         for sensor in CHAR_UUIDS_2:
             value = conn.char_read(CHAR_UUIDS_2[sensor])
             print(sensor)
             value = int.from_bytes(value,byteorder='little')
             print(value)
             sensor_values[sensor] = value
         measurements = []
         for sensor in sensor_values:
             measurement = {"measurement" : sensor, "time" : time_info, "fields" : {"value" : sensor_values[sensor]}}
             measurements.append(measurement)
         wifi_ip = check_output(['hostname', '-I'])
         if wifi_ip.decode() == '000.000.0.00 \n': #IP of rpi 
            try:
               with open('foo.txt') as f:
                 lines = f.readlines()
                 lines= [x.strip() for x in lines]
                 for line in lines:
                    print(line)
                    contents = json.loads(line)
                    db_client.write_points(contents)
               os.remove("foo.txt")
            except Exception as e:
               print ("Error: ", e)
            db_client.write_points(measurements)
         else:
            fo = open("foo.txt", "a")
            json.dump(measurements, fo)
            fo.write('\n')
            fo.close()
         time.sleep(0.1)
         print("end")
  except Exception as e:
      print ("Error: ", e)
      msg = "BLE: [%d] %s"%(time_info, e)
  finally:
      adapter.stop()
if __name__ == '__main__':
  save_prk_values()

grafana dashboard

JSON
JSON model of grafana dashboard
{
  "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": [
    {
      "aliasColors": {},
      "bars": true,
      "dashLength": 10,
      "dashes": false,
      "fill": 1,
      "gridPos": {
        "h": 5,
        "w": 9,
        "x": 0,
        "y": 0
      },
      "id": 26,
      "legend": {
        "alignAsTable": true,
        "avg": true,
        "current": true,
        "max": true,
        "min": true,
        "show": true,
        "total": false,
        "values": true
      },
      "lines": true,
      "linewidth": 1,
      "links": [],
      "nullPointMode": "null",
      "paceLength": 10,
      "percentage": false,
      "pointradius": 2,
      "points": false,
      "renderer": "flot",
      "seriesOverrides": [],
      "stack": false,
      "steppedLine": false,
      "targets": [
        {
          "groupBy": [
            {
              "params": [
                "$__interval"
              ],
              "type": "time"
            },
            {
              "params": [
                "null"
              ],
              "type": "fill"
            }
          ],
          "measurement": "accelZ",
          "orderByTime": "ASC",
          "policy": "default",
          "refId": "A",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": [
                  "value"
                ],
                "type": "field"
              },
              {
                "params": [],
                "type": "integral"
              }
            ]
          ],
          "tags": []
        }
      ],
      "thresholds": [],
      "timeFrom": null,
      "timeRegions": [],
      "timeShift": null,
      "title": "Velocity Z",
      "tooltip": {
        "shared": true,
        "sort": 0,
        "value_type": "individual"
      },
      "type": "graph",
      "xaxis": {
        "buckets": null,
        "mode": "time",
        "name": null,
        "show": true,
        "values": []
      },
      "yaxes": [
        {
          "format": "velocityms",
          "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,
      "decimals": null,
      "fill": 1,
      "gridPos": {
        "h": 5,
        "w": 9,
        "x": 9,
        "y": 0
      },
      "id": 10,
      "legend": {
        "alignAsTable": true,
        "avg": true,
        "current": true,
        "max": true,
        "min": true,
        "show": true,
        "total": false,
        "values": true
      },
      "lines": true,
      "linewidth": 1,
      "links": [],
      "nullPointMode": "null",
      "paceLength": 10,
      "percentage": false,
      "pointradius": 2,
      "points": false,
      "renderer": "flot",
      "seriesOverrides": [],
      "stack": false,
      "steppedLine": false,
      "targets": [
        {
          "groupBy": [
            {
              "params": [
                "$__interval"
              ],
              "type": "time"
            },
            {
              "params": [
                "null"
              ],
              "type": "fill"
            }
          ],
          "measurement": "accelX",
          "orderByTime": "ASC",
          "policy": "default",
          "refId": "A",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": [
                  "value"
                ],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              }
            ]
          ],
          "tags": []
        }
      ],
      "thresholds": [],
      "timeFrom": null,
      "timeRegions": [],
      "timeShift": null,
      "title": "AccelX",
      "tooltip": {
        "shared": true,
        "sort": 0,
        "value_type": "individual"
      },
      "type": "graph",
      "xaxis": {
        "buckets": null,
        "mode": "time",
        "name": null,
        "show": true,
        "values": []
      },
      "yaxes": [
        {
          "format": "accMS2",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        },
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": false
        }
      ],
      "yaxis": {
        "align": false,
        "alignLevel": null
      }
    },
    {
      "gridPos": {
        "h": 5,
        "w": 4,
        "x": 18,
        "y": 0
      },
      "id": 28,
      "links": [],
      "options": {
        "maxValue": "1000",
        "minValue": 0,
        "showThresholdLabels": false,
        "showThresholdMarkers": true,
        "thresholds": [
          {
            "color": "#7EB26D",
            "index": 0,
            "value": null
          },
          {
            "color": "#6ED0E0",
            "index": 1,
            "value": 250
          },
          {
            "color": "#E24D42",
            "index": 3,
            "value": 750
          },
          {
            "color": "#EF843C",
            "index": 2,
            "value": 500
          }
        ],
        "valueMappings": [],
        "valueOptions": {
          "decimals": null,
          "prefix": "",
          "stat": "avg",
          "suffix": "",
          "unit": "ppm"
        }
      },
      "targets": [
        {
          "groupBy": [
            {
              "params": [
                "1s"
              ],
              "type": "time"
            },
            {
              "params": [
                "null"
              ],
              "type": "fill"
            }
          ],
          "measurement": "co2",
          "orderByTime": "ASC",
          "policy": "default",
          "refId": "A",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": [
                  "value"
                ],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              }
            ]
          ],
          "tags": []
        }
      ],
      "timeFrom": null,
      "timeShift": null,
      "title": "CO2",
      "type": "gauge"
    },
    {
      "aliasColors": {},
      "bars": true,
      "dashLength": 10,
      "dashes": false,
      "fill": 1,
      "gridPos": {
        "h": 5,
        "w": 9,
        "x": 0,
        "y": 5
      },
      "id": 24,
      "legend": {
        "alignAsTable": true,
        "avg": true,
        "current": true,
        "max": true,
        "min": true,
        "show": true,
        "total": false,
        "values": true
      },
      "lines": true,
      "linewidth": 1,
      "links": [],
      "nullPointMode": "null",
      "paceLength": 10,
      "percentage": false,
      "pointradius": 2,
      "points": false,
      "renderer": "flot",
      "seriesOverrides": [],
      "stack": false,
      "steppedLine": false,
      "targets": [
        {
          "groupBy": [
            {
              "params": [
                "$__interval"
              ],
              "type": "time"
            },
            {
              "params": [
                "null"
              ],
              "type": "fill"
            }
          ],
          "measurement": "accelY",
          "orderByTime": "ASC",
          "policy": "default",
          "refId": "A",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": [
                  "value"
                ],
                "type": "field"
              },
              {
                "params": [],
                "type": "integral"
              }
            ]
          ],
          "tags": []
        }
      ],
      "thresholds": [],
      "timeFrom": null,
      "timeRegions": [],
      "timeShift": null,
      "title": "Velocity Y",
      "tooltip": {
        "shared": true,
        "sort": 0,
        "value_type": "individual"
      },
      "type": "graph",
      "xaxis": {
        "buckets": null,
        "mode": "time",
        "name": null,
        "show": true,
        "values": []
      },
      "yaxes": [
        {
          "format": "velocityms",
          "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,
      "dashLength": 10,
      "dashes": false,
      "fill": 1,
      "gridPos": {
        "h": 5,
        "w": 9,
        "x": 9,
        "y": 5
      },
      "id": 12,
      "legend": {
        "alignAsTable": true,
        "avg": true,
        "current": false,
        "max": true,
        "min": true,
        "show": true,
        "total": false,
        "values": true
      },
      "lines": true,
      "linewidth": 1,
      "links": [],
      "nullPointMode": "null",
      "paceLength": 10,
      "percentage": false,
      "pointradius": 2,
      "points": false,
      "renderer": "flot",
      "seriesOverrides": [],
      "stack": false,
      "steppedLine": false,
      "targets": [
        {
          "groupBy": [
            {
              "params": [
                "$__interval"
              ],
              "type": "time"
            },
            {
              "params": [
                "null"
              ],
              "type": "fill"
            }
          ],
          "measurement": "accelY",
          "orderByTime": "ASC",
          "policy": "default",
          "refId": "A",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": [
                  "value"
                ],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              }
            ]
          ],
          "tags": []
        }
      ],
      "thresholds": [],
      "timeFrom": null,
      "timeRegions": [],
      "timeShift": null,
      "title": "AccelY",
      "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": false
        }
      ],
      "yaxis": {
        "align": false,
        "alignLevel": null
      }
    },
    {
      "gridPos": {
        "h": 5,
        "w": 4,
        "x": 18,
        "y": 5
      },
      "id": 30,
      "links": [],
      "options": {
        "maxValue": 100,
        "minValue": 0,
        "showThresholdLabels": false,
        "showThresholdMarkers": true,
        "thresholds": [
          {
            "color": "#7EB26D",
            "index": 0,
            "value": null
          },
          {
            "color": "#6ED0E0",
            "index": 1,
            "value": 50
          },
          {
            "color": "#EF843C",
            "index": 2,
            "value": 75
          },
          {
            "color": "#E24D42",
            "index": 3,
            "value": 87.5
          }
        ],
        "valueMappings": [],
        "valueOptions": {
          "decimals": null,
          "prefix": "",
          "stat": "avg",
          "suffix": "",
          "unit": "humidity"
        }
      },
      "targets": [
        {
          "groupBy": [
            {
              "params": [
                "1s"
              ],
              "type": "time"
            },
            {
              "params": [
                "null"
              ],
              "type": "fill"
            }
          ],
          "measurement": "Humidity",
          "orderByTime": "ASC",
          "policy": "default",
          "refId": "A",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": [
                  "value"
                ],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              }
            ]
          ],
          "tags": []
        }
      ],
      "timeFrom": null,
      "timeShift": null,
      "title": "Humidity",
      "type": "gauge"
    },
    {
      "aliasColors": {},
      "bars": true,
      "dashLength": 10,
      "dashes": false,
      "fill": 1,
      "gridPos": {
        "h": 5,
        "w": 9,
        "x": 0,
        "y": 10
      },
      "id": 22,
      "legend": {
        "alignAsTable": true,
        "avg": true,
        "current": true,
        "max": true,
        "min": true,
        "show": true,
        "total": false,
        "values": true
      },
      "lines": true,
      "linewidth": 1,
      "links": [],
      "nullPointMode": "null",
      "paceLength": 10,
      "percentage": false,
      "pointradius": 2,
      "points": false,
      "renderer": "flot",
      "seriesOverrides": [],
      "stack": false,
      "steppedLine": false,
      "targets": [
        {
          "groupBy": [
            {
              "params": [
                "$__interval"
              ],
              "type": "time"
            },
            {
              "params": [
                "null"
              ],
              "type": "fill"
            }
          ],
          "measurement": "accelX",
          "orderByTime": "ASC",
          "policy": "default",
          "refId": "A",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": [
                  "value"
                ],
                "type": "field"
              },
              {
                "params": [],
                "type": "integral"
              }
            ]
          ],
          "tags": []
        }
      ],
      "thresholds": [],
      "timeFrom": null,
      "timeRegions": [],
      "timeShift": null,
      "title": "Velocity X",
      "tooltip": {
        "shared": true,
        "sort": 0,
        "value_type": "individual"
      },
      "type": "graph",
      "xaxis": {
        "buckets": null,
        "mode": "time",
        "name": null,
        "show": true,
        "values": []
      },
      "yaxes": [
        {
          "format": "velocityms",
          "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,
      "dashLength": 10,
      "dashes": false,
      "fill": 1,
      "gridPos": {
        "h": 5,
        "w": 9,
        "x": 9,
        "y": 10
      },
      "id": 14,
      "legend": {
        "alignAsTable": true,
        "avg": true,
        "current": false,
        "max": true,
        "min": true,
        "show": true,
        "total": false,
        "values": true
      },
      "lines": true,
      "linewidth": 1,
      "links": [],
      "nullPointMode": "null",
      "paceLength": 10,
      "percentage": false,
      "pointradius": 2,
      "points": false,
      "renderer": "flot",
      "seriesOverrides": [],
      "stack": false,
      "steppedLine": false,
      "targets": [
        {
          "groupBy": [
            {
              "params": [
                "$__interval"
              ],
              "type": "time"
            },
            {
              "params": [
                "null"
              ],
              "type": "fill"
            }
          ],
          "measurement": "accelZ",
          "orderByTime": "ASC",
          "policy": "default",
          "refId": "A",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": [
                  "value"
                ],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              }
            ]
          ],
          "tags": []
        }
      ],
      "thresholds": [],
      "timeFrom": null,
      "timeRegions": [],
      "timeShift": null,
      "title": "AccelZ",
      "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": false
        }
      ],
      "yaxis": {
        "align": false,
        "alignLevel": null
      }
    },
    {
      "gridPos": {
        "h": 5,
        "w": 4,
        "x": 18,
        "y": 10
      },
      "id": 8,
      "links": [],
      "options": {
        "maxValue": 100,
        "minValue": 0,
        "showThresholdLabels": false,
        "showThresholdMarkers": true,
        "thresholds": [
          {
            "color": "#7EB26D",
            "index": 0,
            "value": null
          },
          {
            "color": "#6ED0E0",
            "index": 1,
            "value": 50
          },
          {
            "color": "#EF843C",
            "index": 2,
            "value": 75
          },
          {
            "color": "#E24D42",
            "index": 3,
            "value": 87.5
          }
        ],
        "valueMappings": [],
        "valueOptions": {
          "decimals": null,
          "prefix": "",
          "stat": "avg",
          "suffix": "",
          "unit": "ppm"
        }
      },
      "targets": [
        {
          "groupBy": [
            {
              "params": [
                "1s"
              ],
              "type": "time"
            },
            {
              "params": [
                "null"
              ],
              "type": "fill"
            }
          ],
          "measurement": "tvoc",
          "orderByTime": "ASC",
          "policy": "default",
          "refId": "A",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": [
                  "value"
                ],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              }
            ]
          ],
          "tags": []
        }
      ],
      "timeFrom": null,
      "timeShift": null,
      "title": "tvoc",
      "type": "gauge"
    },
    {
      "cacheTimeout": null,
      "cards": {
        "cardPadding": null,
        "cardRound": null
      },
      "color": {
        "cardColor": "#b4ff00",
        "colorScale": "sqrt",
        "colorScheme": "interpolateOranges",
        "exponent": 0.5,
        "min": null,
        "mode": "spectrum"
      },
      "dataFormat": "timeseries",
      "description": "",
      "gridPos": {
        "h": 6,
        "w": 22,
        "x": 0,
        "y": 15
      },
      "heatmap": {},
      "highlightCards": true,
      "id": 4,
      "legend": {
        "show": false
      },
      "links": [],
      "targets": [
...

This file has been truncated, please download it to see its full contents.

firmware.bin

C/C++
Binary to be dumped into Rapid prototyping kit
No preview (download only).

Credits

aku

aku

1 project • 3 followers
Thanks to Ben.

Comments