InfluxDB/Grafana return 计数器从零开始

InfluxDB/Grafana return counter starting at zero

我正在监控家中的用水情况,并且我有一个始终向上移动的计数器,它表示自源设备重新启动以来使用的水量(升)。我将其显示在包含 1 天数据的图表上,它很好地指示了用水量。问题是一旦计数器达到几千升就很难阅读图表,因为它显示开始为 10,123,结束为 10,456。我想从图表上的每个值中减去 10,123,使值从零开始。

例如,这是我的查询和结果。我想从返回的每个值中减去 417.388698630137。我很乐意在 Influx 或 Grafana 中找到解决方案。如果解决方案在计数器重置后有效,则可加分。 :-)

> SELECT mean("waterTotalVolumeMeter") 
FROM "detailed_data"."water" 
WHERE time > now() - 6h 
GROUP BY time(1h) fill(null)

name: water
time                mean
----                ----
1592600400000000000 417.388698630137
1592604000000000000 423.9315642458101
1592607600000000000 432.36805555555554
1592611200000000000 443.77777777777777
1592614800000000000 450.3611111111111
1592618400000000000 504.5763888888889
1592622000000000000 544.8134328358209

变化率通常是从计数器计算出来的。 InfluxDB 具有 DERIVATE 函数。但是应该使用 NON_NEGATIVE_DERIVATIVE,因为计数器可以重新启动,负值对于这个用例没有意义。

SELECT NON_NEGATIVE_DERIVATIVE("waterTotalVolumeMeter") 
FROM "detailed_data"."water" 
WHERE time > now() - 6h

文档:https://docs.influxdata.com/influxdb/v1.8/query_language/functions/#non-negative-derivative

查看文档并改进示例查询以满足您的需求。例如,您可能需要根据使用的时间分组指定 unit

我找到了一个似乎有效的解决方案,我不确定它是否是最佳解决方案,但发布它是因为它可能对某些人有用。对于第一个结果,这并不总是 return 0,因为在第一个间隔中可能会有一些计数器增量,但这确实符合我的要求。我 return 编辑了原始值只是为了强调它在做什么。

编辑:我发现您需要设置 fill(previous) 来应对数据中的空白,否则最终结果将不准确并且图表会意外跳转。我还发现它可以很好地应对计数器重置,这就是我们需要 non_negative_derivative.

的原因
SELECT cumulative_sum(non_negative_derivative(mean("waterTotalVolumeMeter"), 1h)), mean("waterTotalVolumeMeter") FROM "detailed_data"."water" WHERE time > now() - 12h GROUP BY time(1h) fill(previous)
name: water
time                cumulative_sum     mean
----                --------------     ----
1592600400000000000 5.993055555555543  416.29008746355686
1592604000000000000 13.93156424581008  423.9315642458101
1592607600000000000 22.368055555555543 432.36805555555554
1592611200000000000 33.77777777777777  443.77777777777777
1592614800000000000 40.361111111111086 450.3611111111111
1592618400000000000 94.57638888888891  504.5763888888889
1592622000000000000 138.69444444444446 548.6944444444445
1592625600000000000 144.27083333333337 554.2708333333334
1592629200000000000 154.91666666666663 564.9166666666666
1592632800000000000 159                569
1592636400000000000 229.09027777777783 639.0902777777778
1592640000000000000 324.88194444444446 734.8819444444445
1592643600000000000 375                785

我还发现这是唯一可以为单个统计数据提供准确结果的方法。如果我们想显示基于计数器的时间间隔内消耗的东西的数量,那么合乎逻辑的方法是从最大值中减去最小值或使用 spread 函数。这些都不能用于计数器重置。为了应对计数器重置,唯一的选择是对所有正增量求和,这就是它所做的。我发现了 3 种在单个统计中使用它的方法:

  1. 保持查询不变,让 Grafana 做最大的事情

SELECT cumulative_sum(non_negative_derivative(mean("waterTotalVolumeMeter"), 1h)) AS X FROM "detailed_data"."water" WHERE time > now() -24h GROUP BY time(1h) fill(previous)

  1. 用原始查询作为子查询做 max influx

SELECT MAX(X) FROM (SELECT cumulative_sum(non_negative_derivative(mean("waterTotalVolumeMeter"), 1h)) AS X FROM "detailed_data"."water" WHERE time > now() - 24h GROUP BY time(1h) fill(previous))

  1. 像这样在 influx 中使用 sum:

SELECT SUM(X) FROM (SELECT non_negative_derivative(mean("waterTotalVolumeMeter"), 1h) AS X FROM "detailed_data"."water" WHERE time > now() - 24h GROUP BY time(1h) fill(previous))