XAgent SDK集成说明

一、准备工作

1.1 获得平台授权信息

云端服务器地址:

  • 测试环境:dev-cm.xlink.cn:1883
  • 公有云:mqtt.xlink.cn:1883
  • 私有云:私有云运维人员提供。

授权证书获取途径:

  • 途径一:【登录管理台】->【开发平台】->【网关授权】-> 【新建网关授权】→【关联要对接的产品】→【完成】
  • 途径二:由对接协调人员提供。

连接器类型获取途径:

  • 途径一:【登录管理台】->【开发平台】->【物联网连接器】->【连接器管理】->【创建连接器】->得到【连接器ID】->完成。 注:连接器ID等同于这里的连接器类型。
  • 途径二:由对接协调人员提供

物模型获取途径:

  • 途径一:【登录管理台】->【进入设备中心】→找到对应【物模型】
  • 途径二:由对接协调人员提供。

二、代码示例片段

2.1 初始化客户端

根据平台授权信息,初始化客户端。

  • 客户端对象在Xagent程序中应为单例模式。
  • 连接器类型用于标识Xagent的类型,如区分是停车系统Xagent、门禁系统Xagent等等
  • 在订阅物模型服务处理时,根据产品ID进行订阅,产品ID用于区分不同物模型的服务

代码示例

public final static String CERT_ID         = "****************";//网关Cid
public final static String CERT_KEY        = "*******************";//网关CKey
public final static String DEVICE_ENDPOINT = "*******";//mqtt地址
public final static String CONNECTOR_TYPE  = "*****"; // 连接器类型,用于标识连接器类别
public final static String PRODUCT_ID     = "******************************";// 产品ID
 
 
private static XlinkCmMqttClient xlinkMqttClient; //定义全局的客户端
 
/**
 * 初始化Xagent 客户端
 */
private static void init() throws Exception {
    //构造器配置
    xlinkMqttClient = XlinkMqttBuilderParams.builder()
            .certId(CERT_ID) //配置授权证书ID
            .certKey(CERT_KEY) //配置授权证书密钥
            .endpoint(DEVICE_ENDPOINT)//云端CM服务器地址
            .connectorType(CONNECTOR_TYPE)//配置连接器类型
            .isOpenLog(true) //开启调试日志
            .addSubscribeServiceName(PRODUCT_ID, "open_door", "close_door")//订阅物模型服务处理
            .build(); //构造XlinkMqttBuilderParams实例
    //建立连接及认证
    xlinkMqttClient.start();
}

2.2 设备上线

一般情况下,对接接入都必须进行设备上线,这里提供通过产品ID、Mac信息进行设备上线。

  • 产品ID获取方式:在物联网管理台->开发平台->产品信息->得到。
  • Mac获取方式::在物联网管理台->开发平台->产品信息-> 设备列表>中获取。设备由【设备注册】进行添加,Mac需在产品下唯一。

方法:xlinkMqttClient.deviceLogin()提供多个重载,可以指定IP,或指定设备在平台的版本信息

代码示例

/**
 * 示例一:在平台进行上线,一般在进行设备初始化时,必须调用
 *
 * @param productId
 * @param mac
 */
private static int deviceLogin(String productId, String mac) throws ExecutionException, InterruptedException {
    //在平台登录上线,并得到返回
    DeviceLoginResultMessage deviceLoginResultMessage = xlinkMqttClient.deviceLogin(productId, mac).get();
    //得到返回结果
    if (deviceLoginResultMessage.getRetCode() == DeviceLoginRetCodeType.SUCCESS) {
        //上线成功,得到平台唯一的设备ID、在物模型下,可以当做thing id使用
        int deviceId = deviceLoginResultMessage.getDeviceId();
        //建议将设备ID在内存保存起来,在后续的操作,会经常使用到。
 
        //自定义代码..
 
        return deviceId;
    } else {
        //上线失败,从RetCode读取错误信息及类型
        DeviceLoginRetCodeType retCode = deviceLoginResultMessage.getRetCode();
 
        //自定义代码..
 
        return 0;
    }
}

2.3 发布物属性

发布属性将属性最新信息上报到物联网平台,平台将保存最新的属性信息。

使用场景:

  1. 当具体环境监测设备传感器监测到气象信息发生变化了,可以通过发布属性信息如:温度、湿度、PM2.5等。
  2. 某设备的最新状态,如设备的开关状态、模式等。

代码示例

/**
 * 示例二:发布物属性,引起平台的最新的物属性变化
 *
 * @param deviceId 设备上线后得到的设备ID
 * @throws Exception
 */
private static void publishAtrribute(int deviceId) throws Exception {
    //物模型的版本号
    int version = 0;
    xlinkMqttClient.publishAttribute(deviceId, version,
            new HashMap() {{
                put("state", "open"); //属性字段
                put("color", "red");//属性字段
            }}, new Date());
 
}

2.4 发布事件

事件是物模型中定义的某一个事件,并且在实际过程中,设备根据事件的定义进行发布到物联网平台,如物模型定义了一个设备故障事件,在设备运行过程中,如果达到”故障“状态,设备发布该”设备故障事件“到云端,并在事件中包含该事件的具体信息(事件字段)。

使用场景:

  1. 门禁开门事件
  2. 道闸通行事件
  3. 视频检测事件
  4. 等等

相关:在2.3 发布物属性后,物联网平台会自动触发“物属性变化事件”。

代码示例

/**
 * 示例三:发布事件
 *
 * @param deviceId 设备上线后得到的设备ID
 */
private static void publishEvent(int deviceId) throws Exception {
    //设备上线后得到的设备ID
    //物模型的版本号
    int version = 0;
    //物模型中的事件名
    String eventName = "xxx";
    xlinkMqttClient.publishEvent(deviceId, version, eventName,
            new HashMap() {{
                put("state", "open"); //事件字段
                put("color", "red");//事件字段
            }}, new Date());
}

2.5 属性设置回调

属性设置回调是云端主动下发的设置属性请求,由终端进行处理后返回告知设置的结果,注:当终端接收了云端的属性设置后,需通过发布物属性将最新属性发布到云端,云端才会更新最新的属性信息。

如使用场景:

  1. 将电灯的“颜色”属性设置为红色或蓝色
  2. 将风扇的运行模式属性设置中档、高档。
  3. 设置门禁的密码信息。
  4. 等等

相关:属性设置是系统内置的特殊服务

代码示例


/**
 * 示例四:监听服务端的属性设置请求,并应答服务端
 */
private static void setAttributeCallback() {
    //监听服务端属性设置回调方法,注意:多个设备ID的属性设置回调方法实现可以为同一个
    xlinkMqttClient.setSetAttributeHandler(request -> {
        //服务端设置下发的属性信息
        Map<String, Object> attribute = request.getAttributes();
        //服务端设置下发的设备ID
        int setDeviceId = request.getDeviceId();
 
        //自定义代码
 
        //构建应答包错误码
        String code = "200";
        //构建应答包
        SetAttributeResponse response = new SetAttributeResponse(code);
        //通过方法返回值进行应答,如方法返回值null,则不会应答。
        return response;
    });
}

2.6 属性获取回调

属性获取回调是云端主动下发的获取属性请求,由终端进行处理后返回属性列表结果,从而使上层应用在读取属性时,会有两种不同数据源:

  • 一种是通过发布物属性,储存在云端的属性信息,
  • 一种是通过本方法回调,直接从终端返回具体是属性信息。

代码示例

/**
 * 示例五:监听服务端的属性获取请求,并应答服务端
 *
 */
private static void getAttributeCallback() {
    //监听服务端属性获取回调方法,注意:多个设备ID的属性获取回调方法实现可以为同一个
    xlinkMqttClient.setGetAttributeHandler(reqeust -> {
        //得到服务端属性获取的设备ID
        int getDeviceId = reqeust.getDeviceId();
 
        //自定义代码
 
        //构建应答的信息属性
        Map<String, Object> attributes = new HashMap() {{
            put("f1", 1);
            put("f2", "str..");
        }};
        //构建应答包错误码
        String code = "200";
        //构建应答包
        GetAttributeResponse response = new GetAttributeResponse(code, attributes);
        //通过方法返回值进行应答,如方法返回值为null,则不会应答
        return response;
    });
}

2.7 服务调用回调

服务是物模型下描述某种行为或能力,设置该服务调用函数,当平台进行服务调用时,会回调该方法,由终端处理后返回。

使用场景:

  1. 门禁物模型可定义开门、关门、设置密码等服务,服务由上层应用调用,下发到客户端进行回调处理后返回。

注:订阅某个服务的回调下发需要在初始化客户端时配置好,服务必须是在物模型定义的服务列表内,并且有严格的输入、输出参数和返回错误码。

代码示例

/**
 * 示例六:监听服务端的服务调用下发,并应答服务端
 */
private static void serviceInvokeCallback() {
    //物模型中的服务名
    //监听服务端服务调用的回调方法,注意:多个设备ID、多个不同服务的服务调用回调方法实现可以为同一个。
    xlinkMqttClient.setServiceInvokeHandler(request -> {
        //得到服务调用的设备ID
        int invokeDeviceId = request.getDeviceId();
        //得到服务调用的服务名
        String invokeServiceName = request.getServiceName();
        //得到服务调用的输入参数
        Map<String, Object> input = request.getInput();
 
        //自定义代码
        switch (invokeServiceName) {
            case "open_door": {
                //...
                break;
            }
            case "close_door": {
                //...
                break;
            }
        }
 
        //构建应答包错误码
        String code = "200";
        //构建应答包输出参数
        Map<String, Object> output = new HashMap() {{
            put("f1", 4);
            put("f2", "str");
        }};
        //构建应答包
        ServiceInvokeResponse serviceInvokeResponse = new ServiceInvokeResponse(code, output);
        //通过方法返回值进行应答,如方法返回值为null,则不会应答
        return serviceInvokeResponse;
    });
}

2.8 上报自定义调试日志

上报自定义调试日志,可在物联网管理台中可以看到具体的日志打印,便于实时查看设备的运行日志。

注:本身设备的基本行为如:上线、上报数据、接收数据都默认在调试日志里会展现。

代码示例

/**
 * 示例七:自定义上报调试日志
 */
xlinkMqttClient.deviceLog(deviceId, "日志内容。。。。");

三、完整代码示例

Maven POM 文件(需在物联云平台内部私有Maven服务下,如不在该访问范围,可联系对接协调人员单独提供。)

pom.xml

<dependency>
    <groupId>cn.xlink</groupId>
    <artifactId>xlink-iot-sdk</artifactId>
    <version>3.5.4-pg</version>
    <scope>compile</scope>
</dependency>

依赖库文件:

xlink-iot-sdk-3.5.4-pg.jar

代码示例

代码示例

import cn.xlink.iot.sdk.XlinkMqttBuilderParams;
import cn.xlink.iot.sdk.mqtt.client.cm.XlinkCmMqttClient;
import cn.xlink.iot.sdk.mqtt.client.subscribe.message.GetAttributeResponse;
import cn.xlink.iot.sdk.mqtt.client.subscribe.message.ServiceInvokeResponse;
import cn.xlink.iot.sdk.mqtt.client.subscribe.message.SetAttributeResponse;
import xlink.cm.message.DeviceLoginResultMessage;
import xlink.cm.message.type.DeviceLoginRetCodeType;
 
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
 
 
 
 
/**
 * Xagent SDK 3.5 Demo
 *
 * @Author shenweiran
 * @Date 2019-08-24 17:51
 */
public class Demo_v3_5 {
 
    public final static String CERT_ID         = "****************";//网关Cid
    public final static String CERT_KEY        = "*******************";//网关CKey
    public final static String DEVICE_ENDPOINT = "*******";//mqtt地址
    public final static String CONNECTOR_TYPE  = "*****"; // 连接器类型,用于标识连接器类别
    public final static String CONNECTOR_TYPE = "*****************"; // 连接器类型,用于标识连接器类别
    public final static String PRODUCT_ID     = "******************************";// 产品ID
 
    //Xagent客户端
    private static XlinkCmMqttClient xlinkMqttClient;
 
    /**
     * 程序启动入口方法
     *
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
 
        //定义Mac地址,或者一个能唯一的标识设备的字符,该Mac信息应该在预先导入对应的产品信息下,否则会发生错误
        String mac = "AB*******CC";
 
        //初始化客户端
        init();
 
        //示例一:在平台进行上线,一般在进行设备初始化、上线时是必须调用,会返回设备唯一标识ID
        int deviceId = deviceLogin(PRODUCT_ID, mac);
 
        //示例二:发布物属性,引起平台的最新的物属性变化
        publishAttribute(deviceId);
 
        //示例三:发布事件
        publishEvent(deviceId);
 
        //示例四:监听服务端的属性设置请求,并应答服务端
        setAttributeCallback();
 
        //示例五:监听服务端的属性获取请求,并应答服务端
        getAttributeCallback();
 
        //示例六:监听服务端的服务调用下发,并应答服务端
        serviceInvokeCallback();
         
        //示例七:设备离线
        xlinkMqttClient.deviceOffline(deviceId);
         
        //示例八:SDK与云端断开并重连时,回调方法设置
        xlinkMqttClient.setReconnectHandler(() -> {
            //这里一般可以会处理设备的重新上线操作。   
        });
 
    }
 
    /**
     * 初始化Xagent 客户端
     */
    private static void init() throws Exception {
        //构造器配置
        xlinkMqttClient = XlinkMqttBuilderParams.builder()
                .certId(CERT_ID) //配置授权证书ID
                .certKey(CERT_KEY) //配置授权证书密钥
                .endpoint(DEVICE_ENDPOINT)//云端CM服务器地址
                .connectorType(CONNECTOR_TYPE)//配置连接器类型
                .addSubscribeServiceName(PRODUCT_ID, "open_door", "close_door")//订阅物模型服务处理
                .build(); //构造XlinkMqttBuilderParams实例
        //建立连接及认证
        xlinkMqttClient.start();
    }
 
 
    /**
     * 示例一:在平台进行上线,一般在进行设备初始化时,必须调用
     *
     * @param productId
     * @param mac
     */
    private static int deviceLogin(String productId, String mac) throws ExecutionException, InterruptedException {
        //在平台登录上线,并得到返回
        DeviceLoginResultMessage deviceLoginResultMessage = xlinkMqttClient.deviceLogin(productId, mac).get();
        //得到返回结果
        if (deviceLoginResultMessage.getRetCode() == DeviceLoginRetCodeType.SUCCESS) {
            //上线成功,得到平台唯一的设备ID、在物模型下,可以当做thing id使用
            int deviceId = deviceLoginResultMessage.getDeviceId();
            //建议将设备ID在内存保存起来,在后续的操作,会经常使用到。
 
            //自定义代码..
 
            return deviceId;
        } else {
            //上线失败,从RetCode读取错误信息及类型
            DeviceLoginRetCodeType retCode = deviceLoginResultMessage.getRetCode();
 
            //自定义代码..
 
            return 0;
        }
    }
 
    /**
     * 示例二:发布物属性,引起平台的最新的物属性变化
     *
     * @param deviceId 设备上线后得到的设备ID
     * @throws Exception
     */
    private static void publishAttribute(int deviceId) throws Exception {
        //物模型的版本号
        int version = 0;
        xlinkMqttClient.publishAttribute(deviceId, version,
                new HashMap() {{
                    put("state", "open"); //属性字段
                    put("color", "red");//属性字段
                }}, new Date());
 
    }
 
    /**
     * 示例三:发布事件
     *
     * @param deviceId 设备上线后得到的设备ID
     */
    private static void publishEvent(int deviceId) throws Exception {
        //设备上线后得到的设备ID
        //物模型的版本号
        int version = 0;
        //物模型中的事件名
        String eventName = "xxx";
        xlinkMqttClient.publishEvent(deviceId, version, eventName,
                new HashMap() {{
                    put("state", "open"); //事件字段
                    put("color", "red");//事件字段
                }}, new Date());
    }
 
    /**
     * 示例四:监听服务端的属性设置请求,并应答服务端
     */
    private static void setAttributeCallback() {
        //监听服务端属性设置回调方法,注意:多个设备ID的属性设置回调方法实现可以为同一个
        xlinkMqttClient.setSetAttributeHandler(request -> {
            //服务端设置下发的属性信息
            Map<String, Object> attribute = request.getAttributes();
            //服务端设置下发的设备ID
            int setDeviceId = request.getDeviceId();
 
            //自定义代码
 
            //构建应答包错误码
            String code = "200";
            //构建应答包
            SetAttributeResponse response = new SetAttributeResponse(code);
            //通过方法返回值进行应答,如方法返回值null,则不会应答。
            return response;
        });
    }
 
    /**
     * 示例五:监听服务端的属性获取请求,并应答服务端
     *
     */
    private static void getAttributeCallback() {
        //监听服务端属性获取回调方法,注意:多个设备ID的属性获取回调方法实现可以为同一个
        xlinkMqttClient.setGetAttributeHandler(reqeust -> {
            //得到服务端属性获取的设备ID
            int getDeviceId = reqeust.getDeviceId();
 
            //自定义代码
 
            //构建应答的信息属性
            Map<String, Object> attributes = new HashMap() {{
                put("f1", 1);
                put("f2", "str..");
            }};
            //构建应答包错误码
            String code = "200";
            //构建应答包
            GetAttributeResponse response = new GetAttributeResponse(code, attributes);
            //通过方法返回值进行应答,如方法返回值为null,则不会应答
            return response;
        });
    }
 
    /**
     * 示例六:监听服务端的服务调用下发,并应答服务端
     */
    private static void serviceInvokeCallback() {
        //物模型中的服务名
        //监听服务端服务调用的回调方法,注意:多个设备ID、多个不同服务的服务调用回调方法实现可以为同一个。
        xlinkMqttClient.setServiceInvokeHandler(request -> {
            //得到服务调用的设备ID
            int invokeDeviceId = request.getDeviceId();
            //得到服务调用的服务名
            String invokeServiceName = request.getServiceName();
            //得到服务调用的输入参数
            Map<String, Object> input = request.getInput();
 
            //自定义代码
            switch (invokeServiceName) {
                case "open_door": {
                    //...
                    break;
                }
                case "close_door": {
                    //...
                    break;
                }
            }
 
            //构建应答包错误码
            String code = "200";
            //构建应答包输出参数
            Map<String, Object> output = new HashMap() {{
                put("f1", 4);
                put("f2", "str");
            }};
            //构建应答包
            ServiceInvokeResponse serviceInvokeResponse = new ServiceInvokeResponse(code, output);
            //通过方法返回值进行应答,如方法返回值为null,则不会应答
            return serviceInvokeResponse;
        });
    }
 
}

四、注意事项

4.1 SDK异常处理

在使用sdk的各种api过程中,有可能会抛出各种XlinkIotException,需要使用者进行捕捉和处理。

  • 上报缺少参数异常:XlinkIotPublishLackException类,可以通过getFieldName()方法获取具体缺少参数的是哪一个字段。
  • 客户端认证失败异常:XlinkNotAuthException类,表示客户端的连接是不合法的。
  • 服务端不可用异常:XlinkIotServiceException类,表示服务端不存在,或者服务端没有回应。

4.2 断线重连

在Xagent重启时,会与云端断开,此时原先在Xagent上线的失败会因重启导致离线,在每次Xagent重启时,需要重新将设备进行上线。

4.3 Xagent多机部署问题

在云端服务器当前的机制下,多个Xagent同时上线同一个设备时会导致互踢,因此,在Xagent进行多机部署时,需让每个Xagent负责上线的设备相互隔离,或者采集简单的主备模式部署。

五、SDK & Demo下载

资源名称 下载地址
XAgent SDK 点此下载
XAgent DEMO 点此下载

六、更新日志

日期 版本号 编写人 更新内容
2019/08/22 1.0 沈伟然 文档创建
2019/08/27 1.1 沈伟然 完成初稿
2019/08/29 1.2 沈伟然 初始化参数重复Connector Type
2019/09/05 1.3 沈伟然 更新SDK 3.5.1,更新内容:支持调试日志显示,见【初始化客户端配置】,默认不开启支持自定义上报调试日志
2019/09/18 1.4 沈伟然 更新SDK 3.5.2,内容:支持设备离线
2019/10/23 1.5 沈伟然 更新SDK3.5.3,内容:当Xagent SDK与云端断开并成功重连时,提供回调方法供告知SDK使用者
2019/10/24 1.6 沈伟然 更新SDK3.5.4,内容:支持新的设备登录返回错误码(新增的自动注册设备特性)
2019/11/11 1.7 沈伟然 补充jar文件
没找到需要的文档?
你可以提交工单反馈 或 阅读常见问题