import { Hono } from "hono"; import debug from "debug"; import type { DeviceMonitorData, } from "../client/share/monitorTypes.ts"; import { DeleteStatus, } from "../client/share/types.ts"; import type { Variables, WithAuth } from "./middlewares.ts"; import { checkAndTriggerAlert, parseTemperatureHumidity } from "./utils/monitor.ts"; const log = { api: debug("api:monitor"), }; // 创建设备监控数据路由 export function createMonitorDataRoutes(withAuth: WithAuth) { const monitorDataRoutes = new Hono<{ Variables: Variables }>(); // 获取设备监控数据列表 monitorDataRoutes.get("/", withAuth, async (c) => { try { const apiClient = c.get('apiClient'); // 获取分页参数 const page = Number(c.req.query("page")) || 1; const pageSize = Number(c.req.query("pageSize")) || 10; const offset = (page - 1) * pageSize; // 获取筛选参数 const deviceId = c.req.query("device_id") ? Number(c.req.query("device_id")) : null; const deviceName = c.req.query("device_name"); const protocol = c.req.query("protocol"); const address = c.req.query("address"); const metricType = c.req.query("metric_type"); const status = c.req.query("status") ? Number(c.req.query("status")) : null; // 构建查询 let query = apiClient.database .table("device_monitor_data as dmd") .leftJoin("device_instances as di", "dmd.device_id", "di.id") .leftJoin("zichan_info as zi", "di.id", "zi.id") .select( "dmd.*", "di.protocol", "di.address", "zi.asset_name as device_name" ) .where("dmd.is_deleted", DeleteStatus.NOT_DELETED) .orderBy("dmd.collect_time", "desc"); // 应用筛选条件 if (deviceId) { query = query.where("dmd.device_id", deviceId); } if (deviceName) { query = query.where("zi.asset_name", "like", `%${deviceName}%`); } if (protocol) { query = query.where("di.protocol", protocol); } if (address) { query = query.where("di.address", "like", `%${address}%`); } if (metricType) { query = query.where("dmd.metric_type", metricType); } if (status !== null && status !== undefined) { query = query.where("dmd.status", status); } // 获取总记录数 const total = await query.clone().count(); // 获取分页数据 const data = await query.limit(pageSize).offset(offset); return c.json({ data, total: Number(total), page, pageSize, }); } catch (error) { log.api("获取设备监控数据失败:", error); return c.json({ error: "获取设备监控数据失败" }, 500); } }); // 添加监控数据 monitorDataRoutes.post("/", withAuth, async (c) => { try { const data = (await c.req.json()) as Partial; // 验证必填字段 if (!data.device_id) { return c.json({ error: "设备ID不能为空" }, 400); } if (!data.metric_type) { return c.json({ error: "监控指标类型不能为空" }, 400); } if (data.metric_value === undefined || data.metric_value === null) { return c.json({ error: "监控值不能为空" }, 400); } const apiClient = c.get('apiClient'); // 检查设备是否存在 const device = await apiClient.database .table("zichan_info") .where("id", data.device_id) .where("is_deleted", DeleteStatus.NOT_DELETED) .first(); if (!device) { return c.json({ error: "设备不存在" }, 404); } // 插入监控数据 const [id] = await apiClient.database.table("device_monitor_data").insert({ ...data, collect_time: data.collect_time || apiClient.database.fn.now(), created_at: apiClient.database.fn.now(), updated_at: apiClient.database.fn.now(), }); // 获取插入的数据 const [insertedData] = await apiClient.database .table("device_monitor_data") .where("id", id); // 检查并触发告警 await checkAndTriggerAlert(apiClient, insertedData); return c.json({ message: "监控数据添加成功", data: insertedData, }); } catch (error) { log.api("添加监控数据失败:", error); return c.json({ error: "添加监控数据失败" }, 500); } }); // 添加原始温湿度数据接口 monitorDataRoutes.post("/raw", withAuth, async (c) => { try { const { device_id, raw_data } = await c.req.json(); // 验证必填字段 if (!device_id) { return c.json({ error: "设备ID不能为空" }, 400); } if (!raw_data) { return c.json({ error: "原始数据不能为空" }, 400); } const apiClient = c.get('apiClient'); // 检查设备是否存在 const device = await apiClient.database .table("zichan_info") .where("id", device_id) .where("is_deleted", DeleteStatus.NOT_DELETED) .first(); if (!device) { return c.json({ error: "设备不存在" }, 404); } // 解析温湿度数据 const { temperature, humidity, error } = parseTemperatureHumidity(raw_data); if (error) { return c.json({ error }, 400); } // 插入温度数据 await apiClient.database.table("device_monitor_data").insert({ device_id, metric_type: "temperature", metric_value: temperature.value, unit: temperature.unit, status: 1, // 正常状态 collect_time: apiClient.database.fn.now(), created_at: apiClient.database.fn.now(), updated_at: apiClient.database.fn.now(), }); // 插入湿度数据 await apiClient.database.table("device_monitor_data").insert({ device_id, metric_type: "humidity", metric_value: humidity.value, unit: humidity.unit, status: 1, // 正常状态 collect_time: apiClient.database.fn.now(), created_at: apiClient.database.fn.now(), updated_at: apiClient.database.fn.now(), }); return c.json({ message: "温湿度数据添加成功", data: { temperature, humidity } }); } catch (error) { log.api("添加原始温湿度数据失败:", error); return c.json({ error: "添加原始温湿度数据失败" }, 500); } }); return monitorDataRoutes; }