50e8519220
- Add 6 renderer components: StatCard, Gauge, List, Progress, AlertBanner, Chart - Add IntegrationWidget container with auto-refresh, loading, error states - Add IntegrationAlertOverlay for layout-level critical alerts - Add IntegrationConfigFields for dynamic form generation from Zod schemas - Register integration type in WidgetRenderer - Extend WidgetCreationForm with integration app/endpoint pickers - Extend AppForm with integration config section and test connection button - Add /api/integrations/alerts endpoint
52 lines
3.1 KiB
Markdown
52 lines
3.1 KiB
Markdown
# Phase 3: NUT/UPS Integration
|
|
|
|
**Status:** ⬜ Not Started
|
|
**Parent plan:** [PLAN.md](./PLAN.md)
|
|
**Domain:** backend
|
|
|
|
## Objective
|
|
Implement the NUT/UPS integration using direct TCP protocol to communicate with NUT servers. This is the only non-HTTP integration — it connects directly to the NUT daemon on port 3493.
|
|
|
|
## Tasks
|
|
|
|
- [ ] Task 1: Create `src/lib/server/integrations/nut/schema.ts` — Zod schemas for auth config (`{ nutHost: string, nutPort: number, upsName: string }`) and endpoint responses.
|
|
- [ ] Task 2: Create `src/lib/server/integrations/nut/client.ts` — NUT TCP protocol client using Node `net` module. Implement commands: `LIST UPS`, `LIST VAR <upsName>`, `GET VAR <upsName> <varName>`. Parse NUT protocol responses. Handle connection timeout and cleanup.
|
|
- [ ] Task 3: Create `src/lib/server/integrations/nut/transform.ts` — Transform raw NUT variables to widget-ready data. Map: `battery.charge` → gauge %, `ups.load` → gauge %, `battery.runtime` → stat-card (formatted as Xh Ym), `ups.status` → alert level (OL=ok, OB=warning, LB=critical).
|
|
- [ ] Task 4: Create `src/lib/server/integrations/nut/index.ts` — Integration implementation. Register with registry. Endpoints: `battery-status` (gauge), `load` (gauge), `runtime` (stat-card), `ups-status` (alert-banner). testConnection: attempt TCP connect + `LIST UPS`.
|
|
- [ ] Task 5: Register NUT integration in `src/lib/server/integrations/registry.ts`.
|
|
- [ ] Task 6: Create API route for NUT alerts `src/routes/api/integrations/alerts/+server.ts` — `GET` returns active critical alerts across all apps with integrations (UPS on battery, etc.). Used by IntegrationAlertOverlay.
|
|
|
|
## Files to Modify/Create
|
|
- `src/lib/server/integrations/nut/schema.ts` — new
|
|
- `src/lib/server/integrations/nut/client.ts` — new
|
|
- `src/lib/server/integrations/nut/transform.ts` — new
|
|
- `src/lib/server/integrations/nut/index.ts` — new
|
|
- `src/lib/server/integrations/registry.ts` — modify: register NUT
|
|
- `src/routes/api/integrations/alerts/+server.ts` — new
|
|
|
|
## Acceptance Criteria
|
|
- NUT client connects to NUT server via TCP and retrieves UPS variables
|
|
- Battery charge displayed as percentage gauge
|
|
- Load displayed as percentage gauge
|
|
- Runtime formatted as human-readable time
|
|
- Status correctly maps OL/OB/LB to alert levels
|
|
- Alert banner fires when status is OB or LB
|
|
- Connection test validates TCP connectivity
|
|
- Handles connection timeouts and refused connections gracefully
|
|
|
|
## Notes
|
|
- NUT protocol is text-based over TCP: send `GET VAR <ups> <var>\n`, receive `VAR <ups> <var> "<value>"\n`
|
|
- Default port: 3493
|
|
- Does NOT use app.url — uses nutHost/nutPort/upsName from extraConfig
|
|
- TCP connections should be short-lived (connect, query, disconnect) — don't keep persistent connections
|
|
- Common UPS variables: battery.charge, battery.runtime, ups.load, ups.status, input.voltage, output.voltage
|
|
|
|
## Review Checklist
|
|
- [ ] All tasks completed
|
|
- [ ] TCP client handles timeouts and errors
|
|
- [ ] No resource leaks (sockets always closed)
|
|
- [ ] Code follows project conventions
|
|
|
|
## Handoff to Next Phase
|
|
<!-- Filled in after completion -->
|