// server/mihome 模块入口: 汇总导出采集/认证/查询, 并提供 /status 聚合 import { prisma } from '../db.js' import * as vendorStats from './vendorStats.js' import * as history from './history.js' import * as auth from './client.js' export { checkAuth, startQrLogin, cancelQrLogin, getQrState, getQrImageUrl, MihomeAuthError } from './client.js' export { syncNow, dailyMaintenance } from './collector.js' export { getDevice, todayBuckets, monthBuckets, yearBuckets, deviceOverview } from './history.js' export { getSpec, ENV_MODELS } from './specs.js' // GET /api/mihome/status 聚合: 授权 + 家庭(设备) + 统计可用性 + 每设备概览(电量/最新/缺日) export async function getStatus() { const authState = await auth.checkAuth() const [homes, devices, account] = await Promise.all([ prisma.mihomeHome.findMany({ orderBy: { id: 'asc' } }), prisma.mihomeDevice.findMany({ orderBy: { id: 'asc' } }), prisma.mihomeAccount.findUnique({ where: { key: 'default' } }), ]) const overviews = await Promise.all( devices.map(async (d) => { const ov = await history.deviceOverview(d) return { did: d.did, latest: ov.latest, missingDays: ov.missingDays, } }) ) const perDevice = new Map(overviews.map((o) => [o.did, o])) // 统计可用性 (探测过的型号才有值, 未探测 undefined) const capability = {} for (const d of devices) { const v = vendorStats.capabilityOf(d.model) if (v !== undefined) capability[d.model] = v } const homeList = homes.map((h) => ({ homeId: h.homeId, name: h.name, devices: devices .filter((d) => d.homeId === h.homeId) .map((d) => ({ did: d.did, model: d.model, name: d.name, alias: d.alias, title: d.alias || d.name, battery: d.battery, batteryAt: d.batteryAt, lastSyncAt: d.lastSyncAt, latest: perDevice.get(d.did)?.latest ?? null, missingDays: perDevice.get(d.did)?.missingDays ?? [], })), })) return { auth: { status: account?.status || authState.status, lastError: account?.lastError || authState.lastError, checkedAt: authState.checkedAt, }, capability, homes: homeList, } }