Raspberry Pi Weather Station

Well it’s been a little over two week and the Raspberry Pi 3 Model B weather station has held up; figured now would be a good time to go a little deeper into the setup.

Telegraf has been solid in ingesting my JSON documents periodically, lets have a look at it’s SensorTag configuration:

# cat /etc/telegraf/telegraf.d/sensor_tag.conf
 command = "cat /sensor_tag.json"
 data_format = "json"
 name_suffix = "_sensor_tag"
 interval = "60s"

This telegraf configuration inserts the output of /sensor_tag.json every 60 seconds into InfluxDB.

In order to keep the JSON document up to date I have cron executing a python script every 60 seconds:

# crontab -l | grep sensor
* * * * * /root/sensor_tag.py A0:??:??:??:??:??

sensor_tag.py is a slightly modified version of my SensorTag code on Github.

Grafana 5.x Running on Raspberry Pi

Got around to upgrading my Raspberry Pi 3 Model B weather station with a newer version of Grafana, the Debian packages for ARM are hosted on Grafana’s download page under ARMv7.

Moving from a 2.x word to a 5.x has been impressive, most notably the drag, drop, and resize functionality.

I’m still using InfluxDB and Telegraf to store and populate my time data points.

Latest Raspbian’s (stretch) comes with Influx 1.0.2 and works nicely:

# dpkg -l | grep influxdb
ii  influxdb     1.0.2+dfsg1-1 armhf

While I needed to grab the Telegraf as a Linux Binary (ARM) from Influx’s download page.


SensorTag data merged with Open Weather Maps

About a week ago I worked on SensorTag metrics with Grafana.

This week had some interesting weather today here in Austin, and I wanted to see to visualize it as well. Luckily Open Weather Maps offers a free API for gather near real-time weather data based on city code.



def __get_open_weather_data():

  url_path = 'http://api.openweathermap.org/data/2.5/weather'
  api_key = '??????????'
  url = '%s?zip=73301&APPID=%s'

  res = requests.get(url % (url_path, api_key))
  if res:
    if res.json().get('main'):
      return res.json()

  res = requests.get(url % (url_path, api_key))
  if res:
    if res.json().get('main'):
      return res.json()

def get_open_weather():

  data = __get_open_weather_data()

  # format our json response
  temp = round(data['main']['temp'] * 9/5 - 459.67, 2)
  pressure = round(data['main']['pressure'], 1)
  humidity = round(data['main']['humidity'], 2)
  rain = round(data['rain'].get('1h', 0.00), 2)
  clouds = data['clouds']['all']
  wind = data['wind']['speed']

  return dict(

Then I merge with my SensorTag data, appending these new keys to my json file:

$ cat /sensor.json
 "open_weather_temperature": 71.65,
 "temperature": 74.19,
 "open_weather_pressure": 1018.5,
 "light": 0,
 "humidity": 55.16,
 "pressure": 989.8,
 "open_weather_humidity": 99,
 "open_weather_rain": 7.07,
 "open_weather_clouds": 48,
 "open_weather_wind": 2.81

SensorTag metrics with Grafana

If you haven’t been following, I’ve done a little research into the Texas Instruments SensorTag starting with post RaspberryPi 3 and SensorTag.

Just the other day I stumbled upon the official Texas Instruments wiki for the SensorTag CC2650, the wiki does a good job outlining the formulas to calculate each sensors value.

This lead me to write a minimal Python class (see on Github) using some of the formulas found in the wiki. Beyond just the Python classes, I wrote in a periodic process; this process will save the sensor data to screen, and write to /root/sensor.json every five seconds.

pi@raspberrypi:~# cat /sensor.json
 "pressure": 987.2,
 "humidity": 58.44,
 "temperature": 75.65,
 "light": 19.43

To better visualize the gathered data I decided to store all metrics in Telegraf, all I needed was a simple execution plugin:

pi@raspberrypi:~# cat /etc/telegraf/telegraf.d/sensor_tag.conf
 command = "cat /sensor.json"
 data_format = "json"
 name_suffix = "_sensor_tag"
 interval = "5s"

Then on my workstation I installed Grafana, and connected Telegraf as a remote data source.

This is the type of data I’ve been gathering and storing from the SensorTag, seems like we could make a weather station pretty easy.



SensorTag Temperature Readings in Python

I wanted to wrap up my previous post (TI SensorTag Temperature Readings) with a little python example, thus this write is going to be short and sweet.

Using the bluepy python library (written by Ian Harvey) I’ve been able to to capture temperature readings, then covert them to Fahrenheit.

To demonstrate I captured a couple temperature samples, a few while sitting on my desk, and a few held up to my air condition vent:

root@raspberrypi:~# python temp.py
79.31 degrees fahrenheit
79.31 degrees fahrenheit
79.31 degrees fahrenheit
78.46 degrees fahrenheit
78.01 degrees fahrenheit
76.1 degrees fahrenheit
76.49 degrees fahrenheit
76.27 degrees fahrenheit
75.99 degrees fahrenheit
76.16 degrees fahrenheit

The Python is pretty straight forward:

#!/usr/bin/env python

from bluepy import btle
from time import sleep

sensor = btle.Peripheral('A0:xx:xx:xx:xx:xx')

sensor.writeCharacteristic(0x24, '\x01', withResponse=True)

sleep(1) # warm up

for i in range(10):
    t_data = sensor.readCharacteristic(0x21)
    msb = ord(t_data[3])
    lsb = ord(t_data[2])
    c = ((msb * 256 + lsb) / 4) * 0.03125
    f = c * 9/5.0 + 32
    print '%s degrees fahrenheit' % round(f, 2)

sensor.writeCharacteristic(0x24, '\x00', withResponse=True)

Happy hacking!