Tau.Acuvim/CLAUDE.md
Renier Forster 99864d0a8b Add CLAUDE.md project onboarding guide
Build commands, architecture overview, library gotchas, and conventions
for the firmware, backend, and frontend components.

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

96 lines
3.4 KiB
Markdown

# Tau Acuvim - IoT Power Meter Monitoring System
## What This Is
IoT platform for monitoring Acuvim II power meters via ESP32 devices. Three components:
1. **Firmware** (`firmware/`) - ESP32-WROVER-B (TTGO T-Call v1.4) C++ firmware, PlatformIO + Arduino
2. **Console Backend** (`console/src/Tau.Acuvim.Console/`) - .NET 10 minimal API + PostgreSQL
3. **Console Frontend** (`console/frontend/`) - React 18 + TypeScript + Vite + Ant Design 5
## Build & Run
### Firmware
```bash
cd firmware
pio run # Build
pio test -e native # Run unit tests (28 tests)
pio run -t upload # Flash to ESP32
pio run -t uploadfs # Upload SPIFFS (captive portal)
```
### Console Backend
```bash
cd console/src/Tau.Acuvim.Console
dotnet build
dotnet run # Starts on http://localhost:5000
```
### Console Tests
```bash
cd console/tests/Tau.Acuvim.Console.Tests
dotnet test # 23 xUnit tests
```
### Console Frontend
```bash
cd console/frontend
npm install
npm run dev # Dev server on http://localhost:5173, proxies to :5000
npm run build # Production build to dist/
```
### Docker (Production)
```bash
cd console
docker compose -f docker-compose.prod.yml up -d
```
## Architecture
### Firmware
- RS485 Modbus RTU reads Acuvim II registers (IEEE 754 Float32)
- WiFi STA+AP concurrent mode; GSM/GPRS failover via TinyGSM/SIM800L
- MQTT for telemetry (QoS 0), commands (QoS 1), heartbeat, alerts
- SD card offline buffering (JSONL, non-blocking drain)
- OTA updates with dual partition rollback; watchdog + crash loop detection
- Captive portal provisioning at 192.168.4.1
### Console Backend
- Minimal API pattern — endpoints in `Endpoints/*.cs`, services in `Services/*.cs`
- PostgreSQL via EF Core with Npgsql; JSONB columns for telemetry data
- MQTTnet 5.x bridge (`MqttBridgeService`) subscribes to device topics
- SignalR hub at `/hubs/devices` for real-time frontend updates
- JWT auth with rate limiting on auth endpoints
### Console Frontend
- Pages in `src/pages/`, components in `src/components/`
- API layer in `src/api/`, hooks in `src/hooks/`
- TanStack Query for data fetching with SignalR cache invalidation
- ECharts for telemetry visualization
## Key Conventions
- **No development without explicit user instruction** — do not proactively add features or refactor
- Firmware pin assignments are in `firmware/include/pin_config.h` — authoritative source
- Modbus register map is in `firmware/include/acuvim_registers.h`
- MQTT topic structure: `acuvim/{device_id}/{topic}` — protocol spec in `docs/mqtt-protocol.md`
- 20 MQTT commands defined in `firmware/src/command_handler.cpp`
- Swagger UI available at `/swagger` in development
## Library Gotchas
- **Swashbuckle 10.x**: Uses `Microsoft.OpenApi` namespace (not `Microsoft.OpenApi.Models`). `AddSecurityRequirement` takes a factory delegate. See Program.cs.
- **MQTTnet 5.x**: `PayloadSegment` has no getter — use `Payload.ToArray()` with `System.Buffers`.
- **EF Core InMemory + JsonDocument**: Needs `ValueConverter<JsonDocument?, string?>` — see `TestHelpers.cs`.
## Specs & Docs
- 10-phase specification: `docs/acuvim-spec-01.md` through `docs/acuvim-spec-10.md`
- Deployment: `docs/deployment-guide.md`
- Field installation: `docs/device-commissioning.md`
- MQTT protocol: `docs/mqtt-protocol.md`
- Wiring: `docs/hardware-wiring.md`
- Troubleshooting: `docs/troubleshooting.md`
- Integration tests: `docs/integration-test-scenarios.md`