Documentation

IoT 传感器常用查询

以下场景说明了用于从 IoT 传感器数据中提取信息的常用查询

以下所有场景都使用 InfluxDB sample提供的 machineProduction 示例数据集。有关更多信息,请参阅示例数据

计算状态持续时间

在此场景中,我们查看生产线是否运行平稳 (state=OK),以及生产线平稳运行或不平稳运行 (state=NOK) 的时间百分比。如果在间隔期间未记录任何数据点 (state=NaN),您可以选择检索间隔之前的最后一个状态。

要可视化状态持续时间,请参阅 Mosaic 可视化

计算机器在每种状态下花费的时间百分比

  1. 导入 contrib/tomhollingworth/events
  2. 查询 state 字段。
  3. 使用 events.duration() 返回每个数据点之间的时间量(以指定单位),并将间隔存储在 duration 列中。
  4. 按状态值列(在本例中为 _value)、_start_stop 和其他相关维度对列进行分组。
  5. duration 列求和以计算每种状态下花费的总时间量。
  6. 将求和的持续时间透视到 _value 列中。
  7. 使用 map() 计算每种状态下花费的时间百分比。
import "contrib/tomhollingworth/events"

from(bucket: "machine")
    |> range(start: 2021-08-01T00:00:00Z, stop: 2021-08-02T00:30:00Z)
    |> filter(fn: (r) => r["_measurement"] == "machinery")
    |> filter(fn: (r) => r["_field"] == "state")
    |> events.duration(unit: 1h, columnName: "duration")
    |> group(columns: ["_value", "_start", "_stop", "station_id"])
    |> sum(column: "duration")
    |> pivot(rowKey: ["_stop"], columnKey: ["_value"], valueColumn: "duration")
    |> map(
        fn: (r) => {
            totalTime = float(v: r.NOK + r.OK)
    
            return {r with NOK: float(v: r.NOK) / totalTime * 100.0, OK: float(v: r.OK) / totalTime * 100.0}
        },
    )

上面的查询侧重于生产线中报告的状态更改的特定时间范围。

  • range() 定义要查询的时间范围。
  • filter() 定义要筛选的字段 (state) 和 measurement (machinery)。
  • events.duration() 计算点之间的时间。
  • group() 按字段值重新分组数据,因此字段值为 OKNOK 的点被分组到单独的表中。
  • sum() 返回每种状态下花费的持续时间总和。

此时查询的输出为

_valueduration
NOK22
_valueduration
OK172

pivot()_value 列中的每个唯一值创建列,然后将关联的持续时间分配为列值。透视操作的输出为

NOKOK
22172

鉴于以上输出,map() 执行以下操作

  1. 添加 NOKOK 值以计算 totalTime
  2. NOK 除以 totalTime,然后将商乘以 100。
  3. OK 除以 totalTime,然后将商乘以 100。

这将返回

NOKOK
11.3402061855670188.65979381443299

结果表明,生产时间有 88.66% 处于 OK 状态,而 11.34% 的时间处于 NOK 状态。

Mosaic 可视化

mosaic 可视化 随时间显示状态变化。在此示例中,mosaic 可视化根据 state 字段显示不同的彩色图块。

from(bucket: "machine")
    |> range(start: 2021-08-01T00:00:00Z, stop: 2021-08-02T00:30:00Z)
    |> filter(fn: (r) => r._measurement == "machinery")
    |> filter(fn: (r) => r._field == "state")
    |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)

当可视化数据时,可能存在比可用像素更多的数据点。要将数据划分为跨越单个像素的时间窗口,请使用 aggregateWindow,并将 every 参数设置为 v.windowPeriod。使用 last 作为聚合 fn 以返回每个时间窗口中的最后一个值。将 createEmpty 设置为 false,以便结果不包含空时间窗口。

计算时间加权平均值

要计算数据点的时间加权平均值,请使用 timeWeightedAvg() 函数

以下示例查询 machinery measurement 中的 oil_temp 字段。timeWeightedAvg() 函数返回基于 5 秒间隔的油温时间加权平均值。

from(bucket: "machine")
    |> range(start: 2021-08-01T00:00:00Z, stop: 2021-08-01T00:00:30Z)
    |> filter(fn: (r) => r._measurement == "machinery" and r._field == "oil_temp")
    |> timeWeightedAvg(unit: 5s)
输出数据
stationID_start_stop_value
g12021-08-01T01:00:00.000Z2021-08-01T00:00:30.000Z40.25396118491921
g22021-08-01T01:00:00.000Z2021-08-01T00:00:30.000Z40.6
g32021-08-01T01:00:00.000Z2021-08-01T00:00:30.000Z41.384505595567866
g42021-08-01T01:00:00.000Z2021-08-01T00:00:30.000Z41.26735518634935

计算事件之间的值

通过获取特定时间范围内的平均值来计算事件之间的值。

以下场景查询四个生产线开始和结束时的数据。以下查询计算该期间每个研磨站的平均油温。

batchStart = 2021-08-01T00:00:00Z
batchStop = 2021-08-01T00:00:20Z

from(bucket: "machine")
    |> range(start: batchStart, stop: batchStop)
    |> filter(fn: (r) => r._measurement == "machinery" and r._field == "oil_temp")
    |> mean()
输出
stationID_start_stop_value
g12021-08-01T01:00:00.000Z2021-08-02T00:00:00.000Z40
g22021-08-01T01:00:00.000Z2021-08-02T00:00:00.000Z40.6
g32021-08-01T01:00:00.000Z2021-08-02T00:00:00.000Z41.379999999999995
g42021-08-01T01:00:00.000Z2021-08-02T00:00:00.000Z41.2

确定现有值范围内的状态

使用多个现有值来确定状态。以下示例根据 machine-production 示例数据中 pressurepressure-target 字段之间的差异计算状态。要通过比较现有字段来确定状态

  1. 查询要比较的字段(在本例中为 pressurepressure_target)。
  2. (可选)使用 aggregateWindow() 将数据窗口化到基于时间的窗口中,并应用聚合函数(如 mean())以返回表示更大时间窗口的值。
  3. 使用 pivot() 将字段值移动到列中。
  4. 使用 map() 比较或操作不同的字段列值。
  5. 使用 map() 分配状态(在本例中为 needsMaintenance),这基于字段列值的关系。
import "math"

from(bucket: "machine")
    |> range(start: 2021-08-01T00:00:00Z, stop: 2021-08-02T00:00:00Z)
    |> filter(fn: (r) => r["_measurement"] == "machinery")
    |> filter(fn: (r) => r["_field"] == "pressure" or r["_field"] == "pressure_target")
    |> aggregateWindow(every: 12h, fn: mean)
    |> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")
    |> map(fn: (r) => ({ r with pressureDiff: r.pressure - r.pressure_target }))
    |> map(fn: (r) => ({ r with needsMaintenance: if math.abs(x: r.pressureDiff) >= 15.0 then true else false }))
输出
_timeneedsMaintenancepressurepressure_targetpressureDiffstationID
2021-08-01T12:00:00.000Zfalse101.83929080014092104.37786394078252-2.5385731406416028g1
2021-08-02T00:00:00.000Zfalse96.04368008245874102.27698650674662-6.233306424287889g1
_timeneedsMaintenancepressurepressure_targetpressureDiffstationID
2021-08-01T12:00:00.000Zfalse101.62490431541765104.83915260886623-3.214248293448577g2
2021-08-02T00:00:00.000Zfalse94.52039415465273105.90869375273046-11.388299598077722g2
_timeneedsMaintenancepressurepressure_targetpressureDiffstationID
2021-08-01T12:00:00.000Zfalse92.23774168403503104.81867444768653-12.580932763651504g3
2021-08-02T00:00:00.000Ztrue89.20867846153847108.2579185520362-19.049240090497733g3
_timeneedsMaintenancepressurepressure_targetpressureDiffstationID
2021-08-01T12:00:00.000Zfalse94.40834093349847107.6827757125155-13.274434779017028g4
2021-08-02T00:00:00.000Ztrue88.61785638936534108.25471698113208-19.636860591766734g4

该表显示,来自 g4 站的 pressureDiff-19.636860591766734 和来自 g3 站的 -19.049240090497733 高于 15,因此状态发生了变化,将 needMaintenance 值标记为“true”,并且需要对该站进行工作以将该值恢复为 false


此页面是否对您有帮助?

感谢您的反馈!


Flux 的未来

Flux 即将进入维护模式。您可以继续像当前一样使用它,而无需对代码进行任何更改。

阅读更多

现已全面上市

InfluxDB 3 Core 和 Enterprise

快速启动。更快扩展。

获取更新

InfluxDB 3 Core 是一个开源、高速、最近数据引擎,可实时收集和处理数据,并将其持久化到本地磁盘或对象存储。InfluxDB 3 Enterprise 构建在 Core 的基础上,增加了高可用性、读取副本、增强的安全性以及数据压缩,从而实现更快的查询和优化的存储。InfluxDB 3 Enterprise 的免费层可供非商业家庭或业余爱好者使用。

有关更多信息,请查看