Threaded MQTT collector for weather/sensor networks, aligned with vantage-publisher configuration style.
- MQTT subscriber with auto-reconnect
- Multiple output sinks:
- InfluxDB
- Signal K websocket deltas with retry backoff on transient gateway failures
- hourly CSV storage with path validation, protected collector metadata, and atomic schema expansion
- Dry mode for safe runtime validation (
--dry) - Web GUI for data download with authentication and access policies
- Login return URLs are restricted to local paths
- Map-based station discovery on the home page
- Data browsing per station with configurable charts and tables
- Station browser table supports per-column header toggles and window statistics
- Live station trend pages (auto-updating charts and latest table)
- Public sensor network dashboard with auto-updating status and alarms
- Per-station public trend-chart Y-axis configuration with controller/admin management
- JSON export/import for station trend-chart setup
- Public station trend charts update incrementally, support full-screen focus with branding, and show per-window min/max/current widgets
- Public station dashboard includes a combined Wind trend chart with wind direction and wind speed on separate Y-axes
- Watchdog anomaly detection with persisted anomaly log (SQLite)
- SMTP notifications (welcome, registration, alarms with fast-login link)
- if
smtpHostis not configured, emails are skipped - if
smtpPort/smtpUser/smtpPassare omitted, SMTP defaults to unauthenticated port25
- if
- Admin-enforced password change and user self-service password update
- Self-service forgot-password and reset-by-email flow
- Web app logo and per-station logo upload/display
- Configurable home-page external links for logo and info
The collector now accepts the same naming style used in vantage-publisher (mqttBroker, mqttPort, signalkServerUrl, pathStorage, httpEnabled, etc.).
Backward-compatible snake_case keys are still accepted.
- Python 3.10+ (CI checks 3.10–3.14; Docker uses 3.11)
- MQTT broker
- Optional:
- InfluxDB v2
- Signal K server
Install:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtRun the regression checks after installing dependencies (startup uses mocked MQTT):
python3 -m unittest discover -s tests -vpython3 main.py --config config.jsonOptions:
--config <path>config file path (defaultconfig.json)--signalk true|falseoverride configsignalk--influxdb true|falseoverride configinfluxdb--storage true|false|<path>true/false: enable/disable storage (uses configuredpathStorage)<path>: enable storage and overridepathStorage
--http true|falseoverride confighttpEnabled--drydry mode (no actual sink writes; log generated outputs)
Examples:
# Normal run (uses config booleans)
python3 main.py --config config.json
# Force only Signal K + storage path override
python3 main.py --config config.json --influxdb false --signalk true --storage /data/collector
# Dry validation of all enabled sinks
python3 main.py --config config.json --dryDetailed documentation has been split into dedicated pages:
- Docker deployment: link
- Continuous integration and image delivery: link
- Production WSGI setup: link
- Configuration reference: link
- Signal K forwarding: link
- CSV storage: link
- Web GUI and policies: link
- InfluxDB sink: link
- How to join with a Vantage Pro2 edge node: link
Components:
- MQTT intake (
paho-mqtt) - payload normalization (flat JSON / GeoJSON)
- timestamp resolver (
Datetime->DatetimeWS-> current UTC) - sink fan-out:
- InfluxDB writer
- Signal K websocket publisher
- CSV hourly storage
- optional Flask web GUI:
- SQLite auth/policy store
- anomaly store + silence state
- station chart settings + chart-control rights
- watchdog notifications
- access-controlled downloads
- live station trend pages
- public network dashboard
- public station dashboard with selectable trend windows persisted in cookies and per-station Y-axis settings
- account emails + fast-login links
- branding (app logo + station logo)
MQTT broker
-> sensor-network-collector
-> normalize payload + timestamp
-> InfluxDB sink (optional)
-> Signal K sink (optional)
-> CSV sink (optional)
CSV sink (pathStorage)
-> web GUI download portal (optional)
-> policy checks (open/account/restricted)
-> ZIP download for selected instruments/date range
-> station trend API (optional)
-> auto-updating chart/table in browser
-> public dashboard API (optional)
-> auto-updating network status and alarms
-> station chart settings store (optional)
-> per-station y-axis min/max/step overrides + JSON import/export
-> watchdog/anomaly detector (optional)
-> anomaly DB log + notification emails + silence window
Assume many publishers send flat data on topics:
it.uniparthenope.meteo.ws1it.uniparthenope.meteo.ws2it.uniparthenope.meteo.ws3
Example config:
{
"mqttBroker": "mqtt-broker.local",
"mqttPort": 1883,
"mqttTopic": "it.uniparthenope.meteo/#",
"storage": true,
"pathStorage": "/data/sensor-network-collector",
"influxdb": false,
"signalk": true,
"signalkServerUrl": "ws://signalk.local:3000/signalk/v1/stream",
"signalkContextPrefix": "meteo",
"signalkPathMap": {
"TempOut": "environment.outside.temperature",
"HumOut": "environment.outside.relativeHumidity",
"Barometer": "environment.outside.pressure",
"WindSpeed": "environment.wind.speedApparent",
"WindDir": "environment.wind.angleApparent"
},
"httpEnabled": true,
"httpHost": "0.0.0.0",
"httpPort": 8080,
"authDbPath": "/data/sensor-network-collector/collector_auth.sqlite",
"webSessionSecret": "replace-with-strong-secret",
"adminUser": "admin",
"adminPassword": "change-me"
}Run:
python3 main.py --config config.jsonContext examples:
- topic
it.uniparthenope.meteo.ws1->meteo.it_uniparthenope_meteo_ws1 - topic
it/uniparthenope/meteo/ws2->meteo.it.uniparthenope.meteo.ws2 - if payload contains
name, it is also sent to Signal K as pathnameinside the computed context
python3 -m py_compile main.py
python3 main.py --config config.json --dry- CSV storage and InfluxDB keep the raw publisher units as received on MQTT.
- Signal K output applies protocol-oriented conversions before publish:
- temperature -> Kelvin
- pressure -> Pa
- humidity percent -> ratio
- angular values -> radians
- rain totals / evapotranspiration totals -> meters
- rain rate -> meters per second
See:
baseUrlis used to compose externally visible links in email messages, including fast-login, onboarding, and password-reset URLs.- Account requests are handled in two steps: request by email/reason, then admin approval, then onboarding with a unique username and strong password.
- Public station dashboard trend-window choice is remembered in browser cookies.
- Station dashboard trend interval choice is also remembered in browser cookies.
- Station browser chart and table preferences are persisted per station and can be exported/imported as JSON.
- The auth SQLite database also stores chart-control rights and per-station trend-chart axis settings used by the Public Station Dashboard.
- Public station dashboard supports
focus=<chart_key>in the query string to open a specific trend chart in focused full-screen mode. - Public station dashboard trend charts show the full date on the x-axis when the displayed day changes.
- Home-page logo can link to
webAppLink, and the unauthenticated nav can showInfofromwebInfoLink. - In focused mode, the chart title includes the selected trend window and the header shows the station name without UUID.
- Change
adminPasswordimmediately. - Set a strong
webSessionSecretin production. - Serve GUI behind TLS/reverse proxy in production deployments.
Apache-2.0