基于华为物联网IOT的应用开发 ---界面管理开发

在前面随笔《基于华为物联网IOT的应用开发 --- 基于.net 的SDK封装》介绍过IOT中应用侧SDK的封装,主要就是基于华为IOT的应用侧封装,以便在应用系统中进行调用。应用侧SDK的封装是一切应用开发的基础,不过华为并无提供对应.net的SDK封装,不过SDK都是基于Web  API 的JSON数据进行交互,所以花了一点时间进行了华为.net 的SDK进行了全面封装,本篇随笔介绍如何基于封装好的IOT 应用侧的SDK进行界面管理的开发,实现对IOT业务数据的管理等。html

一、应用侧SDK封装回顾

应用侧的开发接口通常云平台都会提供不一样平台的SDK,如阿里云开源提供Java SDK/C# SDK等;而华为则提供了Java、PHP等SDK,没有包含.net 的SDK。华为物联网云的应用侧API接口包括:json

 

基于对应应用侧API接口的定义,咱们使用C#进行了对应接口的封装。api

 

 包含了一个测试接口项目、一个SDK封装接口项目,以及一个订阅的消息推送接口的解析和处理,例如新增设备、设备信息变化、设备绑定激活等。服务器

对于事件的通知,咱们通常是在应用端被动的进行相应的处理,所以须要对它们的消息进行转换和处理。微信

相似在管理后台订阅这些事件,而后这些事件触发后会推送给应用服务器。app

 

 

二、接口的测试使用

根据IOT的应用侧API的定义,咱们编写一个快速测试SDK工做状况的Winform程序来测试,如获取受权信息,以及查询产品、注册设备、修改设备、获取设备状态和详细等等接口的正常与否,而后再在Web应用中进行整合,这样能够减小返工调试的问题。post

按照业务接口的归类测试,咱们编写以下程序用来测试对应SDK接口。测试

 

在使用SDK接口前,咱们须要知道,华为IOT的API接口,基本上所有须要证书的对接的,这个和咱们开发微信API有所差别。例如,咱们的Winform测试程序,让它带有一个Cert目录下的证书文件,这个证书文件能够在API的Demo里面找到,或者在华为IOT平台上下载。this

 

 咱们最终用到的是cert/outgoing.CertwithKey.pkcs12这个证书文件。阿里云

 咱们建立一个HTTPRequest对象获取数据的时候,须要指定这个证书,以下所示。

helper.ContentType = "application/json";
helper.ClientCertificates = new X509CertificateCollection() { new X509Certificate2(Constants.CertFilePath, Constants.CertPassword) };

其余部分就是对API接口封装的调用测试了。

如首先是受权的测试,用来获取AccessToken的,这个是调用其余接口的前提。

private void btnLogin_Click(object sender, EventArgs e)
{
    var result = basicApi.Authentication();
    Console.WriteLine(result != null ? "accessToken:" + result.ToJson() : "获取结果出错");

    if (result != null)
    {
        var refreshResult = basicApi.RefreshToken(result.refreshToken);

        Console.WriteLine(refreshResult != null ? "accessToken:" + refreshResult.ToJson() : "获取结果出错");
        this.accessToken = refreshResult.accessToken;//记录待用
    }
}

华为IOT接口不少没有所有整合在一块儿,有的在https://support.huaweicloud.com/api-IoT/iot_06_0003.html ,而有的则在https://support.huaweicloud.com/api-iothub/iot_06_0008.html, 就拿受权来讲,还有另一个版本的接口能够获取,两个接口得到的token均可以通用。

var url = Constants.AppBaseUrl + "/iocm/app/sec/v1.1.0/login";
var url = Constants.AppBaseUrl + "/api/v3.0/auth/tokens";

这两个地址均可以获取AccessToken,如设备建立,也是有多个接口,版本不一样。

咱们针对各个接口的封装,对相关接口进行测试,如基于产品、产品下面的列表等信息,能够在一个接口测试代码里面进行测试,以下所示。

        /// <summary>
        /// 产品相关接口测试
        /// </summary>
        private void btnProduct_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(accessToken))
            {
                MessageUtil.ShowTips("请先鉴权获取AccessToken");
                return;
            }
            try
            {
                var productApi = new ProductApi();
                var deviceApi = new DataCollectionApi();

                //查询产品列表
                var queryJson = new QueryProductJson { ownerAppId = Constants.AppId };
                var result = productApi.QueryProduct(accessToken, queryJson);
                Console.WriteLine(result != null ? result.ToJson() : "no result");

                if (result != null && result.products != null)
                {
                    //遍历产品,根据产品ID获取产品信息
                    foreach (var p in result.products)
                    {
                        var detailResult = productApi.QueryProduct(accessToken, p.productId, Constants.AppId);
                        Console.WriteLine(detailResult != null ? detailResult.ToJson() : "no result");
                    }

                    //遍历产品下面的设备信息
                    foreach (var p in result.products)
                    {
                        var deviceJson = new QueryDeviceJson { ownerAppId = Constants.AppId, productId = p.productId };
                        var deviceResult = deviceApi.BatchQueryDevice2(accessToken, deviceJson);
                        Console.WriteLine(deviceResult != null ? deviceResult.ToJson() : "no result");
                    }
                }
            }
            catch (Exception ex)
            {
                MessageUtil.ShowError(ex.Message);
            }
        }

对于设备,产品、设备组,都属于设备的入口之一,所以设备组也是管理接口设备的一个类别,咱们能够根据SDK对设备组接口进行测试,以下代码所示。

        /// <summary>
        /// 设备分组测试
        /// </summary>
        private void btnDeviceGroup_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(accessToken))
            {
                MessageUtil.ShowTips("请先鉴权获取AccessToken");
                return;
            }

            try
            {
                //根据本身数据修改
                var deviceId = "64bf5869-b271-4007-8db8-fab185e19c10";
                var groupName = "testGroup";
                var groupApi = new DeviceGroupApi();
                var groupJson = new CreateDeviceGroupJson()
                {
                    appId = Constants.AppId,
                    name = groupName,
                    description = "测试设备分组",
                    deviceIds = { deviceId }
                };

                //建立设备组
                var result = groupApi.CreateDeviceGroup(accessToken, groupJson);
                Console.WriteLine(result != null ? result.ToJson() : "no result");

                //查询设备组
                var queryJson = new QueryDeviceGroupJson()
                {
                    accessAppId = Constants.AppId,
                    name = groupName
                };
                var queryResult = groupApi.QueryDeviceGroup(accessToken, queryJson);
                Console.WriteLine(queryResult != null ? queryResult.ToJson() : "no result");

                //查询设备组成员
                if (queryResult != null && queryResult.list != null)
                {
                    foreach (var group in queryResult.list)
                    {
                        //设备明细
                        var groupResult = groupApi.GetDeviceGroup(accessToken, group.id, Constants.AppId);
                        Console.WriteLine(groupResult != null ? groupResult.ToJson() : "no result");

                        //设备组成员
                        var queryMemberJson = new QueryDeviceGroupMemberJson()
                        {
                            appId = Constants.AppId,
                            devGroupId = group.id
                        };
                        var queryMemberResult = groupApi.QueryDeviceGroupMember(accessToken, queryMemberJson);
                        Console.WriteLine(queryMemberResult != null ? queryMemberResult.ToJson() : "no result");
                    }
                }
            }
            catch (Exception ex)
            {
                MessageUtil.ShowError(ex.Message);
            }
        }

 

三、IOT业务界面管理开发

当咱们把大多数接口都跑一遍,并解决相关问题后,咱们就能够根据这些接口进行Web应用的开发了。

为了方便,咱们把IOT相关的业务,定义在一个控制器里面,方便管理,之后若是有须要,能够拆分进行管理。

 

例如,对于数据提供,主要就是分页JSON数据的处理,方便界面控件经过Ajax进行获取数据显示。

例如,对于产品列表,咱们构建了一个控制器方法,以下所示。

        /// <summary>
        /// 根据条件查询产品列表,并返回对象集合(用于分页数据显示)
        /// </summary>
        /// <returns>指定对象的集合</returns>
        public virtual ActionResult FindProductWithPager()
        {
            var pagerInfo = GetPagerInfo();
            var sort = GetSortOrder();
            var accessToken = GetAccessToken();

            var queryJson = new QueryProductJson(pagerInfo) { ownerAppId = Constants.AppId };
            var result = productApi.QueryProduct(accessToken, queryJson);

            var list = result != null ? result.products : null;
            var totalCount = result != null ? result.totalCount : 0;

            //Json格式的要求{total:22,rows:{}}
            var jsonResult = new { total = totalCount, rows = list };
            return ToJsonContent(jsonResult);
        }

其余,如设备组、设备列表等相似的处理,都是先经过接口获取数据,而后组装为对应的JSON格式提供给视图便可。

 

 有时候,除了列表展现外,咱们可能还须要对视图中建立、删除、获取单个明细的接口进行处理,以下所示是设备分组的管理接口。

 

其余的业务对象也是相似的封装,有了这些接口,咱们就能够处理分页、获取详细、编辑、删除等接口的处理了。

在Web应用中定义几个业务菜单,用来管理产品信息、设备组和设备信息。

 

 产品管理界面以下所示。

若是咱们要查看产品明细,调用对应接口进行展现便可。

包含设备列表,咱们根据产品ID获取对应设备列表返回到界面进行展现便可,以下所示效果。

 

  设备分组以下所示。

 

 而设备列表展现能够经过产品和设备组进行限定查询,咱们以下管理这个设备列表的展现的。

 

一样,设备详细信息,经过对应ID调用SDK接口获取数据,并返回到视图便可展现出来了。设备的相关信息,以下历史数据、历史命令等,咱们也能够经过对应接口进行数据获取返回,在界面的Tab控件进行展现便可。

 

如设备历史命令,能够获取到相关历史命令信息。

 

 

以上就是对IOT应用侧API接口的封装和应用界面的管理开发,不过使用过程当中,对于IOT的接口仍是不够完善,但愿华为在这方便可以继续完善和提供良好的开发人员支持,咱们也继续关注,以便在后续项目中整合物联网的硬件设备进行使用。