概述

很多場(chǎng)景下,開(kāi)發(fā)者需要更新設(shè)備的配置信息,包括設(shè)備的系統(tǒng)參數(shù)、網(wǎng)絡(luò)參數(shù)、本地策略等。通常情況下,是通過(guò)固件升級(jí)的方式更新設(shè)備的配置信息。但是,這將加大固件版本的維護(hù)工作,并且需要設(shè)備中斷運(yùn)行以完成更新。為了解決上述問(wèn)題,物聯(lián)網(wǎng)平臺(tái)提供了遠(yuǎn)程配置更新的功能,設(shè)備無(wú)需重啟或中斷運(yùn)行即可在線(xiàn)完成配置信息的更新。本文主要演示如何使用JAVA SDK實(shí)現(xiàn)兩種應(yīng)用場(chǎng)景。

原理說(shuō)明

1、物聯(lián)網(wǎng)平臺(tái)提供的遠(yuǎn)程配置功能,支持:

  • 開(kāi)啟/關(guān)閉遠(yuǎn)程配置。
  • 在線(xiàn)編輯配置文件,并管理版本。
  • 批量更新設(shè)備配置信息。
  • 設(shè)備主動(dòng)請(qǐng)求更新配置信息。

2、流程圖

阿里云物聯(lián)網(wǎng)平臺(tái)遠(yuǎn)程配置功能JAVA 示例參考

3、遠(yuǎn)程配置大致分為三部分:

  • 生成配置文件:您在物聯(lián)網(wǎng)平臺(tái)控制臺(tái)編輯并保存配置信息。
  • 推送配置文件:您在物聯(lián)網(wǎng)平臺(tái)控制臺(tái)批量推送配置信息給設(shè)備。設(shè)備接收后,修改本地配置文件。
  • 設(shè)備主動(dòng)請(qǐng)求配置信息:設(shè)備主動(dòng)向云端請(qǐng)求新的配置文件,并進(jìn)行更新。

遠(yuǎn)程配置使用分為兩種場(chǎng)景,一種是云端推送配置信息給設(shè)備端,一種是設(shè)備端主動(dòng)請(qǐng)求配置信息。根據(jù)場(chǎng)景的不同,遠(yuǎn)程配置的步驟也有所區(qū)別。

場(chǎng)景一:云端推送配置信息給設(shè)備端

1、設(shè)備端業(yè)務(wù)代碼實(shí)現(xiàn)

import com.aliyun.alink.dm.api.DeviceInfo;
import com.aliyun.alink.dm.api.InitResult;
import com.aliyun.alink.dm.api.IoTApiClientConfig;
import com.aliyun.alink.linkkit.api.ILinkKitConnectListener;
import com.aliyun.alink.linkkit.api.IoTMqttClientConfig;
import com.aliyun.alink.linkkit.api.LinkKit;
import com.aliyun.alink.linkkit.api.LinkKitInitParams;
import com.aliyun.alink.linksdk.cmp.connect.channel.MqttSubscribeRequest;
import com.aliyun.alink.linksdk.cmp.core.base.AMessage;
import com.aliyun.alink.linksdk.cmp.core.base.ConnectState;
import com.aliyun.alink.linksdk.cmp.core.listener.IConnectNotifyListener;
import com.aliyun.alink.linksdk.cmp.core.listener.IConnectSubscribeListener;
import com.aliyun.alink.linksdk.tools.AError;
public class DeviceCOTADemo1 {
 public static void main(String[] args) {
 String regionId = "cn-shanghai";
 DeviceInfo deviceInfo = new DeviceInfo();
 deviceInfo.productKey = "******";
 deviceInfo.deviceName = "******";
 deviceInfo.deviceSecret = "********";
 LinkKitInitParams params = new LinkKitInitParams();
 IoTMqttClientConfig config = new IoTMqttClientConfig();
 config.productKey = deviceInfo.productKey;
 config.deviceName = deviceInfo.deviceName;
 config.deviceSecret = deviceInfo.deviceSecret;
 config.channelHost = deviceInfo.productKey + ".iot-as-mqtt." + regionId + ".aliyuncs.com:1883";
 params.mqttClientConfig = config;
 params.connectConfig = new IoTApiClientConfig();
 params.deviceInfo = deviceInfo;
 /**建立連接**/
 LinkKit.getInstance().init(params, new ILinkKitConnectListener() {
 @Override
 public void onError(AError aError) {
 System.out.println("初始化失敗 " + aError.getMsg());
 }
 @Override
 public void onInitDone(InitResult initResult) {
 System.out.println("初始化成功 " + initResult.tsl);
 String pd = deviceInfo.productKey + "/" + deviceInfo.deviceName;
 // 1、cota 請(qǐng)求 Topic
 String requestcotaTopic = "/sys/"+pd+"/thing/config/push";
 // 訂閱Topic
 MqttSubscribeRequest upgradeTopicRequest = new MqttSubscribeRequest();
 upgradeTopicRequest.topic = requestcotaTopic;
 upgradeTopicRequest.isSubscribe = true;
 // 直接做Topic的訂閱
 LinkKit.getInstance().subscribe(upgradeTopicRequest, new IConnectSubscribeListener(){
 @Override
 public void onSuccess() {
 System.out.println("cota訂閱成功");
 }
 @Override
 public void onFailure(AError aError) {
 System.out.println("直接訂閱失敗" + aError.getMsg());
 }
 });
 // 注冊(cè)ota下行監(jiān)聽(tīng)
 LinkKit.getInstance().registerOnNotifyListener(new IConnectNotifyListener() {
 @Override
 public void onNotify(String s, String s1, AMessage aMessage) {
 System.out.println("cota 監(jiān)聽(tīng)響應(yīng):");
 System.out.println(new String((byte[])aMessage.getData()));
 }
 @Override
 public boolean shouldHandle(String s, String s1) {
 return false;
 }
 @Override
 public void onConnectStateChange(String s, ConnectState connectState) {
 System.out.println("連接狀態(tài)發(fā)生變化 :" + s + connectState);
 }
 });
 }
 });
 }
}

2、管理門(mén)戶(hù)配置遠(yuǎn)程控制,詳細(xì)步驟參考鏈接。

阿里云物聯(lián)網(wǎng)平臺(tái)遠(yuǎn)程配置功能JAVA 示例參考

3、啟動(dòng)設(shè)備端程序,管理門(mén)戶(hù)批量更新,設(shè)備端獲取信息(批量更新頻率限制:一小時(shí)內(nèi)僅允許操作一次):

{"method":"thing.config.push","id":"1296799269","params":{"getType":"file","configId":"92eb82a17a7441111f7dcb830e93ed79","sign":"568e9211117eedc9eadbc2907719fe2086348f572ddd3f373d6f297ba5aba4d1","configSize":12,"signMethod":"Sha256","url":"https://otx-devicecenter-thing-config-cn-shanghai-online.oss-cn-shanghai.aliyuncs.com/11zisMUtYDk/1567338668042_gz2Qs7hl?Expires=1567340568&OSSAccessKeyId=1111113rx5dg2JBm&Signature=S0LS9H%1111zJqTg%2Fphf19%2BfE%2F2bs%3D"},"version":"1.0"}

場(chǎng)景二:設(shè)備主動(dòng)請(qǐng)求配置信息

1、設(shè)備端業(yè)務(wù)代碼實(shí)現(xiàn)

import com.aliyun.alink.dm.api.DeviceInfo;
import com.aliyun.alink.dm.api.InitResult;
import com.aliyun.alink.dm.api.IoTApiClientConfig;
import com.aliyun.alink.linkkit.api.ILinkKitConnectListener;
import com.aliyun.alink.linkkit.api.IoTMqttClientConfig;
import com.aliyun.alink.linkkit.api.LinkKit;
import com.aliyun.alink.linkkit.api.LinkKitInitParams;
import com.aliyun.alink.linksdk.cmp.connect.channel.MqttPublishRequest;
import com.aliyun.alink.linksdk.cmp.connect.channel.MqttSubscribeRequest;
import com.aliyun.alink.linksdk.cmp.core.base.AMessage;
import com.aliyun.alink.linksdk.cmp.core.base.ARequest;
import com.aliyun.alink.linksdk.cmp.core.base.AResponse;
import com.aliyun.alink.linksdk.cmp.core.base.ConnectState;
import com.aliyun.alink.linksdk.cmp.core.listener.IConnectNotifyListener;
import com.aliyun.alink.linksdk.cmp.core.listener.IConnectSendListener;
import com.aliyun.alink.linksdk.cmp.core.listener.IConnectSubscribeListener;
import com.aliyun.alink.linksdk.tools.AError;
public class DeviceCOTADemo2 {
 public static void main(String[] args) {
 String regionId = "cn-shanghai";
 DeviceInfo deviceInfo = new DeviceInfo();
 deviceInfo.productKey = "******";
 deviceInfo.deviceName = "******";
 deviceInfo.deviceSecret = "********";
 LinkKitInitParams params = new LinkKitInitParams();
 IoTMqttClientConfig config = new IoTMqttClientConfig();
 config.productKey = deviceInfo.productKey;
 config.deviceName = deviceInfo.deviceName;
 config.deviceSecret = deviceInfo.deviceSecret;
 config.channelHost = deviceInfo.productKey + ".iot-as-mqtt." + regionId + ".aliyuncs.com:1883";
 params.mqttClientConfig = config;
 params.connectConfig = new IoTApiClientConfig();
 params.deviceInfo = deviceInfo;
 /**建立連接**/
 LinkKit.getInstance().init(params, new ILinkKitConnectListener() {
 @Override
 public void onError(AError aError) {
 System.out.println("初始化失敗 " + aError.getMsg());
 }
 @Override
 public void onInitDone(InitResult initResult) {
 System.out.println("初始化成功 " + initResult.tsl);
 String pd = deviceInfo.productKey + "/" + deviceInfo.deviceName;
 // 1、設(shè)備端訂閱Topic:/sys/${productKey}/${deviceName}/thing/config/get_reply
 String requestcotaTopic = "/sys/"+pd+"/thing/config/get_reply";
 MqttSubscribeRequest upgradeTopicRequest = new MqttSubscribeRequest();
 upgradeTopicRequest.topic = requestcotaTopic;
 upgradeTopicRequest.isSubscribe = true;
 LinkKit.getInstance().subscribe(upgradeTopicRequest, new IConnectSubscribeListener(){
 @Override
 public void onSuccess() {
 System.out.println("ota訂閱成功");
 }
 @Override
 public void onFailure(AError aError) {
 System.out.println("直接訂閱失敗" + aError.getMsg());
 }
 });
 // 注冊(cè)下行監(jiān)聽(tīng)
 LinkKit.getInstance().registerOnNotifyListener(new IConnectNotifyListener() {
 @Override
 public void onNotify(String s, String s1, AMessage aMessage) {
 System.out.println("cota 監(jiān)聽(tīng)響應(yīng):");
 System.out.println(new String((byte[])aMessage.getData()));
 }
 @Override
 public boolean shouldHandle(String s, String s1) {
 return false;
 }
 @Override
 public void onConnectStateChange(String s, ConnectState connectState) {
 System.out.println("連接狀態(tài)發(fā)生變化 :" + s + connectState);
 }
 });
 // 4、設(shè)備通過(guò)Topic /sys/${productKey}/${deviceName}/thing/config/get主動(dòng)查詢(xún)最新的配置信息
 String requestTopic = "/sys/"+pd+"/thing/config/get";
 System.out.println("發(fā)送消息" + requestTopic);
 // 訂閱Topic
 MqttPublishRequest request = new MqttPublishRequest();
 request.topic = requestTopic;
 request.payloadObj = "{\"id\":\"123\",\"method\":\"thing.config.get\",\"params\":{\"getType\":\"file\",\"configScope\":\"product\"},\"version\":\"1.0\"}";
 // 直接做Topic的發(fā)送
 LinkKit.getInstance().publish(request, new IConnectSendListener() {
 @Override
 public void onResponse(ARequest aRequest, AResponse aResponse) {
 System.out.println("請(qǐng)求發(fā)送成功 " + aResponse.getData());
 }
 @Override
 public void onFailure(ARequest aRequest, AError aError) {
 System.out.println("請(qǐng)求發(fā)送成功 " + aError.getMsg());
 }
 });
 }
 });
 }
}

2、運(yùn)行結(jié)果(/sys/${productKey}/${deviceName}/thing/config/get_reply 訂閱獲取的內(nèi)容)

{"code":200,"data":{"configId":"a9415f2d6e444d7f9e60a3d46f11d566","configSize":18,"getType":"file","sign":"112f38e7345a2ac46d9f80a401886727f27de96ebf1c82b6825df4b31116ab02","signMethod":"Sha256","url":"https://otx-devicecenter-thing-config-cn-shanghai-online.oss-cn-shanghai.aliyuncs.com/11D8NwXCe56/1567337893929_gpUFnE69?Expires=1567339979&OSSAccessKeyId=11AIRY3rx5dg2JBm&Signature=1112qy8bOsa48elOQFt4qHQGaqk%3D"},"id":"123","method":"thing.config.get","version":"1.0"}

作者:taro_秋刀魚(yú)