安装 Device SDK(HTTP/HTTPS)


本文介绍如何使用 HTTP/HTTPS 协议安装用于 OTA 升级的 Device SDK。

前提条件


了解 EnOS 的 OTA 升级流程,参见 设备固件升级概述

步骤 1:安装 Device SDK

下载 enos-mqtt-sdk-java。如果使用 Maven,可在 pom.xml 中添加以下依赖:

<dependency>
  <groupId>com.envisioniot</groupId>
  <artifactId>enos-http</artifactId>
  <version>0.2.1</version>
</dependency>

步骤 2:下载设备固件


通过云端服务 SDK 下载固件文件:

示例代码


以下是通过 Java SDK 实现设备端 OTA 能力的示例代码:

package http;

import com.envisioniot.enos.iot_http_sdk.HttpConnection;
import com.envisioniot.enos.iot_http_sdk.SessionConfiguration;
import com.envisioniot.enos.iot_http_sdk.StaticDeviceCredential;
import com.envisioniot.enos.iot_http_sdk.file.FileCategory;
import com.envisioniot.enos.iot_mqtt_sdk.core.exception.EnvisionException;
import com.envisioniot.enos.iot_mqtt_sdk.core.internals.SignMethod;
import com.envisioniot.enos.iot_mqtt_sdk.core.msg.IMessageHandler;
import com.envisioniot.enos.iot_mqtt_sdk.message.downstream.ota.OtaUpgradeCommand;
import com.envisioniot.enos.iot_mqtt_sdk.message.upstream.ota.*;
import com.google.common.base.Preconditions;
import org.apache.commons.codec.digest.DigestUtils;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 示例:通过 HTTP 协议实现 EnOS IoT 的固件升级
 */
public class OtaHttpSample {
    // EnOS HTTP Broker URL,从 EnOS 应用门户 > 开发者控制台的环境信息页面获取
    private static final String BROKER_URL = "http://broker_url/";

    // 设备凭证,从 EnOS 应用门户 > 开发者控制台的设备详情页面获取
    private static final String PRODUCT_KEY = "productKey";
    private static final String DEVICE_KEY = "deviceKey";
    private static final String DEVICE_SECRET = "deviceSecret";

    // 上报固件版本
    private static void reportVersion(HttpConnection connection, String version) {
        OtaVersionReportRequest request = OtaVersionReportRequest.builder()
                .setVersion(version)
                .setProductKey(PRODUCT_KEY)
                .setDeviceKey(DEVICE_KEY)
                .build();
        try {
            OtaVersionReportResponse response = connection.publish(request, null);
            System.out.println("Version reported: " + response);
        } catch (EnvisionException | IOException e) {
            e.printStackTrace();
        }
    }

    // 从云端获取可用固件列表
    private static List<Firmware> getFirmwaresFromCloud(HttpConnection connection) {
        OtaGetVersionRequest request = new OtaGetVersionRequest.Builder()
                .setProductKey(PRODUCT_KEY)
                .setDeviceKey(DEVICE_KEY)
                .build();
        try {
            OtaGetVersionResponse response = connection.publish(request, null);
            System.out.println("Get version response: " + response);
            return response.getFirmwareList();
        } catch (EnvisionException | IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    // 设备主动请求升级固件
    private static void upgradeFirmwareByDeviceReq(HttpConnection connection) throws InterruptedException {
        List<Firmware> firmwareList = getFirmwaresFromCloud(connection);
        if (firmwareList != null && !firmwareList.isEmpty()) {
            Firmware firmware = firmwareList.get(0); // 假设只处理第一个固件
            System.out.println("Received firmware: " + firmware);
            reportUpgradeProgress(connection, "20", "Downloading...");
            TimeUnit.SECONDS.sleep(10);
            reportUpgradeProgress(connection, "80", "Installing...");
            TimeUnit.SECONDS.sleep(20);
            reportVersion(connection, firmware.version);
        }
    }

    // 上报升级进度
    private static void reportUpgradeProgress(HttpConnection connection, String progress, String desc) {
        OtaProgressReportRequest request = new OtaProgressReportRequest.Builder()
                .setStep(progress)
                .setDesc(desc)
                .build();
        try {
            OtaProgressReportResponse response = connection.publish(request, null);
            System.out.println("Progress reported: " + response);
        } catch (EnvisionException | IOException e) {
            e.printStackTrace();
        }
    }

    // 注册云端推送升级处理器
    private static void registerUpgradeByCloudPushHandler(HttpConnection connection) {
        connection.setArrivedMsgHandler(OtaUpgradeCommand.class, (command, topics) -> {
            System.out.println("Received command: " + command);
            Firmware firmware = command.getFirmwareInfo();

            // 下载固件文件
            try (InputStream inputStream = connection.downloadFile(firmware.fileUrl, FileCategory.OTA)) {
                // 校验固件签名
                String sign = firmware.signMethod.equalsIgnoreCase(SignMethod.MD5.getName())
                        ? DigestUtils.md5Hex(inputStream)
                        : DigestUtils.sha256Hex(inputStream);
                Preconditions.checkArgument(firmware.sign.equals(sign), "Firmware signature check failed");

                // 模拟升级过程
                reportUpgradeProgress(connection, "20", "Downloading...");
                TimeUnit.SECONDS.sleep(2);
                reportUpgradeProgress(connection, "80", "Installing...");
                TimeUnit.SECONDS.sleep(20);
                reportVersion(connection, firmware.version);
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        });
    }

    public static void main(String[] args) throws InterruptedException {
        // 使用设备凭证构造静态认证
        StaticDeviceCredential credential = new StaticDeviceCredential(PRODUCT_KEY, DEVICE_KEY, DEVICE_SECRET);

        // 配置会话并建立 HTTP 连接
        SessionConfiguration config = SessionConfiguration.builder().lifetime(30_000).build();
        HttpConnection connection = new HttpConnection.Builder(BROKER_URL, credential)
                .sessionConfiguration(config)
                .build();

        // 注册云端推送升级处理器
        registerUpgradeByCloudPushHandler(connection);

        // 上报当前版本并尝试主动升级
        reportVersion(connection, "current_version");
        upgradeFirmwareByDeviceReq(connection);

        // 模拟持续运行
        while (true) {
            Thread.sleep(10_000);
            System.out.println("Current session ID: " + connection.getSessionId());
        }
    }
}