华为云用户手册

  • 添加非直连设备 在添加非直连设备前,确认非直连设备的profile已经上传了,详见上传Profile并注册设备步骤。 在设备或网关登录成功后就可以调用HubService.addDevice(int cookie, IotaDeviceInfo deviceInfo)接口添加非直连设备。 这里非直连设备的设备固有信息是测试数据。真实情况下,网关往往需要跟具体的非直连设备交互,才能得到具体的设备固有信息。 1 2 3 4 5 6 7 8 91011121314 private void addSensor() { SharedPreferences preferences = getSharedPreferences("AgentLiteDemo", MODE_PRIVATE); if (preferences.getString("SENSORID", null) != null) { Toast.makeText(this, "The sensor is already added.", Toast.LENGTH_SHORT).show(); return; } LogUtil.i(this, TAG, "addSensor!"); int cookie; Random random = new Random(); cookie = random.nextInt(65535); IotaDeviceInfo deviceInfo = new IotaDeviceInfo("0123456test", "Huawei", "Motion", "test01", "MQTT"); HubService.addDevice(cookie, deviceInfo);} 注册广播接收器对添加设备结果进行相应处理。添加非直连设备成功后就能从广播中得到非直连设备的“deviceId”。 1 LocalBroadcastManager.getInstance(this).registerReceiver(addDeviceReceiver, new IntentFilter(HubService.TOPIC_ADDDEV_RSP)); 非直连设备添加成功后可以在“设备列表”中看到新增一条记录。
  • 编译安装程序 绑定和登录功能完成后,可以先测试一下网关是否能正常与平台对接,再进行后续功能开发。 将Android设备连到计算机上,点击“”按钮编译安装工程到Android设备上。 在Android设备上运行AgentLiteDemo,修改“平台IP”、“MQTT端口”、“HTTP端口”和“verifyCode”等值。 “平台IP”、“MQTT端口”和“HTTP端口”可以从物联网平台环境开发中心的“对接信息”界面获取。 “verifyCode”则是设备的标识,每个设备对应一个verifyCode,不可重复,所以建议使用IMEI或者MAC地址等天然的设备标识。AgentLiteDemo可以在界面上人工输入设备的verifyCode,测试时只要输入一个没有使用过的verifyCode即可。
  • 非直连设备状态更新 非直连设备添加上时,一般情况下是“离线”状态。所以在非直连设备添加成功后,或者在非直连设备上报数据前,要调用HubService.updateDeviceStatus(int cookie, String deviceId, String status, String statusDetail)进行设备状态更新。 1 2 3 4 5 6 7 8 910111213 private void updateDeviceStatus(String status, String statusDetail) { LogUtil.i(this, TAG, "updateDeviceStatus!"); int cookie; Random random = new Random(); cookie = random.nextInt(65535); SharedPreferences preferences = getSharedPreferences("AgentLiteDemo", MODE_PRIVATE); String deviceId = preferences.getString("SENSORID", null); if (deviceId != null) { HubService.updateDeviceStatus(cookie, deviceId, status, statusDetail); }} AgentLiteDemo中只添加了一个非直连设备,所以updateDeviceStatus()方法中使用的“deviceId”是直接从SharedPreferences中读取的。 注册广播接收器对非直连设备状态更新结果进行相应处理。 1 LocalBroadcastManager.getInstance(this).registerReceiver(devStatusUpdateReceiver, new IntentFilter(HubService.TOPIC_DEVSTATUS_RSP));
  • 初始化 在发起业务前,需要先初始化Agent Lite相关资源,调用API接口BaseService.init(),初始化Agent Lite资源,具体API的参数使用参考Agent Lite API接口文档。可参考“AgentLiteMain.java”中onCreate()方法对BaseService.init()的调用。 1 BaseService.init(WORK_PATH, LOG_PATH, context); “WORK_PATH”为工作路径,不能为空。 “LOG_PATH”为打印日志路径,当“LOG_PATH”为空时,打印路径默认为工作路径,开发者也可以自己定义打印日志路径。
  • 绑定和登录 设备或网关第一次接入IoT联接管理平台时需要进行绑定操作,从而将设备或网关与平台进行关联。开发者通过传入设备序列号以及设备信息,将设备或网关绑定到物联网平台。 设备或网关绑定成功后或重启后,需要进行登录的流程,在设备或网关成功登录物联网平台后,才可以进行其它服务操作,比如接入其他传感器,数据上报等等。如果设备或网关登录成功,那么设备或网关在平台的状态显示为已在线。 修改绑定参数。 绑定时使用的设备固有信息(如设备型号等)是从“config.properties”文件中读取的,所以需要修改./app/src/main/assets/conf目录下config.properties文件中的如下信息: “platformIP”:物联网平台的设备对接地址(MQTTS),可参考平台对接信息获取。 “verifyCode”(设备的标识)和必要的设备信息,包括“Manufacture”(厂商Id)、“deviceType”(设备类型)、“HardwareModel”(设备模型)和“protocolType”(协议类型),其中“manufacturerId”(厂商Id)、“deviceType”(设备类型)、“HardwareModel”(设备模型)和“protocolType”(协议类型)与Profile文件中的定义保持一致。 如果通过“设备管理服务控制台”注册设备,则“verifyCode”填写为设备注册时的“preSecret”(预置密钥)。 如果通过开发中心注册设备,则“verifyCode”填写为设备注册后返回的“nodeId”(设备标识)。 “config.properties”文件中设备固有示例: platformIP=100.100.100.100mqttPort=8883httpPort=8943verifyCode=0123456789Manufacturer=HuaweiHardwareModel=AgentLite01deviceType=GatewayprotocolType=HuaweiM2M 绑定设备。 调用API接口BindConfig.setConfig()设置绑定配置。 123456 private void startBind() { .... configBindPara(); registerBindReceiver(); ...} 1234 private void configBindPara() { BindConfig.setConfig(BindConfig.BIND_CONFIG_ADDR, AgentLiteUtil.get(ConfigName.platformIP)); BindConfig.setConfig(BindConfig.BIND_CONFIG_PORT, AgentLiteUtil.get(ConfigName.httpPort));} 注册广播接收器对设备绑定结果进行相应处理。 1 LocalBroadcastManager.getInstance(this).registerReceiver(mBindStatusReceiver, new IntentFilter(BindService.TOPIC_BINDDEVICE_RSP)); 调用API接口BindService .bind(String verifyCode, IotaDeviceInfo deviceInfo)绑定设备,主要入参为“verifyCode”(设备验证码)和必要的设备信息,包括“nodeId”(设备标识码)、“Manufacture”(厂商Id)、“deviceType”(设备类型)、“HardwareModel”(设备模型)和“protocolType”(协议类型),其中“verifyCode”的值与“nodeId”保持一致。 1 2 3 4 5 6 7 8 9101112131415 private void startBind() { LogUtil.i(this, TAG, "startBind"); String nodeId = AgentLiteUtil.get(ConfigName.verifyCode); String verifyCode = AgentLiteUtil.get(ConfigName.verifyCode); String manufacturerId = AgentLiteUtil.get(ConfigName.Manufacturer); String deviceType = AgentLiteUtil.get(ConfigName.deviceType); String model = AgentLiteUtil.get(ConfigName.HardwareModel); String protocolType = AgentLiteUtil.get(ConfigName.protocolType); IotaDeviceInfo deviceInfo = new IotaDeviceInfo(nodeId, manufacturerId, deviceType, model, protocolType); ... BindService.bind(verifyCode, deviceInfo);} 设备或网关绑定成功,后续就不需要再绑定了,除非设备或网关被删除,才需要重新绑定。 设备绑定成功会收到广播,广播内容请参考Agent Lite API接口文档中设备绑定接口的返回结果说明和demo中mBindStatusReceiver函数的处理。 配置登录参数。 登录前需要通过参数配置接口LoginConfig.setConfig()传入所需的登录信息。 “设备Id”(即网关Id, “LOGIN_CONFIG_DEVICEID”),“appId”(“LOGIN_CONFIG_APPID”)和“密码”(“LOGIN_CONFIG_SECRET”),这些信息是都是从网关绑定成功的广播中得到的。 “平台HTTP地址”(“LOGIN_CONFIG_IOCM_ADDR”)和“MQTT地址”(“LOGIN_CONFIG_MQTT_ADDR”)一般是同一个地址,可以从绑定成功的广播中得到。一般情况下,这个地址和Agent Lite设备或网关对接的平台地址一致。 绑定成功的广播参数获取可以参考mBindStatusReceiver函数的处理。 123456789 private void configLoginPara() { LoginConfig.setConfig(LoginConfig.LOGIN_CONFIG_DEVICEID, GatewayInfo.getDeviceID()); LoginConfig.setConfig(LoginConfig.LOGIN_CONFIG_APPID, GatewayInfo.getAppID()); LoginConfig.setConfig(LoginConfig.LOGIN_CONFIG_SECRET, GatewayInfo.getSecret()); LoginConfig.setConfig(LoginConfig.LOGIN_CONFIG_IOCM_ADDR, GatewayInfo.getHaAddress()); LoginConfig.setConfig(LoginConfig.LOGIN_CONFIG_IOCM_PORT, "8943"); LoginConfig.setConfig(LoginConfig.LOGIN_CONFIG_MQTT_ADDR, GatewayInfo.getHaAddress()); LoginConfig.setConfig(LoginConfig.LOGIN_CONFIG_MQTT_PORT, "8883");} 设备登录。 注册广播接收器对设备登录结果进行相应处理。 1 LocalBroadcastManager.getInstance(this).registerReceiver(LoginConnectReceiver, new IntentFilter(LoginService.TOPIC_LOGIN_CONNECTED)); 调用LoginService.login()进行直连设备登录,具体API的参数使用参考Agent Lite接口文档中设备登录接口的说明。 12345 private void startLogin() { LogUtil.i(this, TAG, "startLogin"); configLoginPara(); LoginService.login();}
  • 使用必读 开发环境要求: Android系统:API_LEVEL21及以上。 工程目录结构及文件说明: 目录结构 目录 说明 Agent LiteDemo │ ├─src │ └─com │ └─huawei │ └─agentlitedemo ├─gen ├─assets │ └─conf ├─bin ├─libs │ └─armeabi └─res src 存放Agent Lite Demo代码 libs 存放Agent Lite提供的jar包和第三方jar包 armeabi 存放Agent Lite编译后的库文件和第三方库文件 conf 存放TLS证书文件、配置文件 如果开发者没有设备,可以直接在X86 Linux系统进行开发。
  • 数据上报和数据发布 设备或网关向物联网平台上报数据可以通过调用SDK的“设备服务数据上报”接口或“数据发布”接口: “设备服务数据上报”接口:pcDeviceId、pcRequstId和pcServiceId由SDK组装为消息的header;pcServiceProperties由SDK组装为消息的body。消息组装格式为JSON。 设备或网关登录成功后可以调用IOTA_ServiceDataReport接口上报数据。 当设备主动上报数据时,“pcRequstId”可以为空。 当上报的数据为某个命令的响应时,“pcRequstId”必须与下发命令中的requstId保持一致。“pcRequestId”可以从广播中获取,请参考API文档中“设备命令接收”接口的“EN_IOTA_DATATRANS_IE_REQUESTID”参数。 “pcServiceID”要与Profile中定义的某个“serviceId”保持一致,否则无法上报数据。 “pcServiceData”实际上是一个JSON字符串,内容是健值对(可以有多组健值对)。每个健是Profile中定义的属性名(propertyName),值就是具体要上报的数据。 1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930 HW_VOID Gateway_DataReport(HW_CHAR **pcJsonStr){ HW_JSON json; HW_JSONOBJ hJsonObj; hJsonObj = HW_JsonObjCreate(); json = HW_JsonGetJson(hJsonObj); HW_JsonAddUint(json, (HW_CHAR*)"storage", (HW_INT)10240); HW_JsonAddUint(json, (HW_CHAR*)"usedPercent", (HW_INT)20); *pcJsonStr = HW_JsonEncodeStr(hJsonObj); Device_ServiceDataReport(g_stGateWayInfo.pcDeviceID, "Storage", pcJsonStr); //another method //Device_ServiceDataReport(pcDeviceId, "Storage", "{\"storage\":20240,\"usedPercent\":20}");}HW_INT Device_ServiceDataReport(const HW_CHAR *pcSensorDeviceID, const HW_CHAR *pcServiceId, const HW_CHAR *pcServiceProperties){ HW_CHAR aszRequestId[BUFF_MAX_LEN]; HW_GetRequestId(aszRequestId); if (HW_TRUE != g_uiLoginFlg) { //TODO e.g. resend service data HW_LOG_INF("Device_MApiMsgRcvHandler():GW discon,pcJsonStr=%s", pcServiceProperties); return HW_ERR; } IOTA_ServiceDataReport(HW_GeneralCookie(), aszRequestId, pcSensorDeviceID, pcServiceId, pcServiceProperties); return HW_OK;} 注册广播接收器对网关数据上报结果进行相应处理。广播过滤参数为“IOTA_TOPIC_DATATRANS_REPORT_RSP/{deviceId}”。 12 sprintf(acBuf, "%s/%s", IOTA_TOPIC_DATATRANS_REPORT_RSP, g_stGateWayInfo.pcDeviceID);HW_BroadCastReg(acBuf, Device_ServiceDataReportResultHandler); “数据发布”接口:topic固定为“/cloud/signaltrans/v2/categories/data”;“pbstrServiceData”参数作为消息体(包括header和body),SDK只进行透传,不进行格式调整和组装。 设备或网关登录成功后可以调用IOTA_MqttDataPub接口发布数据。 “pucTopic”为发布数据的topic。 “uiQos”为mqtt协议中的一个参数。 “pbstrServiceData”实际上是一个json字符串,内容是健值对(可以有多组健值对)。每个健是profile中定义的属性名(propertyName),值就是具体要上报的。 12345 HW_INT Device_ServiceDataPub(const HW_UCHAR *pucTopic, HW_UINT uiQos, const HW_BYTES *pbstrServiceData){ IOTA_MqttDataPub(HW_GeneralCookie(),pucTopic,uiQos,pbstrServiceData); return HW_OK;} 注册广播接收器对网关数据上报结果进行相应处理。广播过滤参数为“IOTA_TOPIC_DATATRANS_PUB_RSP”。 1 HW_BroadCastReg(IOTA_TOPIC_DATATRANS_PUB_RSP, Device_ServiceDataPubResultHandler);
  • 添加非直连设备 在添加非直连设备前,确认非直连设备的profile已经上传,详见上传Profile并注册设备步骤。 在设备或网关登录成功后,可以调用IOTA_HubDeviceAdd接口添加非直连设备。 此处非直连设备的设备固有信息是测试数据。真实情况下,网关需要与具体的非直连设备交互,才能得到非直连设备的固有信息。 1 2 3 4 5 6 7 8 9101112131415161718192021 HW_VOID AddSensors(){ ST_IOTA_DEVICE_INFO stDeviceInfo = {0}; FILE *fp = NULL; HW_CHAR szdeviceInfoFileName[BUFF_MAX_LEN] = {0}; HW_INT file_size; HW_CHAR *pcJsonStr; HW_JSONOBJ jsonObj; HW_JSON json; //get device info stDeviceInfo.pcNodeId = "SN Number_8532157"; stDeviceInfo.pcManufacturerName = "Huawei"; stDeviceInfo.pcManufacturerId = "Huawei"; stDeviceInfo.pcDeviceType = "Motion"; stDeviceInfo.pcModel = "test01"; stDeviceInfo.pcProtocolType = "Z-Wave"; IOTA_HubDeviceAdd(g_uiCookie, &stDeviceInfo); return;} 注册广播接收器对添加设备结果进行相应处理。添加非直连设备成功后就能从广播中得到非直连设备的deviceId。 1 HW_BroadCastReg(IOTA_TOPIC_HUB_ADDDEV_RSP, Device_AddResultHandler); Demo在设备添加成功一段时间后会再调用删除设备接口进行设备删除。如果再次运行sdk.out前,还没执行删除设备接口,再次添加相同设备会失败。可以修改“NodeId”的值或者调用设备删除接口把原来的设备删除掉再进行测试。 非直连设备添加成功后可以在“设备列表”中看到新增一条记录。
  • 非直连设备状态更新 非直连设备添加上时,一般情况下是“离线”状态。所以在非直连设备添加成功后,或者在非直连设备上报数据前,要调用IOTA_DeviceStatusUpdate()进行设备状态更新。 1 IOTA_DeviceStatusUpdate(g_uiCookie, g_cDeviceId, "ONLINE", "NONE"); AgentLiteDemo中只添加了一个非直连设备,所以IOTA_DeviceStatusUpdate中的g_cDeviceId直接使用全局变量。 注册广播接收器对非直连设备状态更新结果进行相应处理。 1 HW_BroadCastReg(IOTA_TOPIC_DEVUPDATE_RSP, Device_DevUpDateHandler);
  • 使用必读 开发环境要求: 操作系统 工具链 当前支持的系统: ARM Linux (Embedded Linux) MIPS Linux (Embedded Linux) x86 Linux x86_64 Linux x86 Windows x86_64 Windows 需要支持以下工具链之一: gcc-linaro-arm-linux-gnueabihf-raspbian arm-none-linux-gnueabi arm-linux-uclibceabi Demo工程目录结构及文件说明: 目录结构 目录 说明 Demo │ ├─demo.c ├─demo.h ├─*.h ├─libcrypto.so/libssl.so ├─libuspsdk.so └─conf demo.c demo源文件 demo.h demo头文件 *.h Agent Lite头文件 libcrypto.so/libssl.so openssl库文件 libuspsdk.so Agent Lite编译后的库文件 conf 存放TLS证书文件 如果开发者没有设备,可以直接在X86 Linux系统进行开发。 交叉编译环境检测: 准备网关或设备。本文档将以树莓派为例,说明如何集成网关。 将Agent Lite SDK (Linux)解压到本地。 用sftp工具把mytest测试工具上传到树莓派上。 因为使用的设备是树莓派,所以使用RaspberryPi目录下的mytest测试工具。开发者可以选择根据实际情况选择不同目录下的mytest测试工具进行测试,尽量选择与自己的系统信息相近的目录下的测试工具进行测试。 修改所有文件的权限,进入mytest所在目录,运行“mytest”。 123 cd /opt/agentLitechmod -R 777 *./mytest 如果最后出现“AUTO TEST END SUCC”字样,说明通过检测。
  • 绑定和登录 设备或网关第一次接入物联网平台时需要进行绑定操作,从而将设备或网关与平台进行关联。开发者通过传入设备序列号以及设备信息,将设备或网关绑定到物联网平台。 设备或网关绑定成功后或重启后,需要进行登录的流程,在设备或网关成功登录物联网平台后,才可以进行其它服务操作,比如接入其他传感器,数据上报等等。如果设备或网关登录成功,那么设备或网关在平台的状态显示为已在线。 修改绑定参数。 绑定时使用的设备固有信息(如设备型号等)是从“gwreginfo.json”文件中读取的,所以需要修改demo目录下“gwreginfo.json”文件中的如下信息: “platformaddr”:物联网平台的设备对接地址(MQTTS),可参考平台对接信息获取。 “mac”:MAC地址,每个设备对应一个MAC地址,不可重复,所以建议使用IMEI或者MAC地址等天然的设备标识。测试时只要输入一个没有使用过的MAC地址即可。 如果开发者通过“设备管理服务控制台”注册设备,则“mac”填写为设备注册时的“preSecret”(预置密钥)。 如果通过开发中心注册设备,则“verifyCode”填写为设备注册时设置的“nodeId”(设备标识)。 “manufacturerId”(厂商Id)、“deviceType”(设备类型)、“model”(设备模型)和“protocolType”(协议类型)与Profile文件中的定义保持一致。 “gwreginfo.json”文件中设备固有示例: { "mac":"1234567", "platformAddr":"127.0.0.1", "platformPort":8943, "manufacturerId":"Huawei", "deviceType":"Gateway", "model":"AgentLite01", "protocolType":"HuaweiM2M", "loglevel":255} 绑定设备。 绑定前先调用API接口IOTA_ConfigSetXXX()设置物联网平台的IP与端口。 12 IOTA_ConfigSetStr(EN_IOTA_CFG_IOCM_ADDR, const pucPlatformAddr);IOTA_ConfigSetUint(EN_IOTA_CFG_IOCM_PORT, uiPort); 注册广播接收器对设备绑定结果进行相应处理。 1 HW_BroadCastReg(IOTA_TOPIC_BIND_RSP, Device_RegResultHandler); 调用API接口IOTA_Bind()进行设备绑定,主要入参为MAC地址和必要的设备信息,包括“nodeId”(设备标识码)、“manufacturerId”(厂商Id)、“deviceType”(设备类型)、“model”(设备模型)和“protocolType”(协议类型),其中MAC地址与“nodeId”的值保持一致。 1 2 3 4 5 6 7 8 91011121314 HW_UINT DEVICE_BindGateWay(){ …… stDeviceInfo.pcMac = HW_JsonGetStr(json, IOTA_DEVICE_MAC); stDeviceInfo.pcNodeId = stDeviceInfo.pcMac; stDeviceInfo.pcManufacturerId = HW_JsonGetStr(json, IOTA_MANUFACTURE_ID); stDeviceInfo.pcDeviceType = HW_JsonGetStr(json, IOTA_DEVICE_TYPE); stDeviceInfo.pcModel = HW_JsonGetStr(json, IOTA_MODEL); stDeviceInfo.pcProtocolType = HW_JsonGetStr(json, IOTA_PROTOCOL_TYPE); …… IOTA_ConfigSetStr(EN_IOTA_CFG_IOCM_ADDR, pucPlatformAddr); IOTA_ConfigSetUint(EN_IOTA_CFG_IOCM_PORT, uiPort); IOTA_Bind(stDeviceInfo.pcMac, &stDeviceInfo);} 设备或网关绑定成功,后续就不需要再绑定了,除非设备或网关被删除,才需要重新绑定。 设备绑定成功会收到广播,广播内容请参考Agent Lite API接口文档中设备绑定接口的返回结果说明和demo中Device_RegResultHandler函数的处理。Device_RegResultHandler把从广播中得到的网关设备信息保存在“gwbindinfo.json”文件中。 配置登录参数。 登录前需要通过参数配置API接口IOTA_ConfigSetXXX()传入所需的登录信息。 “设备Id”(“EN_IOTA_CFG_DEVICEID”),“appId”(“EN_IOTA_CFG_APPID”)和“密码”(“EN_IOTA_CFG_DEVICESECRET”)从绑定成功的广播中得到的。 “HTTP地址”(“EN_IOTA_CFG_IOCM_ADDR”)和“MQTT地址”(“EN_IOTA_CFG_MQTT_ADDR”)一般为同一个地址,可以从绑定成功的广播中得到。一般情况下,这个地址和Agent Lite设备或网关对接的平台地址一致。 绑定成功的广播参数获取可以参考Device_RegResultHandler函数的处理。 1234567 IOTA_ConfigSetStr(EN_IOTA_CFG_DEVICEID, g_stGateWayInfo.pcDeviceID); IOTA_ConfigSetStr(EN_IOTA_CFG_IOCM_ADDR, g_stGateWayInfo.pcIOCMAddr);IOTA_ConfigSetStr(EN_IOTA_CFG_APPID, g_stGateWayInfo.pcAppID);IOTA_ConfigSetStr(EN_IOTA_CFG_DEVICESECRET, g_stGateWayInfo.pcSecret); IOTA_ConfigSetStr(EN_IOTA_CFG_MQTT_ADDR, g_stGateWayInfo.pcIOCMAddr);IOTA_ConfigSetUint(EN_IOTA_CFG_MQTT_PORT, g_stGateWayInfo.pcMqttPort);IOTA_ConfigSetUint(EN_IOTA_CFG_IOCM_PORT, g_stGateWayInfo.pcIOCMPort); 注册广播接收器对设备登录结果进行相应处理。 1 HW_BroadCastReg(IOTA_TOPIC_CONNECTED_NTY, Device_ConnectedHandler); 设备登录。 调用API接口LoginService.login()进行直连设备登录,具体API的参数使用参考Agent Lite API接口文档中设备登录接口的说明。 1 IOTA_Login();
  • 初始化 在发起业务前,需要先初始化Agent Lite相关资源,调用API接口IOTA_Init(),初始化Agent Lite资源。具体API接口的参数使用请参考Agent Lite API接口文档。可参考demo.c中main()方法对IOTA_Init()的调用。 1 IOTA_Init(const CONFIG_PATH,const HW_NULL); “CONFIG_PATH”为工作路径,不能为空,该参数必须带结束符‘\0’。 第二个参数为打印日志路径,当它为空时,打印路径默认为工作路径。开发者也可以自己定义打印日志路径,该参数必须带结束符‘\0’。
  • 编译并运行程序 绑定和登录功能完成后,可以先测试一下设备或网关是否能正常与平台对接,再进行后续功能开发。 用sftp工具把demo目录上传到树莓派上。 进行交叉编译。 进入“/opt/agentLite/demo/”路径。 “/opt/agentLite/demo/”路径需要根据实际情况修改。 输入“chmod -R 777 *”命令修改权限。 输入“export LD_LIBRARY_PATH=./”设置程序共享库位置。 输入“gcc demo.c -L /opt/agentLite/demo/ -lpthread -ldl -lrt -luspsdk -lssl -lcrypto -o sdk.out”命令,如果交叉编译成功,会产生sdk.out库文件。 “luspsdk”、“lssl”和“lcrypto”分别表示库文件“libuspsdk.so”、“libssl.so”和“libcrypto.so”,具体linux交叉编译命令gcc请开发者自行学习。 运行Demo。 启动demo命令为“./ sdk.out”,输入该命令程序就能运行起来了。 程序运行后,Agent Lite SDK就会主动发送绑定消息给平台。因为此时还没有使用应用侧接口在平台上注册此设备,所以会提示“The device has not registered yet”。
  • Profile打包 Profile写作完成后,需要按如下层级结构打包: Profile打包需要遵循如下几点要求: Profile文件的目录层级结构必须如上图所示,不能增删。例如:第二层级只能有“profile”和“service”两个文件夹,每个服务下面必须包含“profile”文件夹等。 图中橙色字体的命名不能改动。 Profile文件以zip形式压缩。 Profile文件的命名必须按照deviceType_manufacturerId_model的格式命名,其中的deviceType、manufacturerId、model必须与devicetype-capability.json中对应字段的定义一致。例如:本实例中devicetype-capability.json的主要字段如下: { "devices": [ { "manufacturerId": "TestUtf8ManuId", "manufacturerName": "HZYB", "model": "NBIoTDevice", "protocolType": "CoAP", "deviceType": "WaterMeter", "serviceTypeCapabilities": **** } ] } 图中的WaterMeterBasic、WaterMeterAlarm、Battery等都是devicetype-capability.json中定义的服务。 Profile文件中的文档格式都是JSON,在编写完成后可以在互联网上查找一些格式校验网站,检查JSON的合法性。
  • 服务能力定义样例 servicetype-capability.json记录了该设备的服务信息: { "services": [ { "serviceType": "WaterMeterBasic", "description": "WaterMeterBasic", "commands": [ { "commandName": "SET_PRESSURE_READ_PERIOD", "paras": [ { "paraName": "value", "dataType": "int", "required": true, "min": 1, "max": 24, "step": 1, "maxLength": 10, "unit": "hour", "enumList": null } ], "responses": [ { "responseName": "SET_PRESSURE_READ_PERIOD_RSP", "paras": [ { "paraName": "result", "dataType": "int", "required": true, "min": -1000000, "max": 1000000, "step": 1, "maxLength": 10, "unit": null, "enumList": null } ] } ] } ], "properties": [ { "propertyName": "registerFlow", "dataType": "int", "required": true, "min": 0, "max": 0, "step": 1, "maxLength": 0, "method": "R", "unit": null, "enumList": null }, { "propertyName": "currentReading", "dataType": "string", "required": false, "min": 0, "max": 0, "step": 1, "maxLength": 0, "method": "W", "unit": "L", "enumList": null }, { "propertyName": "timeOfReading", "dataType": "string", "required": false, "min": 0, "max": 0, "step": 1, "maxLength": 0, "method": "W", "unit": null, "enumList": null }, ...... ] } ]} 各字段的解释: 字段 子字段 必选/可选 描述 services 必选 包含了一个服务的完整信息(根节点不可修改)。 serviceType 必选 指示服务的类型,与devicetype-capability.json中serviceType字段保持一致。 description 必选 指示服务的描述信息。 非功能性字段,仅起到描述作用,可置为null。 commands 必选 指示设备可以执行的命令,如果本服务无命令则置null。 commandName 必选 指示命令的名字,命令名与参数共同构成一个完整的命令。 paras 必选 命令包含的参数。 paraName 必选 命令中参数的名字。 dataType 必选 指示命令参数的数据类型。 取值范围:string、int、string list、decimal、DateTime、jsonObject、enum、boolean。 上报数据时,复杂类型数据格式如下: string list:["str1","str2","str3"] DateTime:yyyyMMdd’T’HHmmss’Z’如:20151212T121212Z jsonObject:自定义json结构体,物联网平台不解析,仅进行透传 required 必选 指示本命令是否必选,取值为true或false,默认取值false(非必选)。 目前本字段是非功能性字段,仅起到描述作用。 min 必选 指示最小值。 仅当dataType为int、decimal时生效。 max 必选 指示最大值。 仅当dataType为int、decimal时生效。 step 必选 指示步长。 暂不使用,填0即可。 maxLength 必选 指示字符串长度。 仅当dataType为string、string list、DateTime时生效。 unit 必选 指示单位,英文。 取值根据参数确定,如: 温度单位:“C”或“K” 百分比单位:“%” 压强单位:“Pa”或“kPa” enumList 必选 指示枚举值。 如开关状态status可有如下取值: "enumList" : ["OPEN","CLOSE"] 目前本字段是非功能性字段,仅起到描述作用,建议准确定义。 responses 必选 命令执行的响应。 responseName 必选 命名可以在该responses对应命令的commandName后面添加“_RSP”。 paras 必选 命令响应的参数。 paraName 必选 命令中参数的名字。 dataType 必选 指示数据类型。 取值范围:string、int、string list、decimal、DateTime、jsonObject 上报数据时,复杂类型数据格式如下: string list:["str1","str2","str3"] DateTime:yyyyMMdd’T’HHmmss’Z’如:20151212T121212Z jsonObject:自定义json结构体,物联网平台不解析,仅进行透传 required 必选 指示本命令响应是否必选,取值为true或false,默认取值false(非必选)。 目前本字段是非功能性字段,仅起到描述作用。 min 必选 指示最小值。 仅当dataType为int、decimal时生效,逻辑大于等于。 max 必选 指示最大值。 仅当dataType为int、decimal时生效,逻辑小于等于。 step 必选 指示步长。 暂不使用,填0即可。 maxLength 必选 指示字符串长度。 仅当dataType为string、string list、DateTime时生效。 unit 必选 指示单位,英文。 取值根据参数确定,如: 温度单位:“C”或“K” 百分比单位:“%” 压强单位:“Pa”或“kPa” enumList 必选 指示枚举值。 如开关状态status可有如下取值: "enumList" : ["OPEN","CLOSE"] 目前本字段是非功能性字段,仅起到描述作用,建议准确定义。 properties 必选 上报数据描述,每一个子节点为一条属性。 propertyName 必选 指示属性名称。 dataType 必选 指示数据类型。 取值范围:string、int、string list、decimal、DateTime、jsonObject 上报数据时,复杂类型数据格式如下: string list:["str1","str2","str3"] DateTime:yyyyMMdd’T’HHmmss’Z’如:20151212T121212Z jsonObject:自定义json结构体,物联网平台不解析,仅进行透传 required 必选 指示本条属性是否必选,取值为true或false,默认取值false(非必选)。 目前本字段是非功能性字段,仅起到描述作用。 min 必选 指示最小值。 仅当dataType为int、decimal时生效,逻辑大于等于。 max 必选 指示最大值。 仅当dataType为int、decimal时生效,逻辑小于等于。 step 必选 指示步长。 暂不使用,填0即可。 method 必选 指示访问模式。 R:可读;W:可写;E:可订阅。 取值范围:R、RW、RE、RWE 、null。 unit 必选 指示单位,英文。 取值根据参数确定,如: 温度单位:“C”或“K” 百分比单位:“%” 压强单位:“Pa”或“kPa” maxLength 必选 指示字符串长度。 仅当dataType为string、string list、DateTime时生效。 enumList 必选 指示枚举值。 如电池状态(batteryStatus)可有如下取值: "enumList" : [0, 1, 2, 3, 4, 5, 6] 目前本字段是非功能性字段,仅起到描述作用,建议准确定义。
  • 设备能力定义样例 devicetype-capability.json记录了该设备的基础信息: { "devices": [ { "manufacturerId": "TestUtf8ManuId", "manufacturerName": "HZYB", "model": "NBIoTDevice", "protocolType": "CoAP", "deviceType": "WaterMeter", "omCapability":{ "upgradeCapability" : { "supportUpgrade":true, "upgradeProtocolType":"PCP" }, "fwUpgradeCapability" : { "supportUpgrade":true, "upgradeProtocolType":"LWM2M" }, "configCapability" : { "supportConfig":true, "configMethod":"file", "defaultConfigFile": { "waterMeterInfo" : { "waterMeterPirTime" : "300" } } } }, "serviceTypeCapabilities": [ { "serviceId": "WaterMeterBasic", "serviceType": "WaterMeterBasic", "option": "Mandatory" }, { "serviceId": "WaterMeterAlarm", "serviceType": "WaterMeterAlarm", "option": "Mandatory" }, { "serviceId": "Battery", "serviceType": "Battery", "option": "Optional" }, { "serviceId": "DeliverySchedule", "serviceType": "DeliverySchedule", "option": "Mandatory" }, { "serviceId": "Connectivity", "serviceType": "Connectivity", "option": "Mandatory" } ] } ]} 各字段的解释: 字段 子字段 可选/必选 描述 devices 必选 包含了一个设备的完整能力信息(根节点不能修改)。 manufacturerId 必选 指示设备的制造商ID。 manufacturerName 必选 指示设备的制造商名称 (只允许英文)。 model 必选 指示设备的型号,考虑到一款设备下的多种型号,建议包含字母或数字以保证可扩展性。 protocolType 必选 指示设备接入物联网平台的协议类型。如NB-IoT的设备取值为CoAP。 deviceType 必选 指示设备的类型。 omCapability 可选 定义设备的软件升级、固件升级和配置更新的能力,字段含义详情见下文中的:omCapability结构描述。 如果设备不涉及软件/固件升级,本字段可以删除。 serviceTypeCapabilities 必选 包含了设备具备的服务能力描述。 serviceId 必选 服务的Id,如果设备中同类型的服务类型只有一个则serviceId与serviceType相同, 如果有多个则增加编号,如三键开关 Switch01、Switch02、Switch03。 serviceType 必选 服务类型,与servicetype-capability.json中serviceType字段保持一致。 option 必选 标识服务字段的类型,取值范围:Master(主服务), Mandatory(必选服务), Optional(可选服务)。 目前本字段为非功能性字段,仅起到描述作用。 omCapability结构描述 字段 子字段 可选/必选 描述 upgradeCapability 可选 设备软件升级能力。 supportUpgrade 可选 true:设备支持软件升级。 false:设备不支持软件升级。 upgradeProtocolType 可选 升级使用的协议类型,此处不同于设备的protocolType,例如CoAP设备软件升级协议使用PCP。 fwUpgradeCapability 可选 设备固件升级能力。 supportUpgrade 可选 true:设备支持固件升级。 false:设备不支持固件升级。 upgradeProtocolType 可选 升级使用的协议类型,此处不同于设备的protocolType,当前物联网平台仅支持LWM2M固件升级。 configCapability 可选 设备配置更新能力。 supportConfig 可选 true:设备支持配置更新。 false:设备不支持配置更新。 configMethod 可选 file:使用文件的方式下发配置更新。 defaultConfigFile 可选 设备默认配置信息(Json格式),具体配置信息由设备商自定义。物联网平台只储存该信息供下发时使用,不解析处理配置字段的具体含义。
  • Profile模板 将一款新设备接入到物联网平台,首先需要编写这款设备的Profile。物联网平台提供了一些Profile文件模板,如果新增接入设备的类型和功能服务已经在物联网平台提供的设备Profile模板中包含,则可以直接选择使用;如果在物联网平台提供的设备Profile模板中未包含,则需要自己定义。 例如:接入一款水表 ,可以直接选择物联网平台上对应的Profile模板,修改设备型号标识属性和设备服务列表。 物联网平台提供的Profile模板会不断更新,如下表格列举设备类型和服务类型示例,仅供参考。 设备型号识别属性: 属性 Profile中key 属性值 设备类型 deviceType WaterMeter 厂商ID manufacturerId TestUtf8ManuId 厂商名称 manufacturerName HZYB 型号 model NBIoTDevice 协议类型 protocolType CoAP 设备的服务列表 服务描述 服务标识(serviceId) 服务类型(serviceType) 选项(option) 水表的基本功能 WaterMeterBasic Water Mandatory 告警服务 WaterMeterAlarm Battery Mandatory 电池服务 Battery Battery Optional 数据的上报规则 DeliverySchedule DeliverySchedule Mandatory 水表的连通性 Connectivity Connectivity Mandatory
  • 命名规范 在Profile的开发过程中,需要遵循如下命名规范: 设备类型(deviceType)、服务类型(serviceType)、服务标识(serviceId)采用单词首字母大写的命名法。例如:WaterMeter、Battery。 属性使用第一个单词首字母小写,其余单词的首字母大写的命名法。例如:batteryLevel、internalTemperature。 命令使用所有字母大写,单词间用下划线连接的格式。例如:DISCOVERY,CHANGE_COLOR。 设备能力描述json文件固定命名devicetype-capability.json。 服务能力描述json文件固定命名servicetype-capability.json。 厂商ID和型号唯一标识一款产品,故这些信息的组合在不同的Profile文件中不能重复,且仅支持英文。 要注重名称的通用性,简洁性;对于服务能力描述,还要考虑其功能性。例如:对于多传感器设备,可以命名为MultiSensor;对于具有显示电量的服务,可以命名为Battery。
  • 控制命令下发测试 控制命令下发测试用于测试设备接收和处理控制命令的能力,目的是验证Profile中定义的命令字段是否正确。如果平台与设备交互的“数据格式”为二进制码流,还会验证编解码插件与Profile的映射关系是否正确。由于下发的命令是立即下发模式,设备需要在线。 如果使用业务应用进行测试,还会测试业务应用是否正确调用物联网平台“创建设备命令”接口给设备下发命令的能力。 在控制命令下发测试界面,单击“下一步”开始测试。 根据向导进入测试界面,物联网平台会根据Profile的定义向设备下发一条命令。在真实设备应答后,查看测试用例执行结果。 如果是使用业务应用接入物联网平台,则操作业务应用向设备下发一条命令,在真实设备应答后,进入“上传应用下发命令截图”界面,单击界面中的“+”,上传业务应用命令下发成功的截图。此图作为业务应用正确调用物理网平台“创建设备命令”接口的凭证。 测试成功,单击“下一步”进入下一阶段测试。 测试失败,排查并处理问题后,单击“重新测试”重测测试用例。
  • 命令下发响应测试 命令下发响应测试用于测试设备在接收物联网平台命令后主动上报执行结果的能力。当Profile中定义了“命令下发响应字段”,即设备需要返回命令执行结果时,开发者才需要进行命令下发响应测试。由于下发的命令是立即下发模式,设备需要在线。 在命令下发响应测试界面,单击“下一步”开始测试。 根据向导进入测试界面,物联网平台会根据Profile的定义向设备下发一条命令,如果是业务应用接入物联网平台,则操作业务应用向设备下发一条命令。 如果真实设备支持自动返回命令执行结果,则在真实设备收到命令后,直接查看测试用例执行结果。如果真实设备不支持自动返回命令执行结果,则根据真实设备收到的命令,手动操作真实设备上报命令执行结果后,查看测试用例执行结果。 测试成功,单击“下一步”进入下一阶段测试。 测试失败,排查并处理问题后,单击“重新测试”重测测试用例。
  • 应用接收推送数据测试 应用接收推送数据测试主要是测试业务应用是否可以正确接收物联网平台推送设备数据的能力。 在应用接收推送数据测试界面,单击“下一步”开始测试。 根据向导进入测试界面,操作真实设备上报一条profile中定义的属性数据,物联网平台获取数据并推送给业务应用,查看测试用例执行结果。 数据推送成功,单击“下一步”进入“上传应用接收截图”界面。 数据推送失败,排查并处理故障后,单击“重新测试”重测测试用例。 单击“上传应用接收截图”界面中的“+”,上传业务应用接收到物联网平台推送数据的截图。此图是业务应用正确接收物联网平台推送数据的凭证。 上传的图片大小不能超过20MB。
  • 设备绑定测试 设备绑定测试用于测试设备接入物联网平台的能力,包括设备注册和设备上线两个步骤。 设备绑定测试是进行其他测试的前提条件,如果测试失败,则无法进行其他测试。 在设备绑定测试界面,单击“下一步”,进入注册设备界面。 根据向导进入测试界面,选择“安全模式”,并填写“设备标识”和“模组名称”,单击“下一步”。 如果安全模式选择“加密”,还需要填写“PSK”。 如果不是使用模组进行测试,则“模组名称”填写无。 根据向导操作真实设备接入物联网平台进行绑定,查看测试用例执行结果。 测试成功,单击“下一步”进入下一阶段测试。 测试失败,排查并处理问题后,单击“重新测试”重测测试用例。
  • 数据上报测试 数据上报测试用于测试设备上报数据的能力,目的是验证Profile中定义的属性字段是否正确。如果物联网平台与设备交互的“数据格式”为二进制码流,还会验证编解码插件与Profile的映射关系是否正确。 在数据上报测试界面,单击“下一步”开始测试。 根据向导进入测试界面,操作真实设备上报Profile中定义的属性数据,如果设备的所有属性数据都已上报完成,可以点击“终止测试”完成数据上报测试并查看测试用例执行结果。 测试成功,单击“下一步”进入下一阶段测试。 测试失败,排查并处理问题后,单击“重新测试”重测测试用例。 平台会检测所有上报成功的属性数据,并记录到测试报告中,重复上报的属性只会记录一次。
  • 无线参数上报测试 无线参数上报测试用于测试设备上报无线参数属性数据的能力,包括信号强度、覆盖等级、信噪比和小区ID。 如果测试此用例,需要在Profile中定义如下无线参数属性,并在编解码插件中建立对应的映射关系。 参数 类型 描述 RSRP/rsrp/signalStrength/SignalPower int 信号强度,取值范围-140~-40。 ECL/signalECL int 覆盖等级,取值范围0~2。 SNR/snr/SINR/sinr/signalSNR int 信噪比,取值范围-20~30。 CellID/cellId int 小区ID,取值范围0~2147483647。 在无线参数上报测试界面,单击“下一步”开始测试。 根据向导进入测试界面,操作真实设备上报Profile中定义的无线参数属性数据,查看测试用例执行结果。 测试成功,单击“下一步”进入下一阶段测试。 测试失败,排查并处理问题后,单击“重新测试”重测测试用例。 上报的无线参数值必须在数据范围内才算有效数据。
  • 调测“获取IAM用户Token”接口 在访问物联网平台业务接口前,应用服务器需要调用“获取IAM用户Token”接口鉴权,华为云认证通过后向应用服务器返回鉴权令牌X-Subject-Token。 应用服务器需要构造一个HTTP请求,请求示例如下: POST https://iam.cn-north-4.myhuaweicloud.com/v3/auth/tokens Content-Type: application/json { "auth": { "identity": { "methods": [ "password" ], "password": { "user": { "name": "username", "password": "********", "domain": { "name": "domainname" } } } }, "scope": { "project": { "name": "xxxxxxxx" } } } } 接下来参考API文档,调测“获取IAM用户Token”接口。 配置“获取IAM用户Token”接口的HTTP方法、URL和Headers。 配置“获取IAM用户Token”接口的Body。 点击“Send”,在下方查看返回码和响应消息内容。 请将返回头域中的的X-Subject-Token更新到“OcceanConnect”环境的“X-Auth-Token”参数中,以便于在调用其它接口时使用。若超过令牌有效时间,需要重新调用鉴权接口。 这里我们已经在postman中自动更新了“X-Auth-Token”参数,使用时无需手动操作。
  • 调测“查询产品”接口 应用服务器如果需要查询之前创建的产品详情,可以调用此接口。 应用服务器需要构造一个请求,请求示例如下: GET https://iotdm.cn-north-4.myhuaweicloud.com/v5/iot/{project_id}/products/{product_id}Content-Type: application/jsonX-Auth-Token: ********
  • 配置Postman 导入Postman环境变量。 点击右上角的图标,打开“MANAGE ENVIRONMENTS”窗口。 点击“Import”,导入OceanConnect.postman_environment.json文件。 点击“Manage Environments”,选择导入的“OcceanConnect”环境,修改IAM终端节点“IAMEndpoint”、物联网平台终端节点“IOTDMEndpoint”、华为云用户名“IAMUserName”、华为云密码“IAMPassword”、华为云账号名“IAMDoaminId”、区域“region”。这里已经填写好北京四站点对应的IAM终端节点、物联网平台终端节点和区域,如果您是在北京四站点订购的“设备管理”服务,只需要修改华为云用户名、华为云密码和华为云账号名。 返回主页,选择环境变量为刚导入的“OcceanConnect”。 导入“应用侧API调用(V5版本).postman_collection.json”。 成功后:
  • 调测“查询IAM用户可以访问的项目列表”接口 在访问物联网平台业务接口前,应用服务器需要调用“查询IAM用户可以访问的项目列表”接口获取用户的项目ID,用于后续访问物联网平台业务接口。 应用服务器需要构造一个HTTP请求,请求示例如下: GET https://iam.cn-north-4.myhuaweicloud.com/v3/auth/projectsContent-Type: application/jsonX-Auth-Token: ********
  • 调测“创建产品”接口 在设备接入物联网平台前,应用服务器需要调用此接口创建产品,后续注册设备时需要使用这里创建的产品。 应用服务器需要构造一个请求,请求示例如下: POST https://iotdm.cn-north-4.myhuaweicloud.com/v5/iot/{project_id}/productsContent-Type: application/jsonX-Auth-Token: ********{ "name" : "Thermometer", "device_type" : "Thermometer", "protocol_type" : "LWM2M", "data_format" : "binary", "manufacturer_name" : "ABC", "industry" : "smartCity", "description" : "this is a thermometer produced by Huawei", "service_capabilities" : [ { "service_type" : "temperature", "service_id" : "temperature", "description" : "temperature", "properties" : [ { "unit" : "centigrade", "min" : "1", "method" : "R", "max" : "100", "data_type" : "decimal", "description" : "force", "step" : 0.1, "enum_list" : [ "string" ], "required" : true, "property_name" : "temperature", "max_length" : 100 } ], "commands" : [ { "command_name" : "reboot", "responses" : [ { "response_name" : "ACK", "paras" : [ { "unit" : "km/h", "min" : "1", "max" : "100", "para_name" : "force", "data_type" : "string", "description" : "force", "step" : 0.1, "enum_list" : [ "string" ], "required" : false, "max_length" : 100 } ] } ], "paras" : [ { "unit" : "km/h", "min" : "1", "max" : "100", "para_name" : "force", "data_type" : "string", "description" : "force", "step" : 0.1, "enum_list" : [ "string" ], "required" : false, "max_length" : 100 } ] } ], "option" : "Mandatory" } ], "app_id" : "jeQDJQZltU8iKgFFoW060F5SGZka"}
  • 调测“注册设备”接口 在设备接入物联网平台前,应用服务器需要调用此接口在物联网平台注册设备。在设备接入物联网平台时携带设备唯一标识,完成设备的接入认证。 应用服务器需要构造一个HTTP请求,请求示例如下: POST https://iotdm.cn-north-4.myhuaweicloud.com/v5/iot/{project_id}/devicesContent-Type: application/jsonX-Auth-Token: ********{ "node_id" : "ABC123456789", "device_name" : "dianadevice", "product_id" : "b640f4c203b7910fc3cbd446ed437cbd", "auth_info" : { "auth_type" : "SECRET", "secure_access" : true, "fingerprint" : "dc0f1016f495157344ac5f1296335cff725ef22f", "secret" : "3b935a250c50dc2c6d481d048cefdc3c", "timeout" : 300 }, "description" : "watermeter device"} 接下来参考API文档,调测物联网平台“注册设备”接口。 注:在以下步骤中,只呈现样例调测用到的参数。 配置“注册设备”接口的HTTP方法、URL和Headers。 配置“注册设备”接口的Body。 点击“Send”,在下方查看返回码和响应消息内容。 请将返回的“device_id”更新到“OceanConnect”环境中的“device_id”参数中,用于后续其它接口使用。 这里我们已经在postman中自动更新了“device_id”参数,使用时无需手动操作。
共100000条