Scaffold Phase 1 hvac app — NewBook-driven room TRV heating scheduler

Ports the state machine, retry/backoff, and guest-override detection from
the retired homeassistant-newbook-heating-component, without depending on
Home Assistant. Backend (Fastify/pg) + frontend (React/Vite/TS) following
standard stack conventions; LXC 128 (127 was already taken by utilities).

MHI/Midea/Daikin/boiler drivers and the shared MQTT broker (LXC 104) are
later phases/infra, not included here.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
jtricerolph 2026-07-26 18:00:42 +00:00
commit 276c04f8c6
42 changed files with 5461 additions and 0 deletions

View file

@ -0,0 +1,25 @@
import { requireAuth, requireCap } from '../auth.js'
import { testConnection } from '../lib/newbook.js'
import { isConnected as mqttConnected } from '../lib/mqtt.js'
// Settings-page-backing endpoints that don't fit the generic config.js key/value
// store: connection tests and the MQTT broker's live status. The Home Assistant
// integration itself is configured centrally in the shared `settings` app, not
// here — this just reports whether it's reachable (via the driver's own no-op
// behaviour when unconfigured).
export async function settingsRoutes(app) {
app.addHook('preHandler', requireAuth)
app.post('/api/settings/newbook-test', { preHandler: requireCap('settings') }, async () => {
return testConnection()
})
app.get('/api/settings/mqtt-status', { preHandler: requireCap('settings') }, async () => {
return {
connected: mqttConnected(),
note: mqttConnected()
? 'Connected to the shared MQTT broker.'
: 'Not connected — the shared MQTT broker (LXC 104) may not be provisioned yet, or hvac-backend has no credentials in settings.',
}
})
}