温度平均值图



我有一些温度传感器,我用它们来监测我的环境。我最近已经从在rrd中捕获这些图形并使用rrd绘制图形转变为将数据存储在MySQL中并使用Chart.js绘制图形,因为它为图形的外观和感觉提供了更多选项,如果我想的话,它也给了我将来移动到不同图表库的灵活性。

我的问题更多的是关于什么是存储数据的最佳方法。此刻,我每分钟都在调查温度,并储存所有数据。然后,我使用MySQL查询来获取以下数据:

  1. Last Hour - MySQL查询提取最近60个读数(输出60个值)
  2. Last Day - MySQL查询每小时平均60个读数(输出24个值)
  3. 上周- MySQL查询平均每小时读数的一天平均值(输出7个值)

我真的不确定这是获得每日和每周读数的最佳方法,然后我还想要每月和每年的读数。

谁能提出一个更好的方法来处理这些数据?更好的查询,因为它们是相当密集的数学,它是更好的存储每月读数在平均读数的另一个表,我应该多久平均一次数据?

请帮忙!(也不确定把它放在堆栈溢出的哪个类别):)

概述

这不是一件容易的事。您将看到大量后端工作和绘图。画了很多图。所以我做这一切都是为了你。

根据我的理解,您需要以下内容:

  1. 能够取温度值的平均值。
  2. 能够对数据进行排序/按周、月等显示数据
  3. 有一个好看的,现代的,交互式的图表/图形。
  4. 以一种干净、高效、有效的方式存储和处理数据。

这整个答案都是基于我对Flot的了解,并且假设你将使用它,但是这里的大部分知识和代码可以应用于几乎所有的javascript图表库。

<标题>

1。平均价值Flot有一个平均插件,它在图形上放置一条线来表示平均值。这可以让你看到温度随时间在平均值附近波动的图形。我会想象一个昼夜之间的正弦曲线。这对我来说已经足够好了,但我确实想要一个实际的平均值。

使用这里Array链接中的Sum值,如果稍微修改一下代码,我们可以从Flot期望的数据格式中提取平均值。我已经这样做了。

var myData = [['2013-01-22', 0], ['2013-01-29', 1], ['2013-02-05', 21]];
var myTotal = 0;  // Variable to hold your total
var myAverage = 0; // Variable to hold your average
var myNumber = 0; // Variable to hold the number of items to divide by
for(var i = 0, len = myData.length; i < len; i++) {
myTotal += myData[i][1];  // Iterate over your first array and then grab the second element add the values up
myNumber++; // This will give us the number of items we added
}
myAverage = myTotal / myNumber;
document.write(myTotal); // 22 in this instance
document.write(myNumber); // 3 in this instance (useful for knowing how many data points you have)
document.write(myAverage); // 7.3 in this instance

我不知道你说的

是什么意思

我应该多久平均一次数据?

不确定你是想摆脱数据点,还是只想要一个平均值,还是…但你不需要去掉数据点。平均值在上面。如果你迫切希望用更少的数据点来节省空间/处理时间,那么有一个用于Flot的Downsample插件,它可以在不产生明显差异的情况下删除数据点,正是出于这个原因。

<标题>

2。显示数据再次假定您最终将使用Flot,此函数内置于Flot中。我想您已经为收集的数据设置了时间戳。通过在Flot中绘制时间图,您可以使用按钮轻松显示一个月,两个月,最后一天的数据……任何你想要的时间段。这在这个示例Time Series Interaction中显示。

如果你想要一个更好的交互性形式,请查看Flot的交互性示例。

<标题>

3。一个好看的图表这是Flot的自然属性!你可以调整不同区域的颜色,选择填充或不填充,但实际上,它们看起来已经很好了。

<标题>4。存储和使用数据

现在,这里有三个结果,但我只讲两个。

  1. 你把你的数据保存在数据库中。
  2. 你恢复使用日志文件。
  3. 你是实时的(未覆盖)。

概述这部分试图回答

我的问题更多的是关于什么是存储数据的最佳方法。此刻,我每分钟都在调查温度,并储存所有数据。然后,我使用MySQL查询来获取以下数据:

Last Hour - MySQL查询提取最近60个读数(输出60个值)最后一天- MySQL查询平均60个读数为一个小时的平均值(输出24个值)上周- MySQL查询平均每小时读数的一天平均值(输出7个值)我真的不确定这是获得每日和每周读数的最佳方法,然后我还想要每月和每年的读数。

谁能提出一个更好的方法来处理这些数据?更好的查询,因为它们是相当密集的数学,将每月读数存储在平均读数的另一个表中是否更好

在我个人看来,存储数据的最佳方法是按照图表库所需的格式存储数据。然而,如果你不是实时的,你可以使用任何最简单的方法,因为你不会很快加载数以百万计的数据点,这应该无关紧要/产生太大的差异。

我假设你使用日志的RRDtool,现在MySQL。对于获得每日和每周阅读的最佳方法,我认为这与MySQL无关。后端的工作是收集、存储和呈现数据。前端(即Flot)将为您对这些数据进行排序,并呈现每日和每周的读数,如第二部分所述。这将为您省去这些复杂的查询。

对于更好地处理数据,我的建议是让后端不使用查询和平均等单独文件处理数据,而是简单地将其呈现给Flot,并让Flot处理数据以仅呈现您想要的数据。现在让后端绘制数据图…

Flot将需要以下格式的数据:

[[timestamp, data], [timestamp, data]]

让我们把它放在那里。

1。MySQL/PHP

好了,所以你就懒得回到log了。或者你从来没用过,随便哪一个。

你必须用正确的时间戳将MySQL值转换成正确的格式。嗯。现在,我不知道您是如何存储时间戳的,所以让我们假设您利用了每分钟轮询一次数据的知识(crontab?)。我们不知道你是什么时候开始轮询这些数据的,所以我们必须随着时间的推移而回溯。

首先,获取数据。

我发现这个Export MySQl Table To File非常快。下面的代码将从MySQL表中获取数据并将其写入文件。方便。我假设每个值都有一个新行。

<?php
$pdo = new PDO(...);
$results = $pdo->query("SELECT * FROM myTable INTO OUTFILE 'data.txt'");
$dummy = $result->fetchAll(); 
?>

。我们已经将数据保存在一个文件中,现在是时间戳。

<?php
$time = time() * 1000;
$file = fopen("data.txt", "w+");
foreach(file("data.txt") as $line) {
if ($file > 0) {
$write = ", [" . $time . ", " . $line . "]";
fwrite($file, $write);
} else {
$write = "[" . $time . ", " . $line . "]";
fwrite($file, $write);
}
$time = $time - 60000;
}
fclose($file);
?>

好的,让我逐行解释。

javascript库将期望以毫秒为单位的epoch时间,但PHP以秒为单位表示,因此将其乘以1000。

接下来,我们要将数据输出写入文件。这很容易在Flot中定义,也为您以后提供了更大的灵活性。因此,我们提前打开该文件,以表示每次解析新行时都会打开该文件。

然后我们逐行检查,并以适当的格式将数据写入文件,并在前面加上时间戳。这里假设刚刚收集了数据。

然后,每次迭代返回一分钟(60000毫秒),所以它在时间上向后工作。Flot将为您处理。

然后关闭文件。

之后,Flot可以从文件中读取数据。很好地完成了。

2。PHP/日志

好,这很有趣。你恢复到使用RRDtool的日志格式,我完全假设它有。

我将用下面的代码引导您。

<?php
$file = fopen("log.txt", "r");
$tempOneFile = fopen("tempOne.txt", "w+");
$tempTwoFile = fopen("tempTwo.txt", "w+");
while ($first = fscanf($file, "%st%st%sn")) {
list ($timestamp, $temperatureone, $temperaturetwo) = $first;
$time = $timestamp * 1000;
if ($file > 0) {
$one = ", [" . $time . ", " . $temperatureone . "]";
$two = ", [" . $time . ", " . $temperaturetwo . "]";
$fwrite($tempOneFile, $one);
$fwrite($tempOneFile, $two);
} else {
$one = "[" . $time . ", " . $temperatureone . "]";
$two = "[" . $time . ", " . $temperaturetwo . "]";
$fwrite($tempOneFile, $one);
$fwrite($tempOneFile, $two);
}
}
fclose($file);
?>

Ok。因此,可能有更好的方法来处理数据,但我个人喜欢用正确的格式创建数据文件。它很容易阅读,而且,如你所愿,它是非常灵活的。

对日志文件执行此操作。

3。实时/Nodejs

一开始很吓人,从PHP/MySQL到实时javascript和web套接字等等。但也没那么糟。基本上,您通过web套接字传输数据。但我不会涉及这个,因为它不是你需要的温度。

结论

我希望这个极长的回答涵盖了你的问题。下一步实际上是使用Flot将数据转换为图形。在整个回答过程中,我对数据的格式做了很多假设。请不要害怕评论,如果有些东西不起作用,是不同的,你不知道如何使用它或类似的事情。谢谢你!

最新更新