Tau.Acuvim/docs/acuvim-spec-09.md
Renier Forster 84a0668c54 Initial commit: Tau Acuvim IoT monitoring system
Complete IoT monitoring platform for Acuvim II power meters via ESP32.

Firmware (Phases 1-7):
- ESP32-WROVER-B (TTGO T-Call v1.4) with RS485 Modbus RTU
- WiFi STA+AP concurrent mode with GSM/GPRS failover
- Transport abstraction layer with 4 priority modes
- MQTT protocol with 20 commands, LWT, QoS, exponential backoff
- SD card offline buffering with JSONL rotation and non-blocking drain
- OTA firmware updates with dual partition rollback protection
- Watchdog timer, crash loop detection, Acuvim health monitoring
- Captive portal provisioning with AP mode

Console backend (Phase 8):
- .NET 10 minimal API with PostgreSQL + EF Core
- JWT authentication, SignalR real-time updates
- MQTTnet 5.x bridge service with health monitoring
- Device, telemetry, firmware, alert, group management
- Rate limiting, security headers, Swagger/OpenAPI

Frontend (Phase 9):
- React 18 + TypeScript + Vite with Ant Design 5
- ECharts telemetry visualization, TanStack Query
- SignalR live updates, device management UI
- Dashboard, fleet management, firmware deployment

Testing & Production (Phase 10):
- 28 firmware unit tests (Modbus, JSON, config, version)
- 23 xUnit backend tests (device, telemetry, command, alert)
- Docker Compose with nginx, TLS MQTT, PostgreSQL
- Production deployment, commissioning, and troubleshooting docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-16 19:05:32 +02:00

28 KiB
Raw Permalink Blame History

Phase 9: Console Application Frontend

Objective

Build the web-based frontend dashboard for the console application. The frontend provides device fleet management, real-time telemetry visualization, remote configuration, OTA firmware deployment, and alert management. It connects to the backend API (Phase 8) and uses SignalR for real-time updates.

Prerequisites

  • Phase 8 complete (backend API running)
  • Node.js 18+ (for frontend build tooling)
  • Design system chosen

Deliverables

  1. React SPA with responsive dashboard
  2. Device fleet overview with status indicators
  3. Individual device detail page (telemetry, config, health)
  4. Real-time telemetry charts
  5. Remote configuration interface
  6. Firmware management and deployment UI
  7. Alert management dashboard
  8. User authentication flow

9.1 Technology Stack

Component Technology Justification
Framework React 18 Component-based, large ecosystem
Language TypeScript Type safety, better DX
Build Vite Fast HMR, modern bundling
Routing React Router v6 Standard React routing
State TanStack Query (React Query) Server state caching, auto-refresh
UI Library Ant Design 5 Complete component set, tables, forms, charts
Charts Apache ECharts (via echarts-for-react) High-performance, rich chart types
Real-time @microsoft/signalr SignalR client for live updates
HTTP Axios HTTP client with interceptors
Forms Ant Design Form Built-in validation
Icons Ant Design Icons Consistent with UI library

9.2 Project Structure

console/
├── frontend/
│   ├── package.json
│   ├── tsconfig.json
│   ├── vite.config.ts
│   ├── index.html
│   ├── public/
│   │   └── favicon.ico
│   └── src/
│       ├── main.tsx
│       ├── App.tsx
│       ├── api/
│       │   ├── client.ts              # Axios instance with auth interceptor
│       │   ├── devices.ts             # Device API calls
│       │   ├── telemetry.ts           # Telemetry API calls
│       │   ├── firmware.ts            # Firmware API calls
│       │   ├── alerts.ts              # Alert API calls
│       │   ├── auth.ts                # Auth API calls
│       │   └── commands.ts            # Command API calls
│       ├── hooks/
│       │   ├── useDevices.ts
│       │   ├── useTelemetry.ts
│       │   ├── useSignalR.ts
│       │   └── useAuth.ts
│       ├── pages/
│       │   ├── LoginPage.tsx
│       │   ├── DashboardPage.tsx
│       │   ├── DeviceListPage.tsx
│       │   ├── DeviceDetailPage.tsx
│       │   ├── FirmwarePage.tsx
│       │   ├── AlertsPage.tsx
│       │   ├── GroupsPage.tsx
│       │   └── SettingsPage.tsx
│       ├── components/
│       │   ├── layout/
│       │   │   ├── AppLayout.tsx
│       │   │   ├── Sidebar.tsx
│       │   │   └── Header.tsx
│       │   ├── devices/
│       │   │   ├── DeviceTable.tsx
│       │   │   ├── DeviceCard.tsx
│       │   │   ├── DeviceStatusBadge.tsx
│       │   │   ├── DeviceConfigForm.tsx
│       │   │   ├── WifiScanModal.tsx
│       │   │   └── CommandModal.tsx
│       │   ├── telemetry/
│       │   │   ├── TelemetryChart.tsx
│       │   │   ├── LiveReadings.tsx
│       │   │   ├── PowerGauge.tsx
│       │   │   └── EnergyCounter.tsx
│       │   ├── firmware/
│       │   │   ├── FirmwareUpload.tsx
│       │   │   ├── FirmwareTable.tsx
│       │   │   └── DeployModal.tsx
│       │   ├── alerts/
│       │   │   ├── AlertTable.tsx
│       │   │   └── AlertBadge.tsx
│       │   └── dashboard/
│       │       ├── FleetSummary.tsx
│       │       ├── DeviceMap.tsx
│       │       └── RecentAlerts.tsx
│       ├── types/
│       │   ├── device.ts
│       │   ├── telemetry.ts
│       │   ├── firmware.ts
│       │   └── alert.ts
│       └── utils/
│           ├── formatters.ts
│           └── constants.ts

9.3 Page Layouts

Dashboard (Home)

Fleet-level overview — the first thing operators see.

┌─────────────────────────────────────────────────────────────┐
│  ☰  Tau Acuvim Console                    admin ▼  [Logout] │
├──────┬──────────────────────────────────────────────────────┤
│      │                                                      │
│ Nav  │  Fleet Overview                                      │
│      │  ┌──────────┬──────────┬──────────┬──────────┐      │
│ 📊   │  │ Total    │ Online   │ Degraded │ Offline  │      │
│Dash  │  │   24     │   21     │    1     │    2     │      │
│      │  └──────────┴──────────┴──────────┴──────────┘      │
│ 📱   │                                                      │
│Devs  │  ┌────────────────────┬──────────────────────┐      │
│      │  │ Recent Alerts      │ Fleet Power           │      │
│ 📦   │  │ ⚠ Overvoltage     │ ┌─────────────────┐  │      │
│FW    │  │   ACV-001 2m ago  │ │    Line chart    │  │      │
│      │  │ ⚠ Modbus error    │ │  (total kW over  │  │      │
│ 🔔   │  │   ACV-015 5m ago  │ │   last 24h)      │  │      │
│Alert │  │ ● Device offline  │ └─────────────────┘  │      │
│      │  │   ACV-008 1h ago  │                       │      │
│ ⚙    │  └────────────────────┴──────────────────────┘      │
│Sets  │                                                      │
│      │  Device Status Grid                                  │
│      │  ┌──────┬──────┬──────┬──────┬──────┬──────┐       │
│      │  │●001  │●002  │●003  │●004  │●005  │●006  │       │
│      │  │230V  │231V  │229V  │232V  │ OFF  │230V  │       │
│      │  │10kW  │12kW  │9kW   │11kW  │ --   │8kW   │       │
│      │  └──────┴──────┴──────┴──────┴──────┴──────┘       │
│      │                                                      │
└──────┴──────────────────────────────────────────────────────┘

Device List

┌──────────────────────────────────────────────────────────────┐
│  Devices                          [+ Add Group] [⚡ Deploy]  │
├──────────────────────────────────────────────────────────────┤
│ Filter: [All ▼] [Online ▼] [Group ▼]  Search: [________]    │
├──────────────────────────────────────────────────────────────┤
│ Status │ Device ID       │ Name          │ FW    │ Conn │ P  │
│────────┼─────────────────┼───────────────┼───────┼──────┼────│
│ ●      │ ACV-AABBCCDDEEFF│ Building A    │ 1.0.0 │ WiFi │10kW│
│ ●      │ ACV-112233445566│ Building B    │ 1.0.0 │ GSM  │12kW│
│ ◐      │ ACV-FFEEDDCCBBAA│ Warehouse     │ 0.9.0 │ WiFi │ 9kW│
│ ○      │ ACV-998877665544│ Solar Farm    │ 1.0.0 │ --   │ -- │
├──────────────────────────────────────────────────────────────┤
│ Showing 1-20 of 24 devices           < 1  2 >               │
└──────────────────────────────────────────────────────────────┘

Status indicators: ● Online  ◐ Degraded  ○ Offline

Device Detail

┌──────────────────────────────────────────────────────────────┐
│  ← Devices / ACV-AABBCCDDEEFF - Building A                  │
├──────────────────────────────────────────────────────────────┤
│ [Overview] [Telemetry] [Config] [Alerts] [Commands] [OTA]   │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  ── Overview Tab ──                                          │
│                                                              │
│  Device Info                    │ Connection                  │
│  ID: ACV-AABBCCDDEEFF          │ Type: WiFi                  │
│  Name: Building A              │ SSID: MyNetwork             │
│  Hardware: TTGO T-Call v1.4    │ RSSI: -45 dBm              │
│  Firmware: v1.0.0              │ IP: 192.168.1.100           │
│  Uptime: 3d 2h 15m            │ MQTT: Connected             │
│  Boot count: 12               │ GSM: Available (standby)    │
│  Last heartbeat: 30s ago       │ SD: 4GB (0.1% used)         │
│                                │                              │
│  ┌──────────────────────────────────────────────────────┐   │
│  │ Live Readings                               ● LIVE   │   │
│  │                                                       │   │
│  │ Phase Voltages        Phase Currents                  │   │
│  │ Va: 230.1 V          Ia: 15.2 A                      │   │
│  │ Vb: 231.4 V          Ib: 14.8 A                      │   │
│  │ Vc: 229.8 V          Ic: 15.5 A                      │   │
│  │                                                       │   │
│  │ Power                 Energy                          │   │
│  │ Active:   10.5 kW    Import: 12,345.6 kWh            │   │
│  │ Reactive:  2.1 kVAR  Export:     0.0 kWh             │   │
│  │ Apparent: 10.7 kVA   PF: 0.98                        │   │
│  │ Freq:    50.01 Hz                                     │   │
│  └──────────────────────────────────────────────────────┘   │
│                                                              │
│  [Restart] [WiFi Scan] [Send Command]                        │
└──────────────────────────────────────────────────────────────┘

Device Detail - Telemetry Tab

┌──────────────────────────────────────────────────────────────┐
│ [Overview] [Telemetry] [Config] [Alerts] [Commands] [OTA]   │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│ Time Range: [Last 24h ▼]  [Custom Range]  [Export CSV]       │
│                                                              │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │  Phase Voltages (V)                                      │ │
│ │  240 ┤                                                   │ │
│ │  235 ┤    ╭─╮                                            │ │
│ │  230 ┤───╯   ╰────────────────────────────────────      │ │
│ │  225 ┤                                                   │ │
│ │  220 ┤                                                   │ │
│ │      └──┬────┬────┬────┬────┬────┬────┬────┬────┬──     │ │
│ │        00   03   06   09   12   15   18   21   24       │ │
│ │  ── Va  ── Vb  ── Vc                                    │ │
│ └──────────────────────────────────────────────────────────┘ │
│                                                              │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │  Active Power (kW)                                       │ │
│ │  15 ┤         ╭───╮                                      │ │
│ │  10 ┤────╮   ╯     ╰───────╮                            │ │
│ │   5 ┤    ╰──╯               ╰──────                     │ │
│ │   0 ┤                                                    │ │
│ │      └──┬────┬────┬────┬────┬────┬────┬────┬────┬──     │ │
│ └──────────────────────────────────────────────────────────┘ │
│                                                              │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │  Power Factor & Frequency                                │ │
│ │  ... similar chart ...                                   │ │
│ └──────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘

Device Detail - Config Tab

┌──────────────────────────────────────────────────────────────┐
│ [Overview] [Telemetry] [Config] [Alerts] [Commands] [OTA]   │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│ WiFi Configuration          │ MQTT Configuration             │
│ SSID: [MyNetwork____]       │ Broker: [broker.example.com]   │
│ Password: [**********]      │ Port: [1883]                   │
│ Enabled: [✓]                │ Username: [device1]            │
│ [Scan Networks] [Save]      │ Password: [**********]         │
│                              │ Topic: [acuvim]                │
│ GSM Configuration            │ TLS: [ ]                      │
│ APN: [internet]              │ [Test] [Save]                 │
│ Enabled: [✓]                │                                │
│ Priority: [WiFi first ▼]   │ Sleep Configuration            │
│ [Save]                      │ Enabled: [ ]                   │
│                              │ Sleep: [15] min                │
│ Modbus Configuration         │ Wake: [300] sec                │
│ Slave Address: [1]           │ [Save]                         │
│ Baud Rate: [9600 ▼]        │                                │
│ Poll Interval: [5] sec      │ Console URL                    │
│ [Save]                      │ [https://console.example.com]  │
│                              │ [Save]                         │
│                                                              │
│ ⚠ Changes are pushed to the device immediately via MQTT.     │
│   The device will apply settings and reconnect as needed.    │
└──────────────────────────────────────────────────────────────┘

Firmware Management Page

┌──────────────────────────────────────────────────────────────┐
│  Firmware Management                        [Upload New]     │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│ Version │ Size   │ Date         │ Devices │ Status │ Action  │
│─────────┼────────┼──────────────┼─────────┼────────┼─────────│
│ v1.2.0  │ 1.2 MB │ May 16, 2026 │ 0 / 24  │ Active │ [Deploy]│
│ v1.1.0  │ 1.1 MB │ May 10, 2026 │ 3 / 24  │ Active │ [Deploy]│
│ v1.0.0  │ 1.0 MB │ May 01, 2026 │ 21 / 24 │ Active │ [Deploy]│
│ v0.9.0  │ 0.9 MB │ Apr 15, 2026 │ 0 / 24  │ Archived│         │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│ Deploy v1.2.0 to:                                            │
│ ( ) All devices (24)                                         │
│ ( ) Group: [Building A ▼] (8 devices)                       │
│ (●) Select devices:                                          │
│     [✓] ACV-001 - Building A (v1.0.0)                        │
│     [✓] ACV-002 - Building B (v1.0.0)                        │
│     [ ] ACV-003 - Warehouse (v0.9.0)                         │
│                                                              │
│ Release Notes:                                               │
│ Added THD monitoring improvements                            │
│                                                              │
│              [Deploy to 2 devices]                            │
└──────────────────────────────────────────────────────────────┘

Alerts Page

┌──────────────────────────────────────────────────────────────┐
│  Alerts                    Unresolved: 5  [Mark All Read]    │
├──────────────────────────────────────────────────────────────┤
│ Filter: [All ▼] [Warning ▼] [Active ▼]  Search: [________]  │
├──────────────────────────────────────────────────────────────┤
│ Sev │ Device    │ Alert          │ Value   │ Time    │ Ack   │
│─────┼───────────┼────────────────┼─────────┼─────────┼───────│
│ ⚠  │ ACV-001   │ Overvoltage    │ 265.3V  │ 2m ago  │ [ ]   │
│ ⚠  │ ACV-015   │ Modbus errors  │ 12%     │ 5m ago  │ [ ]   │
│ ●  │ ACV-008   │ Device offline │ --      │ 1h ago  │ [ ]   │
│   │ ACV-003   │ Low PF         │ 0.82    │ 2h ago  │ [✓]  │
│ ⚠  │ ACV-001   │ Undervoltage   │ 198V    │ 3h ago  │ [✓]  │
├──────────────────────────────────────────────────────────────┤
│ Showing 1-20 of 45 alerts            < 1  2  3 >            │
└──────────────────────────────────────────────────────────────┘

Severity: ● Critical  ⚠ Warning   Info

9.4 SignalR Integration

Real-Time Hook

// useSignalR.ts
function useSignalR() {
    const connection = new HubConnectionBuilder()
        .withUrl("/hubs/devices", { accessTokenFactory: () => getToken() })
        .withAutomaticReconnect()
        .build();

    useEffect(() => {
        connection.start();

        connection.on("DeviceStatusChanged", (deviceId, status) => {
            queryClient.invalidateQueries(["devices"]);
        });

        connection.on("TelemetryReceived", (deviceId, data) => {
            queryClient.setQueryData(["telemetry", deviceId, "latest"], data);
        });

        connection.on("AlertCreated", (deviceId, alert) => {
            queryClient.invalidateQueries(["alerts"]);
            notification.warning({ message: alert.message });
        });

        return () => connection.stop();
    }, []);
}

Live Data Updates

  • Device status badges update in real-time (no page refresh)
  • Telemetry readings update live on device detail page
  • New alerts appear as toast notifications
  • Dashboard counters update automatically

9.5 Authentication Flow

Login Page

┌──────────────────────────────────────┐
│                                      │
│     Tau Acuvim Console               │
│                                      │
│  Email:    [________________]        │
│  Password: [________________]        │
│                                      │
│         [Login]                      │
│                                      │
│  Forgot password?                    │
│                                      │
└──────────────────────────────────────┘

Auth Implementation

// Protected route wrapper
function ProtectedRoute({ children }) {
    const { isAuthenticated } = useAuth();

    if (!isAuthenticated) {
        return <Navigate to="/login" />;
    }

    return children;
}
  • JWT token stored in memory (not localStorage) for security
  • Refresh token in httpOnly cookie
  • Axios interceptor adds Authorization header automatically
  • On 401 response: redirect to login

9.6 Responsive Design

  • Desktop (>1200px): Full sidebar + content layout
  • Tablet (768-1200px): Collapsible sidebar, adjusted grid
  • Mobile (<768px): Bottom navigation, stacked cards, simplified tables

Ant Design's grid system handles responsive breakpoints. Charts resize automatically using ECharts' responsive mode.

9.7 Build and Deploy

Development

cd console/frontend
npm install
npm run dev          # Vite dev server with HMR (port 5173)

Production Build

npm run build        # Output to dist/

Integration with Backend

  • In development: Vite proxy forwards /api and /hubs to the .NET backend
  • In production: the .NET backend serves the built frontend files from wwwroot/
  • vite.config.ts configures the proxy for development
// vite.config.ts
export default defineConfig({
    server: {
        proxy: {
            '/api': 'http://localhost:5000',
            '/hubs': {
                target: 'http://localhost:5000',
                ws: true
            }
        }
    }
});

Docker Integration

Add to the Phase 8 Dockerfile:

# Build frontend
FROM node:18 AS frontend
WORKDIR /app/frontend
COPY console/frontend/package*.json ./
RUN npm ci
COPY console/frontend/ ./
RUN npm run build

# Build backend
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS backend
# ... build steps ...

# Runtime
FROM mcr.microsoft.com/dotnet/aspnet:8.0
# ... copy backend build ...
COPY --from=frontend /app/frontend/dist ./wwwroot/

9.8 Testing & Validation

Test Method Pass Criteria
Login Enter valid credentials Redirected to dashboard
Dashboard loads Navigate to / Summary cards, alerts, grid visible
Device list Navigate to /devices All devices listed with status
Device detail Click a device Overview tab shows live data
Telemetry charts Select Telemetry tab Charts render with historical data
Time range Change to Last 7 days Charts update with correct range
Config push Edit WiFi settings, save Config sent to device via MQTT
WiFi scan Click Scan Networks Networks returned and displayed
Firmware upload Upload a .bin file File uploaded, appears in list
Firmware deploy Deploy to selected devices OTA commands sent
Alert display Trigger alert from device Alert appears in list and as toast
Alert acknowledge Click acknowledge Alert marked as acknowledged
Real-time update Watch dashboard while device publishes Values update without refresh
Responsive Resize browser to mobile Layout adapts correctly
Auth protection Access /devices without login Redirected to /login
CSV export Export telemetry Valid CSV downloaded
Send command Send restart command Device restarts, response received

9.9 Phase 9 Completion Criteria

  • React frontend builds and serves
  • Login/logout flow with JWT authentication
  • Dashboard shows fleet summary, alerts, device grid
  • Device list with filtering, search, pagination
  • Device detail with tabs: Overview, Telemetry, Config, Alerts, Commands, OTA
  • Live telemetry readings update via SignalR
  • Historical telemetry charts with time range selection
  • Remote configuration push (WiFi, MQTT, GSM, sleep, Modbus)
  • WiFi scan triggered from console and results displayed
  • Firmware upload and deployment UI
  • Alert management (list, filter, acknowledge)
  • Responsive design (desktop, tablet, mobile)
  • Integrated into .NET backend for production deployment

Previous Phase: Phase 8 — Console Application Backend Next Phase: Phase 10 — Integration Testing & Production Hardening