产品定价 立即试用
云平台
欧洲地区
文档 > 核心概念 > 时间序列数据
入门
指南 API 常见问题
目录

遥测数据

ThingsBoard提供与时间序列数据相关的一系列功能:

  • 采集:通过多种协议与集成从设备采集数据;
  • 存储:在SQL(PostgreSQL)或NoSQL(Cassandra或Timescale)数据库中存储时间序列数据;
  • 查询:灵活聚合查询最新值或指定时间范围内全部数据;
  • 订阅:通过WebSockets订阅数据更新,用于可视化或实时分析;
  • 可视化:使用可配置、高度自定义的部件和dashboards展示时间序列数据;
  • 筛选与分析:通过灵活的Rule Engine处理数据;
  • 生成alarms:基于采集数据生成告警;
  • 转发:使用External Rule Nodes(如Kafka或RabbitMQ Rule Nodes)将数据转发到外部系统。

本文档概述上述功能,并提供获取更多详情的链接。

数据点

ThingsBoard内部将时间序列数据视为带时间戳的key-value对。我们称单个带时间戳的key-value对为数据点。 key-value格式的灵活性和简洁性使得与市场上的几乎任何IoT设备的无缝集成。 Key始终为一个字符串,基本上是数据点的关键字,value可以是字符串、布尔值、双精度数、整数或JSON。

文档信息图标

下面的示例使用内部数据格式。设备本身可能使用各种协议和数据格式上载数据。 查看Time-series数据上载API以了解更多细节。

下面的JSON有大约5个数据点:temperature(双精数)、humidity(整数)、hvacEnabled(布尔值)、hvacState(字符串)和configuration(JSON):

1
2
3
4
5
6
7
8
9
10
11
{
 "temperature": 42.2, 
 "humidity": 70,
 "hvacEnabled": true,
 "hvacState": "IDLE",
 "configuration": {
    "someNumber": 42,
    "someArray": [1,2,3],
    "someNestedObject": {"key": "value"}
 }
}

您可能会注意到上述JSON没有时间戳信息。在这种情况下,ThingsBoard会使用当前服务器时间戳。 但是,您可以在消息中包含时间戳信息。请参见下面的示例:

1
2
3
4
5
6
7
{
  "ts": 1527863043000,
  "values": {
    "temperature": 42.2,
    "humidity": 70
  }
}

时间序列数据上传API

您可以使用内置的传输协议实现:

上述大多数协议都支持JSON、Protobuf或自己的数据格式。对于其他协议,请查看“如何连接您的设备?”指南。

数据可视化

我们假设您已经将时间序列数据推送到ThingsBoard。现在您可以在仪表盘中使用它。 我们建议查阅仪表盘概览以开始使用。 一旦您熟悉了如何创建仪表盘和配置数据源, 您可以使用部件来可视化最新值或实时变化和历史值。 可视化最新值的良好示例是数字模拟仪表,或卡片图表用于可视化历史和实时值,地图用于可视化设备和资产的移动。

您也可以使用输入部件来允许仪表盘用户使用仪表盘输入新的时间序列值。

数据存储

ThingsBoard Cloud在Cassandra数据库中存储时间序列数据,复制因子为3。 ThingsBoard的本地部署支持在SQL(PostgreSQL)或NoSQL(Cassandra或Timescale)数据库中存储时间序列数据。

数据保留

ThingsBoard Cloud使用可配置的生存时间(TTL)参数来存储时间序列数据。 该参数的值由您的订阅计划决定。 您可以在”Save Timeseries(保存时间序列)”规则节点中,或在消息元数据中通过TTL字段覆盖默认值,从而优化存储占用。 TTL的最大允许值为5年(以秒计)。例如,您可以将”原始”数据存储3个月,将聚合数据存储3年。

数据耐久性

发送包含时间序列数据的消息到ThingsBoard的设备,在消息成功写入为该设备配置的规则引擎队列(见设备配置中的队列名)后,会收到确认。

作为租户管理员,您可以为队列配置处理策略(见队列处理策略文档)。可以配置队列在消息处理失败时重试或忽略,从而对时间序列数据及规则引擎处理的其他消息的耐久性提供细粒度控制。

规则引擎

规则引擎负责处理各种传入的数据和事件。 下面列出在规则引擎中使用时间序列或属性的常见场景:

基于时间序列值的逻辑表达式生成告警

使用告警规则通过UI配置常见的告警条件,或使用过滤节点结合自定义JS函数来实现更复杂的用例。

在写入数据库前修改传入的时间序列数据

使用消息类型切换规则节点过滤包含“Post telemetry”请求的消息,然后使用转换规则节点修改消息内容。

计算前后时间序列值差分(delta)

使用calculate delta规则节点基于智能电表读数计算电力、水等消费量。

获取历史时间序列值以分析传入遥测数据

使用originator telemetry规则节点,将设备的历史时间序列数据附加到传入的遥测消息中。

获取属性值以分析传入遥测数据

使用enrichment规则节点,将设备、相关资产、客户或租户的属性附加到传入的遥测消息中。这是一种非常强大的技术,可根据属性中存储的设置调整处理逻辑和参数。

使用分析规则节点对相关资产的数据进行聚合

使用analytics规则节点,从多个设备或资产中聚合数据,例如基于多台水表的数据计算建筑或区域的总用水量。

数据查询REST API

ThingsBoard提供以下REST API来获取实体的时间序列数据:

文档信息图标

注意:这些API可通过Swagger UI访问。有关更多详情,请查看通用的REST API文档。 API与ThingsBoard v1.0+向后兼容,这也是API调用URL中包含”plugin”的原因之一。

获取特定实体的时间序列数据键

您可以通过向以下URL发起GET请求来获取指定实体类型和实体ID的所有时间序列数据键:

1
http(s)://host:port/api/plugins/telemetry/{entityType}/{entityId}/keys/timeseries

支持的实体类型:TENANT、CUSTOMER、USER、DASHBOARD、ASSET、DEVICE、ALARM、ENTITY_VIEW

获取特定实体的最新时间序列值

您可以通过向以下URL发起GET请求来获取指定实体类型和实体ID的最新时间序列值(可通过 keys 指定多个键):

1
http(s)://host:port/api/plugins/telemetry/{entityType}/{entityId}/values/timeseries?keys=key1,key2,key3

支持的实体类型同上。

获取特定实体的历史时间序列值

您也可以通过以下URL获取指定实体类型和实体ID的历史时间序列值:

1
http(s)://host:port/api/plugins/telemetry/{entityType}/{entityId}/values/timeseries?keys=key1,key2,key3&startTs=1479735870785&endTs=1479735871858&interval=60000&limit=100&agg=AVG

支持的参数说明:

  • keys - 要获取的遥测键的逗号分隔列表。
  • startTs - 以毫秒为单位的Unix时间戳,表示查询区间的起始时间。
  • endTs - 以毫秒为单位的Unix时间戳,表示查询区间的结束时间。
  • interval - 聚合间隔,单位为毫秒。
  • agg - 聚合函数:MIN、MAX、AVG、SUM、COUNT、NONE。
  • limit - 返回的数据点或要处理的间隔的最大数量。

ThingsBoard将使用 startTsendTsinterval 来识别聚合分区或子查询,并执行异步数据库查询以利用内建的聚合函数。

支持的实体类型同上。

WebSocket接口

WebSocket广泛用于ThingsBoard Web UI。WebSocket API与REST API功能相似,并提供订阅设备数据变化的能力。 您可以通过以下URL打开到遥测服务的WebSocket连接:

1
ws(s)://host:port/api/ws

打开连接后,您需在10秒内使用认证命令对会话进行认证:

1
2
3
4
5
6
{
  "authCmd": {
    "cmdId": 0,
    "token": "$JWT_TOKEN"
  }
}

之后,您可以发送订阅命令并接收订阅更新(相关命令与更新格式在ThingsBoard源码中有定义)。常用字段说明:

  • cmdId - 唯一命令ID(在对应的WebSocket连接内唯一)。
  • entityType - 实体类型,支持:TENANT、CUSTOMER、USER、DASHBOARD、ASSET、DEVICE、ALARM。
  • entityId - 实体唯一标识符。
  • keys - 以逗号分隔的数据键列表。
  • timeWindow - 时间序列订阅的抓取窗口,单位为毫秒。数据将在区间[now()-timeWindow, now()]内被抓取。
  • startTs - 历史数据查询的开始时间(毫秒)。
  • endTs - 历史数据查询的结束时间(毫秒)。

示例与更多资源见: