Adds actual room-temperature capture for TRVs over MQTT and a background Modbus poller for AC mode/fan/lock/room-temp, so the dashboard tile can show real setpoint-vs-actual readings, an AC status block, and up to 3 radiator icons per zone instead of just the setpoint. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
61 lines
2.1 KiB
JavaScript
61 lines
2.1 KiB
JavaScript
import Fastify from 'fastify'
|
|
import cookie from '@fastify/cookie'
|
|
import cors from '@fastify/cors'
|
|
import multipart from '@fastify/multipart'
|
|
import staticFiles from '@fastify/static'
|
|
import { fileURLToPath } from 'url'
|
|
import { dirname, join } from 'path'
|
|
import { initDb } from './db.js'
|
|
import { connect as connectMqtt } from './lib/mqtt.js'
|
|
import { startScheduler } from './lib/scheduler.js'
|
|
import { startAcPoller } from './lib/ac-poller.js'
|
|
import { zoneRoutes } from './routes/zones.js'
|
|
import { deviceRoutes } from './routes/devices.js'
|
|
import { statusRoutes } from './routes/status.js'
|
|
import { overrideRoutes } from './routes/override.js'
|
|
import { configRoutes } from './routes/config.js'
|
|
import { settingsRoutes } from './routes/settings.js'
|
|
import { mhiGatewayRoutes } from './routes/mhi-gateways.js'
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
const UPLOADS_DIR = join(__dirname, '..', 'uploads')
|
|
|
|
const app = Fastify({ logger: true, trustProxy: true })
|
|
const startedAt = Date.now()
|
|
|
|
await app.register(cookie)
|
|
await app.register(cors, {
|
|
origin: process.env.CORS_ORIGIN || false,
|
|
credentials: true,
|
|
})
|
|
await app.register(multipart, { limits: { fileSize: 10 * 1024 * 1024 } })
|
|
await app.register(staticFiles, {
|
|
root: UPLOADS_DIR,
|
|
prefix: '/api/uploads/',
|
|
decorateReply: false,
|
|
})
|
|
|
|
app.get('/health', async () => ({ status: 'healthy', version: process.env.BUILD_VERSION || String(startedAt) }))
|
|
|
|
await app.register(zoneRoutes)
|
|
await app.register(deviceRoutes, { uploadsDir: UPLOADS_DIR })
|
|
await app.register(statusRoutes)
|
|
await app.register(overrideRoutes)
|
|
await app.register(configRoutes)
|
|
await app.register(settingsRoutes)
|
|
await app.register(mhiGatewayRoutes)
|
|
|
|
try {
|
|
await initDb()
|
|
|
|
// MQTT broker (shared infra, LXC 104) may not exist yet — connect() handles that
|
|
// gracefully with its own backoff and never blocks startup.
|
|
connectMqtt().catch(err => app.log.warn(`MQTT connect failed at startup: ${err.message}`))
|
|
|
|
await startScheduler()
|
|
await startAcPoller().catch(err => app.log.warn(`AC poller failed to start: ${err.message}`))
|
|
await app.listen({ port: 3001, host: '0.0.0.0' })
|
|
} catch (err) {
|
|
app.log.error(err)
|
|
process.exit(1)
|
|
}
|