使用 Bluemix 中的 Time Series Database 处理家庭监视数据

随着家庭自动化越来越普及,记录统计数据的传感器数量和提供该数据所需的信息也越来越多。通过使用Bluemix 中的 Time Series Database,您可以轻松地记录记录了时间的数据,并查询和报告该数据。在本教程中,我们将介绍如何使用 Time Series Database 来创建、存储并最终报告信息。我们还将使用该数据库跨多个传感器关联数据点,跟踪一个多区域住宅里的供热系统的效率。

                   


创建核心应用程序

 

我们的应用程序的核心是一个 Node.js 应用程序,它被连接到后端(也就是 Time Series Database)。

首先,在 Bluemix 仪表板中创建一个新的 Node.js 应用程序:

  1. 登录到 Bluemix
  2. 单击 Create an App
  3. 单击 Node.js App Starter 并配置您的应用程序参数。

创建您的应用程序并为其命名后,添加一个新的服务,即 Time Series Database。

完成这个步骤后,需要访问该代码。我喜欢下载软件包,然后使用 cf 命令行工具与该流程交互。这为我提供了快速更改,然后使用 cf push 更新正在运行的 Bluemix 实例上的版本的功能。

无论您希望如何与代码交互和处理它,您应用程序的核心都是在应用程序包的顶级目录中创建的 app.js 文件。

在该文件中有不同的部分。顶部的一节包含配置信息和核心集成,用于确定应用程序应如何连接其他组件。以下代码显示了这个标头部分的示例。

  
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 
 
 
/*jshint node:true*/
// app.js
// This file contains the server-side JavaScript code for your application.
// This sample application uses express as the web application framework ( http://expressjs.com/ ),
// and jade as the template engine ( http://jade-lang.com/ ).
var express = require( 'express' );
// setup middleware
var app = express();
var fs = require( 'fs' );
app.use(app.router);
app.use(express.errorHandler());
app.use(express. static (__dirname + '/public' )); //setup static public directory
app.set( 'view engine' , 'jade' );
app.set( 'views' , __dirname + '/views' ); //optional because express defaults to CWD/views
// render index page
app.get( '/' , function (req, res){
res.render( 'index' );
});
// There are many useful environment variables available in process.env.
// VCAP_APPLICATION contains useful information about a deployed application.
var appInfo = JSON.parse(process.env.VCAP_APPLICATION || "{}" );
// TODO : Get application information and use it in your app.
// VCAP_SERVICES contains all the credentials of services bound to
// this application. For details of its content, please refer to
// the document or sample of each service.
var services = JSON.parse(process.env.VCAP_SERVICES || "{}" );
// TODO : Get service credentials and communicate with bluemix services.
// The IP address of the Cloud Foundry DEA (Droplet Execution Agent) that hosts this application:
var host = (process.env.VCAP_APP_HOST || 'localhost' );
// The port on the DEA for communication with the application:
var port = (process.env.VCAP_APP_PORT || 3000 );

这里有很多行,其中许多行仅在初始化时使用。最重要的一行将会获取当前服务的信息:

  
  
1
 
var services = JSON.parse(process.env.VCAP_SERVICES || "{}" );

此过程抓取的信息包括您应用程序中所有已配置的服务的访问信息。具体地讲,它将包含用于访问您的 Time Series Database 的 URL 和凭据。

另一个重要的代码段将会确定在访问您应用程序中某个特定 URL 时执行的操作:

  
  
1
2
3
4
 
// render index page
app.get( '/' , function (req, res){
res.render( 'index' );
});

在本例中,只要 myapp.bluemix.net/(根或索引)被访问,Node.js 应用程序就会直接响应或调用另一个函数。在这里,我们使用了调用 render() 函数的内联 JavaScript 函数调用另一个函数。这是 res (response) 对象上的一个方法,基本上讲,它会读取该文件的内容并返回一个索引文档。

请求传递到该函数,展示对采用这种方法调用所有函数都很有用的一个元素。请求包含 URL 信息和任何可能包含在 URL 内的查询参数。本教程后面将讨论如何处理该信息。

无论对每个元素的响应是什么,一个重要事实是:app.get() 函数定义一个路线来将访问的 URL 映射到一个需要返回的操作、函数或页面。请记住,我们实质上是在一个 JavaScript 应用程序的界限内运行此应用程序,所以我们必须拥有一种在访问的 URL 与响应之间建立连接的方法。app.get() 方法是一个注册 URL 和该 URL 对应用程序的含义的方法。

app.js 文件的最后一部分包含启动应用程序(并开始监听传入请求)的函数,以及一个记录已启动的应用程序的行:

  
  
1
2
 
app.listen(port, host);
console.log( 'App started on port ' + port);

再次声明,请记住这是一个 JavaScript 应用程序,所以没有 stdout 或 stderr 需要讲解。您使用 console.log() 方法记录错误和信息。对于 BlueMix 应用程序,此信息可通过仪表板提供,可以使用对 cf 命令行工具的 'cf log appname' 调用来获得。

在开始处理数据之前,需要打开一个与 Time Series Database 的连接。

链接到 Time Series Database 

Bluemix 中的 Time Series Database 可以通过许多不同的接口提供,具体情况取决于应用程序环境。对于 Node.js 应用程序,有两个解决方案:使用 REST API 或使用 Mongo API。如果想要为基础数据提供一个直接转交接口,例如在提取图表和其他信息时,那么 REST 接口可能很有用。

我们使用了 Mongo API,因为它提供了非常简单的方式来访问 Node.js 应用程序中的数据,也那就是说,使用 JSON 执行调用来描述、分割和定义记录和信息。

要创建一个接口,必须知道连接数据库的凭据(URL,包括用户名和密码)。此信息在服务变量内提供,该变量本身已在之前在 Node.js 脚本中自动填充。事实上,要处理多个服务,需要连接到主要服务对象中的 timeseriesdatabase 对象类的第一个 URL,类似以下代码:

  
  
1
 
services.timeseriesdatabase[ 0 ].credentials.json_url

要实际访问数据库,可以将整个流程嵌入在一个连接调用中:

  
  
1
2
3
 
require( 'mongodb' ).connect(services.timeseriesdatabase[ 0 ].credentials.json_url, function (err, conn) {
}

这将使用所提取的凭据,通过 MongoDB API 打开与 Time Series Database 的一个连接,调用一个函数来提供错误和连接对象。尽管这看似有点浪费,但它提供了跟踪任何问题或错误并从中恢复的最佳方法。

需要通过 MongoDB 连接来访问数据。MongoDB 中的数据存储在集合中,集合大体上相当于典型 SQL 数据库中的一个数据表。

存储时序条目

 

存储在 Time Series Database 中的信息是为了引用和链接到某个特定的度量结果和环境而设计的。可以将 Time Series Database 视为一个日记条目,您在其中记录您在何处、度量类型和值。因为它是一个时序数据库,所以您能够不断查看同一个值,确定度量结果趋势是上升还是下降,或者最新的度量结果比一个历史值更高还是更低。

得益于 Time Series Database 的工作方式,必须为每个度量结果提供一些限制和参数,包括:

  • 它必须有一个度量单位 (measure_unit)。在此应用程序,该单位为摄氏度,但它也可以是 MB、秒或 mm,只要存储的是这类数据。
  • 它必须有一个位置或身份 (loc_esi_id)。此信息定义了此条目的标识符。
  • 它必须有一个方向 (direction),也就是说,它是一个生产者(即创建者或值)还是一个使用者(它们的使用者)。这是一个字节值:P 或 C。
  • 它自己必须有一个值 (value)。无法记录一个 'empty' 或 NULL 值。该值实际记录为小数类型,最多精确到小数点后 3 位。
  • 它必须有一个读取时间戳 (tstamp)。时间戳必须具有格式 2014-01-01 00:00:00.00000。

与传统数据库不同,时间戳必须以 15 为单位。所以,在过去的每个小时,可在 00、15、30 或 45 分钟时记录一个值。也可仅为时间戳、方向、度量单位和位置记录一个值。例如,如果记录在特定的一天 16:11:00 来自休息室中的一个温度传感器的值,这是惟一的数据点。但是,同时可记录来自车库的温度,因为这是一个不同的位置。

所有数据都写入一个叫做 ts_data_v 的集合中。因为我们可将不同的位置记录在此表中,所以我们只需一个表即可,因为我们可能仅使用一个不同的位置或度量类型。但是,请记住您不能对同一个位置(比如休息室)记录两个温度(度量类型 C),不过完全可以使用'lounge_front' 和 'lounge_back'

所以,可以创建一条像这样的记录:

  
  
1
2
3
4
5
6
7
 
{
"direction" : "P" ,
"tstamp" : "2014-09-16 11:17:15.00000" ,
"measure_unit" : "C" ,
"value" : 21 ,
"loc_esi_id" : "lounge"
}

要记录该值,需要将一个 URL 解析到一个应用程序,这样才能提取该位置和值。可以通过处理来自路线调用(来自 app.get())的请求对象来实现此目的:

  
  
1
2
3
4
 
var parsedUrl = require( 'url' ).parse(req.url, true );
var queryObject = parsedUrl.query;
var name = (queryObject[ "name" ] || 'lounge' );
var temppoint = parseFloat((queryObject[ "temp" ] || 0 ));

首先,解析来自请求对象的 URL。这会生成一个 queryObject,您可以从中提取 URL 值,在本例中为位置和温度点。所以,下面这行:

  
  
1
 
http: //mcslptds.mybluemix.net/reading?name=kitchen&temp=23

为我们提供了位置 'kitchen' 和值 '23'

接下来,我们需要构造一种合适的时间戳格式。您一定还记得,它必须与数据库需要的格式准确匹配。这意味着您需要在其中填充 0,构造一种合适的字符串与日期/时间组合。

与提取的 URL 值相结合,将得到:

点击查看代码清单

这会创建 create_datapoint() 函数,需要在此应用程序中添加连接到该函数的路线,所以我们还添加了一个适合其他路线的条目:

  
  
1
2
3
 
app.get( "/reading" , function (req, res) {
create_datapoint(req,res);
});

现在您已经有了传入数据的方式,您可以通过再次将应用程序部署到 Bluemix 来测试它,然后,使用 curl 记录一个点:

  
  
1
 
$ curl 'http://mcslptds.mybluemix.net/reading?name=kitchen&temp=23'

我们已拥有传入数据的方式,接下来看看如何传出数据。

检索一个条目列表

0
 

要获取一个条目列表,可以使用 MongoDB 接口连接到数据库,然后,使用collection.find() 函数提取存储在数据库中的值:

点击查看代码清单

首先,返回一个有效的标头 (HTTP 200)。然后,连接到数据库,使用所提供的名称或默认的'lounge' 在数据库上执行查询。

为了简便起见,我们使用 URL /dumplist 在应用程序中注册此函数:

  
  
1
2
3
 
app.get( "/dumplist" , function (req, res) {
list_datapoint(req,res);
});

然后会返回一个值列表。当然,这不是很有用。返回一个输出曲线图是个一种不错的方法,这样我们就可更轻松地了解趋势和值随时间的变化。毕竟这是一个时序数据库。

创建曲线图 

提供温度数据的输出曲线图实际上包含两步:

  • 构建一个方法来生成一个适合曲线图的值列表。
  • 构建一个 HTML 页面,它包含曲线图绘制软件并调用该 URL 来获取数据。

要首先完成第二步,我们的方法是创建一个静态 HTML 页面,在调用一个特定 URL 时,我们将会解析该页面并将它显示给用户:

  
  
1
2
3
4
5
 
var graph_view = function (req, res) {
fs.readFile( './public/graph.html' , function (err, data) {
res.end(data);
});
}

这会从应用程序目录中返回 /public/graph.html 的内容。要显示该页面,我们向此函数添加一个路径 /graph

  
  
1
2
3
 
app.get( "/graph" , function (req, res) {
graph_view(req,res);
});

该 HTML 本身非常简单。加载 JQuery,然后加载 JQuery FLOT 库来打印图表信息:

  
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 
<html>
<head>
<title>Graph</title>
<link rel= "stylesheet" type= "text/css" href= "stylesheets/style.css" />
</head>
<body>
<script src= "jquery.js" ></script>
<script src= "jquery.flot.js" ></script>
<script src= "jquery.flot.time.js" ></script>
<script>
$(document).ready( function () {
var dataseries = [];
$.getJSON( "/graphpoints" , function (json) {
$.plot($( "#plot" ) , [json],{ xaxis: { mode: "time" }});
});
});
</script>
<div id= "plot" ></div>
<div id= "plotdata" ></div>
</body>
</html>

确保您将此信息添加到正确的位置,使之与之前调用的 parse() 函数相匹配。

关键部分是定义该数据的内联函数。在本例中,我们通过 URL /graphpoints 调用我们自己的应用程序,并通过 Ajax 来加载它:

  
  
1
2
3
 
$.getJSON( "/graphpoints" , function (json) {
$.plot($( "#plot" ) , [json],{ xaxis: { mode: "time" }});
});

该信息需要具有特定的格式,包含一个嵌套数组,其中每个嵌套的数组是一对 X 和 Y 轴。例如:

  
  
1
 
[[ 1 , 21 ],[ 2 , 23 ],…]

第一个元素是一个顺序号或日期/时间字符串,可由 Flot 库解析为数据。

要输出此数据,我们需要创建 /dumplist 函数的一个修改版本,以正确的格式生成该信息。

整个函数类似于:

点击查看代码清单

该函数的核心是调用 Mongo API 来访问该集合。该集合按时间戳字段,以降序自动排序。然后,对于每个返回的条目,会创建一个包含日期时间字符串(从时间戳解析而来)的数组:

  
  
1
2
 
timeint = ( new Date(items[i].tstamp).getTime())/ 1000 ;
dataseries.push([timeint,items[i].value]);

访问曲线图页面时,将返回 HTML 页面,并且 Ajax 代码会加载 /graphpoints URL,这会从 Time Series Database 返回数据,描绘这些值并为我们提供一个曲线图。

结束语

 

使用 Bluemix 和 Node.js 创建一个新应用程序实际上非常简单。通过使用样板内容和现成的应用程序,您可以非常轻松地创建一个基本应用程序。对于 Node.js 应用程序,关键元素包括类似于 REST 的 API(可创建它来提交和返回信息),以及解析内容以显示传统的 HTML 页面的能力。通过将这些元素与一个后端数据库(比如 Time Series Database)相组合,可以非常轻松地存储和检索信息。使用 Time Series Database,数据的顺序和排序的复杂性已得到处理,您获得的是正确排序的信息。

点击这里,查看原文。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Matlab,可以使用timeseries对象来处理时间序列数据。要将timeseries数据导出,可以使用以下步骤: 1. 首先,确保你已经创建了一个timeseries对象,例如通过使用timeseries函数或从其他数据源导入数据。 2. 使用timeseries对象的数据属性来访问时间序列数据。例如,如果你的timeseries对象名为"ts",你可以使用"ts.Data"来获取数据。 3. 将数据导出到一个文件,可以使用Matlab的各种文件写入函数,如csvwrite、writematrix等。选择适合你需求的函数,并将timeseries数据作为输入参数传递给这些函数。 下面是一个示例代码,演示如何将timeseries数据导出到CSV文件: ```matlab % 创建一个示例的timeseries对象 time = \[1 2 3 4 5\]; data = \[10 20 30 40 50\]; ts = timeseries(data, time); % 将timeseries数据导出到CSV文件 csvwrite('output.csv', ts.Data); ``` 在上面的示例,我们创建了一个timeseries对象"ts",其包含了时间序列数据。然后,我们使用csvwrite函数将数据导出到名为"output.csv"的CSV文件。 请注意,这只是一个示例,你可以根据你的具体需求进行调整和修改。另外,还可以使用其他文件写入函数,如writematrix、writetable等,具体取决于你想要导出的文件格式和数据结构。 #### 引用[.reference_title] - *1* [matlab simulink数据导出到变量区](https://blog.csdn.net/qingfengxd1/article/details/88074802)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值