Monitor air condition with Stackdriver Monitoring and Raspberry Pi Zero

TL;DR

It’s really fun to watch data from BME680 on Stackdriver Monitoring.

Preface

One day, my colleague and I were taking a look at Pimoroni and found interesitng breakout and sensors for Raspoberry Pi Zero.

I had been thinking to have some monitoring system to track air condition at home, and I decided to create one with these gadgets and Stackdriver Monitoring.

BME680

What is BME680?

Quating from BOSCH’s website of BME680.

BME680 is an integrated environmental sensor developed specifically for mobile applications and wearables where size and low power consumption are key requirements. Expanding Bosch Sensortec’s existing family of environmental sensors, the BME680 integrates for the first time high-linearity and high-accuracy gas, pressure, humidity and temperature sensors.

BME680

Pimoroni has its breakout that enables you to read its sensor data via I2C.

Setup

As prerequisite, Raspberry Pi Zero W runs Raspbian (Stretch).

First, before getting started, I2C interface in Raspberry Pi have to be enabled.

$ sudo raspi-config

Launch raspi-config and select ‘Interfacing Option’.

Then select ‘I2C’,

And enable I2C interface.

Then install Debian packages for I2C. One thing to note is that python3-smbus is not mandatory if you can install smbus module via PyPI. Unfortunately I couldn’t install it properly via pip when I tried, so I installed it from apt repository.

$ sudo apt-get install python3-venv i2c-tools read-edid libi2c-dev python3-smbus
$ python3 -m venv --system-site-packages .venv
$ .venv/bin/pip install bme680
$ wget https://raw.githubusercontent.com/pimoroni/bme680-python/master/examples/read-all.py
$ .venv/bin/python3 read-all.py

If you see results on tty while you are running read-all.py, it’s all set! You can start

Send data to Stackdriver Monitoring

What is Stackdriver Monitoring?

Stackdriver Monitoring is a monitoring tool from Google Cloud Platform that provides visibility to all application health and performance. Stackdriver Monitoring expects its agent is running in the instance to monitor that samples system and application metrics. Especially, Stackdriver Monitoring Agent is able to work with well-known products such as databases and middlewares with pre-defined config.

Custom metrics

Not only pre-defined metrics, but you can send custom metrics. Though, of course, you can send custom metrics via Stackdriver Monitoring Agent, this time I’d like to use Stackdriver Monitoring API v3.1

As I tested if BME680 works correctly using Python 3, I chose Python 3 to implement this demonstration.

Setup dependent libraries

In addition to the libraries I installed for read-all.py, we need to install google-cloud-monitoring module from PyPI. One of the dependencies is grpcio module that is tricky part on installating google-cloud-monitoring.

As of mid March 2019, the latest version is 1.19.0, and as you see on grpcio’s “Download” page, they don’t distribute a wheel file of version 1.19.0 for “Python 3.5 (Raspbian Stretch’s default Python 3 version)” on “ARMv6 (Raspberry Pi Zero’s CPU architecture)”.

Expecting the wheel file for that combination, I checked piwheels, and still there is not.

Here you have some choices. I came up with the following options2:

  1. Specifying grpcio version 1.18.0 or less in constraints.txt3 and give --extra-index-url=https://www.piwheels.org/simple option to pip install.
  2. Building grpcio 1.19.0 on Raspberry Pi from source code with --build and --cache-dir options not to see tmpfs mounted directory.4

I wanted to check if the latest grpcio package works fine, so I picked option #2. (It took 30 minutes or so.)

$ TMPDIR=$HOME/tmp .venv/bin/pip install --cache-dir=$TMPDIR/cache --build=$TMPDIR/build google-cloud-monitoring

Interact with Stackdriver Monitoring API v3

1. Create metrics

All the following flow is documented in Stackdriver Monitoring’s official document. In order to record custom metrics, you need to register MetricDescriptor, which is metadata for metrics, in advance of sending metrics data.

The steps are:

  1. Create an client instance for Stackdriver Monitoring
  2. Create an instance of MetricDescriptor, and configure custome metrics name, metric’s type, metric’s value type, description and labels.
  3. Pass the MetricDescriptor instance to the client.

The following snippet is the part to create the custom metric temperature.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 1. Create Stackdriver Monitoring client
client = monitoring_v3.MetricServiceClient()
project_name = client.project_path(project_id)

# 2. Create `MetricDescriptor` instance and set metadata of it
descriptor = monitoring_v3.types.MetricDescriptor()
## 2.1 Metric name
descriptor.type = "custom.googleapis.com/temperature"

## 2.2 Metric type, its value type and description
descriptor.metric_kind = (
    monitoring_v3.enums.MetricDescriptor.MetricKind.GAUGE)
descriptor.value_type = (
    monitoring_v3.enums.MetricDescriptor.ValueType.DOUBLE)
descriptor.description = "room temperature"
## 2.3 labels
room_label = descriptor.labels.add()
room_label.key = "placement"
room_label.value_type = (
    monitoring_v3.enums.LabelDescriptor.ValueType.STRING)
room_label.description = "placement of the sensor in the room"

# 3. Pass `MetricDescriptor` instance to the client
descriptor = client.create_metric_descriptor(project_name, descriptor)

I added label "placement" that holds information where in the room the data are taken, looking at expanding this monitoring system to have multiple sensors in the room. In that case, you will be able to filter data using that label.

In real use case such as web application, you are looking at “response data size” metric, and you can filter data with “HTTP status code” label.

Another practical know-how is this create_metric_descriptor() method doesn’t return error when you try to create identical data or update the data. So, you can put this part at the beginning of you program and run it over again without error handling.

Items

Raspberry Pi Zero W

  • publisher/maker:Pimoroni
  • media:electronics

Breakout Garden pHAT

  • publisher/maker:Pimoroni
  • media:electronics

References

BME680

Stackdriver Monitoring V3


  1. Though OpenCensus is official recommend library to send metrics to Stackdriver Monitoring, I chose direct integration with Stackdriver Monitoring API v3 to illustrate the concepts of Stackdriver Monitoring.

    [return]
  2. There are other options such as building cp35-linux-armv6l.whl with QEMU environment and copy it to the Raspberry Pi, but I picked the smallest effort option.

    [return]
  3. google-cloud-monitoring depends on 1.8.0+ of grpcio. [return]
  4. In order to extend the life of the SD card for Raspberry Pi, it is common to create partitions with tmpfs for /tmp and /var/tmp. However, this is a trap on building Python packages locally on Raspberry Pi because its process uses temporary directory, and it causes disk full error when we use tmpfs for the directory.

    [return]