6f9eee5dc0025739cbbaa36066d045ebff6114fc
go-weatherstation
Starter weather-station data pipeline:
- MQTT ingest of WS90 payloads -> TimescaleDB
- ECMWF (Open-Meteo) forecast polling -> TimescaleDB
- Web UI with live metrics, comparisons, and charts
Quick start
-
Start services:
docker compose up -d -
Configure: edit
config.yaml(ortest.yaml) with your MQTT broker, topics, and site coordinates. -
Run the ingest service locally:
go run ./cmd/ingestd -config config.yaml -
Open the UI:
http://localhost:8080
Configuration reference
config.yaml is the single config file for ingest, forecast polling, and the web UI.
mqtt:
broker: "tcp://mosquitto:1883" # MQTT broker URL
client_id: "go-weatherstation-ingestd" # Client ID
username: "" # Optional username
password: "" # Optional password
qos: 1 # Default MQTT QoS (0, 1, or 2)
topics:
- name: "ws90"
topic: "ecowitt/ws90" # WS90 payload topic
type: "ws90"
- name: "baro"
topic: "sensors/barometer" # Barometric pressure topic
type: "baro"
db:
conn_string: "postgres://postgres:postgres@timescaledb:5432/micrometeo?sslmode=disable"
site:
name: "home"
latitude: -33.8688 # WGS84 latitude
longitude: 151.2093 # WGS84 longitude
elevation_m: 50 # Currently informational (not used by Open-Meteo ECMWF endpoint)
pollers:
open_meteo:
enabled: true
interval: "30m" # How often to fetch forecast data
model: "ecmwf" # Stored as metadata; endpoint is fixed to ECMWF
web:
enabled: true
listen: ":8080" # Web UI listen address
wunderground:
enabled: false
station_id: "YOUR_STATION_ID"
station_key: "YOUR_STATION_KEY"
interval: "60s" # Upload cadence
Notes
- The Open-Meteo ECMWF endpoint is queried by the poller only. The UI reads forecasts from TimescaleDB.
- Web UI supports Local/UTC toggle and date-aligned ranges (6h, 24h, 72h, 7d).
mqtt.topicis still supported for single-topic configs, butmqtt.topicsis preferred.
Schema & tables
TimescaleDB schema is initialized from db/init/001_schema.sql and includes:
observations_ws90(hypertable): raw WS90 observations with payload metadata, plus the full JSON payload (payload_json).observations_baro(hypertable): barometric pressure observations from other MQTT topics.forecast_openmeteo_hourly(hypertable): hourly forecast points keyed by(site, model, retrieved_at, ts).- Continuous aggregates:
cagg_ws90_1m: 1‑minute rollups (avg/min/max for temp, humidity, wind, uvi, light, rain).cagg_ws90_5m: 5‑minute rollups (same metrics ascagg_ws90_1m).
Retention/compression:
observations_ws90has a 90‑day retention policy and compression after 7 days.observations_barohas a 90‑day retention policy and compression after 7 days.
Existing databases
If you’re on an existing database, you’ll need to apply the new table definition once (the init SQL only runs on a fresh DB). Example:
docker compose exec -T timescaledb psql -U postgres -d micrometeo -f /docker-entrypoint-initdb.d/001_schema.sql
Or copy just the observations_baro section into a manual psql -c.
Publish a test WS90 payload
mosquitto_pub -h localhost -t ecowitt/ws90 -m '{"model":"Fineoffset-WS90","id":70618,"battery_ok":1,"battery_mV":3180,"temperature_C":24.2,"humidity":60,"wind_dir_deg":129,"wind_avg_m_s":0,"wind_max_m_s":0,"uvi":0,"light_lux":0,"flags":130,"rain_mm":0,"rain_start":0,"supercap_V":0.5,"firmware":160,"data":"3fff000000------0000ff7ff70000","mic":"CRC","protocol":"Fine Offset Electronics WS90 weather station","rssi":-44,"duration":32996}'
Description
Languages
Go
53%
JavaScript
27.1%
HTML
8.2%
Python
5.6%
CSS
5.3%
Other
0.8%