2、产品与设备模型定义:在IoTDA控制台创建产品,定义设备服务、属性、命令等物模型,理解产品模型(Profile)的作用
好,咱们接着往下走。上一章我们把IoTDA环境搭好了,设备也注册了。但说实话,那会儿的设备就是个“空壳子”——它没有灵魂。灵魂是什么?就是今天要聊的产品模型(Profile)。
我个人习惯把产品模型比作设备的“身份证”加“说明书”。身份证告诉平台你是谁(什么类型),说明书告诉平台你能干什么、长什么样(有哪些属性、服务、命令)。没有这个,平台根本不知道你的设备上报的温度是啥意思,也不知道该下发什么指令。
2.1 为什么需要产品模型?
你想想看,一个温度传感器上报了一个数值“25.6”。平台收到后,它怎么知道这是摄氏度还是华氏度?是当前温度还是目标温度?
这就是产品模型要解决的问题。它用一套标准化的语言,把设备的“能力”描述清楚。说白了,就是给设备和平台之间定个“翻译规则”。
产品模型的核心作用:
- 标准化数据:让平台能读懂设备上报的二进制或JSON数据
- 定义交互接口:明确平台可以下发哪些命令,设备能响应什么
- 实现设备管理:基于属性值做告警、规则引擎触发等
- 支持多厂商互通:只要遵循同一Profile,不同厂商的设备可以无缝替换
我在项目中遇到过最典型的坑:客户买了一批温湿度传感器,厂家给了个私有协议,没做Profile。结果每次对接新平台都要重新解析数据,折腾了整整两周。后来我强制要求所有设备必须先定义Profile,再谈接入。嗯,从那以后,这类问题再没出现过。
2.2 在IoTDA控制台创建产品
好,咱们动手实操。登录华为云IoTDA控制台,找到“产品”菜单。点击“创建产品”,你会看到这样一个界面:
| 字段 | 说明 | 我的建议 |
|---|---|---|
| 产品名称 | 给你的产品起个名字,比如“智能温控器” | 建议用英文+数字,方便后续API调用 |
| 所属资源空间 | 选择你创建的资源空间 | 一般选默认即可,多项目时注意隔离 |
| 协议类型 | MQTT、CoAP、HTTP等 | 绝大多数场景选MQTT,我几乎只用这个 |
| 数据格式 | JSON或二进制 | JSON调试方便,二进制省流量 |
| 厂商名称 | 设备制造商 | 填真实厂商,方便后期维护 |
填完这些,点击“确定”。产品就创建好了。但别急,这只是一个空壳子。接下来才是重头戏——定义物模型。
2.3 定义设备服务(Service)
一个产品可以包含多个服务。每个服务代表一类功能。比如一个智能插座,可以有“电参数服务”(电压、电流、功率)和“开关控制服务”(开关状态、开关命令)。
我个人习惯这样划分:
- 基础服务:设备基本信息,如固件版本、设备ID
- 数据服务:传感器采集的数据,如温度、湿度
- 控制服务:可被平台下发的命令,如开关、调速
在IoTDA控制台,进入产品详情,点击“新建服务”。我一般这样填:
服务ID:temperature_humidity
服务类型:sensor
描述:温湿度采集服务
服务ID建议全小写加下划线,别用中文。为什么?因为后续API调用时,中文容易出编码问题。我曾经被这个坑过,调试了一下午才发现是服务ID里有个中文空格。
2.4 定义属性(Property)
属性是设备上报的数据点。比如温度传感器的“当前温度”。每个属性需要定义:
| 属性定义项 | 说明 | 示例 |
|---|---|---|
| 属性名称 | 显示名称 | 当前温度 |
| 属性ID | 唯一标识,用于API | current_temperature |
| 数据类型 | int、float、string、enum等 | float |
| 取值范围 | 最小值~最大值 | -40 ~ 125 |
| 步长 | 精度 | 0.1 |
| 单位 | 如℃、%RH | ℃ |
| 读写类型 | 只读、可写、可读可写 | 只读 |
小技巧:属性ID一旦定义,后续修改很麻烦。我建议在定义前,先画个表格,把所有属性列清楚。尤其是枚举类型的属性,比如“设备状态”,取值要写全:0-离线、1-在线、2-故障。少一个,后面设备上报了平台就解析不了。
举个例子,定义一个温湿度服务的属性:
服务:temperature_humidity
属性1:
- 名称:当前温度
- ID:current_temperature
- 类型:float
- 范围:-40~125
- 单位:℃
- 读写:只读
属性2:
- 名称:当前湿度
- ID:current_humidity
- 类型:float
- 范围:0~100
- 单位:%RH
- 读写:只读
2.5 定义命令(Command)
命令是平台下发给设备的指令。比如“打开开关”、“设置温度”。命令可以带参数,也可以不带。
定义命令时,需要指定:
- 命令名称:如 set_temperature
- 命令ID:唯一标识
- 输入参数:平台下发时携带的参数,比如目标温度值
- 输出参数:设备执行后返回的结果,比如成功/失败
我记得有一次做智能灯控项目,客户要求“调光命令”必须带两个参数:亮度和色温。我一开始只定义了一个参数,结果设备收到命令后只调了亮度,色温没变。后来我改成两个参数,问题解决。所以,命令参数一定要想清楚,别漏。
在控制台定义命令的界面,我一般这样填:
命令名称:设置目标温度
命令ID:set_target_temperature
输入参数:
- 参数名称:目标温度值
- 参数ID:target_temp
- 数据类型:float
- 取值范围:16~30
- 步长:0.5
- 单位:℃
输出参数:
- 参数名称:执行结果
- 参数ID:result
- 数据类型:enum
- 取值:0-成功,1-失败,2-超范围
2.6 产品模型的作用——为什么它这么重要?
好,定义完了。但你可能想问:这玩意儿到底有什么用?我直接发JSON不行吗?
嗯,这里要注意。没有Profile,你确实可以发JSON。但平台不知道这个JSON里每个字段的含义。比如你上报{"temp": 25.6},平台只知道有个叫temp的字段值是25.6,但它不知道这是温度、单位是什么、是否在合理范围内。
有了Profile之后,平台就能:
- 自动解析数据:把二进制或JSON映射成有意义的属性值
- 做规则引擎:比如“当温度大于30℃时,触发告警”
- 做数据存储:把属性值存入时序数据库,方便后续分析
- 做OTA升级:基于固件版本属性,判断是否需要升级
- 做设备影子:平台缓存设备最新状态,即使设备离线也能查询
避坑指南:我曾经遇到一个项目,开发人员图省事,把所有属性都定义成string类型。结果后面做数据统计时,发现温度值没法做数值比较,因为“30”和“30.0”在字符串比较里不一样。最后不得不重新定义Profile,所有设备重新上报数据。所以,数据类型一定要选对,别偷懒。
2.7 小结与实操建议
今天的内容其实就一句话:先定义Profile,再开发设备。顺序别搞反了。
我个人建议的实操步骤:
- 先在纸上画出设备有哪些功能(服务)
- 每个服务下有哪些数据点(属性)
- 平台需要控制设备做什么(命令)
- 在IoTDA控制台按这个结构创建Profile
- 用控制台提供的“模拟设备”功能测试一下
下一章,我们会把定义好的Profile和设备关联起来,然后真正实现设备上报数据、平台下发命令。到时候你会发现,前面这些准备工作做得越细,后面就越省心。
好,今天就到这儿。有问题随时交流。