什么是物模型?
官方文档:物模型TSL(Thing Specification Language)是一个JSON格式的文件,它是物理空间中的实体,如传感器、车载装置、楼宇、工厂等在云端的数字化表示,从属性、服务和事件三个维度,分别描述了该实体是什么、能做什么、可以对外提供哪些信息。(property,service,event)定义了物模型的这三个维度,即完成了产品功能的定义。物模型相关概念和使用限制_物联网平台-阿里云帮助中心
简单来说,物模型就是在云平台上对设备的抽象,抽象后方便设备和平台进行交互,统一一个交互规则;通过对设备的属性、服务、事件定义后以物模型为依据,定义一个设备和云平台的通信通道,即通信topic;设备抽象完成,通信通道也定义完成,最后一步就是按物模型解析和封装数据,这个处理逻辑和方法需要云平台和设备统一,像阿里就提供基于SDK的全部操作,也可以和设备约定固定的达成共识的方法,才能完成对应的数据抽象;
事件和服务后面跟的method是什么?
在物模型中,"method" 字段通常用于服务(Service)的定义中,表示服务调用的方法名称。这个名称是根据服务的唯一标识符(identifier)生成的,用于在设备端和物联网平台之间进行服务调用时的标识。
作用:
- 标识服务:每个服务都有一个唯一的方法名称,使得物联网平台能够识别和调用相应的服务。
- 实现服务调用:设备端需要根据这个方法名称来实现服务的具体逻辑,物联网平台则通过这个方法名称来调用设备端的服务。
比如说
- identifier: "control_light" 是服务的唯一标识符。
- method: "thing.service.control_light" 是根据服务的标识符生成的方法名称。
添加物模型的操作
- 创建产品:在物联网平台的控制台中创建产品。产品是设备的集合,通常是一组具有相同功能定义的设备集合。例如,产品可以指同一个型号的产品,设备则是该型号下的某个设备。
- 进入控制台:登录物联网平台的控制台,进入设备管理界面。
- 定义物模型:在产品管理界面中,找到并点击“查看详情”,进入物模型定义页面。物模型将产品功能类型分为三类:属性、服务和事件。
- 添加属性:在物模型定义页面,点击“添加自定义功能”,选择功能类型为“属性”。设置属性的名称、标识符、数据类型、取值范围、步长、单位、读写类型等参数,然后点击“确认”。例如,可以添加“卧室温度”、“卧室灯开关”和“温度预警”属性。
- 添加服务:同样在“添加自定义功能”对话框中,选择功能类型为“服务”。添加输入参数和输出参数,设置完成后点击“确认”。
- 添加事件:在“添加自定义功能”对话框中,选择功能类型为“事件”。设置事件类型(如信息、告警、故障)和相关参数,然后点击“确认”。例如,可以添加一个信息事件。
- 导出物模型:完成物模型定义后,可以点击“查看物模型”,导出模型文件(如model.json),以备后用。以后需要相同或类似的定义时,可以通过“导入物模型”快速实现。
- 生成设备端代码:点击“生成设备端代码”,可以下载一个以ProductKey命名的C语言程序,作为编程参考。
- 注册设备:在物联网平台的设备管理界面,点击“添加设备”,注册设备并获取身份三元组(PublicKey、DeviceName、DeviceSecret)。这些信息在设备通信及认证中都会用到。
- 设备上报数据:设备端根据物模型通讯协议生成数据,完成上报。物联网平台会校验设备端上报的属性、事件数据和行为调用数据,并将校验通过的数据显示在物联网平台控制台对应设备的设备详情页面下。
- 物模型数据存储:设备上报的物模型数据默认会自动写入时序数据存储空间,可以根据业务需要设置存储时效。
为什么属性没有desc,而服务和事件有呢?
在阿里云物联网平台的物模型(TSL,Thing Specification Language)中,属性(Properties)、事件(Events)和服务(Services)是定义设备行为和特征的三个主要组成部分。TSL 使用 JSON 格式来描述这些组件。
为什么在 TSL JSON 代码中属性没有 desc(描述)字段,而事件和服务有,可能有以下几个原因:
- 设计选择:设计者可能决定只为事件和服务提供描述,因为它们通常与设备的行为和功能更直接相关,而属性更多地是关于设备状态的数据点。
- 属性的直观性:设备的属性通常比较直观,如温度、湿度等,这些名称本身就能很好地说明它们的含义,因此可能不需要额外的描述。
- 简化模型:为了简化物模型的定义,可能有意省略了属性的描述,使得开发者可以更专注于定义属性的数据类型和访问权限。
- 版本差异:不同版本的物模型定义可能有不同的要求和特性。有可能在某些版本中,属性确实包含描述字段,而在其他版本中则省略了。
- 扩展性:设计者可能预留了扩展性,允许在需要时通过其他方式或属性来补充描述信息。
- 实际应用需求:在某些应用场景中,事件和服务的描述可能对开发者和用户来说更为重要,因为它们涉及到设备的操作和响应,而属性更多是状态的简单报告。
物模型中的specs是什么意思?
specs 在物模型中通常指的是“规格”或“规范”,它定义了物模型组件的具体参数和行为。
"specs": {
"min": "参数最小值(int、float、double类型特有)。",
"max": "参数最大值(int、float、double类型特有)。",
"unit": "属性单位(int、float、double类型特有,非必填)。",
"unitName": "单位名称(int、float、double类型特有,非必填)。",
"size": "数组元素的个数,最大512(array类型特有)。",
"step": "步长(text、enum类型无此参数)。",
"length": "数据长度,最大10240(text类型特有)。",
"0": "0的值(bool类型特有)。",
"1": "1的值(bool类型特有)。",
"item": {
"type": "数组元素的类型(array类型特有)。"
}
}
在物模型中如何判断一个事件发生的条件?
举个例子,在物联网设备中,定义了事件如 lamp_event 后,需要在设备端编写代码来检测实际的电压值,并在电压过低时触发上报该事件。
步骤:
- 读取电压值:通过连接到电压传感器的代码来实时获取电压值。
- 判断电压是否过低:将读取的电压值与预定义的阈值比较。
- 构建事件数据:如果电压过低,构建包含电压值的事件数据。
- 上报事件:通过物联网平台支持的通信协议(如 MQTT、CoAP 等)将事件数据发送到物联网平台。
示例代码:
假设使用的是一个基于 Arduino 或类似微控制器的设备,并且使用 MQTT 协议来上报事件。以下是伪代码示例:
C语言代码:
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADS1015.h>
#define VOLTAGE_THRESHOLD 20.0 // 定义电压过低的阈值
Adafruit_ADS1015 ads; // 使用 Adafruit 的 ADS1015 模组来读取电压
void setup() {
Serial.begin(9600);
if (!ads.begin()) {
Serial.println("Failed to initialize ADS1015");
while (1);
}
}
void loop() {
float voltage = readVoltage(); // 读取电压值
if (voltage < VOLTAGE_THRESHOLD) {
reportVoltageTooLowEvent(voltage); // 电压过低,上报事件
}
delay(1000); // 等待1秒再次检测
}
float readVoltage() {
// 读取电压传感器的值
int16_t adcValue = ads.readADC_SingleEnded(0); // 假设使用 ADS1015 的第一个通道
float voltage = (adcValue * 24.0) / 2047.0; // 转换为实际电压值
return voltage;
}
void reportVoltageTooLowEvent(float voltage) {
// 构建事件数据
char eventData[50];
sprintf(eventData, "{\"voltage\": %.2f}", voltage);
// 上报事件
char topic[50];
sprintf(topic, "/sys/%s/%s/event/voltage_too_low", "设备标识符", "设备名称");
// 这里需要根据实际使用的 MQTT 库来发送消息
mqtt.publish(topic, eventData);
}
代码位置:
- 设备端代码:通常在设备的微控制器或边缘计算设备上运行。
- 固件:作为设备固件的一部分,可能在设备制造时烧录到设备中。
- 应用程序:如果是更高级的设备,代码可能作为设备上的应用程序运行。
注意事项:
- 阈值设置:VOLTAGE_THRESHOLD 应该根据设备的实际需求和安全标准来设置。
- 通信协议:根据实际使用的物联网平台和设备支持的通信协议来选择。
- 安全性:在上报数据时,确保使用加密和安全连接,以保护数据的安全性。
通过这样的方式,设备能够智能地检测电压状态,并在必要时上报事件,从而实现物联网的智能监控和管理。
Alink JSON和TSL JSON的比较与区别
Alink JSON
Alink JSON是阿里云物联网平台定义的一种标准数据格式,用于设备与平台之间的数据交换。它遵循特定的协议结构,包括“id”、“version”、“params”等字段,方便云端进行标准化处理。Alink JSON的数据格式和Topic如下:
设备上报属性:
请求Topic:/sys/${productKey}/${deviceName}/thing/event/property/post
响应Topic:/sys/${productKey}/${deviceName}/thing/event/property/post_reply
请求数据格式:
json
{
"id": "123",
"version": "1.0",
"params": {
"temperature": "30.5"
},
"method": "thing.service.property.set"
}
响应数据格式:
json
{
"id": "123",
"code": 200,
"data": {},
"message": "success",
"version": "1.0"
}
设备上报事件:
请求Topic:/sys/${productKey}/${deviceName}/thing/event/${tsl.event.identifier}/post
响应Topic:/sys/${productKey}/${deviceName}/thing/event/${tsl.event.identifier}/post_reply
请求数据格式:
json
{
"id": "123",
"version": "1.0",
"params": {
"value": {
"Power": "on",
"WF": "2"
},
"time": 1524448722000
},
"method": "thing.event.${tsl.event.identifier}.post"
}
响应数据格式:
json
{
"id": "123",
"code": 200,
"data": {},
"message": "success",
"version": "1.0"
}
设备服务调用:
请求Topic:/sys/${productKey}/${deviceName}/thing/service/${tsl.service.identifier}
响应Topic:/sys/${productKey}/${deviceName}/thing/service/${tsl.service.identifier}_reply
请求数据格式:
json
{
"method": "thing.service.SetWeight",
"id": "105917531",
"params": {
"NewWeight": 100.8
},
"version": "1.0"
}
响应数据格式:
json
{
"id": "105917531",
"code": 200,
"data": {
"CollectTime": "1536228947682",
"OldWeight": 100.101
},
"message": "success",
"version": "1.0"
}
TSL JSON
TSL(Thing Specification Language)JSON是物联网设备物模型的数据格式,用于定义设备的属性、事件和服务。TSL JSON格式通常用于设备的功能描述和功能定义,而不是直接用于数据交换。TSL JSON的示例如下:
json
{
"schema": "https://iot-tsl.oss-cn-shanghai.aliyuncs.com/schema.json",
"link": "/sys/${productKey}/airCondition/thing/",
"profile": {
"productKey": "${productKey}",
"deviceName": "airCondition"
},
"events": [
{
"identifier": "alarm",
"name": "alarm",
"desc": "风扇警报",
"type": "alert",
"required": true,
"outputData": [
{
"identifier": "errorCode",
"name": "错误码",
"dataType": {
"type": "text",
"specs": {
"length": "255"
}
}
}
],
"method": "thing.event.alarm.post"
}
]
}
### 主要区别
1. **用途**:
- **Alink JSON**:用于设备与物联网平台之间的实际数据交换,包括属性上报、事件上报和服务调用。
- **TSL JSON**:用于定义设备的物模型,包括属性、事件和服务的功能描述。
2. **结构**:
- **Alink JSON**:包含“id”、“version”、“params”、“method”等字段,用于标准化数据交换。
- **TSL JSON**:包含“schema”、“link”、“profile”、“events”等字段,用于描述设备的功能和数据结构。
3. **数据交换**:
- **Alink JSON**:直接用于设备与平台之间的数据上报和响应。
- **TSL JSON**:用于设备的功能定义,通常不直接用于数据交换,但定义了设备如何通过Alink JSON格式上报数据。
通过这两种格式,物联网平台能够实现设备的功能定义和数据交换的标准化处理,确保设备与平台之间的通信高效、一致。
service中为什么没有accessmode,而是添加了calltype呢?
在物联网平台的物模型中,Service(服务)通常用于描述设备可以执行的操作或行为。每个服务可以有输入参数和输出参数,并且可以定义服务的调用类型(calltype)。而accessmode(访问模式)通常与属性(Properties)相关,而不是服务。
物模型的Service中使用calltype而不是accessmode的原因:
- 行为的多样性:服务通常代表设备可以执行的动作,比如开关控制、数据同步等。这些行为可能需要不同的调用模式,比如同步调用或异步调用。
- 调用方式的区分:calltype 可以定义服务的调用类型,例如:async:异步调用,服务调用后可能需要一些时间来处理,结果会在稍后返回。sync:同步调用,服务调用后会立即返回结果。这种区分有助于明确服务的执行方式和预期行为。
- 权限控制的简化:服务的调用通常涉及到设备的行为控制,而不是数据的读取或写入。因此,使用calltype可以更直接地描述服务的执行方式,而不是通过访问权限来控制。
- 属性和事件的访问模式:accessmode 主要用于属性和事件,定义它们是只读(readonly)、可读写(readwrite)还是只写(writeonly)。属性和事件更多地涉及到数据的状态和变化,因此需要明确访问权限。
- 实现的灵活性:在某些情况下,服务的实现可能需要根据具体的业务逻辑来决定是同步执行还是异步执行。通过定义calltype,开发者可以更灵活地实现服务的逻辑。
在定义时,什么时候用bool,什么时候用enum?
数据类型 enum(枚举)和 bool(布尔)是两种不同的数据类型,它们在用途和表示方式上有所区别:
- bool(布尔型):
- 用途:布尔型数据通常用于表示开关状态、二元选择或简单的真/假值。
- 表示:布尔型数据只有两个可能的值:true(真)或 false(假)。
- 应用场景:控制设备开关(如电灯开/关)、设备在线/离线状态等。
- enum(枚举型):
- 用途:枚举型数据用于表示一组有限的、固定的选项。这些选项通常用于描述设备的状态或参数,且每个选项都有一个具体的数值和名称。
- 表示:枚举型数据由一系列预定义的值组成,每个值都有一个标识符和名称。例如,一个颜色枚举可能包括 "red"、"green"、"blue" 等选项。
- 应用场景:设备模式选择(如加热/制冷/自动)、设备状态(如空闲/工作/故障)等。
区别:
- 值的数量:布尔型只有两个值(true/false),而枚举型可以有多个预定义的值。
- 值的意义:布尔型通常表示简单的开/关或真/假,而枚举型可以表示更丰富的状态或选项。
- 数据结构:布尔型数据结构简单,通常只需要一个标志位;枚举型则需要一个值列表,每个值都有对应的标识符和名称。
- 使用灵活性:枚举型提供了更多的灵活性,可以定义多种不同的状态或选项,而布尔型则主要用于简单的二元选择。
适用场景:
- 布尔型:适用于简单的开关控制或状态指示,如电灯开关、设备在线状态等。
- 枚举型:适用于需要选择多个预定义选项的场景,如设备工作模式、颜色选择、状态指示等。
规则引擎与数据转发
物模型(Thing Model)通常与规则引擎(Rule Engine)结合使用,以实现数据的自动化处理和转发。规则引擎允许开发者定义一系列的规则,这些规则基于设备上报的数据触发特定的动作,如数据转发、事件处理或执行某些服务。Json代码
{
"rules": [
{
"id": "rule1",
"name": "Temperature Alert Rule",
"description": "Send alert when temperature exceeds threshold",
"trigger": {
"type": "property",
"property": "temperature",
"condition": ">",
"value": 30
},
"actions": [
{
"type": "forward",
"endpoint": "https://example.com/alert",
"method": "POST",
"dataTemplate": "{ \"device_id\": \"{{device_id}}\", \"temperature\": \"{{temperature}}\" }"
}
]
}
]
}
在这个示例中:
- rules 是规则列表。
- trigger 定义了触发条件,这里是当温度属性(temperature)超过30时触发。
- actions 定义了触发条件满足时执行的动作,这里是将数据转发到 https://example.com/alert。
数据模板使用设备属性值填充,如 {{device_id}} 和 {{temperature}},这些值在运行时将被实际的设备属性值替换。
设备上下行的消息解析
物联网平台定义设备消息的标准数据格式为Alink JSON。对于低配置且资源受限或者对网络流量有要求的设备,不适合直接构造JSON数据与物联网平台通信,可将原数据透传到物联网平台。物联网平台提供消息解析功能,可以根据脚本,将消息数据在设备自定义格式和JSON格式之间转换。
自定义格式(十六进制)和云平台标准设备消息数据格式Alink JSON的上行下行解析结果示例:
支持两类消息解析:
- 自定义Topic上行消息:将设备通过自定义Topic上报给物联网平台云端的自定义格式数据Payload解析为JSON格式。
- 上、下行物模型Topic的消息:将设备上报给物联网平台云端的自定义格式物模型数据解析为Alink JSON格式;将云端下发的Alink JSON格式数据解析为设备自定义的格式。
这里介绍物模型Topic的消息解析:
数据格式为透传/自定义的产品下的设备与云端进行物模型数据通信时,需要物联网平台调用编写的消息解析脚本,将上、下行物模型消息数据分别解析为物联网平台定义的标准格式(Alink JSON)和设备的自定义数据格式。
物联网平台接收到来自设备的数据时,先运行解析脚本,将透传的消息数据转换成Alink JSON格式的数据,再进行业务处理;物联网平台下发消息给设备前,也会先通过脚本将消息数据转换为设备的自定义格式,再下发给设备。
数据解析流程图:
上行:
下行:
以js代码为例:
var COMMAND_REPORT = 0x00; //属性上报。
var COMMAND_SET = 0x01; //属性设置。
var COMMAND_REPORT_REPLY = 0x02; //上报数据返回结果。
var COMMAND_SET_REPLY = 0x03; //属性设置设备返回结果。
var COMMAD_UNKOWN = 0xff; //未知的命令。
var ALINK_PROP_REPORT_METHOD = 'thing.event.property.post'; //物联网平台Topic,设备上传属性数据到云端。
var ALINK_PROP_SET_METHOD = 'thing.service.property.set'; //物联网平台Topic,云端下发属性控制指令到设备端。
var ALINK_PROP_SET_REPLY_METHOD = 'thing.service.property.set'; //物联网平台Topic,设备上报属性设置的结果到云端。
var SELF_DEFINE_TOPIC_UPDATE_FLAG = '/user/update' //自定义Topic:/user/update。
var SELF_DEFINE_TOPIC_ERROR_FLAG = '/user/update/error' //自定义Topic:/user/update/error。
/*
示例数据:
设备上报属性数据:
传入参数:
0x000000000100320100000000
输出结果:
{"method":"thing.event.property.post","id":"1","params":{"prop_float":0,"prop_int16":50,"prop_bool":1},"version":"1.0"}
属性设置的返回结果:
传入参数:
0x0300223344c8
输出结果:
{"code":"200","data":{},"id":"2241348","version":"1.0"}
*/
function rawDataToProtocol(bytes) {
var uint8Array = new Uint8Array(bytes.length);
for (var i = 0; i < bytes.length; i++) {
uint8Array[i] = bytes[i] & 0xff;
}
var dataView = new DataView(uint8Array.buffer, 0);
var jsonMap = new Object();
var fHead = uint8Array[0]; // command
if (fHead == COMMAND_REPORT) {
jsonMap['method'] = ALINK_PROP_REPORT_METHOD; //ALink JSON格式,属性上报topic。
jsonMap['version'] = '1.0'; //ALink JSON格式,协议版本号固定字段。
jsonMap['id'] = '' + dataView.getInt32(1); //ALink JSON格式,标示该次请求id值。
var params = {};
params['prop_int16'] = dataView.getInt16(5); //对应产品属性中prop_int16。
params['prop_bool'] = uint8Array[7]; //对应产品属性中prop_bool。
params['prop_float'] = dataView.getFloat32(8); //对应产品属性中prop_float。
jsonMap['params'] = params; //ALink JSON格式,params标准字段。
} else if(fHead == COMMAND_SET_REPLY) {
jsonMap['version'] = '1.0'; //ALink JSON格式,协议版本号固定字段。
jsonMap['id'] = '' + dataView.getInt32(1); //ALink JSON格式,标示该次请求id值。
jsonMap['code'] = ''+ dataView.getUint8(5);
jsonMap['data'] = {};
}
return jsonMap;
}
/*
示例数据:
云端下发属性设置指令:
传入参数:
{"method":"thing.service.property.set","id":"12345","version":"1.0","params":{"prop_float":123.452, "prop_int16":333, "prop_bool":1}}
输出结果:
0x0100003039014d0142f6e76d
设备上报的返回结果:
传入数据:
{"method":"thing.event.property.post","id":"12345","version":"1.0","code":200,"data":{}}
输出结果:
0x0200003039c8
*/
function protocolToRawData(json) {
var method = json['method'];
var id = json['id'];
var version = json['version'];
var payloadArray = [];
if (method == ALINK_PROP_SET_METHOD) //属性设置。
{
var params = json['params'];
var prop_float = params['prop_float'];
var prop_int16 = params['prop_int16'];
var prop_bool = params['prop_bool'];
//按照自定义协议格式拼接 rawData。
payloadArray = payloadArray.concat(buffer_uint8(COMMAND_SET)); //command字段。
payloadArray = payloadArray.concat(buffer_int32(parseInt(id))); //ALink JSON格式 'id'。
payloadArray = payloadArray.concat(buffer_int16(prop_int16)); //属性'prop_int16'的值。
payloadArray = payloadArray.concat(buffer_uint8(prop_bool)); //属性'prop_bool'的值。
payloadArray = payloadArray.concat(buffer_float32(prop_float)); //属性'prop_float'的值。
} else if (method == ALINK_PROP_REPORT_METHOD) { //设备上报数据返回结果。
var code = json['code'];
payloadArray = payloadArray.concat(buffer_uint8(COMMAND_REPORT_REPLY)); //command字段。
payloadArray = payloadArray.concat(buffer_int32(parseInt(id))); //ALink JSON格式'id'。
payloadArray = payloadArray.concat(buffer_uint8(code));
} else { //未知命令,对于这些命令不做处理。
var code = json['code'];
payloadArray = payloadArray.concat(buffer_uint8(COMMAD_UNKOWN)); //command字段。
payloadArray = payloadArray.concat(buffer_int32(parseInt(id))); //ALink JSON格式'id'。
payloadArray = payloadArray.concat(buffer_uint8(code));
}
return payloadArray;
}
/*
示例数据
自定义Topic:
/user/update,上报数据。
输入参数:
topic:/{productKey}/{deviceName}/user/update
bytes: 0x000000000100320100000000
输出参数:
{
"prop_float": 0,
"prop_int16": 50,
"prop_bool": 1,
"topic": "/{productKey}/{deviceName}/user/update"
}
*/
function transformPayload(topic, bytes) {
var uint8Array = new Uint8Array(bytes.length);
for (var i = 0; i < bytes.length; i++) {
uint8Array[i] = bytes[i] & 0xff;
}
var dataView = new DataView(uint8Array.buffer, 0);
var jsonMap = {};
if(topic.includes(SELF_DEFINE_TOPIC_ERROR_FLAG)) {
jsonMap['topic'] = topic;
jsonMap['errorCode'] = dataView.getInt8(0)
} else if (topic.includes(SELF_DEFINE_TOPIC_UPDATE_FLAG)) {
jsonMap['topic'] = topic;
jsonMap['prop_int16'] = dataView.getInt16(5);
jsonMap['prop_bool'] = uint8Array[7];
jsonMap['prop_float'] = dataView.getFloat32(8);
}
return jsonMap;
}
//以下是部分辅助函数。
function buffer_uint8(value) {
var uint8Array = new Uint8Array(1);
var dv = new DataView(uint8Array.buffer, 0);
dv.setUint8(0, value);
return [].slice.call(uint8Array);
}
function buffer_int16(value) {
var uint8Array = new Uint8Array(2);
var dv = new DataView(uint8Array.buffer, 0);
dv.setInt16(0, value);
return [].slice.call(uint8Array);
}
function buffer_int32(value) {
var uint8Array = new Uint8Array(4);
var dv = new DataView(uint8Array.buffer, 0);
dv.setInt32(0, value);
return [].slice.call(uint8Array);
}
function buffer_float32(value) {
var uint8Array = new Uint8Array(4);
var dv = new DataView(uint8Array.buffer, 0);
dv.setFloat32(0, value);
return [].slice.call(uint8Array);
}
代码是将原始数据(raw data)转换为物联网平台可以理解的协议格式,以及将协议格式转换回原始数据格式。代码中定义了一些常量、函数和辅助函数,用于处理数据的序列化和反序列化。
常量定义:
- COMMAND_REPORT、COMMAND_SET、COMMAND_REPORT_REPLY、COMMAND_SET_REPLY 和 COMMAD_UNKOWN 是用于标识不同命令类型的常量,它们分别对应不同的操作,如属性上报、属性设置、上报数据返回结果和属性设置设备返回结果。
- ALINK_PROP_REPORT_METHOD 和 ALINK_PROP_SET_METHOD 是物联网平台的Topic,用于设备与云端的通信。
- SELF_DEFINE_TOPIC_UPDATE_FLAG 和 SELF_DEFINE_TOPIC_ERROR_FLAG 是自定义Topic,用于特定的数据上报和错误上报。
函数定义:
- rawDataToProtocol(bytes):
- 将原始字节数据转换为协议格式的JSON对象。
- 使用 Uint8Array 和 DataView 来处理字节数据。
- 根据命令头(fHead)的不同,构建不同的JSON对象。
- protocolToRawData(json):
- 将协议格式的JSON对象转换为原始字节数据。
- 根据 method 字段的不同,拼接不同的字节数据。
- transformPayload(topic, bytes):
- 根据Topic和原始字节数据,转换为相应的JSON对象。
- 处理自定义Topic /user/update 和 /user/update/error。
示例数据:
- 设备上报属性数据和属性设置的返回结果的示例数据,展示了如何将原始数据转换为JSON格式。
辅助函数:
- buffer_uint8(value)、buffer_int16(value)、buffer_int32(value) 和 buffer_float32(value):
- 这些函数用于将不同的数值类型转换为字节数组,以便在原始数据和协议格式之间进行转换。
代码解析:
- rawDataToProtocol(bytes) 函数首先将传入的字节数据转换为 Uint8Array 和 DataView 对象,然后根据命令头(fHead)的不同,读取不同的字节数据,并构建相应的JSON对象。
- protocolToRawData(json) 函数根据传入的JSON对象的 method 字段,确定是属性设置还是设备上报数据返回结果,并拼接相应的字节数据。
- transformPayload(topic, bytes) 函数根据传入的Topic和字节数据,确定是处理错误数据还是上报数据,并构建相应的JSON对象。
示例用法:
- 设备上报属性数据:
javascript
var bytes = [0x00, 0x00, 0x00, 0x01, 0x00, 0x32, 0x01, 0x00, 0x00, 0x00];
var json = rawDataToProtocol(bytes);
console.log(json);
- 云端下发属性设置指令:
javascript
var json = {
"method": "thing.service.property.set",
"id": "12345",
"version": "1.0",
"params": {
"prop_float": 123.452,
"prop_int16": 333,
"prop_bool": 1
}
};
var rawData = protocolToRawData(json);
console.log(rawData);
什么时候用info,什么时候用alert,什么时候用error?
- Info(信息):
- 用途:用于上报设备的正常运行状态或完成的任务,通常不表示任何问题或需要立即关注的情况。
- 场景:例如,设备完成了一次自检、成功执行了一个命令、或设备状态正常。
- 示例:设备上报“电池电量正常”、“设备启动完成”等信息。
- Alert(告警):
- 用途:用于上报需要用户注意但不一定立即处理的事件。这类事件通常表示设备运行中出现了一些异常或警告,但设备仍能继续运行。
- 场景:例如,设备检测到电压接近最低阈值、设备运行效率降低、或设备即将需要维护。
- 示例:设备上报“电压过低”、“设备温度过高”等告警信息。
- Error(错误):
- 用途:用于上报设备无法正常运行或需要立即处理的严重问题。这类事件通常表示设备出现了故障或严重错误,可能影响设备的正常使用。
- 场景:例如,设备检测到硬件故障、软件崩溃、或设备完全停止响应。
- 示例:设备上报“设备无法启动”、“传感器故障”等错误信息。
选择事件类型的考虑因素:
- 严重性:根据事件的严重性来决定使用info、alert还是error。严重性较高的事件应使用error。
- 用户反馈:考虑用户对事件的反应和处理方式。需要用户立即注意的事件应使用alert或error。
- 设备状态:根据设备的状态变化来决定事件类型。设备状态正常或完成预期任务时使用info,状态异常或需要维护时使用alert,设备完全失效时使用error。
电压过低的事件通常表示设备虽然还能运行,但电压已经接近或低于正常工作所需的最低阈值,可能很快就会影响设备的正常运行或导致设备停止工作。因此,这种情况下应该选择 alert(告警) 类型。
选择 alert 的原因:
- 预警性:告警事件通常用于提醒用户注意潜在的问题,虽然当前设备可能还能正常运行,但电压过低是一个需要关注的信号。
- 优先级:告警事件的优先级高于一般信息(info),但低于错误(error),适合用于描述这种需要用户注意但尚未导致设备立即停止运行的情况。
- 处理时机:用户在收到告警后,可能会采取一些预防措施,比如检查电源、更换电池或进行维护,以避免设备因电压过低而停止工作。
什么是Alink JSON?
Alink JSON格式是阿里云物联网平台中使用的一种标准数据格式,用于设备与物联网平台之间的数据交换。以下是Alink JSON格式的详细介绍:
1. 基本概念
Alink JSON格式遵循特定的协议结构,包括“id”、“version”、“params”等字段,方便云端进行标准化处理。设备按照物联网平台定义的标准数据格式生成消息并上报,即直接构造和上报JSON格式的数据11。
2. 数据格式
Alink JSON格式的主要字段包括:
- id:消息ID号,需定义为String类型的数字,且每个消息ID在当前设备中具有唯一性。
- version:协议版本号,目前协议版本号为1.0。
- params:请求或响应的参数。
- method:请求方法,根据不同的操作有不同的取值。
- code:结果状态码,200表示成功。
- data:请求成功时的返回结果。
- message:返回结果信息,请求成功时返回"success"。
什么是OTA升级?
OTA(Over-The-Air Technology)升级,即空中下载技术升级,是一种通过无线网络远程向设备发送软件更新的方式。这种技术广泛应用于各种智能设备,包括智能手机、平板电脑、智能电视、智能家居设备以及物联网(IoT)设备等。
OTA升级的流程:
设备制造商开发软件更新,这些更新可能包括新功能、性能改进、安全补丁等。测试这些更新,确保其稳定性和兼容性。测试通过后,更新会被上传到服务器,准备分发给用户设备。设备通过无线网络连接到服务器,检测是否有可用的更新。用户同意后,设备开始下载更新文件。下载完成后,设备会在合适的时间(如夜间或设备空闲时)自动安装更新。安装完成后,设备会确认更新成功,并可能向服务器发送反馈。
安全性考虑:
- 加密:更新数据在传输过程中通常会被加密,以防止被截获或篡改。
- 验证:设备在安装更新前会验证更新文件的完整性和来源,确保其未被篡改。
应用场景:
- 智能手机和平板电脑:操作系统和应用程序的更新。
- 智能电视和流媒体设备:固件和应用程序的更新。
- 智能家居设备:如智能灯泡、智能插座、智能恒温器等设备的固件更新。
- 汽车:车载系统的软件更新,包括导航系统、娱乐系统等。
- 工业设备:如工业自动化设备的固件更新。
什么是透传格式数据,什么是非透传格式数据?
"透传格式数据"(Transparent Transmission Format Data)通常指的是在数据通信过程中,数据以原始格式或未经过封装的格式直接传输的方式。这种方式允许接收方直接读取和解析数据内容,而不需要进行额外的格式转换或解码。
应用场景:
- 物联网设备:在物联网(IoT)中,设备可能会发送原始传感器数据,这些数据以透传格式直接发送到服务器或网关,进行进一步处理。
- 远程监控系统:在工业自动化和远程监控系统中,设备状态和性能数据可能会以透传格式发送,以便进行实时监控。
- 数据采集系统:在数据采集和传输系统中,原始数据可能会以透传格式直接发送到数据中心,进行存储和分析。
- 设备间通信:在某些设备间的直接通信中,为了减少处理时间和提高效率,可能会使用透传格式。
非透传格式数据(Non-transparent Transmission Format Data)是指在数据传输过程中,数据经过封装或封装成特定的协议格式,使得原始数据被包装在额外的协议信息中。这种方式与透传格式数据相对,透传格式数据则是以原始格式直接传输,不需要额外的封装。
如Alink JSON格式
应用场景:
- 网络协议:如TCP/IP协议,数据在传输前会被封装成IP数据包,包含源地址、目的地址、数据长度等信息。
- 物联网平台:设备与物联网平台通信时,数据通常会被封装成特定的协议格式,如MQTT或CoAP。
- 移动通信:在移动通信中,数据通过GSM、LTE等协议传输,包含控制信息和用户数据。
- 企业应用:在企业级应用中,数据传输可能需要遵循特定的企业协议或标准,如SOAP或REST。