Grafana中基于InfluxDB时序状态数据生成加热系统状态时长饼图的实现方法
Grafana中基于InfluxDB时序状态数据生成加热系统状态时长饼图的实现方法
嘿,我来帮你搞定这个饼图需求!你现在手里的是InfluxDB里的状态变更时序数据——每次加热状态变化时记录时间和新状态,要做饼图就得先算出每个状态在指定时间范围内的总持续时长,我给你一步步拆解:
一、核心思路:计算每个状态的持续时间并汇总
你的原始数据是「状态变更点」,所以每个状态的持续时间 = 下一次状态变更的时间 - 当前状态变更的时间。最后一个状态的持续时间则是时间范围的结束时间减去它的变更时间(因为还没到下一次变更)。
用InfluxQL的SHIFT()函数就能轻松获取下一条记录的时间,再结合COALESCE()处理最后一条数据的边界情况,最后按状态分组求和就行。
二、完整的InfluxDB查询语句
直接用下面的查询替换你现在的语句就行,我已经适配了Grafana的时间变量($timeFilter、$__timeFrom()、$__timeTo()):
SELECT state, -- 把纳秒转换成小时,也可以换成/60000000000得到分钟 SUM(duration)/3600000000000 AS total_duration_hours FROM ( SELECT "value" AS state, -- 计算当前状态的持续时间:下一个状态时间 - 当前时间;最后一条用时间范围结束时间补全 COALESCE(SHIFT(time) - time, $__timeTo() - time) AS duration FROM "state" WHERE ("entity_id"::tag = 'heating_status') AND $timeFilter ) GROUP BY state
代码说明:
SHIFT(time):将下一行的时间戳移到当前行,用来计算当前状态的持续时长COALESCE(a, b):如果a是null(比如最后一条记录没有下一个状态),就用b的值(时间范围的结束时间)- 外层的
SUM(duration):把同一个状态的所有持续时长加起来,转换成小时方便展示
三、Grafana饼图面板设置
查询搞定后,剩下就是在Grafana里配置饼图:
- 新建一个Pie Chart面板,选择你的InfluxDB数据源
- 把上面的查询粘贴到查询编辑器里
- 切换到「Field」标签页:
- 将
state字段设置为Label(饼图的分类标签) - 将
total_duration_hours设置为Value(饼图的数值依据)
- 将
- 切换到「Display」标签页:
- 可以开启「Show values」「Show percentages」,让饼图更直观
- 如果想把时长显示成
21:30这种时分格式,回到「Field」标签页,点击total_duration_hours的格式化按钮,选择「Duration」,然后设置单位为h:mm即可
四、小细节提示
如果你的时间范围(比如某天)开始时,加热系统已经处于某个状态(比如凌晨0点之前就是idle),当前查询不会计算0点到第一次状态变更的时长。如果要补上这部分,可以额外加一个子查询,获取时间范围开始前的最后一个状态,计算它从$__timeFrom()到第一次变更的时长,再合并到结果里——不过对于新手来说,先搞定基础版的查询已经能满足大部分需求啦!
备注:内容来源于stack exchange,提问作者Woozar




