179 lines
9.2 KiB
Markdown
179 lines
9.2 KiB
Markdown
# Portal
|
|
|
|
## Admin page
|
|

|
|
|
|
## Devices
|
|

|
|
|
|
## Device details
|
|

|
|
|
|
## Device ports
|
|

|
|
|
|
## Sensors
|
|

|
|
|
|
- A customer-facing web portal for lease operators to view their devices, see live status, issue commands, run calibrations, and view historical and SIM-usage data.
|
|
- Proper multi-user authentication with per-customer data isolation enforced server-side.
|
|
- Real-time UI: device state changes reflected in under a second.
|
|
- Mobile-friendly — operators use this on boats.
|
|
- Calibration wizard delivered first; other dashboards migrate over time.
|
|
|
|
## 3. Non-Goals
|
|
|
|
- Not replacing Grafana for deep historical analysis (can embed panels where useful).
|
|
- Not replacing ThingsBoard for telemetry storage.
|
|
- Not replacing Node-RED — Node-RED remains the orchestration and protocol-bridging layer.
|
|
- Not building native mobile apps. Web only, mobile-responsive.
|
|
|
|
## 4. Required Integrations
|
|
|
|
These are fixed. Everything else is the implementer's choice.
|
|
|
|
### 4.1 PostgREST
|
|
|
|
All persistent state — devices, customers, calibration sessions, command logs, configuration — is read and written via the existing PostgREST API. Authorization is enforced through PostgreSQL row-level security, keyed off claims in the Authentik-issued JWT. The portal must not bypass PostgREST to talk to the database directly.
|
|
|
|
### 4.2 MQTT (over WebSockets)
|
|
|
|
The portal subscribes to live device data via MQTT, almost certainly over secure WebSockets (WSS) from the browser. The MQTT broker is the source of truth for ephemeral state — online/offline, awake/asleep, live calibration values, sensor readings during streaming. Retained messages provide last-known state on initial connection; non-retained messages drive live updates.
|
|
|
|
Topic ACLs on the broker must restrict each user to topics for devices they own. Authentication mechanism (JWT plugin, dynamic credentials, per-user passwords) is a decision for the implementer in consultation with the existing infrastructure.
|
|
|
|
### 4.3 Node-RED
|
|
|
|
Node-RED is the command orchestration and protocol-bridging layer. The portal does **not** call Node-RED HTTP endpoints for routine work. Instead, the portal writes intent (a command row, a session start) to PostgREST, and Node-RED picks it up via PostgreSQL `LISTEN/NOTIFY`, publishes the appropriate MQTT command, watches for device acknowledgement, and updates state.
|
|
|
|
A small number of synchronous operations may justify a direct Node-RED HTTP endpoint, but this should be the exception, not the rule.
|
|
|
|
## 5. Functional Requirements
|
|
|
|
### 5.1 Authentication and User Management
|
|
|
|
- Users authenticate via Authentik (existing SSO).
|
|
- JWT used for both PostgREST authorization (RLS) and MQTT broker authentication.
|
|
- Users see only devices and data belonging to their organisation.
|
|
- Role model (admin, operator, viewer, etc.) to be confirmed — see open questions.
|
|
|
|
### 5.2 Device Management
|
|
|
|
- List view of all devices accessible to the user, with current status indicators.
|
|
- Filter and search by name, location, status, type.
|
|
- Detail view per device: configuration, location on map, last-seen timestamp, current readings, recent commands, calibration history.
|
|
- Edit configurable fields (name, notes, alarm thresholds, calibration config) through PostgREST.
|
|
|
|
### 5.3 Real-Time Monitoring
|
|
|
|
- Live status indicators per device: online/offline, awake/asleep, battery, signal strength, last reading.
|
|
- Updates reflected in the UI within ~1s of the device publishing.
|
|
- Visual indication when data is stale (no heartbeat for N seconds).
|
|
- Driven by MQTT subscriptions; reconnection handled gracefully.
|
|
|
|
### 5.4 Commands
|
|
|
|
- Users can issue commands to devices (wake, sleep, restart, trigger reading, enter/exit calibration mode, etc.).
|
|
- Issuing a command writes a row to a command-log table via PostgREST. The UI does not publish MQTT directly for commands.
|
|
- Node-RED publishes the MQTT command, watches for ack, updates the row's status.
|
|
- The UI shows command lifecycle in real time: pending → sent → acknowledged → completed (or failed/timed out).
|
|
- Per-device audit trail of all commands issued, by whom, with timestamps and outcome.
|
|
|
|
### 5.5 Calibration Wizard (priority feature)
|
|
|
|
A multi-step flow that replaces the existing Node-RED calibration page.
|
|
|
|
- User selects a device and sensor type to calibrate.
|
|
- Wizard creates a `calibration_session` record (or equivalent) via PostgREST.
|
|
- Wizard issues a "enter calibration mode" command (via the command flow above).
|
|
- While in calibration mode, the device publishes higher-rate raw values on a dedicated calibration topic; the wizard subscribes and displays them live.
|
|
- User captures reference points one at a time. Each captured point persists immediately to the database (so the session is resumable if interrupted).
|
|
- On finish, calibration coefficients are computed and saved to the session record. The device is taken out of calibration mode and the new coefficients are applied (mechanism via Node-RED).
|
|
- Past calibrations are listed per device, with timestamps, operator, and resulting coefficients.
|
|
- Where the calibration math runs (browser, Node-RED, PostgreSQL function, dedicated service) is the implementer's call.
|
|
|
|
### 5.6 Maps
|
|
|
|
- Map view showing all accessible devices with status-coloured markers.
|
|
- Aquaculture lease boundaries displayed as polygons where data is available.
|
|
- Marker popups link to device detail page.
|
|
- Live status updates reflected on the map.
|
|
|
|
### 5.7 Historical Data and Charts
|
|
|
|
- Per-device time-series charts of sensor readings over selectable time ranges.
|
|
- Implementer chooses charting library.
|
|
- Data source: PostgREST views over PostgreSQL. Where ThingsBoard or Grafana already provide a better view, embedding is acceptable.
|
|
|
|
### 5.8 Hologram SIM Usage
|
|
|
|
- Per-device cellular data usage and SIM status.
|
|
- Hologram API must be proxied through a backend — the API key is never exposed to the browser.
|
|
- Proxy implementation is the implementer's choice (Node-RED flow, small dedicated service, or PostgREST RPC calling out — all viable).
|
|
- Display: current-period usage summary plus a usage-over-time chart.
|
|
|
|
## 6. Non-Functional Requirements
|
|
|
|
### 6.1 Performance
|
|
|
|
- Usable over 4G connections from boats.
|
|
- Real-time UI changes within ~1s of MQTT message receipt.
|
|
- Initial page load under 3s on broadband, under 6s on mobile.
|
|
|
|
### 6.2 Security
|
|
|
|
- All traffic over TLS (HTTPS, WSS).
|
|
- Hologram API key, and any other backend-only credentials, never reachable from the browser.
|
|
- Authorization enforced server-side via RLS and broker ACLs. The UI may hide controls a user cannot use, but the server is the authority.
|
|
- MQTT topic ACLs restrict each user to their own devices' topics.
|
|
|
|
### 6.3 Reliability
|
|
|
|
- Portal degrades gracefully when MQTT or PostgREST is temporarily unavailable.
|
|
- MQTT WebSocket reconnects automatically with backoff.
|
|
- Stale-state warnings when live data has not updated within an expected window.
|
|
|
|
### 6.4 Maintainability
|
|
|
|
- Clear separation of concerns:
|
|
- PostgREST for persistent CRUD state.
|
|
- MQTT for ephemeral live state.
|
|
- Command flows: write to DB, observe state changes — never bypass.
|
|
- Consistent component library and design system across the app.
|
|
- Reasonable test coverage of the calibration wizard logic in particular.
|
|
|
|
## 7. Architecture Overview
|
|
|
|
Two parallel data paths in the browser:
|
|
|
|
1. **Persistent state** — PostgREST for reads and writes of devices, sessions, commands, configuration. Authorized via Authentik JWT and PostgreSQL RLS.
|
|
2. **Live state** — MQTT over WSS for real-time device status, telemetry streams during calibration, command-result events. Authorized via broker ACLs tied to the same JWT identity.
|
|
|
|
Command flow:
|
|
|
|
```
|
|
Browser → PostgREST insert (command row)
|
|
→ PostgreSQL NOTIFY
|
|
→ Node-RED LISTEN
|
|
→ MQTT publish to device
|
|
→ Device acts, publishes status
|
|
→ Browser MQTT subscription updates UI
|
|
→ Node-RED updates command row status
|
|
```
|
|
|
|
The browser is the consumer; Node-RED is the orchestrator; PostgreSQL is the system of record; the MQTT broker is the live event bus.
|
|
|
|
|
|
## 9. Open Questions
|
|
|
|
- **User provisioning:** Who creates user accounts in Authentik? Self-service, admin-only, or invitation-based?
|
|
- **Role model:** What roles exist beyond a simple admin/user split? Is there a "field operator" role distinct from a "lease manager" role?
|
|
- **Lease boundaries:** Where does the polygon data come from? State government open data, customer-supplied KML, manually drawn?
|
|
- **Offline tolerance:** Does the portal need to function partially offline, or is "shows a connection error" acceptable?
|
|
- **Branding:** Is there an existing visual identity to honour, or is the implementer free to choose?
|
|
- **Migration:** What happens to existing Node-RED dashboard users during cutover? Run both in parallel?
|
|
- **Historical data source:** Should historical charts read from PostgreSQL, ThingsBoard, or both? Is there a single canonical place?
|
|
- **Alarm and notification model:** Out of scope for v1, or required from day one?
|
|
- **Audit and compliance:** Are there regulatory requirements (data retention, traceability) that affect the calibration audit trail?
|
|
|