快速入门:将智能设备连接至 EnOS™ Cloud


该教程将指导你如何通过 Java SDK 模拟智能设备直连入 EnOS Cloud,在设备与 EnOS Cloud 之间发送数据,并从 EnOS 管理控制台 查看设备通信信息。

场景描述

接入场景参考 设备接入方案 当中提到的“场景1.1”。

任务描述

本示例以用户光伏逆变器接入为例进行说明,逆变器采集器出厂烧录逆变器设备三元组。逆变器上电、联网以后,基于设备三元组认证直连云端 IoT Hub。整体流程如下图所示:

../_images/device_connection_task_description.png

基于上述接入流程图,本示例主要有以下任务:

  1. 创建设备模型。

  2. 创建产品。

  3. 注册设备。

  4. 为测点数据配置存储策略。

  5. 通过设备 SDK 模拟设备发送数据。

  6. 查看设备通信状态。

  7. 查看设备数据。

步骤 1:创建设备模型

该步骤假设没有可以复用的设备模型,我们创建一个名称为 Inverter_Demo,功能定义如下表的新的模型:

功能类型

名称

标识符

数据类型

数据定义

属性

逆变器类型

invType

enum

{0:Central,1:String}

属性

组件容量

capacity

float

kWp

测点

有功功率

INV.GenActivePW

double

kW

服务

控制

INV.Control

调用方式:异步调用

事件

故障信息

Error

事件类型:故障

创建该模型的步骤如下:

  1. EnOS 管理控制台 中选择 模型

  2. 私有模型 标签页,点击 创建模型, 并在 创建模型 窗口提供以下配置信息:

    • 模型标识符: Inverter_Demo_0

    • 模型名称:Inverter_Demo

    • 分类:无

    • 模型关系:无

    • 模型模板:无

    • 模型描述:Inverter model for demo project

  3. 点击 确定 完成操作。

    ../_images/model_inverter.png
  4. 点击 edit ,在 模型详情页面,点击 功能定义 标签。

  5. 点击 编辑,再点击 新增 ,选择 新建自定义功能 ,在 添加功能 表单填入以下信息:

    • 属性1

      • 名称:逆变器类型/Inverter_Type

      • 标识符:invType

      • 数据类型:enum

      • 枚举项

        • 参数值:0;参数描述:Central

        • 参数值:1;参数描述:String

      • 是否必填:是

    • 属性2

      • 名称:组件容量/Inverter_Capacity

      • 标识符:capacity

      • 数据类型:float

      • 单位:kWp

      • 是否必填:是

    • 测点

      • 名称:有功功率/Active_Power

      • 标识符:INV.GenActivePW

      • 数据类型:double

      • 测点类型:AI

      • 单位:kW

    • 服务

      • 名称:控制/Control

      • 标识符:INV.Control

      • 输入参数

        • 参数名称:control

        • 标识符:control

        • 数据类型:enum

        • 枚举项:

          • 参数值:0;参数描述:Stop

          • 参数值:1;参数描述:Start

      • 输出参数

        • 参数名称:execResult

        • 标识符:execResult

        • 数据类型:enum

        • 枚举项:

          • 参数值:0;参数描述:Failure

          • 参数值:1;参数描述:Success

    • 事件

      • 名称:故障信息/Error

      • 标识符:Error

      • 事件类型:故障

  6. 点击 发布,让该模型的功能定义生效。

有关设备模型设置的详细信息,参见 创建模型

步骤 2:创建产品

在该步骤,我们创建一个名为 Inverter_Product 的产品,我们假设该产品型号的设备通过 JSON 格式上送数据且数据传输不使用 CA 证书加密。

  1. EnOS 管理控制台 中选择 设备管理 > 产品管理

  2. 点击在页面 创建产品,在 创建产品 窗口提供以下配置信息。

    • 产品名称:Inverter_Product

    • 节点类型:设备

    • 设备模型:Inverter_Demo

    • 数据格式:Json

    • 证书双向认证:禁用

    • 产品描述:Inverter product for demo

  3. 点击 确定 完成操作。

    ../_images/create_product.png

有关产品设置的详细信息,参见 创建产品

步骤 3:注册设备

在该步骤中,我们创建一个名称为 INV001 的设备,该设备属于在上一步骤中创建的 Inverter_Product 产品型号。

  1. EnOS 管理控制台 中选择 设备管理 > 设备资产

  2. 点击 添加设备 ,在弹出窗口配置如下信息:

    • 产品:Inverter_Product

    • 设备名称:INV001

    • 时区/城市:UTC+14:00

    • 逆变器类型:0:Central,表示集中式逆变器

    • 组件容量:5.0

    ../_images/register_device.png

有关设备设置的详细信息,参见 创建设备

完成设备注册后,获取设备三元组 ProductKeyDeviceKeyDeviceSecret,将在下一步中使用。

步骤 4:为测点数据配置存储策略

在完成设备注册、开始连接设备到云端之前,我们需要为设备测点(INV.GenActivePW)的数据配置存储策略,否则测点数据不会被存储到时序数据管理。为测点数据配置存储策略的步骤如下:

  1. 如未申请开通时序数据管理资源,在 EnOS 管理控制台 中选择 资源管理 > 资源列表,在 企业数据平台 标签下,申请时序数据库资源。有关资源申请和管理的详细信息,参见 资源管理概述

  2. EnOS 管理控制台 中选择 时序数据管理 > 存储策略,为设备测点数据配置相应的存储类型和时长。有关配置存储策略的详细步骤,参见 配置 TSDB 存储

步骤 5:SDK模拟设备发送数据

在该步骤中,我们通过设备端 SDK 模拟发送逆变器有功功率至云端。

  1. 获取 设备端SDK。更多信息,参考该 SDK 的 GitHub readme 文件。

  2. 配置 EnOS Cloud 连接地址。

  3. 将 Cloud 端地址 environment_address 及注册设备获取的设备三元组(ProductKey,DeviceKey,DeviceSecret)配置至 sample 连接程序当中。设备三元组为注册设备步骤中获得。

  4. 修改 initWithCallback 方法,将设备与云端建立连接。

  5. 修改 postMeasurepoint() 方法,配置发送数据测点名称,这里发送逆变器有功功率点,设置点名 INV.GenActivePW,以及对应的点值。

    连接设备并模拟设备发送数据的代码示例如下:

    import com.envisioniot.enos.iot_mqtt_sdk.core.ConnCallback;
    import com.envisioniot.enos.iot_mqtt_sdk.core.MqttClient;
    import com.envisioniot.enos.iot_mqtt_sdk.core.exception.EnvisionException;
    import com.envisioniot.enos.iot_mqtt_sdk.message.upstream.tsl.MeasurepointPostRequest;
    import com.envisioniot.enos.iot_mqtt_sdk.sample.SimpleSendReceive;
    
    import java.util.Random;
    
    public class demo1 {
        public static final String url = "tcp://{environment_address}";
        public static final String productKey = "ProductKey";
        public static final String deviceKey = "{DeviceKey}";
        public static final String deviceSecret = "{DeviceSecret}";
        private static MqttClient client;
        private static Random random = new Random();
        private static final char[] HEX_CHAR = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    
        public demo() {
        }
    
        public static void main(String[] args) throws Exception {
            initWithCallback();
            postMeasurepoint();
        }
    
        public static void initWithCallback() {
            System.out.println("start connect with callback ... ");
    
            try {
                client = new MqttClient(url, productKey, deviceKey, deviceSecret);
                client.getProfile().setConnectionTimeout(60).setAutoReconnect(false);
                client.connect(new ConnCallback() {
                    public void connectComplete(boolean reconnect) {
                        SimpleSendReceive.subDeviceLogin();
                        System.out.println("connect success");
                    }
    
                    public void connectLost(Throwable cause) {
                        System.out.println("onConnectLost");
                    }
    
                    public void connectFailed(Throwable cause) {
                        System.out.println("onConnectFailed : " + cause);
                    }
                });
            } catch (Throwable var1)  {
            }
    
            System.out.println("connect result :" + client.isConnected());
        }
    
        public static void postMeasurepoint() {
            Random random = new Random();
            System.out.println("start post measurepoint ...");
            MeasurepointPostRequest request = (MeasurepointPostRequest)MeasurepointPostRequest.builder().addMeasurePoint("INV.GenActivePW", random.nextDouble()).build();
    
            try {
                client.fastPublish(request);
                System.out.println(" post measurepoint success...");
            } catch (Exception var3) {
                var3.printStackTrace();
            }
        }
    
  6. 使用handleServiceInvocation()方法响应云端的服务命令。

    public static void handleServiceInvocation() {
        IMessageHandler<ServiceInvocationCommand, ServiceInvocationReply> handler = new IMessageHandler<ServiceInvocationCommand, ServiceInvocationReply>() {
            public ServiceInvocationReply onMessage(ServiceInvocationCommand request, List<String> argList) throws Exception {
                System.out.println("rcvn async serevice invocation command" + request + " topic " + argList);
                return (ServiceInvocationReply)ServiceInvocationReply.builder().addOutputData("execResult", 0).build();
            }
        };
        client.setArrivedMsgHandler(ServiceInvocationCommand.class, handler);
    }
    

SDK具体使用参考 SDK设备端连接

步骤 6:查看设备连接状态

EnOS 管理控制台 中选择 设备管理,在设备列表中,查看 INV001 设备的状态,确认设备处于 在线 状态。

../_images/device_status.png

步骤 7:查看设备数据

  1. 在设备列表中,找到 INV001 设备,并点击 操作 列中的 查看 图标,进入 设备详情 页面。

  2. 点击 测点 标签,找到测点 INV.GenActivePW,点击 查看数据,打开 时序洞察 页面。

  3. 查看测点的最新数据。如果已为该测点配置存储策略,亦可在时序洞察页面生成该测点的历史数据图表。有关时序洞察的详细信息,参见 生成时序数据图表

步骤 8:通过在线调试工具调试测点置数

  1. 点击 设备管理 > 产品管理,点击所需调试设备所属的产品操作栏的 查看

  2. 在产品详情页,点击 在线调试

  3. 选择所需调试的设备。

  4. 调试功能 下拉菜单中选择所需调试的模型点及 方法,在该示例中,选择 INV.GenActivePW设置,并点击 发送指令

    ../_images/debug_postmeasurepoint.png

测点置数成功后,在Java开发环境中你会收到以下回应:

AnswerableMessageBody{id='21', method='thing.service.measurepoint.set', version='1.0', params=IVN.GenActivePW=2.0}}