AT+MQTTPUB=<LinkID>,<"topic">,<"data">,<qos>,<retain>
LinkID: 当前只支持 0
topic: 发布主题, 最长 64 字节
data: 发布消息, data 不能包含 \0, 请确保整条 AT+MQTTPUB 不超过 AT 指令的最大长度限制
qos: 发布服务质量, 参数可选 0,1,2, 默认为 0
retain: 发布 retain
主要对这个数据上传的命令问题,这个命令用串口调试助手发给ESP8266可以成功上传,但是CC2530去发给ESP8266的时候对data长度有一定的限制,太长了是发送不出去,甚至没有任何响应报错都没有。
要是选择阿里云的AlinkJSON数据格式创建的产品,按照它这种方式在编程里会变得很长例如下面这种
sprintf(strTemp,"AT+MQTTPUB=0,\"/sys/i2u8FoillVa/coordinator/thing/event/property/post\",\"{\\\"meth od\\\":\\\"thing.service.property.set\\\"\\\,\\\"id\\\":\\\"2012934117\\\"\\\,\\\"params\\\":{\\\"co2\\\":51}\\\,\\\"version\\\":\\\"1.0.0\\\"}\",1,0\r\n");
各种转义"”和,的看着也累,这样就导致data过长发送不成功。
我的解决方法是不采用阿里云定义的这种AlinkJSON数据格式,选择透传自定义
选择这种上传格式后需要我们自己去解析消息。
这里就是将消息转换成AlinkJSON格式完成物模型数据的上传,主要就是编写一个JavaScript脚本,下面贴一下我写的
var ALINK_PROP_SET_METHOD="thing.event.property.post"; //AlinkJSON的method属性 thing.service.property.set
/**
* 将设备自定义topic数据转换为json格式数据, 设备上报数据到物联网平台时调用
* 入参:topic string 设备上报消息的topic
* 入参:rawData byte[]数组 不能为空
* 出参:jsonObj JSON对象 不能为空
*/
function transformPayload(topic, rawData) {
var jsonObj = {};
return jsonObj;
}
function ascll2String(array) {
let result = "";
for (let i = 0; i < array.length; i++) {
result += String.fromCharCode(array[i]);
}
return result;
}
function toParams(str){
//str =str.substring(1,str.length-1);
let arr = str.split(",");
let params = {};
for(let i =0;i<arr.length;i++){
let map = arr[i].split(":");
params[map[0]]= parseInt(map[1]);
}
return params;
}
/**
* 将设备的自定义格式数据转换为Alink协议的数据,设备上报数据到物联网平台时调用
* 入参:rawData byte[]数组 不能为空
* 出参:jsonObj Alink JSON对象 不能为空
*/
function rawDataToProtocol(rawData) {
var byteString = ascll2String(rawData);
var data = toParams(byteString);
var jsonObj = {params:data,method:ALINK_PROP_SET_METHOD,version:"1.0.0"};
//var jsonObj = {params:rawData}
return jsonObj;
}
/**
* 将Alink协议的数据转换为设备能识别的格式数据,物联网平台给设备下发数据时调用
* 入参:jsonObj Alink JSON对象 不能为空
* 出参:rawData byte[]数组 不能为空
*
*/
function protocolToRawData(jsonObj) {
let result={};
result.id = jsonObj.id;
result.code = jsonObj.code;
result.data = jsonObj.data;
let jsonStr = JSON.stringify(result);
var rawdata = [];
//rawdata.push(jsonObj)
rawdata = strToAscll(jsonStr);
return rawdata;
}
function strToAscll(jStr){
let res = [];
let arry = jStr.split("");
for(let i =0;i<arry.length;i++){
res.push(arry[i].charCodeAt());
}
return res;
}
rawDataToProtocol();这个函数就是将消息转换成AlinkJSON,这里要主要入参的rawData 是一个ASCLL码数组,但是你测试的时候需要在下方输入的是16进制的数据比如这条
636f323a35312c74656d70657261747572653a3135
对应的字符串
co2:51,temperature:15
转换后的结果就是
这样就符合AlinkJSON格式了,可以成功上传物模型数据。
这里的疑惑点是在设备端我们不需要将信息转换成16进制,阿里云会帮我们转换吃16进制的。我们只要正常传消息 co2:51,temperature:15就可以了。
protocolToRawData();这个函数主要是设备上传数据以后会有一个reply返回给设备说上传成功还是失败的消息。透传自定义的设备默认是不订阅这个topic的,需要你自己订阅。
这个函数在测试的时候主要主要传入的是一个object不是它写的16进制很坑!
其实这个函数你只要不订阅那个replay的topic就不用管,只不过设备日志里会报错,直接用这个就可以处理。