草庐IT

MQTT自定义透传_DTU连接阿里云

jameslan520 2024-03-10 原文

阿里云物联网平台定义的标准数据格式为Alink JSON。对于低配置且资源受限或者对网络流量有要求的设备,不适合直接构造JSON数据与物联网平台通信,可将原数据透传到物联网平台。物联网平台提供数据解析功能,可以根据您提交的脚本,将数据在设备自定义格式和JSON格式之间转换。

自定义透传适合的场景为采用廉价单片机、功能比较弱的DTU方案,这些DTU对json这种格式解析可能比较费劲。

一、新建产品

1.新建产品

我们选择“自定义品类”,节点类型为“直连设备”,最重要的是数据格式一定要选择“透传/自定义”。

 2.添加功能

 3.编写解析脚本

 

var COMMAND_REPORT = 0x00;
var COMMAND_SET = 0x01;
var ALINK_PROP_REPORT_METHOD = 'thing.event.property.post'; //标准ALink JSON格式topic, 设备 上传属性数据到 云端
var ALINK_PROP_SET_METHOD = 'thing.service.property.set'; //标准ALink JSON格式topic, 云端 下发属性控制指令 到设备端

/**
 * 将设备自定义topic数据转换为json格式数据, 设备上报数据到物联网平台时调用
 * 入参:topic   string 设备上报消息的topic
 * 入参:rawData byte[]数组 不能为空
 * 出参:jsonObj JSON对象 不能为空
 */
function transformPayload(topic, rawData) {
	var jsonObj = {};
	return jsonObj;
}   

/**
 * 将设备的自定义格式数据转换为Alink协议的数据,设备上报数据到物联网平台时调用
 * 入参:bytes byte[]数组 不能为空
 * 出参:jsonMap Alink JSON对象 不能为空
 */
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];
	if (fHead == COMMAND_REPORT) {
		jsonMap['method'] = ALINK_PROP_REPORT_METHOD;
		jsonMap['version'] = '1.0';
		jsonMap['id'] = '' + dataView.getInt32(1);
		var params = {};
		params['LightVolt'] = dataView.getInt32(5);
		params['PowerSwitch'] = uint8Array[9];
		jsonMap['params'] = params;
	}
	return jsonMap;
}

/**
 *  将Alink协议的数据转换为设备能识别的格式数据,物联网平台给设备下发数据时调用
 *  入参:json Alink JSON对象  不能为空
 *  出参:payloadArray byte[]数组      不能为空
 *
 */
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_int32 = params['LightVolt'];
            var prop_bool = params['PowerSwitch'];
            //按照自定义协议格式拼接 rawdata
            payloadArray = payloadArray.concat(buffer_uint8(COMMAND_SET));
            payloadArray = payloadArray.concat(buffer_int32(parseInt(id)));
            payloadArray = payloadArray.concat(buffer_int32(parseInt(prop_int32)));
            payloadArray = payloadArray.concat(buffer_uint8(prop_bool));
        }
        return payloadArray;
    }

//以下是部分辅助函数
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);
}

// 以下为脚本模版,您可以基于以下模版进行脚本编写

/**
 * 将设备自定义topic数据转换为json格式数据, 设备上报数据到物联网平台时调用
 * 入参:topic   string 设备上报消息的topic
 * 入参:rawData byte[]数组 不能为空
 * 出参:jsonObj JSON对象 不能为空
 */
/* function transformPayload(topic, rawData) {
    var jsonObj = {};
    return jsonObj;
} */

/**
 * 将设备的自定义格式数据转换为Alink协议的数据,设备上报数据到物联网平台时调用
 * 入参:rawData byte[]数组 不能为空
 * 出参:jsonObj Alink JSON对象 不能为空
 */
/* function rawDataToProtocol(rawData) {
    var jsonObj = {};
    return jsonObj;
} */

/**
 *  将Alink协议的数据转换为设备能识别的格式数据,物联网平台给设备下发数据时调用
 *  入参:jsonObj Alink JSON对象  不能为空
 *  出参:rawData byte[]数组      不能为空
 *
 */
/* function protocolToRawData(jsonObj) {
    var rawdata = [];
    return rawdata;
}
 */

二、配置dtu

如下图所示记录好平台的如下几个连接参数

ProductKey

DeviceName

DeviceSecret

mqttHostUrl

port

订阅Topic

发布Topic

  

我们要用到的topic为物模型通信Topic,打开产品详情,并选择Topic类列表-物模型通信Topic,我们需要的是下面红框内的这两个topic

 

配置DUT三要素及通信参数

按如下次序操作设置DTU,并将上面记录的通信参数对应填入。

 

三、测试上传

先发一个初始数据000320f2e30000000001(注意使用十六进制发送)

 阿里云状态变更

 上报一条新的000320f2e30000000500

 状态立即更新

 

四、测试下发

找到监控运维,在线调试,我们在属性调试内设置好属性数据然后点击“设置”下发一条指令

 

设备端收到的数据如下(注意:记得选择十六进制显示不然是乱码)

 本文参考自:dtu阿里云自定义透传 (openluat.com)

有关MQTT自定义透传_DTU连接阿里云的更多相关文章

  1. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  2. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  3. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  4. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  5. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  6. ruby - 无法在 60 秒内获得稳定的 Firefox 连接 (127.0.0.1 :7055) - 2

    我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类

  7. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  8. ruby - 定义方法参数的条件 - 2

    我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano

  9. ruby - 如何在 Grape 中定义哈希数组? - 2

    我使用Ember作为我的前端和GrapeAPI来为我的API提供服务。前端发送类似:{"service"=>{"name"=>"Name","duration"=>"30","user"=>nil,"organization"=>"org","category"=>nil,"description"=>"description","disabled"=>true,"color"=>nil,"availabilities"=>[{"day"=>"Saturday","enabled"=>false,"timeSlots"=>[{"startAt"=>"09:00AM","endAt"=>

  10. ruby - 获取模块中定义的所有常量的值 - 2

    我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c

随机推荐