Files
web-app-launcher/plans/service-integrations/phase-3-nut.md
T
alexei.dolgolyov 50e8519220 feat(service-integrations): phase 2 — integration widget & app form UI
- 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
2026-03-25 22:07:51 +03:00

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 -->