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

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