5.9 KiB
GetNetatmoData v2
A small Flask service that polls Netatmo's Weather API every ten minutes, stores the readings in RRDtool databases, and serves a responsive graph dashboard.
What it stores
The service creates netatmo_outdoor.rrd, netatmo_pressure.rrd,
netatmo_wind.rrd, netatmo_rain.rrd,
netatmo_bedroom.rrd, netatmo_study.rrd, and netatmo_living.rrd. Each has
ten-minute archives for the last two weeks and six-hour archives covering a
year. Day, two-week, and year PNG graphs are rendered on demand. The wind graph
splits average wind into 12 colored direction bands and draws gusts as a line.
The rain database stores Netatmo's sum_rain_1 and cumulative sum_rain_24
readings. Day and two-week graphs show rain accumulated per hour; the year graph
shows rain accumulated per day. The midnight reset of sum_rain_24 is preserved,
and MAX consolidation retains daily totals in the longer-term archive.
The Outdoor module does not contain a pressure sensor, so the dedicated pressure
graph reads it from the main station. Its Y axis is fixed at 900–1100 mbar. A
module without dashboard_data is skipped until it becomes reachable again.
Prerequisites and setup
Install the RRDtool Python binding and native library using your operating
system package manager (for example apt install python3-rrdtool on Debian or
Ubuntu), then set up the Python application. If your distribution does not
provide the binding, pip install -r requirements.txt installs its PyPI package
but may require the RRDtool development headers and a C compiler.
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
cp config.example.yaml config.yaml
Add the client ID and secret for the Netatmo application GetNetatmoData v2
to the private config.yaml. Ensure netatmo.redirect_uri exactly matches a
redirect URI configured for that application, then perform the initial
read_station authorization:
.venv/bin/python scripts/get_netatmo_token.py
The helper opens Netatmo's consent page. After approval, paste the complete URL
from the browser's address bar back into the prompt. This works even if the local
callback page itself cannot be reached. The script exchanges the authorization
code and writes the token file with mode 0600.
The service loads netatmo.token_file at startup. Before an access token expires,
it refreshes it and atomically saves both the new access token and any rotated
refresh token. Values in the token file take precedence over initial token values
in YAML. Client credentials remain in the private configuration and are never written to
the token file or an RRD.
Run the service; host, port, and URL prefix all come from config.yaml:
.venv/bin/python wsgi.py
For production, use the Waitress entry point. It reads host, port, thread count,
and all application settings from config.yaml:
.venv/bin/python serve.py
With the example settings, open http://localhost:30225/w/. Keep one application worker because the polling
scheduler runs inside the service process. Alternatively set
collector.enabled: false in web workers and invoke this from a system timer:
.venv/bin/flask --app wsgi collect-now
storage.rrd_folder configures the database directory (default ./rrd). The
modules section allows the Netatmo display names to be changed.
Set server.url_prefix: /w to mount the dashboard, static assets, and every API endpoint
below /w; leave it empty to serve from the site root. When a prefix is set,
open http://localhost:5000/w/ instead.
logging.file selects a rotating application log (by default
RRD_FOLDER/netatmo_service.log). Every Netatmo HTTP attempt records success or
failure, HTTP status, endpoint, and duration without credentials. Collector,
Flask, uncaught main-thread, and uncaught worker-thread exceptions are written to
the same log. logging.max_bytes defaults to 5 MiB and backup_count to five.
The service account must have write permission on the log directory. Console
logging remains enabled by default so python wsgi.py displays its listening
address; set logging.console: false to use only the logfile.
systemd installation
The included deploy/netatmo.service runs Waitress from /srv/service_netatmo
under a dedicated, non-login netatmo account. As root, create the account and
writable data directory:
useradd --system --home-dir /srv/service_netatmo --shell /usr/sbin/nologin netatmo
install -d -o netatmo -g netatmo -m 0750 /var/lib/rrd
chown netatmo:netatmo /srv/service_netatmo/config.yaml
chmod 0600 /srv/service_netatmo/config.yaml
Create the virtual environment and install dependencies as that account:
sudo -u netatmo python3 -m venv /srv/service_netatmo/.venv
sudo -u netatmo /srv/service_netatmo/.venv/bin/pip install -r /srv/service_netatmo/requirements.txt
Install and start the unit:
install -o root -g root -m 0644 /srv/service_netatmo/deploy/netatmo.service /etc/systemd/system/netatmo.service
systemctl daemon-reload
systemctl enable --now netatmo.service
systemctl status netatmo.service
Follow service output and the rotating application log with:
journalctl -u netatmo.service -f
tail -f /var/lib/rrd/netatmo_service.log
HTTP API
GET /last/<rrd-name>/<data-point>
GET /graph/<rrd-name>/<period>
GET /graph/<rrd-name><period> # compact compatibility form
GET /health
Periods are day, 2weeks, and year. Examples:
curl http://localhost:5000/last/outdoor/humidity
curl --output wind.png http://localhost:5000/graph/wind/2weeks
Data points are:
outdoor:temperature,min_temp,max_temp,humidity,pressurepressure:pressurewind:gust,average,anglerain:sum_rain_24,sum_rain_1bedroom,study,living:temperature,co2,humidity
The service creates missing RRDs at startup but deliberately does not alter an existing RRD schema. If a schema is changed in code, migrate or archive the old files before restarting.