2026-01-26 12:46:06 +11:00
2026-01-27 16:51:58 +11:00
2026-01-27 16:51:58 +11:00
2026-01-26 12:40:47 +11:00
2026-01-26 12:40:47 +11:00
2026-01-29 14:04:18 +11:00

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

  1. Start services: docker compose up -d

  2. Configure: edit config.yaml (or test.yaml) with your MQTT broker, topics, and site coordinates.

  3. Run the ingest service locally: go run ./cmd/ingestd -config config.yaml

  4. 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.topic is still supported for single-topic configs, but mqtt.topics is 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: 1minute rollups (avg/min/max for temp, humidity, wind, uvi, light, rain).
    • cagg_ws90_5m: 5minute rollups (same metrics as cagg_ws90_1m).

Retention/compression:

  • observations_ws90 has a 90day retention policy and compression after 7 days.
  • observations_baro has a 90day retention policy and compression after 7 days.

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
No description provided
Readme 492 KiB
Languages
Go 53%
JavaScript 27.1%
HTML 8.2%
Python 5.6%
CSS 5.3%
Other 0.8%