如何写产品驱动
各平台协议驱动方式的对比
本项目的产品驱动,主推的执行引擎是magic,它是基于ASM字节码技术,语法有点介于 Java 和 JavaScript 混合的味道。别慌上手很简单,使用起来也很方便也很爽!先来对比一下!
各大平台对协议编解码方式对比
| NexIoT | 阿里云 IoT | 华为云 IoT | 腾讯云 IoT | |
|---|---|---|---|---|
| 功能名词 | 产品驱动(在线IDE) | 消息解析 | 插件开发 | 云端解析 |
| 支持方式 | Spring Bean 远程驱动(JAR包) JavaScript ✅magic-script | JavaScript Python PHP | 图形化开发 脚本化开发(JavaScript) FunctionGraph | JavaScript |
| 灵活性 | 高(三种方式可选) | 中(多脚本语言) | 高(图形化+脚本化) | 中(单一脚本) |
| 适用场景 | 企业级应用、灵活复杂协议、高性能需求 | 快速开发、多语言支持 | 快速开发、可视化配置 | 简单协议解析 |
为什么只开放了magic
- 平台最大亮点,会JS、Java等任意一种,大学生都能上手
- SpringBean需硬编码和重启服务器,调试起来复杂
- JavaScript在JDK生态支持太弱(ES5),实现一个MD5方法都要自己写
- 上传JAR方式仅限内部安全的环境适应
必须三个方法
preDecode提取设备身份标识。平台要知道你是谁decode设备数据转平台格式。乱七八糟的设备字符转成JSONencode平台台指令转设备格式。平台JSON转成设备能识别的字符
js
/**
* 预解码:提取设备身份标识
* @param {String} payload 设备原始报文(可能是二进制、JSON、16进制字符串等)
* @param {String} context 对于这里就是topic
* @returns {Object} {deviceId, productKey}
*/
var preDecode = (payload,context) => {
var deviceId;
context=StrUtil.str(context);
//cat4_lock/p2p/GID_lock@@@123456789012345
//topic格式五花八门,比如这种nexiot/up/zxabc123456
if(context.contains("/")){
var parts=context.split("\\/");
deviceId = parts[parts.length - 1];
}
//可能deviceId来自消息体
else if(JSONUtil.isTypeJSON(payload)){
payload=toJson(payload);
device=payload.deviceId;
}
if(deviceId==null){
//没解出来,不执行了
return null;
}
var rs = {
"deviceId": deviceId
};
return rs;
};
/**
* 编码:平台指令转设备格式
* @param {Object} payload 平台指令
* @returns {String} 设备可识别的报文(二进制、JSON、16进制字符串等)
*/
var encode = payload => {
var result = "";
// TODO:实现编码逻辑
return result;
};
/**
* 解码:设备数据转平台格式
* @param {String} payload 设备原始报文(二进制、JSON、16进制字符串等)
* @returns {Array} 平台标准消息数组,每个元素结构:
* [
* {
* messageType: "PROPERTIES", // 属性类型
* properties: {} // 解析后的属性键值对(根据物模型动态调整)
* },
* {
* messageType: "EVENT", // 事件类型
* event: "", // 事件名称
* data: {} // 事件参数
* }
* ]
*/
var decode = payload => {
var rs = [];
// 属性
var properties = {
"messageType": "PROPERTIES",
"properties": {
"slaveAddress":9
},
"subDevice":true
};
rs.push(properties);
// 事件
var event = {
"messageType": "EVENT",
"event": "",
"data": {}
};
rs.push(event);
return rs;
};
// 调试示例(正式使用请删除以下)
//return preDecode("");
// return encode({});
//return decode('{"temperture": 25.3}')开始编写
设备上线
只要平台收到任意的一条设备的消息,则会自动上线,超过阈值(默认24小时)没有收到消息,会自动下线。
- 任意一种驱动的实现,属性、事件必须遵守以下规范,下面主要以IDE的为例
来一条属性
json
{
"messageType": "PROPERTIES", //属性
"properties": {
"sourcePayload": "02240000001302031003CA00DE000000000000000000000058", //调试阶段原始消息建议保留
"humidity": 97, //湿度:与物模型对齐
"temperature": 22.2, //温度:与物模型对齐
"illumination": 88, //光照:与物模型对齐
}
}来一条事件
json
{
"messageType": "EVENT",
"event": "online", //上线事件,请于物模型对齐
"data": {} //事件可以塞进去自定义内容
}属性和事件一起
支持属性和事件组成一个数组上报,提高性能
json
[
{
"data": {},
"event": "online",
"messageType": "EVENT"
},
{
"messageType": "PROPERTIES",
"properties": {
"humidity": 97,
"illumination": 88,
"sourcePayload": "02240000001302031003CA00DE000000000000000000000058",
"temperature": 22.2
}
}
]高级特性
对于JT808,IEC104等复杂和自定义协议的设备,必须要有完整的交互才能正常通信(有点像TCP三次握手)
收到消息立马回复
在组装报文的同时,增加replyPayload,填设备需要回复的内容。支持TCP、MQTT
json
{
"messageType": "PROPERTIES", //属性
"properties": {
"sourcePayload": "02240000001302031003CA00DE000000000000000000000058", //调试阶段原始消息建议保留
"humidity": 97, //湿度:与物模型对齐
"temperature": 22.2, //温度:与物模型对齐
"illumination": 88, //光照:与物模型对齐
},
"replyPayload": "123456", 这里填回复的内容;平台会自动检测,如有值就会执行下发
}聪明的你会问,如果组装数组10条属性报文,都带replyPayload会不会回复设备10次
操作步骤:
理论支持,其实不建议
回复特定主题(MQTT)
平台支持在产品详情设置端云配置,支持内置#{deviceId}和#{productKey}等通配符,在下发的时候会自动匹配
信息
操作步骤:
- 进入
所有产品→ 选择对应的产品 →产品详情 - 找到
端云配置选项,点击编辑按钮 - 填入 你想要的任意,保存配置

json
{
"messageType": "PROPERTIES",
"properties": {
"temperture": 25.3
},
"replyPayload": "nexiotyanshi14",
"downTopic": "nexiot/down1/zxabc123456" //这里可以直接写死回复的主题topic
}