From 1d69915cf3aa764acbd9ee5b806c61879bea76b4 Mon Sep 17 00:00:00 2001 From: "jif2.zhang" Date: Mon, 21 Sep 2026 11:52:24 +0800 Subject: [PATCH] =?UTF-8?q?=E7=B1=B3=E5=AE=B6=E8=B0=83=E5=BA=A6=E7=8B=AC?= =?UTF-8?q?=E7=AB=8B=E6=A8=A1=E5=9D=97=E6=B3=A8=E5=86=8C,=20=E9=81=BF?= =?UTF-8?q?=E5=85=8D=E8=A2=AB=E5=AE=B9=E5=99=A8=E4=B8=AD=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E7=9A=84=E6=97=A7=20cron.js=20=E8=BF=9E?= =?UTF-8?q?=E5=B8=A6=E5=A4=B1=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/cron.js | 36 ------------------------------------ server/index.js | 3 +++ server/mihome/scheduler.js | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 36 deletions(-) create mode 100644 server/mihome/scheduler.js diff --git a/server/cron.js b/server/cron.js index 0dd088e..8bc0bbd 100644 --- a/server/cron.js +++ b/server/cron.js @@ -5,7 +5,6 @@ import { fetchNewsList, persistNews } from '../scripts/fetchers/news.fetcher.js' import { checkAfterRefresh } from './alert-engine.js' import { insertCronAlert } from '../scripts/lib/cron-alert.js' import { ApizeroError, oil, history } from './apizero/index.js' -import * as mihome from './mihome/index.js' function parseUrl(url) { const u = new URL(url) @@ -78,38 +77,3 @@ function scheduleOilHistory() { scheduleNews() scheduleOilHistory() - -// 环境监控: 每小时 5 分小时采样 + 每日 03:05 聚合/电量/vendor 历史补齐 (Asia/Shanghai) -// 整点 +5min 缓冲, 避开米家高峰 -function scheduleMihome() { - cron.schedule('5 * * * *', async () => { - console.log('[cron] 米家小时采样触发 @ 上海 xx:05') - try { - const r = await mihome.syncNow() - console.log('[cron] 米家采样完成: 家庭=' + r.homes + ' 设备=' + r.devices + ' 采样=' + r.sampled + ' 聚合=' + r.aggregated + ' (' + r.ms + 'ms)') - } catch (e) { - console.error('[cron] 米家小时采样失败:', e.message) - } - }, { timezone: 'Asia/Shanghai' }) - console.log('[cron] 已注册: 每小时 xx:05 米家温湿度采样') - - cron.schedule('5 0,3 * * *', async () => { - console.log('[cron] 米家每日维护触发 (00:05 / 03:05)') - try { - const r = await mihome.dailyMaintenance() - console.log('[cron] 米家聚合完成: 采样=' + r.sampled + ' 聚合=' + r.aggregated - + ' vendor小时=' + r.vendorHours + ' vendor天=' + r.vendorDays + ' 缺口聚合=' + r.gapAggregated) - } catch (e) { - console.error('[cron] 米家每日维护失败:', e.message) - } - }, { timezone: 'Asia/Shanghai' }) - console.log('[cron] 已注册: 每天 00:05/03:05 米家日聚合 + vendor 补齐') - - // 启动追赶: 服务重启/停机恢复后立即补一次 (不打断 5 分钟内的整点采样) - setTimeout(() => { - mihome.dailyMaintenance().catch((e) => console.error('[cron] 米家启动追赶失败:', e.message)) - }, 8000) - console.log('[cron] 已注册: 启动后 8s 执行米家追赶同步') -} - -scheduleMihome() diff --git a/server/index.js b/server/index.js index 8f00352..60372a3 100644 --- a/server/index.js +++ b/server/index.js @@ -58,6 +58,9 @@ app.use((err, _req, res, _next) => { // 启动定时任务: 每天凌晨 3 点拉取新闻 import('./cron.js').catch((e) => console.error('[cron] 加载失败:', e.message)) +// 米家环境监控定时调度 (独立注册, 不与 cron.js 绑定, 见 server/mihome/scheduler.js) +import('./mihome/scheduler.js').catch((e) => console.error('[cron] 米家调度注册失败:', e.message)) + app.listen(PORT, () => { console.log(`[iboard-api] listening on http://127.0.0.1:${PORT}`) console.log(`[iboard-api] static dist: ${HAS_DIST ? DIST_DIR : '(not built, API only)'}`) diff --git a/server/mihome/scheduler.js b/server/mihome/scheduler.js new file mode 100644 index 0000000..11d7d4a --- /dev/null +++ b/server/mihome/scheduler.js @@ -0,0 +1,38 @@ +// 米家环境监控定时调度 +// 独立于 server/cron.js 注册: 容器镜像不含 scripts/, 旧 cron.js 顶层 import 脚本模块会整体加载失败, +// 故米家节拍不依赖它, 由 server/index.js 单独加载本模块, 确保采样/聚合在部署环境一定生效。 +import cron from 'node-cron' +import * as mihome from './index.js' + +export function registerMihomeScheduler() { + cron.schedule('5 * * * *', async () => { + console.log('[cron] 米家小时采样触发 @ 上海 xx:05') + try { + const r = await mihome.syncNow() + console.log('[cron] 米家采样完成: 家庭=' + r.homes + ' 设备=' + r.devices + ' 采样=' + r.sampled + ' 聚合=' + r.aggregated + ' (' + r.ms + 'ms)') + } catch (e) { + console.error('[cron] 米家小时采样失败:', e.message) + } + }, { timezone: 'Asia/Shanghai' }) + console.log('[cron] 已注册: 每小时 xx:05 米家温湿度采样') + + cron.schedule('5 0,3 * * *', async () => { + console.log('[cron] 米家每日维护触发 (00:05 / 03:05)') + try { + const r = await mihome.dailyMaintenance() + console.log('[cron] 米家聚合完成: 采样=' + r.sampled + ' 聚合=' + r.aggregated + + ' vendor小时=' + r.vendorHours + ' vendor天=' + r.vendorDays + ' 缺口聚合=' + r.gapAggregated) + } catch (e) { + console.error('[cron] 米家每日维护失败:', e.message) + } + }, { timezone: 'Asia/Shanghai' }) + console.log('[cron] 已注册: 每天 00:05/03:05 米家日聚合 + vendor 补齐') + + // 启动追赶: 服务重启/停机恢复后立即补一次 (不打断 5 分钟内的整点采样) + setTimeout(() => { + mihome.dailyMaintenance().catch((e) => console.error('[cron] 米家启动追赶失败:', e.message)) + }, 8000) + console.log('[cron] 已注册: 启动后 8s 执行米家追赶同步') +} + +registerMihomeScheduler() \ No newline at end of file