3、设备管理集成:创建设备、获取设备列表、更新设备属性、删除设备

设备管理,说白了就是跟 ThingsBoard 里的设备实体打交道。你想想看,一个物联网平台,核心就是管设备。增删改查,这四个动作你绕不开。我个人习惯,在开始集成之前,先把 REST API 的调用方式摸透,尤其是 Token 怎么传、返回结构长什么样。

这一章,我们就来手把手过一遍。我会用实际的 HTTP 请求示例,带你走完设备管理的完整生命周期。

3.1 准备工作:拿到你的 Access Token

在调用任何 API 之前,你得先有个身份。ThingsBoard 用的是 JWT(JSON Web Token)。你拿用户名和密码去换一个 Token,后续所有请求都带着它。

获取 Token 的请求:

POST http://your-thingsboard-server/api/auth/login
Content-Type: application/json

{
  "username": "tenant@thingsboard.org",
  "password": "your_password"
}

返回结果里有个 token 字段,把它存下来。嗯,这里要注意,Token 是有过期时间的,默认好像是 24 小时。我在项目中遇到过,因为 Token 过期导致半夜告警推送失败,排查了半天才发现是这个问题。后来我加了个自动刷新机制。

小技巧: 建议把 Token 缓存起来,并在过期前 5 分钟自动刷新。别每次都重新登录,那样效率太低了。

3.2 创建设备

创建设备,是设备管理的第一步。说白了,就是在 ThingsBoard 里注册一个设备实体。你需要给它一个名字,还可以指定一个设备类型(Device Profile)。

API 端点:

POST http://your-thingsboard-server/api/device
Content-Type: application/json
X-Authorization: Bearer YOUR_TOKEN

{
  "name": "温度传感器_001",
  "type": "default",
  "label": "车间A区温度传感器"
}

这里我解释一下几个字段:

  • name:设备名称,必须唯一。我习惯用「设备类型_编号」的命名方式,方便后期检索。
  • type:设备类型,对应 ThingsBoard 里的 Device Profile。如果你没创建自定义 Profile,就用 "default"。
  • label:设备标签,相当于一个更友好的描述。这个字段在界面上显示,建议写清楚位置或用途。

返回结果会包含设备的完整信息,其中 id 字段特别重要,后面所有操作都靠它。

返回示例:
{
  "id": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  },
  "name": "温度传感器_001",
  "type": "default",
  "label": "车间A区温度传感器",
  "createdTime": 1680000000000
}

3.3 获取设备列表

设备多了以后,你肯定需要分页查询。ThingsBoard 提供了非常灵活的查询接口,支持分页、排序、按名称搜索。

API 端点:

GET http://your-thingsboard-server/api/tenant/devices?pageSize=10&page=0&sortProperty=createdTime&sortOrder=DESC&textSearch=温度
X-Authorization: Bearer YOUR_TOKEN

参数说明:

参数 说明 示例值
pageSize 每页条数 10
page 页码,从0开始 0
sortProperty 排序字段 createdTime
sortOrder 排序方向 DESC
textSearch 模糊搜索名称 温度

返回结果是一个分页对象,包含 data(设备列表)、totalPages(总页数)、totalElements(总记录数)。

注意: 如果你不传 textSearch,会返回租户下所有设备。我曾经在一个客户现场,他们租户下有 5 万多台设备,一次性全查出来直接把应用搞 OOM 了。所以,一定要分页,别偷懒。

3.4 更新设备属性

设备创建后,你可能会需要修改它的名称、标签或者类型。更新操作本质上就是一次 PUT 请求,把整个设备对象传回去。

API 端点:

PUT http://your-thingsboard-server/api/device
Content-Type: application/json
X-Authorization: Bearer YOUR_TOKEN

{
  "id": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  },
  "name": "温度传感器_001_已校准",
  "type": "default",
  "label": "车间A区温度传感器(已校准)"
}

这里有个坑,我踩过好几次:更新时必须带上完整的设备对象,包括 id 字段。如果你只传 namelabel,ThingsBoard 会认为你要创建一个新设备(因为没传 id),结果就变成重复创建了。

所以我的做法是:先调用一次 GET 获取设备当前信息,然后修改需要变更的字段,再整体 PUT 回去。虽然多了一次查询,但安全可靠。

3.5 删除设备

删除操作很简单,但也很危险。一旦删除,设备的所有数据(包括遥测、告警、事件)都会被清除,无法恢复。

API 端点:

DELETE http://your-thingsboard-server/api/device/a1b2c3d4-e5f6-7890-abcd-ef1234567890
X-Authorization: Bearer YOUR_TOKEN

返回状态码 200 表示成功。如果设备不存在,会返回 404。

警告: 删除操作不可逆!我在项目中曾经因为脚本写错了条件,一次性删除了 200 多台设备。虽然可以从备份恢复,但中间丢失了 3 个小时的遥测数据。所以,建议在删除前先做一次确认,比如先查询设备是否存在,或者加一个「二次确认」的交互逻辑。

3.6 完整集成示例(Python)

说了这么多,我们来写一个完整的 Python 示例。这个脚本实现了设备的增删改查,你可以直接拿去用。

import requests
import json

# 配置
BASE_URL = "http://your-thingsboard-server"
USERNAME = "tenant@thingsboard.org"
PASSWORD = "your_password"

# 1. 获取 Token
def get_token():
    url = f"{BASE_URL}/api/auth/login"
    payload = {"username": USERNAME, "password": PASSWORD}
    response = requests.post(url, json=payload)
    response.raise_for_status()
    return response.json()["token"]

# 2. 创建设备
def create_device(token, name, label):
    url = f"{BASE_URL}/api/device"
    headers = {"X-Authorization": f"Bearer {token}"}
    payload = {"name": name, "type": "default", "label": label}
    response = requests.post(url, json=payload, headers=headers)
    response.raise_for_status()
    return response.json()

# 3. 获取设备列表
def get_devices(token, page=0, page_size=10):
    url = f"{BASE_URL}/api/tenant/devices?pageSize={page_size}&page={page}"
    headers = {"X-Authorization": f"Bearer {token}"}
    response = requests.get(url, headers=headers)
    response.raise_for_status()
    return response.json()

# 4. 更新设备
def update_device(token, device_id, name, label):
    url = f"{BASE_URL}/api/device"
    headers = {"X-Authorization": f"Bearer {token}"}
    payload = {"id": {"id": device_id}, "name": name, "type": "default", "label": label}
    response = requests.put(url, json=payload, headers=headers)
    response.raise_for_status()
    return response.json()

# 5. 删除设备
def delete_device(token, device_id):
    url = f"{BASE_URL}/api/device/{device_id}"
    headers = {"X-Authorization": f"Bearer {token}"}
    response = requests.delete(url, headers=headers)
    response.raise_for_status()
    return response.status_code == 200

# 主流程
if __name__ == "__main__":
    token = get_token()
    print("Token 获取成功")

    # 创建设备
    device = create_device(token, "测试设备_001", "这是一个测试设备")
    device_id = device["id"]["id"]
    print(f"设备创建成功,ID: {device_id}")

    # 获取设备列表
    devices = get_devices(token, page=0, page_size=5)
    print(f"当前共有 {devices['totalElements']} 台设备")

    # 更新设备
    update_device(token, device_id, "测试设备_001_已更新", "已更新标签")
    print("设备更新成功")

    # 删除设备
    delete_device(token, device_id)
    print("设备删除成功")
经验之谈: 在实际项目中,我一般会把 Token 管理、请求重试、异常处理封装成一个基类。这样每个 API 调用只需要关注业务逻辑,不用重复写鉴权代码。另外,建议加上日志,方便排查问题。

3.7 避坑指南

最后,我总结几个常见的坑,都是我曾经踩过的:

  • Token 过期:别忘了刷新,否则半夜告警推送会挂。
  • 设备名称重复:ThingsBoard 不允许同名设备,创建前最好先查一下。
  • 更新时漏传 id:不带 id 的 PUT 请求会被当成创建,导致重复设备。
  • 删除前不确认:建议先 GET 一次,确认设备存在再删除。
  • 分页查询不设上限:一次性查太多数据,内存会爆。

好了,设备管理的集成就讲到这里。下一章我们会聊设备遥测数据的上报与查询,那个才是物联网平台的核心价值所在。