ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Grafana实例-设备闲置状态>15min

2026/8/27 13:15:49 拓冰建站 浏览量
Grafana实例-设备闲置状态>15min Grafana8.2.7 InfluxDB1.x ECharts2.2.4 对设备运行状态闲置超过15分钟的次数进行统计一、基础查询SELECT valueInt FROM prod_process_values WHERE (topic CT/OESL/AS/CHN/QDA/HCS/Extrusion_Area/ERS104_Extrusion_Line/MachineState) AND time ${__from}ms AND time ${__to}ms -12h二、EChart 面板 JS 设备闲置15min常规获取数据的功能functionconsole.log( 完整 Grafana 数据结构 , data); console.log( 数据系列列表 , data.series); console.log( 查询状态 , data.state); console.log( 数据系列数量 , data.series.length); /** * 按refId查找数据系列 * param {Object|null|undefined} data - 根数据对象 * param {string} refId - 查询ID如A、B、C * returns {Object|null} 数据系列对象 */ function getSeriesByRefId(data, refId) { // 安全校验根对象不存在 / series不是数组 直接返回null if (!data || !Array.isArray(data.series)) { return null; } return data.series.find(s s.refId refId) ?? null; } /** * 从Grafana数据系列中提取指定名称字段的buffer数组 * param {Object|null|undefined} series - 单个数据系列对象 * param {string} fieldName - 字段名称如Time、Value * returns {Array} field.values.buffer 原始数组无数据返回[] */ function getFieldValues(series, fieldName) { // 校验series和fields数组 if (!series || !Array.isArray(series.fields)) { return []; } const field series.fields.find(f f.name fieldName); // 逐层判空字段存在 → values存在 → 有buffer则返回否则空数组 if (!field || !field.values || field.values.buffer null) { return []; } return field.values.buffer; }; // 提取数据查询A const Series getSeriesByRefId(data, A); const Times getFieldValues(Series, Time); const Values getFieldValues(Series, Value); console.log(Series:,Series); console.log(Times:,Times); console.log(Values:,Values);实际代码示例// console.log( 完整 Grafana 数据结构 , data); // console.log( 顶层 series 数组 , data?.series ?? []); // console.log( 查询状态 , data?.state); // console.log( 系列总数 , Array.isArray(data?.series) ? data.series.length : 0); /** * 工具安全判断有效非空数组 * param {*} arr * returns {boolean} */ function isSafeArray(arr) { return Array.isArray(arr) arr.length 0; } /** * 按 refId 匹配返回对应单条系列对象 * param {Object|null|undefined} data Grafana 根数据 * param {string} refId 查询标识 A/B/C * returns {Object|null} 单个series对象 */ function getSeriesByRefId(data, refId) { if (!data || !isSafeArray(data.series)) return null; return data.series.find(item item.refId refId) || null; } /** * 根据字段固定下标提取数值数组 * 约定fields[0] Timefields[1] valueInt * param {Object|null} singleSeries 单个series对象 * param {number} fieldIndex 0Time / 1valueInt * returns {Array} 数据数组无数据返回[] */ function getFieldByIndex(singleSeries, fieldIndex) { // 校验series和fields数组 if (!singleSeries || !isSafeArray(singleSeries.fields)) return []; // 下标越界直接返回空 if (fieldIndex 0 || fieldIndex singleSeries.fields.length) return []; const targetField singleSeries.fields[fieldIndex]; if (!targetField?.values) return []; // 兼容 Grafana 两种存储格式buffer / 直接values数组 const valueList targetField.values.buffer ?? targetField.values; return isSafeArray(valueList) ? valueList : []; } // 业务提取逻辑 // 1. 根据refId获取目标单系列对象 const targetSeriesItem getSeriesByRefId(data, A); // 2. 按下标分别提取时间、数值 const timeArr getFieldByIndex(targetSeriesItem, 0); // fields[0] Time const valueArr getFieldByIndex(targetSeriesItem, 1); // fields[1] valueInt console.log(时间数组 Time(fields[0]), timeArr); console.log(整型数组 valueInt(fields[1]), valueArr); // 配置常量闲置状态值、阈值15分钟毫秒 const IDLE_STATE 0; // 自行替换你实际代表闲置的valueInt数值 const THRESHOLD_MS 15 * 60 * 1000; // 15分钟毫秒数 let over15MinIdleCount 0; // 2. 数据校验无数据直接次数0 if (timeArr.length 2 || valueArr.length ! timeArr.length) { over15MinIdleCount 0; } else { let currentIdleStartTs null; // 记录一段闲置起始时间戳 for (let i 0; i timeArr.length; i) { const ts timeArr[i]; const state valueArr[i]; if (state IDLE_STATE) { // 当前是闲置未记录起始则初始化 if (currentIdleStartTs null) { currentIdleStartTs ts; } } else { // 退出闲置状态计算本段闲置时长 if (currentIdleStartTs ! null) { const durationMs ts - currentIdleStartTs; if (durationMs THRESHOLD_MS) { over15MinIdleCount 1; } currentIdleStartTs null; // 重置闲置起始 } } } console.log( 闲置次数 , over15MinIdleCount); // 处理时间段末尾仍处于闲置的片段最后一段闲置未结束 if (currentIdleStartTs ! null) { // 用查询窗口最后时间作为结束时间 const windowEndTs timeArr[timeArr.length - 1]; const durationMs windowEndTs - currentIdleStartTs; if (durationMs THRESHOLD_MS) { over15MinIdleCount 1; } } } // 3. ECharts配置纯文本红底白字隐藏所有图表元素 return { backgroundColor: transparent, title: { text: ${over15MinIdleCount}, left: center, top: middle, textStyle: { fontSize: 36, color: #ff0000, fontWeight: bold } }, xAxis: {show:false}, yAxis: {show:false}, series:[] }