You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

新手求助:如何用InfluxDB/Grafana统计24小时内IoT设备状态占比?

统计IoT设备24小时状态占比:InfluxDB查询+Grafana展示指南

嘿,作为刚接触InfluxDB和Grafana的新手,这个统计设备状态占比的需求其实挺常见的,我来一步步给你捋清楚怎么做~

一、先搞定InfluxDB的查询逻辑

核心思路是:先计算每个状态持续的总时长,再除以24小时的总秒数(86400秒)得到占比。下面分InfluxDB 1.x(用InfluxQL)和2.x(用Flux)两种情况说明:

1. InfluxDB 1.x(InfluxQL)

假设你的数据存在名为device_power的测量表(记得替换成你实际的表名),可以用嵌套查询来实现:

SELECT 
  (SUM(elapsed_time) / 86400) * 100 AS percentage,
  -- 把数字状态转成友好名称
  CASE state
    WHEN 0 THEN '关机(off)'
    WHEN 1 THEN '待机(idle)'
    WHEN 2 THEN '运行(on)'
  END AS state_name
FROM (
  -- 计算每个状态持续的秒数:ELAPSED函数会返回当前点和上一个点的时间差(单位1秒)
  SELECT ELAPSED(state, 1s) AS elapsed_time, state
  FROM device_power
  -- 筛选最近24小时的数据
  WHERE time >= now() - 24h
)
-- 按状态分组求和
GROUP BY state

说明

  • 内层查询用ELAPSED()计算相邻两条状态记录的时间差,得到每个状态片段的持续时长
  • 外层查询对每个状态的时长求和,除以86400(24*3600)再乘100,得到百分比
  • CASE WHEN把数字状态转成易读的名称,方便后续Grafana展示

2. InfluxDB 2.x(Flux)

如果用的是InfluxDB 2.x,需要用Flux查询语言,逻辑类似:

// 替换成你的bucket名称和测量表名
data = from(bucket: "iot_bucket")
  |> range(start: -24h)
  |> filter(fn: (r) => r._measurement == "device_power" and r._field == "state")
  |> sort(columns: ["_time"], desc: false) // 按时间正序排列
  |> elapsed(unit: 1s, columnName: "duration") // 计算相邻点的时间差(秒)
  |> filter(fn: (r) => exists r.duration) // 去掉最后一条没有下一个时间点的记录
  |> group(columns: ["_value"]) // 按状态值分组
  |> sum(column: "duration") // 求和每个状态的总时长
  |> map(fn: (r) => ({
      r with
      // 计算百分比,转成友好名称
      state_name: if r._value == 0 then "关机(off)" else if r._value ==1 then "待机(idle)" else "运行(on)",
      percentage: (float(v: r.duration) / 86400.0) * 100.0
    }))

说明

  • elapsed()函数生成每个状态片段的持续时间,filter(fn: (r) => exists r.duration)是为了移除最后一条没有后续时间点的记录(避免空值)
  • map()里同时完成百分比计算和状态名称转换

二、在Grafana中可视化占比

拿到查询结果后,推荐用**饼图(Pie Chart)或者条形图(Bar Chart)**来展示占比,步骤如下:

  1. 新建面板,选择你的InfluxDB数据源(1.x或2.x)
  2. 把上面的查询语句粘贴到查询编辑器中
  3. 配置面板展示:
    • 如果用饼图:在「Panel options」里,把「Legend」设置为state_name(InfluxQL)或state_name(Flux),「Value」选择percentage
    • 如果用条形图:把X轴设为state_name,Y轴设为percentage,可以更直观对比各状态占比
  4. 可选优化:在Grafana的查询别名里直接设置状态名称,或者调整面板样式(比如给不同状态设置对应颜色)

小提醒:避坑要点

  • 如果设备存在断连情况(比如中间没有状态数据),ELAPSED()可能会算出超大的时间差,这时候可以加个过滤条件,比如在内层查询里加WHERE elapsed_time < 3600(忽略超过1小时的异常时长)
  • 如果设备运行不足24小时,想基于实际运行时间计算占比,可以把固定的86400换成查询到的总时长(比如用SUM(elapsed_time)的总和作为分母)

内容的提问来源于stack exchange,提问作者resolver101

火山引擎 最新活动