天天看點

IoT 存量裝置 零改造,泛化SDK實作整體業務遷移上雲

在物聯網實際項目中,有些裝置采用私有協定接入了本地裝置管理系統,有些 NB-IoT 裝置被迫接入了電信 AEP 平台,有些裝置接入了移動 OneNET 平台。但甲方客戶的整體業務都部署在阿裡雲上,我們如何實作整體業務上雲呢?

阿裡雲 IoT 物聯網平台提供了泛化協定SDK接入的方案,在 IoT 裝置零改造的前提下,幫助企業快速建構雲上橋接服務,通過網橋實作 IoT 終端裝置與阿裡雲 IoT 物聯網平台的雙向資料通信。

技術架構

IoT 存量裝置 零改造,泛化SDK實作整體業務遷移上雲

方案1:泛化SDK

泛化協定SDK是協定自适應的架構,用以建構與阿裡雲物聯網平台進行高效雙向通信的橋接服務。

IoT 存量裝置 零改造,泛化SDK實作整體業務遷移上雲

适用場景

泛化協定SDK面向的目标場景包括:

  • 裝置無 Internet 聯網能力。
  • 裝置采用私有協定。
  • 存量裝置不修改固件邏輯

泛化協定SDK使得網橋Server具備與物聯網平台進行通信的能力。

  • 提供基于配置檔案的靜态配置管理能力。
  • 提供裝置連接配接管理能力。
  • 提供上行通信能力。
  • 提供下行通信能力。

   接入流程  **

使用泛化協定SDK,橋接裝置與物聯網平台的整體流程圖,如下:

IoT 存量裝置 零改造,泛化SDK實作整體業務遷移上雲

   開發實戰  **

泛化 SDK 依賴

泛化協定僅支援Java開發語言,添加泛化協定SDK的項目Maven依賴,如下:

<dependency>
  <groupId>com.aliyun.openservices</groupId>
  <artifactId>iot-as-bridge-sdk-core</artifactId>
  <version>2.1.3</version>
</dependency>           

初始化 SDK 

您需要建立一個BridgeBootstrap對象執行個體,并調用bootstrap方法。泛化協定SDK初始化工作完成後,讀取網橋資訊,并向雲端發起網橋裝置上線請求等。

此外,可以在調用bootstrap方法的同時,向泛化協定SDK注冊一個DownlinkChannelHandler回調,用于接收雲端下行消息。

BridgeBootstrap bridgeBootstrap = new BridgeBootstrap();
bridgeBootstrap.bootstrap(new DownlinkChannelHandler() {
    @Override
    public boolean pushToDevice(Session session, String topic, byte[] payload) {
        // 雲端下行控制指令
        String content = new String(bytes);
        log.info("Get DownLink message, session:{}, {}, {}", session, topic, content);
        return true;
    }
    @Override
    public boolean broadcast(String topic, byte[] payload) {
        return false;
    }
});           

配置泛化網橋身份 

建立網橋産品

IoT 存量裝置 零改造,泛化SDK實作整體業務遷移上雲

注冊網橋裝置

IoT 存量裝置 零改造,泛化SDK實作整體業務遷移上雲

網橋配置預設使用配置檔案方式。預設從Java工程預設資源檔案路徑(一般是src/main/resources/)下的application.conf中讀取配置檔案。

# Server endpoint
http2Endpoint = "https://你的ProductKey.iot-as-http2.cn-shanghai.aliyuncs.com:443"
authEndpoint = "https://iot-auth.cn-shanghai.aliyuncs.com/auth/bridge"
# Gateway device info, productKey & deviceName & deviceSecret
productKey = ${bridge-ProductKey}
deviceName = ${bridge-DeviceName}
deviceSecret = ${bridge-DeviceSecret}

# subDeviceConnectMode = 3,即子裝置線上狀态和網關是否線上無關
subDeviceConnectMode = 3           

配置網橋下裝置身份 

建立子裝置産品

IoT 存量裝置 零改造,泛化SDK實作整體業務遷移上雲

注冊裝置,擷取身份三元組

IoT 存量裝置 零改造,泛化SDK實作整體業務遷移上雲

配置裝置原始身份辨別符和裝置證書資訊的映射關系。預設使用配置檔案方式,預設從Java工程的預設資源檔案路徑(一般是src/main/resources/)下的devices.conf中讀取配置檔案。

${device-original-Identity} {
  productKey : ${device-ProductKey}
  deviceName : ${device-DeviceName}
  deviceSecret : ${device-DeviceSceret}
  
}           

裝置上線 

裝置上線時,需要傳Session。下行消息回調時,會把Session回調給網橋。Session中包含裝置的原始身份辨別符字段,以便網橋判斷消息屬于哪個裝置。

UplinkChannelHandler uplinkHandler = new UplinkChannelHandler();
//建立Session
Object channel = new Object();
Session session = Session.newInstance(originalIdentity, channel);
//裝置上線
boolean success = uplinkHandler.doOnline(session, originalIdentity);
if (success) {
    // 裝置上線成功,網橋接受後續裝置通信請求。
} else {
    // 裝置上線失敗,網橋可以拒絕後續裝置通信請求,如斷開連接配接。
}           
IoT 存量裝置 零改造,泛化SDK實作整體業務遷移上雲

裝置通過網橋上報資料 

網橋使用泛化協定 SDK 代理裝置上報消息,代碼如下:

// originalIdentity 裝置上報資料
DeviceIdentity deviceIdentity = ConfigFactory.getDeviceConfigManager().getDeviceIdentity(originalIdentity);
ProtocolMessage protocolMessage = new ProtocolMessage();
protocolMessage.setPayload(payload);
protocolMessage.setQos(0);
protocolMessage.setTopic(String.format(TOPIC_TEMPLATE_USER_DEFINE, deviceIdentity.getProductKey(), deviceIdentity.getDeviceName()));
// 網橋代理上報
uplinkChannelHandler.doPublishAsync(originalIdentity, protocolMessage);           
IoT 存量裝置 零改造,泛化SDK實作整體業務遷移上雲

裝置接收雲端指令

雲端可以調用Pub API給裝置下發控制指令,網橋監聽和處理雲端消息的代碼如下:

private static ExecutorService executorService  = new ThreadPoolExecutor(
    Runtime.getRuntime().availableProcessors(),
    Runtime.getRuntime().availableProcessors() * 2,
    60, TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(1000),
    new ThreadFactoryBuilder().setDaemon(true).setNameFormat("bridge-downlink-handle-%d").build(),
    new ThreadPoolExecutor.AbortPolicy());
public static void main(String args[]) {
    //Use application.conf & devices.conf by default
    bridgeBootstrap = new BridgeBootstrap();
    bridgeBootstrap.bootstrap(new DownlinkChannelHandler() {
        @Override
        public boolean pushToDevice(Session session, String topic, byte[] payload) {
            //get message from cloud
            //get downlink message from cloud
            executorService.submit(() -> handleDownLinkMessage(session, topic, payload));
            return true;
        }
        @Override
        public boolean broadcast(String s, byte[] bytes) {
            return false;
        }
    });
}
private static void handleDownLinkMessage(Session session, String topic, byte[] payload) {
    String content = new String(payload);
    log.info("Get DownLink message, session:{}, topic:{}, content:{}", session, topic, content);
    Object channel = session.getChannel();
    String originalIdentity = session.getOriginalIdentity();
    //for example, you can send the message to device via channel, it depends on you specific server implementation
}           
IoT 存量裝置 零改造,泛化SDK實作整體業務遷移上雲
IoT 存量裝置 零改造,泛化SDK實作整體業務遷移上雲

裝置下線

當裝置從網橋斷開後,可以調用下線接口,告知雲端:

upLinkHandler.doOffline(originalIdentity);           

【往期回顧】

1、39張IoT傳感器工作原理GIF圖彙總 2、IoT 裝置發送 MQTT 請求的曲折經曆 3、20元體 Arduino 環境監測儀開發 4、智能手持測溫槍開發實踐 5、JMeter 壓測 MQTT 服務性能實戰