Documentation

物联网传感器常见问题

以下场景展示了用于提取IoT传感器数据的信息的常见查询:

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

计算状态中的时间

在这种情况下,我们查看生产线是否顺利运行 (state=OK),以及生产线顺利运行或不顺利运行的时间百分比 (state=NOK)。如果在该时间段内没有记录任何数据 (state=NaN),您可以选择检索该时间段之前的最后状态。

要可视化状态时间,请参见 Mosaic visualization

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

  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) 和测量 (machinery)。
  • events.duration() 计算两个点之间的时间。
  • group() 按字段值重新分组数据,因此具有 OKNOK 字段值的点被分组到不同的表中。
  • sum() 返回每个状态花费的持续时间的总和。

此时查询的输出为:

_值持续时间
不良22
_值持续时间
好的172

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

不合格合格
22172

根据上面的输出, map() 执行以下操作:

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

这将返回:

不合格合格
11.3402061855670188.65979381443299

结果显示,生产在OK状态下的时间占88.66%,而在NOK状态下的时间占11.34%。

马赛克可视化

马赛克可视化展示了随时间变化的状态。 在这个例子中,马赛克可视化根据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测量中的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)
输出数据
站点编号开始时间结束时间数值
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()
输出
站点编号开始时间结束时间数值
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

确定一个具有现有值的状态

使用多个现有值来确定状态。 以下示例根据机器生产样本数据中 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 }))
输出
时间需要维护压力目标压力压力差站点ID
2021-08-01T12:00:00.000Z错误101.83929080014092104.37786394078252-2.5385731406416028g1
2021-08-02T00:00:00.000Zfalse96.04368008245874102.27698650674662-6.233306424287889g1
时间需要维护压力目标压力压力差站点ID
2021-08-01T12:00:00.000Zfalse101.62490431541765104.83915260886623-3.214248293448577g2
2021-08-02T00:00:00.000Zfalse94.52039415465273105.90869375273046-11.388299598077722g2
时间需要维护压力目标压力压力差站点ID
2021-08-01T12:00:00.000Z92.23774168403503104.81867444768653-12.580932763651504g3
2021-08-02T00:00:00.000Z89.20867846153847108.2579185520362-19.049240090497733g3
时间需要维护压力目标压力压力差站点ID
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 开源版本现已公开Alpha测试

InfluxDB 3 Open Source is now available for alpha testing, licensed under MIT or Apache 2 licensing.

我们将发布两个产品作为测试版的一部分。

InfluxDB 3 核心,是我们新的开源产品。 它是一个用于时间序列和事件数据的实时数据引擎。 InfluxDB 3 企业版是建立在核心基础之上的商业版本,增加了历史查询能力、读取副本、高可用性、可扩展性和细粒度安全性。

有关如何开始的更多信息,请查看:

由TSM驱动的InfluxDB Cloud