-
-
Save vlsoft/92a82edb5fc225cacbfb5f23acc53b3b to your computer and use it in GitHub Desktop.
Fetch Netatmo Weather Station measurements and store in InfluxDB
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import os | |
import sys | |
import json | |
import time | |
import requests | |
# Get your client ID and secret by creating an App at https://dev.netatmo.com/ | |
NETATMO_CLIENT_ID = "" | |
NETATMO_CLIENT_SECRET = "" | |
NETATMO_USERNAME = "" | |
NETATMO_PASSWORD = "" | |
# Ensure that the hostname and database name are correct for your InfluxDB | |
INFLUX_HOST = 'localhost' | |
INFLUX_PORT = '8086' | |
INFLUX_DATABASE = 'netatmo' | |
INFLUXDB_WRITE_URL = 'http://{}:{}/write?precision=s&db={}'.format(INFLUX_HOST, INFLUX_PORT, INFLUX_DATABASE) | |
print('Will write measurements to InfluxDB at endpoint {}'.format(INFLUXDB_WRITE_URL)) | |
data = dict(grant_type='password', client_id=NETATMO_CLIENT_ID, | |
client_secret=NETATMO_CLIENT_SECRET, username=NETATMO_USERNAME, | |
password=NETATMO_PASSWORD, scope='read_station') | |
resp = requests.post('https://api.netatmo.com/oauth2/token', data=data) | |
if resp.status_code == 200: | |
token = resp.json() | |
token['expiry'] = int(time.time()) + token['expires_in'] | |
while True: | |
# Check if token needs refresh | |
if token['expiry'] - int(time.time()) < 600: | |
data = dict(grant_type='refresh_token', refresh_token=token['refresh_token'], client_id=NETATMO_CLIENT_ID, client_secret=NETATMO_CLIENT_SECRET) | |
resp = requests.post('https://api.netatmo.com/oauth2/token', data=data) | |
if resp.status_code == 200: | |
token = resp.json() | |
token['expiry'] = int(time.time()) + token['expires_in'] | |
# Fetch measurements | |
resp = requests.get('https://api.netatmo.com/api/getstationsdata?access_token=' + token['access_token']) | |
if resp.status_code == 200: | |
data = resp.json() | |
payload = "" | |
for device in data['body']['devices']: | |
timestamp = device['dashboard_data']['time_utc'] | |
# Normalize station name and module names to ensure they become valid InfluxDB label values | |
stationname = device['station_name'].replace(' ', '_').encode('utf-8') | |
modulename = device['module_name'].replace(' ', '_').encode('utf-8') | |
for datatype in device['data_type']: | |
payload += '{0},station_name={1},module_name={2} value={3} {4}\n'.format(datatype, stationname, modulename, device['dashboard_data'][datatype], timestamp) | |
for module in device['modules']: | |
modulename = module['module_name'].replace(' ', '_').encode('utf-8') | |
for datatype in module['data_type']: | |
if datatype == 'Wind': | |
for subtype in ['WindStrength', 'WindAngle', 'GustStrength', 'GustAngle']: | |
payload += '{0},station_name={1},module_name={2} value={3} {4}\n'.format(subtype, stationname, modulename, module['dashboard_data'][subtype], timestamp) | |
else: | |
payload += '{0},station_name={1},module_name={2} value={3} {4}\n'.format(datatype, stationname, modulename, module['dashboard_data'][datatype], timestamp) | |
# Debug output to ensure payload contains data and has valid InfluxDB format | |
print('Writing the following data points to InfluxDB:') | |
print(payload) | |
# Write to InfluxDB | |
resp = requests.post(INFLUXDB_WRITE_URL, data=payload) | |
# New data arrives every 10 min so the sleep period is a bit shorter to ensure you get it all | |
time.sleep(480) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment