# 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. ```sh 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: ```sh .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`: ```sh .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`: ```sh .venv/bin/python serve.py ``` With the example settings, open . 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: ```sh .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 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: ```sh 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: ```sh 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: ```sh 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: ```sh journalctl -u netatmo.service -f tail -f /var/lib/rrd/netatmo_service.log ``` ## HTTP API ```text GET /last// GET /graph// GET /graph/ # compact compatibility form GET /health ``` Periods are `day`, `2weeks`, and `year`. Examples: ```sh 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`, `pressure` - `pressure`: `pressure` - `wind`: `gust`, `average`, `angle` - `rain`: `sum_rain_24`, `sum_rain_1` - `bedroom`, `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.