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
3.1 KiB
3.1 KiB
Phase 3: NUT/UPS Integration
Status: ⬜ Not Started Parent plan: 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 Nodenetmodule. 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—GETreturns 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— newsrc/lib/server/integrations/nut/client.ts— newsrc/lib/server/integrations/nut/transform.ts— newsrc/lib/server/integrations/nut/index.ts— newsrc/lib/server/integrations/registry.ts— modify: register NUTsrc/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, receiveVAR <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