What is OpenSonde?
OpenSonde is a platform for collecting, storing, and visualising data from environmental sensor devices (sondes). It consists of two .NET applications backed by a PostgreSQL database: a device-facing API and a user-facing web app.
The two applications
OpenSonde.API
A lightweight REST API that sensor devices communicate with directly. Devices authenticate using a token-based scheme (DeviceAuth) and POST their readings to /api/readings.
Each request can carry:
- One or more timestamped sensor samples, each with a set of parameter values (e.g. temperature, conductivity, pH)
- Optional GPS coordinates (latitude/longitude)
- Battery percentage
The API stores the raw request body, creates Reading and ReadingValue records in the database, and updates the device's last-seen timestamp, ping count, battery level, and location. It also handles the case where a request contains no samples at all, treating it as a heartbeat/keep-alive.
OpenSonde.App
A server-rendered MVC web application (Razor + Tailwind CSS) for users to manage and view their devices. Key areas:
- Devices — list all devices accessible to the user, view real-time status (online/offline, missed heartbeats, battery), browse sensor readings in a table or chart, and inspect raw API requests. Devices can be assigned to sites and customised (e.g. toggling the battery chart).
- Sites — logical locations that group devices. Sites track when they last received a reading.
- Dashboards — user-configurable grid-based dashboards with draggable tiles. Currently supports text tiles; the layout is persisted as JSON.
- Incidents — a section exists in the nav (stub, no logic yet).
- Organisations — members can belong to organisations, which controls which devices they can see.
- Authentication — cookie-based login with password reset support.
Data model highlights
| Entity | What it represents |
|---|---|
Device | A physical sensor unit, linked to a member and optionally a site |
DeviceModel | The make/model of a device, including expected heartbeat interval |
DeviceParameter | A mapping between a device's raw data key and a named parameter |
Parameter | A named, unitised measurement type (e.g. "Temperature (°C)") |
Reading | One timestamped sample from a device |
ReadingValue | A single parameter value within a reading |
DeviceRequest | The full raw request payload from a device (for debugging) |
Site | A named monitoring location |
Dashboard | A user-defined grid layout storing tile configuration as JSONB |
Organisation | A group that members can belong to for shared device access |
Tech stack
- Backend: ASP.NET Core (.NET), Entity Framework Core, PostgreSQL
- Frontend: Razor Views, Tailwind CSS, Vite
- Auth: Cookie auth for the web app; custom token scheme for devices
- Observability: Sentry (error tracking and tracing)