基于NB-IoT的智慧路灯监控系统(PC应用开发)

目录

1、项目结构

2、系统组织结构图

3、业务逻辑概述

4、使用技术

5、开发环境与工具

6、功能介绍

7、核心功能代码

作为IoT云平台的数据交互PC客户端,对平台的数据进行展示,实现本地与远程终端的数据交互,进而展现出依赖云平台的应用使用的具体场景,进一步展现云品台的优势。

1、项目结构

整个使用常规的传统的三层架构,同时引入MVVM架构模式,属于混合型架构设计,将各个层次之间实现理论解耦,提高了系统各个层次之间的独立性和可拓展性。

基于NB-IoT的智慧路灯监控系统(PC应用开发)_第1张图片

项目结构概述如下:

  • HandyC.HW:项目实际入口,表现层,实际用户操作逻辑的输入输出部分。
  • HandyC.HW.ViewModels:与表现层与之对应的视图实体类部分,对用户交互逻辑的主要实现处理模块,同时在该项目中进行相关数据实体和视图实体的相互转换工作。
  • HandyC.HW.Data:用于处理来自于IoT平台的数据源,为业务层提供需求的数据结果。
  • HandyC.HW.Service:项目的实际业务逻辑处理,组织数据层提供的数据。
  • HandyC.HW.Tools:项目整体结构中需要使用到的基础辅助类集合,包括网络请求相关类,缓存,数据序列化和反序列化,特殊数据格式处理等。
  • 对应测试项目与之对应,前缀为Test.*,此处忽略。

2、系统组织结构图

本系统分为两个大的功能模块,平台监管以及数据采集两个模块,平台监管主要是对设备实时动态进行监管,数据采集,处理来自IOT云平台的历史相关数据并展示。

基于NB-IoT的智慧路灯监控系统(PC应用开发)_第2张图片

3、业务逻辑概述

PC端主要分为两个部分,一个是通过https请求双向认证获取到来自于IoT平台提供的相关Api接口的目标数据,将数据进行处理根据View的需求进行相关的ViewModel处理之后展示到页面中;一个是需要PC端与IoT平台上的挂载设备进行数据交互时,实现本地命令的发送,进而间接控制设备的数据响应。

4、使用技术

  • 网络通信相关技术(数据接口请求)
  • WPF(UI框架)
  • MvvmLight(MVVM框架)
  • 依赖注入
  • 简单缓存
  • LiveCharts(图标框架)
  • HandyControl(WPF组件框架)
  • 非对称双向认证(Https)
  • AutoMapper(DTO转换框架)

5、开发环境与工具

  • 开发环境:Windows 7 sp1、.Net Framework 4.7.2
  • 开发语言:C#
  • 开发工具:Microsoft Visual Studio professional 2019(VS 2019)

6、功能介绍

设备管理页面的主页面,设备统计部分包含了对当前设备的设备类型、设备状态、设备的协议类型的相关统计信息,属于设备总体的一个统计信息。设备列表中展示的是当前的存在的设备,以卡片的方式展示出来,包括设备的名称、设备的型号、设备的编号等预览。

基于NB-IoT的智慧路灯监控系统(PC应用开发)_第3张图片

 显示设备的详细信息。

基于NB-IoT的智慧路灯监控系统(PC应用开发)_第4张图片

设备的最新数据显示页面,能够动态实时请求道IoT平台上的设备下发的最近历史信息。

基于NB-IoT的智慧路灯监控系统(PC应用开发)_第5张图片

云平台联动主页中的卡片为一卡片一设备,点击设备卡片,可以对设备进行联动模式控制,有三种联动方式:终端联控模式、分段定时模式和自动调光模型。

终端联控模式,默认手动模式,可以通过手动直接下发指令到IoT平台,通过平台将命令通知对应的设备执行。

基于NB-IoT的智慧路灯监控系统(PC应用开发)_第6张图片

 分段定时模式,用户可以通过点击切换至定时模式,设定时间后,将点击发送定时设备,等待设定的命令发送至IoT平台。

基于NB-IoT的智慧路灯监控系统(PC应用开发)_第7张图片

自动调光模式,自动模式与手动模式的操作类似,用户通过开启和关闭实现对IoT平台上挂载的设备的执行模式的设定,关闭时,设备默认执行,为上一次的模式运行状态,开启时,变更为根据实际的自动条件进行自身状态的控制 。

基于NB-IoT的智慧路灯监控系统(PC应用开发)_第8张图片

设备历史数据显示页面,主要功能为查询功能,用于显示从IoT平台获取到的当前设备对应的历史记录信息,可通过查询条件进行更加细致数据查找。

基于NB-IoT的智慧路灯监控系统(PC应用开发)_第9张图片

命令历史数据的主页面,默认显示第一个设备的相关历史数据,能够查询到多端给设备发送的相关命令指令历史信息。 

基于NB-IoT的智慧路灯监控系统(PC应用开发)_第10张图片

7、核心功能代码

鉴权代码如下: 

using HandyC.HW.Tools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace HandyC.HW.Data
{
/// 
/// 鉴权数据处理类
/// 
public class Authentication:IAuthentication
{
private readonly string accessTokenName = "Authentication";
private ICacheAdapter cache;
public Authentication(ICacheAdapter adapter)
{
cache = adapter;
}

/// 
/// 获取鉴权的数据实例
/// 
/// 异常时执行回调
/// 权限信息
public ApiAuthInfo GetApiAuth(Action ErrorCallBack)
{
//判定缓存中是否存在用户项目信息
ApiAuthInfo apiAuthInfo = GetCertificateCache();
if (apiAuthInfo != null)
{
return apiAuthInfo;
}
//获取证书
var cer = AuthContext.SSLConfig.X509Certificate2;
#region 设定当前请请求
Dictionary dataDic = new Dictionary {
{ "appId",AuthContext.ClientInfo.AppId },
{"secret",AuthContext.ClientInfo.Secret }
};
//实例化RequestMessage
HttpRequestMessage requestMessage = HttpHelper.SetRequestMessage(AuthContext.ClientInfo.Host, ApiUrls.Login, "POST", dataDic,null);
requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
#endregion
//获取实例请求
apiAuthInfo = HttpHelper.PostResponse(requestMessage,cer);
if (apiAuthInfo == null)
{
//处理异常信息
ErrorCallBack(HttpHelper.ApiException);
return apiAuthInfo;
}
//添加实例类到缓存中
cache.Set(accessTokenName, apiAuthInfo,DateTime.Now.AddSeconds(apiAuthInfo.ExpiresIn));
return apiAuthInfo;
}
/// 
/// 刷新Token值-服务端异常
/// 
/// 异常时执行回调
/// 权限信息
public ApiAuthInfo RefreshApiAuth(Action ErrorCallBack)
{
//判定缓存中是否存在用户项目信息
ApiAuthInfo apiAuthInfo = GetCertificateCache();
//若当前缓存中不存在鉴权
if (apiAuthInfo == null)
{
return null;
}
//获取证书
var cer = AuthContext.SSLConfig.X509Certificate2;
#region 设定当前请请求
Dictionary dataDic = new Dictionary {
{"appId",AuthContext.ClientInfo.AppId },
{"secret",AuthContext.ClientInfo.Secret },
{ "refreshToken",apiAuthInfo.RefreshToken}
};
//实例化
HttpRequestMessage requestMessage = HttpHelper.SetRequestMessage(AuthContext.ClientInfo.Host, ApiUrls.RefreshToken, "POST", dataDic, null);
//此处为智障代码切记小心
if (requestMessage.Content != null)
{
requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
}

#endregion
//获取实例请求
apiAuthInfo = HttpHelper.GetResponse(requestMessage, cer);
if (apiAuthInfo == null)
{
//处理异常信息
ErrorCallBack(HttpHelper.ApiException);
return apiAuthInfo;
}
//添加实例类到缓存中
cache.Set(accessTokenName, apiAuthInfo, DateTime.Now.AddSeconds(apiAuthInfo.ExpiresIn));
return apiAuthInfo;
}
/// 
///刷新密钥
///校验当前密钥是否过期
/// 
/// 权限信息
public ApiAuthInfo GetCertificateCache()
{
ApiAuthInfo apiAuth = cache.Get(accessTokenName);
return apiAuth;
}
}
} 
  

获取设备信息代码如下:

using HandyC.HW.Tools;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace HandyC.HW.Data
{
    /// 
    /// 数据采集操作实体
    /// 
    public class DataCollection: IDataCollection
    {
        private IAuthentication _authentication;
        public DataCollection(IAuthentication authentication)
        {
            _authentication = authentication;
        }
        //查询单个设备信息
        public QuerySingleDeviceInfoOutDTO QuerySingleDeviceInfo(string deviceId, Action ErrorCallBack)
        {
            if (string.IsNullOrEmpty(deviceId))
            {
                throw new NullReferenceException("deviceId 不能为Null");
            }
            //获取accessToken信息
            ApiAuthInfo apiAuthInfo = _authentication.GetApiAuth(ErrorCallBack);
            if (apiAuthInfo == null)
            {
                return null;
            }
            //构建请求需要的header和body
            //Headers
            Dictionary headerDic = new Dictionary
            {
                { "app_key",AuthContext.ClientInfo.AppId},
                { "Authorization",$"{apiAuthInfo.TokenType} {apiAuthInfo.AccessToken}"}
            };
            //Body
            Dictionary dataDic = new Dictionary();

            string localPath = ApiUrls.queryDeviceInfo.Replace("{deviceId}", deviceId);


            HttpRequestMessage requestMessage = HttpHelper.SetRequestMessage(AuthContext.ClientInfo.Host, localPath, "GET", dataDic, headerDic);
            //此处为智障代码切记小心
            if (requestMessage.Content != null)
            {
                requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            }
            //获取证书
            var cer = AuthContext.SSLConfig.X509Certificate2;
            var result = HttpHelper.PostResponse(requestMessage, cer);
            if (result == null)
            {
                //处理异常信息
                ErrorCallBack(HttpHelper.ApiException);
                return null;
            }
            return result;
        }
        //批量查询设备信息列表
        public QueryBatchDevicesInfoOutDTO QueryBatchDevicesInfo(QueryBatchDevicesInfoInDTO filter, Action ErrorCallBack)
        {
            if (filter is null)
            {
                throw new NullReferenceException("filter 不能为Null");
            }
            //获取accessToken信息
            ApiAuthInfo apiAuthInfo = _authentication.GetApiAuth(ErrorCallBack);
            if (apiAuthInfo == null)
            {
                //处理异常信息
                return null;
            }
            //构建请求需要的header和body
            //Headers
            Dictionary headerDic = new Dictionary
            {
                { "app_key",AuthContext.ClientInfo.AppId},
                { "Authorization",$"{apiAuthInfo.TokenType} {apiAuthInfo.AccessToken}"}
            };
            //Body
            Dictionary pathDic = new Dictionary();
            //遍历获取对应实体的所有当前类自身属性
            Type type = filter.GetType();
            System.Reflection.PropertyInfo[] properties = type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);
            foreach (var property in properties)
            {
                var value = property.GetValue(filter);
                if (!(value is null))
                {
                    var customAttribute = property.CustomAttributes.FirstOrDefault(x => x.AttributeType == typeof(Newtonsoft.Json.JsonPropertyAttribute));
                    if (customAttribute != null)
                    {
                        //获取到符合条件的参数信息
                        var namedArgument = customAttribute.NamedArguments.FirstOrDefault(x => x.MemberName == "PropertyName");
                        //判定参数名称参数对应的别名名称不为空
                        if (namedArgument != null && namedArgument.TypedValue.Value != null)
                        {
                            pathDic.Add(namedArgument.TypedValue.Value.ToString(), value.ToString());
                        }
                    }
                    else
                    {
                        pathDic.Add(property.Name, value.ToString());
                    }
                }
            }
            string strPath = pathDic.DictionaryToString();
            string localPath = ApiUrls.queryDevices.Replace("?", $"?{strPath}");
            HttpRequestMessage requestMessage = HttpHelper.SetRequestMessage(AuthContext.ClientInfo.Host, localPath, "GET", new Dictionary(), headerDic);
            //此处为智障代码切记小心
            if (requestMessage.Content != null)
            {
                requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            }

            //requestMessage.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Postman/6.5.2 Chrome/59.0.3071.115 Electron/1.8.4 Safari/537.36");
            //获取证书
            var cer = AuthContext.SSLConfig.X509Certificate2;
            var result = HttpHelper.GetResponse(requestMessage, cer);
            if (result == null)
            {
                //处理异常信息
                ErrorCallBack(HttpHelper.ApiException);
                return null;
            }
            return result;
        }
        //查询设备历史信息
        public DeviceDataSource QueryDeviceDataHistory(QueryDeviceDataHistoryInDTO filter, Action ErrorCallBack)
        {
            if (filter is null)
            {
                throw new NullReferenceException("filter 不能为Null");
            }
            //获取accessToken信息
            ApiAuthInfo apiAuthInfo = _authentication.GetApiAuth(ErrorCallBack);
            if (apiAuthInfo == null)
            {
                return null;
            }
            //构建请求需要的header和body
            //Headers
            Dictionary headerDic = new Dictionary
            {
                { "app_key",AuthContext.ClientInfo.AppId},
                { "Authorization",$"{apiAuthInfo.TokenType} {apiAuthInfo.AccessToken}"}
            };
            //Body
            Dictionary pathDic = new Dictionary();
            //遍历获取对应实体的所有当前类自身属性
            Type type = filter.GetType();
            System.Reflection.PropertyInfo[] properties = type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);
            foreach (var property in properties)
            {
                var value = property.GetValue(filter);
                if (!(value is null))
                {
                    var customAttribute = property.CustomAttributes.FirstOrDefault(x => x.AttributeType == typeof(Newtonsoft.Json.JsonPropertyAttribute));
                    if (customAttribute != null)
                    {
                        //获取到符合条件的参数信息
                        var namedArgument = customAttribute.NamedArguments.FirstOrDefault(x => x.MemberName == "PropertyName");
                        //判定参数名称参数对应的别名名称不为空
                        if (namedArgument != null && namedArgument.TypedValue.Value != null)
                        {
                            pathDic.Add(namedArgument.TypedValue.Value.ToString(), value.ToString());
                        }
                    }
                    else
                    {
                        pathDic.Add(property.Name, value.ToString());
                    }
                }
            }
            string strPath = pathDic.DictionaryToString();
            string localPath = ApiUrls.queryHistoryDevice.Replace("?", $"?{strPath}");
            HttpRequestMessage requestMessage = HttpHelper.SetRequestMessage(AuthContext.ClientInfo.Host, localPath, "GET", new Dictionary(), headerDic);
            //此处为智障代码切记小心
            if (requestMessage.Content != null)
            {
                requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            }
            //获取证书
            var cer = AuthContext.SSLConfig.X509Certificate2;
            var result = HttpHelper.GetResponse(requestMessage, cer);
            if (result == null)
            {
                //处理异常信息
                ErrorCallBack(HttpHelper.ApiException);
                return null;
            }
            return result;
        }
        //查询影子历史数据信息
        public DeviceDesiredSource QueryDeviceDesiredHistory(QueryDeviceDesiredHistoryInDTO filter, Action ErrorCallBack)
        {
            if (filter is null)
            {
                throw new NullReferenceException("filter 不能为Null");
            }
            //获取accessToken信息
            ApiAuthInfo apiAuthInfo = _authentication.GetApiAuth(ErrorCallBack);
            if (apiAuthInfo == null)
            {
                return null;
            }
            //构建请求需要的header和body
            //Headers
            Dictionary headerDic = new Dictionary
            {
                { "app_key",AuthContext.ClientInfo.AppId},
                { "Authorization",$"{apiAuthInfo.TokenType} {apiAuthInfo.AccessToken}"}
            };
            //Body
            Dictionary pathDic = new Dictionary();
            //遍历获取对应实体的所有当前类自身属性
            Type type = filter.GetType();
            System.Reflection.PropertyInfo[] properties = type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);
            foreach (var property in properties)
            {
                var value = property.GetValue(filter);
                if (!(value is null))
                {
                    var customAttribute = property.CustomAttributes.FirstOrDefault(x => x.AttributeType == typeof(Newtonsoft.Json.JsonPropertyAttribute));
                    if (customAttribute != null)
                    {
                        //获取到符合条件的参数信息
                        var namedArgument = customAttribute.NamedArguments.FirstOrDefault(x => x.MemberName == "PropertyName");
                        //判定参数名称参数对应的别名名称不为空
                        if (namedArgument != null && namedArgument.TypedValue.Value != null)
                        {
                            pathDic.Add(namedArgument.TypedValue.Value.ToString(), value.ToString());
                        }
                    }
                    else
                    {
                        pathDic.Add(property.Name, value.ToString());
                    }
                }
            }
            string strPath = pathDic.DictionaryToString();
            string localPath = ApiUrls.queryHistoryShadowDevice.Replace("?", $"?{strPath}");
            HttpRequestMessage requestMessage = HttpHelper.SetRequestMessage(AuthContext.ClientInfo.Host, localPath, "GET", new Dictionary(), headerDic);
            //此处为智障代码切记小心
            if (requestMessage.Content != null)
            {
                requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            }
            //获取证书
            var cer = AuthContext.SSLConfig.X509Certificate2;
            var result = HttpHelper.GetResponse(requestMessage, cer);
            if (result == null)
            {
                //处理异常信息
                ErrorCallBack(HttpHelper.ApiException);
                return null;
            }
            return result;
        }

        //查询设备服务信息
        public DeviceCapabilitySource QueryDeviceCapability(QueryDeviceCapabilitiesInDTO filter, Action ErrorCallBack)
        {
            if (filter is null)
            {
                throw new NullReferenceException("filter 不能为Null");
            }
            //获取accessToken信息
            ApiAuthInfo apiAuthInfo = _authentication.GetApiAuth(ErrorCallBack);
            if (apiAuthInfo == null)
            {
                return null;
            }
            //构建请求需要的header和body
            //Headers
            Dictionary headerDic = new Dictionary
            {
                { "app_key",AuthContext.ClientInfo.AppId},
                { "Authorization",$"{apiAuthInfo.TokenType} {apiAuthInfo.AccessToken}"}
            };
            //Body
            Dictionary pathDic = new Dictionary();
            //遍历获取对应实体的所有当前类自身属性
            Type type = filter.GetType();
            System.Reflection.PropertyInfo[] properties = type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);
            foreach (var property in properties)
            {
                var value = property.GetValue(filter);
                if (!(value is null))
                {
                    var customAttribute = property.CustomAttributes.FirstOrDefault(x => x.AttributeType == typeof(Newtonsoft.Json.JsonPropertyAttribute));
                    if (customAttribute != null)
                    {
                        //获取到符合条件的参数信息
                        var namedArgument = customAttribute.NamedArguments.FirstOrDefault(x => x.MemberName == "PropertyName");
                        //判定参数名称参数对应的别名名称不为空
                        if (namedArgument != null && namedArgument.TypedValue.Value != null)
                        {
                            pathDic.Add(namedArgument.TypedValue.Value.ToString(), value.ToString());
                        }
                    }
                    else
                    {
                        pathDic.Add(property.Name, value.ToString());
                    }
                }
            }
            string strPath = pathDic.DictionaryToString();
            string localPath = ApiUrls.queryDeviceServices.Replace("?", $"?{strPath}");
            HttpRequestMessage requestMessage = HttpHelper.SetRequestMessage(AuthContext.ClientInfo.Host, localPath, "GET", new Dictionary(), headerDic);
            //此处为智障代码切记小心
            if (requestMessage.Content != null)
            {
                requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            }
            //获取证书
            var cer = AuthContext.SSLConfig.X509Certificate2;
            var result = HttpHelper.GetResponse(requestMessage, cer);
            if (result == null)
            {
                //处理异常信息
                ErrorCallBack(HttpHelper.ApiException);
                return null;
            }
            return result;
        }
    }
} 
  

下发命令代码如下:

using HandyC.HW.Tools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace HandyC.HW.Data
{
    /// 
    /// 设备命令数据处理类
    /// 
    public class DeviceCommand: IDeviceCommand
    {
        private IAuthentication _authentication;
        public DeviceCommand(IAuthentication authentication)
        {
            _authentication = authentication;
        }
        //创建设备命令
        public PostDeviceCommandOutDTO2 CreateDeviceCommand(PostDeviceCommandInDTO2 dataComand, Action ErrorCallBack)
        {
            if (dataComand is null)
            {
                throw new NullReferenceException("dataComand 不能为Null");
            }
            //获取accessToken信息
            ApiAuthInfo apiAuthInfo = _authentication.GetApiAuth(ErrorCallBack);
            if (apiAuthInfo == null)
            {
                return null;
            }
            //构建请求需要的header和body
            //Headers
            Dictionary headerDic = new Dictionary
            {
                { "app_key",AuthContext.ClientInfo.AppId},
                { "Authorization",$"{apiAuthInfo.TokenType} {apiAuthInfo.AccessToken}"}
            };
            //Body
            string strJson = dataComand.ObjectToJson();
            HttpRequestMessage requestMessage = HttpHelper.SetRequestMessage(AuthContext.ClientInfo.Host, ApiUrls.createDeviceCmd, "POST", strJson, headerDic);
            //此处为智障代码切记小心
            if (requestMessage.Content != null)
            {
                requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            }
            //获取证书
            var cer = AuthContext.SSLConfig.X509Certificate2;
            var result = HttpHelper.GetResponse(requestMessage, cer);
            if (result == null)
            {
                //处理异常信息
                ErrorCallBack(HttpHelper.ApiException);
                return null;
            }
            return result;
        }

        //查询设备命令
        public QueryDeviceCommandOutDTO2 QueryDeviceCommand(QueryDeviceCommandInDTO2 filter, Action ErrorCallBack)
        {
            if (filter is null)
            {
                throw new NullReferenceException("filter 不能为Null");
            }
            //获取accessToken信息
            ApiAuthInfo apiAuthInfo = _authentication.GetApiAuth(ErrorCallBack);
            if (apiAuthInfo == null)
            {
                return null;
            }
            //构建请求需要的header和body
            //Headers
            Dictionary headerDic = new Dictionary
            {
                { "app_key",AuthContext.ClientInfo.AppId},
                { "Authorization",$"{apiAuthInfo.TokenType} {apiAuthInfo.AccessToken}"}
            };
            //Body
            Dictionary dataDic = new Dictionary();
            //Queries
            Dictionary pathDic = new Dictionary();
            //遍历获取对应实体的所有当前类自身属性
            Type type = filter.GetType();
            System.Reflection.PropertyInfo[] properties = type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);
            foreach (var property in properties)
            {
                var value = property.GetValue(filter);
                if (!(value is null))
                {
                    var customAttribute = property.CustomAttributes.FirstOrDefault(x => x.AttributeType == typeof(Newtonsoft.Json.JsonPropertyAttribute));
                    if (customAttribute != null)
                    {
                        //获取到符合条件的参数信息
                        var namedArgument = customAttribute.NamedArguments.FirstOrDefault(x => x.MemberName == "PropertyName");
                        //判定参数名称参数对应的别名名称不为空
                        if (namedArgument != null && namedArgument.TypedValue.Value != null)
                        {
                            pathDic.Add(namedArgument.TypedValue.Value.ToString(), value.ToString());
                        }
                    }
                    else
                    {
                        pathDic.Add(property.Name, value.ToString());
                    }
                }
            }
            string queryStr = pathDic.DictionaryToString();
            string localPath = ApiUrls.queryDeviceCmd.Replace("?", $"?{queryStr}");
            HttpRequestMessage requestMessage = HttpHelper.SetRequestMessage(AuthContext.ClientInfo.Host, localPath, "GET", dataDic, headerDic);
            //此处为智障代码切记小心
            if (requestMessage.Content != null)
            {
                requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            }
            //获取证书
            var cer = AuthContext.SSLConfig.X509Certificate2;
            var result = HttpHelper.GetResponse(requestMessage, cer);
            if (result == null)
            {
                //处理异常信息
                ErrorCallBack(HttpHelper.ApiException);
                return null;
            }
            return result;
        }

        //修改设备命令
        public ModifyDeviceCommandOutDTO ModifyDeviceCommand(ModifyDeviceCommandInDTO filter,string deviceCommandId, Action ErrorCallBack)
        {
            if (filter is null)
            {
                throw new NullReferenceException("filter 不能为Null");
            }
            //获取accessToken信息
            ApiAuthInfo apiAuthInfo = _authentication.GetApiAuth(ErrorCallBack);
            if (apiAuthInfo == null)
            {
                return null;
            }
            //构建请求需要的header和body
            //Headers
            Dictionary headerDic = new Dictionary
            {
                { "app_key",AuthContext.ClientInfo.AppId},
                { "Authorization",$"{apiAuthInfo.TokenType} {apiAuthInfo.AccessToken}"}
            };
            //Body
            string strJson = filter.ObjectToJson();
            string localPath = ApiUrls.modifyDeviceCmd.Replace("{deviceCommandId}", deviceCommandId);
            HttpRequestMessage requestMessage = HttpHelper.SetRequestMessage(AuthContext.ClientInfo.Host, localPath, "PUT", strJson, headerDic);
            //此处为智障代码切记小心
            if (requestMessage.Content != null)
            {
                requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            }
            //获取证书
            var cer = AuthContext.SSLConfig.X509Certificate2;
            var result = HttpHelper.GetResponse(requestMessage, cer);
            if (result == null)
            {
                //处理异常信息
                ErrorCallBack(HttpHelper.ApiException);
                return null;
            }
            return result;
        }

        //查询特定设备命令状态
        public DeviceCommandRespV4 QueryDeviceCommandStatus(string deviceId, string commandId, Action ErrorCallBack)
        {
            if (string.IsNullOrEmpty(deviceId))
            {
                throw new NullReferenceException("deviceId 不能为Null");
            }
            if (string.IsNullOrEmpty(commandId))
            {
                throw new NullReferenceException("commandId 不能为Null");
            }
            //获取accessToken信息
            ApiAuthInfo apiAuthInfo = _authentication.GetApiAuth(ErrorCallBack);
            if (apiAuthInfo == null)
            {
                return null;
            }
            //构建请求需要的header和body
            //Headers
            Dictionary headerDic = new Dictionary
            {
                { "app_key",AuthContext.ClientInfo.AppId},
                { "Authorization",$"{apiAuthInfo.TokenType} {apiAuthInfo.AccessToken}"}
            };
            //Body
            Dictionary dataDic = new Dictionary();
            //Path
            string localPath = ApiUrls.queryDeviceCmdStatus.Replace("{deviceId}", deviceId).Replace("{commandId}",commandId);
            HttpRequestMessage requestMessage = HttpHelper.SetRequestMessage(AuthContext.ClientInfo.Host, localPath, "GET", dataDic, headerDic);
            //此处为智障代码切记小心
            if (requestMessage.Content != null)
            {
                requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            }
            //获取证书
            var cer = AuthContext.SSLConfig.X509Certificate2;
            var result = HttpHelper.GetResponse(requestMessage, cer);
            if (result == null)
            {
                //处理异常信息
                ErrorCallBack(HttpHelper.ApiException);
                return null;
            }
            return result;
        }
        //批量创建设备命令

        //创建设备命令撤销任务
        public CreateDeviceCmdCancelTaskOutDTO CreateDeviceCmdCancelTask(CreateDeviceCmdCancelTaskInDTO dataComand, Action ErrorCallBack)
        {
            if (dataComand is null)
            {
                throw new NullReferenceException("dataComand 不能为Null");
            }
            //获取accessToken信息
            ApiAuthInfo apiAuthInfo = _authentication.GetApiAuth(ErrorCallBack);
            if (apiAuthInfo == null)
            {
                return null;
            }
            //构建请求需要的header和body
            //Headers
            Dictionary headerDic = new Dictionary
            {
                { "app_key",AuthContext.ClientInfo.AppId},
                { "Authorization",$"{apiAuthInfo.TokenType} {apiAuthInfo.AccessToken}"}
            };
            //Body
            string strJson = dataComand.ObjectToJson();
            HttpRequestMessage requestMessage = HttpHelper.SetRequestMessage(AuthContext.ClientInfo.Host, ApiUrls.createDeviceCancleTasks, "POST", strJson, headerDic);
            //此处为智障代码切记小心
            if (requestMessage.Content != null)
            {
                requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            }
            //获取证书
            var cer = AuthContext.SSLConfig.X509Certificate2;
            var result = HttpHelper.GetResponse(requestMessage, cer);
            if (result == null)
            {
                //处理异常信息
                ErrorCallBack(HttpHelper.ApiException);
                return null;
            }
            return result;
        }
        //查询设备命令撤销任务
        public QueryDeviceCmdCancelTaskOutDTO2 QueryDeviceCommandTask(QueryDeviceCmdCancelTaskInDTO2 filter,Action ErrorCallBack)
        {
            if (filter is null)
            {
                throw new NullReferenceException("filter 不能为Null");
            }
            //获取accessToken信息
            ApiAuthInfo apiAuthInfo = _authentication.GetApiAuth(ErrorCallBack);
            if (apiAuthInfo == null)
            {
                return null;
            }
            //构建请求需要的header和body
            //Headers
            Dictionary headerDic = new Dictionary
            {
                { "app_key",AuthContext.ClientInfo.AppId},
                { "Authorization",$"{apiAuthInfo.TokenType} {apiAuthInfo.AccessToken}"}
            };
            //Body
            Dictionary dataDic = new Dictionary();
            //遍历获取对应实体的所有当前类自身属性
            Type type = filter.GetType();
            System.Reflection.PropertyInfo[] properties = type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);
            foreach (var property in properties)
            {
                var value = property.GetValue(filter);
                if (!(value is null))
                {
                    dataDic.Add(property.Name, value.ToString());
                }
            }
            HttpRequestMessage requestMessage = HttpHelper.SetRequestMessage(AuthContext.ClientInfo.Host, ApiUrls.queryDeviceCancleTasks, "GET", dataDic, headerDic);
            //此处为智障代码切记小心
            if (requestMessage.Content != null)
            {
                requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            }
            //获取证书
            var cer = AuthContext.SSLConfig.X509Certificate2;
            var result = HttpHelper.GetResponse(requestMessage, cer);
            if (result == null)
            {
                //处理异常信息
                ErrorCallBack(HttpHelper.ApiException);
                return null;
            }
            return result;
        }
        //设备服务调用
    }
} 
  

设备管理代码如下:
























































































using GalaSoft.MvvmLight.Messaging;
using HandyC.HW.Datas;
using HandyC.HW.ViewModels;
using HandyControl.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace HandyC.HW.Views
{
    /// 
    /// DeviceManage.xaml 的交互逻辑
    /// 
    public partial class DeviceManage
    {
        public DeviceManage()
        {
            InitializeComponent();
            InitialMessager();
        }

        /// 
        /// 初始化事件注册
        /// 
        private void InitialMessager()
        {
            //避免token值重名使用
            this.Loaded += (e, arg) => {
                Messenger.Default.Register(this, MessageToken.NewDeviceDialog, NewDeviceDialog);
                Messenger.Default.Register(this, MessageToken.QueryLastestDeviceData, LastestDeviceData);
            };
            this.Unloaded += (e, arg) =>
            {
                Messenger.Default.Unregister(this, MessageToken.NewDeviceDialog);
                Messenger.Default.Unregister(this, MessageToken.QueryLastestDeviceData);
            };
        }
        /// 
        /// 构建设备最新数据监听窗体
        /// 
        /// 设备数据信息
        private void LastestDeviceData(DeviceInfoViewModel obj)
        {
            if (obj != null)
            {
                var deviceDynamicData = new DeviceDynamicData(obj);
                deviceDynamicData.Show();
            }
        }

        private void NewDeviceDialog(DeviceInfoViewModel model)
        {
            if (model != null)
            {
                //消息明细展示框
                Dialog.Show(new DeviceDetials(model), MessageToken.MainToken);
                //加载框
                //Dialog.Show(new CommonLoading());
                //HandyControl.Controls.MessageBox.Show($"查看设备:{model.Name}信息");
            }
        }
    }
}
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using HandyC.HW.Data;
using HandyC.HW.Datas;
using HandyC.HW.Service;
using HandyC.HW.Tools;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using CommonServiceLocator;

namespace HandyC.HW.ViewModels
{
    /// 
    /// 设备管理视图实体
    /// 
    public class DeviceManageViewModel : ViewModelBase
    {
        private readonly IDeviceInfoService _deviceInfoService;
        public DeviceManageViewModel(IDeviceInfoService deviceInfo)
        {
            _deviceInfoService = deviceInfo;
            //获取初始化构造数据
            InitialData();
        }

        /// 
        /// 初始化设定页面数据
        /// 
        private void InitialData()
        {
            var filter = new QueryBatchDevicesInfoInDTO
            {
                PageNo = 0,
                PageSize = 20
            };
            //开启加载
            Messenger.Default.Send(true, MessageToken.LoadingToken);
            Task.Factory.StartNew(() =>
            {
                //实例化
                var datas = _deviceInfoService.QueryBatchDevicesInfo(filter, ErrorCellbackMethod);
                if (datas != null)
                {
                    //数据转化
                    DeviceInfos = AutoMapper.Mapper.Map, List>(datas.Devices);
                    DeviceSummary.GetSummaryData(DeviceInfos);
                }
                //关闭加载
                Messenger.Default.Send(false, MessageToken.LoadingToken);
            });

            ContextMenus = new List
            {
                new ContextMenuViewModel(new RelayCommand(QueryDeviceInfo))
                {
                    Header="查看",
                    IsEnable = true
                },
                //new ContextMenuViewModel(new RelayCommand(QueryDeviceInfo))
                //{
                //    Header="编辑",
                //    IsEnable = true
                //},
                new ContextMenuViewModel(new RelayCommand(QueryLastest))
                {
                    Header="动态",
                    IsEnable = true
                }
            };
        }

        /// 
        /// 查询设备对应的最新数据
        /// 
        /// 
        private void QueryLastest(DeviceInfoViewModel obj)
        {
            if (obj != null)
            {
                DeviceDynamicViewModel dyVm = (DeviceDynamicViewModel)ServiceLocator.Current.GetInstance(typeof(DeviceDynamicViewModel));
                if (dyVm != null)
                {
                    dyVm.InitialDeviceId(obj);
                }
                Messenger.Default.Send(obj, MessageToken.QueryLastestDeviceData);
            }
        }

        /// 
        /// 网络请求服务异常结果处理
        /// 
        /// 
        private void ErrorCellbackMethod(object obj)
        {
            string result = $"{this.GetType().Name} InitialData:{obj.ToString()}";
            OperationResult operation = new OperationResult(result);
            Messenger.Default.Send(operation, MessageToken.MsgToken);
        }

        private List deviceInfos;
        /// 
        /// 设备列表
        /// 
        public List DeviceInfos
        {
            get
            {
                if (deviceInfos == null)
                {
                    deviceInfos = new List();
                }
                return deviceInfos;
            }
            set
            {
                deviceInfos = value;
                RaisePropertyChanged();
            }
        }

        private DeviceSummaryViewModel deviceSummary;
        /// 
        /// 设备信息汇总
        /// 
        public DeviceSummaryViewModel DeviceSummary
        {
            get
            {
                if (deviceSummary == null)
                {
                    deviceSummary = new DeviceSummaryViewModel();
                }
                return deviceSummary;
            }
            set
            {
                deviceSummary = value;
                RaisePropertyChanged();
            }
        }

        private List contextMenus;
        /// 
        /// 设备信息菜单实体
        /// 
        public List ContextMenus
        {
            get
            {
                if (contextMenus == null)
                {
                    contextMenus = new List();
                }
                return contextMenus;
            }
            set
            {
                contextMenus = value;
                RaisePropertyChanged();
            }
        }

        /// 
        /// 查询设备详信息
        /// 
        /// 设备实体
        private void QueryDeviceInfo(DeviceInfoViewModel entity)
        {
            if (entity != null)
            {
                Messenger.Default.Send(entity, MessageToken.NewDeviceDialog);
            }
        }

    }
}

设备历史信息代码如下:


    
        
            
            
            
        
        
            
                
                
                
            
        
        
            
                
                
                
                
                
                
                    
                        
                            
using GalaSoft.MvvmLight.Messaging;
using HandyC.HW.Datas;
using HandyC.HW.ViewModels;
using HandyControl.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace HandyC.HW.Views
{
    /// 
    /// DataHistory.xaml 的交互逻辑
    /// 
    public partial class DataHistory
    {
        public DataHistory()
        {
            InitializeComponent();
            InitialMsg();
        }

        private void InitialMsg()
        {
            //避免token值重名使用
            this.Loaded += (e, arg) => {
                Messenger.Default.Register(this, MessageToken.NewDeviceDataDetails, NewDeviceDataDialog);
            };
            this.Unloaded += (e, arg) => Messenger.Default.Unregister(this, MessageToken.NewDeviceDataDetails);
        }
        /// 
        /// 显示数据信息明细
        /// 
        /// 
        private void NewDeviceDataDialog(DeviceDataViewModel obj)
        {
            if (obj != null)
            {
                Dialog.Show(new DeviceDataInfo(obj), MessageToken.MainToken);
            }
        }
    }
}
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using HandyC.HW.Data;
using HandyC.HW.Datas;
using HandyC.HW.Service;
using HandyC.HW.Tools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;

namespace HandyC.HW.ViewModels
{
    /// 
    /// 历史数据实体实体
    /// 
    public class DataHistoryViewModel : ViewModelBase
    {
        private readonly IDataCollectionService _collectionService;
        public DataHistoryViewModel(IDataCollectionService collectionService)
        {
            _collectionService = collectionService;
            InitialData();
        }
        /// 
        /// 初始化数据
        /// 
        private void InitialData()
        {
            Task.Factory.StartNew(() =>
            {
                //获取设备信息
                Devices = GetDevices();
                //默认获取第一个设备的历史数据
                if (Devices.Count > 0)
                {
                    SelectedDevice = Devices.FirstOrDefault();
                    //获取设备服务列表
                    DeviceServices = GetDeviceServices(SelectedDevice);
                    pageSize = 10;//默认设定为10  
                    PageNo = 1;//设定默认起始页码
                }
            });
            //设定当前默认数据列表配置值
        }
        /// 
        /// 获取设备服务列表
        /// 
        /// 当前设备
        /// 
        private List GetDeviceServices(DeviceInfoViewModel selectedDevice)
        {
            List services = new List();
            List deviceCapabilitys;
            var filter = new QueryDeviceCapabilitiesInDTO
            {
                DeviceId = selectedDevice.DeviceId,
                GatewayId = selectedDevice.GatewayId
            };
            var datas = _collectionService.QueryDeviceCapability(filter, ErrorCellbackMethod);
            if (datas != null)
            {
                deviceCapabilitys = AutoMapper.Mapper.Map, List>(datas.DeviceCapabilities);
            }
            else
            {
                deviceCapabilitys = new List();
            }
            if (deviceCapabilitys == null || deviceCapabilitys.Count < 0)
            {
                return services;
            }

            DeviceCapabilityViewModel deviceCapability = deviceCapabilitys.FirstOrDefault(x => x.DeviceId == selectedDevice.DeviceId);
            if (deviceCapability != null)
            {
                services = deviceCapability.ServiceCapabilities;
            }

            return services;
        }

        /// 
        /// 获取当前设备列表信息
        /// 
        /// 
        private List GetDevices()
        {
            List result;
            //获取当前默认设备对应的数据信息
            var filter = new QueryBatchDevicesInfoInDTO
            {
                PageNo = 0,
                PageSize = 1000//默认获取0-1000范围内的设备记录信息
            };
            //实例化
            var datas = _collectionService.QueryBatchDevicesInfo(filter, ErrorCellbackMethod);
            if (datas != null)
            {
                //数据转化
                result = AutoMapper.Mapper.Map, List>(datas.Devices);
            }
            else
            {
                result = new List();
            }
            return result;
        }

        /// 
        /// 网络请求服务异常结果处理
        /// 
        /// 
        private void ErrorCellbackMethod(object obj)
        {
            string result = $"{this.GetType().Name} InitialData:{obj.ToString()}";
            OperationResult operation = new OperationResult(result);
            Messenger.Default.Send(operation, MessageToken.MsgToken);
        }
        #region 页面数据
        private List devices;
        /// 
        /// 设备集合
        /// 
        public List Devices
        {
            get
            {
                if (devices == null)
                {
                    devices = new List();
                }
                return devices;
            }
            set
            {
                devices = value;
                RaisePropertyChanged();
            }
        }

        #endregion
        //Cmds
        private ICommand pageChangedCmd;
        /// 
        /// 当前页变更命令
        /// 
        public ICommand PageChangedCmd
        {
            get
            {
                if (pageChangedCmd == null)
                {
                    pageChangedCmd = new RelayCommand(PageChanged);
                }
                return pageChangedCmd;
            }
            set => pageChangedCmd = value;
        }

        private ICommand searchCmd;
        public ICommand SearchCmd
        {
            get
            {
                if (searchCmd == null)
                {
                    searchCmd = new RelayCommand(SearchData);
                }
                return searchCmd;
            }
        }

        /// 
        /// 查询设备函数
        /// 
        private void SearchData()
        {
            if (PageNo != 1)
            {
                PageNo = 1;
            }
            else
            {
                //获取当前默认设备对应的数据信息
                var filter = new QueryDeviceDataHistoryInDTO
                {
                    PageNo = 0,
                    PageSize = PageSize,
                    DeviceId = SelectedDevice.DeviceId,
                    GatewayId = SelectedDevice.GatewayId,
                    ServiceId = SelectedService.ServiceId
                };
                Refresh(filter);
            }
        }

        #region 分页控件相关属性和函数
        /// 
        /// 当前页变更触发事件
        /// 
        /// 
        private void PageChanged(object obj)
        {
            //获取当前默认设备对应的数据信息
            var filter = new QueryDeviceDataHistoryInDTO
            {
                PageNo = PageNo - 1,
                PageSize = PageSize,
                DeviceId = SelectedDevice.DeviceId,
                GatewayId = SelectedDevice.GatewayId,
                ServiceId = SelectedService.ServiceId
            };
            Refresh(filter);
        }
        /// 
        /// 刷新当前数据列表
        /// 
        public void Refresh(QueryDeviceDataHistoryInDTO filter)
        {
            Task.Factory.StartNew(() =>
            {
                //实例化
                var datas = _collectionService.QueryDeviceDataHistory(filter, ErrorCellbackMethod);
                if (datas != null)
                {
                    TotalCount = datas.TotalCount;
                    MaxPageCount = GetMaxPageCount();
                    DeviceDataSource = AutoMapper.Mapper.Map, List>(datas.DeviceDataHistoryDTOs).ToList();
                }
            });
        }
        /// 
        /// 获取当前最大记录条数
        /// 
        private long GetMaxPageCount()
        {
            long pageCount;
            pageCount = TotalCount / PageSize;
            int result = Convert.ToInt32(TotalCount % PageSize);
            if (result != 0)
            {
                pageCount += 1;
            }

            return pageCount;
        }

        /// 
        /// 查询的记录数量
        /// 
        private long totalCount;
        private long pageNo;
        private long pageSize;
        /// 
        /// 最大显示记录数量
        /// 
        public long MaxPageCount
        {
            get => maxPageCount;
            set
            {
                maxPageCount = value;
                RaisePropertyChanged();
            }
        }
        /// 
        /// 查询的记录数量
        /// 
        public long TotalCount
        {
            get { return totalCount; }
            set
            {
                totalCount = value;
                RaisePropertyChanged();
            }
        }

        /// 
        /// 查询的页码
        /// 
        public long PageNo
        {
            get => pageNo;
            set
            {
                pageNo = value;
                RaisePropertyChanged();
            }
        }
        /// 
        /// 查询每页信息的数量
        /// 
        public long PageSize
        {
            get => pageSize;
            set
            {
                pageSize = value;
                RaisePropertyChanged();
            }
        }
        #endregion

        #region 设备列表
        private List deviceDataSource;
        private DeviceInfoViewModel selectedDevice;
        private long maxPageCount;

        /// 
        /// 设备数据信息集合
        /// 
        public List DeviceDataSource
        {
            get
            {
                if (deviceDataSource == null)
                {
                    deviceDataSource = new List();
                }
                return deviceDataSource;
            }
            set
            {
                deviceDataSource = value;
                RaisePropertyChanged();
            }
        }
        //选中项设备记录
        public DeviceInfoViewModel SelectedDevice
        {
            get => selectedDevice;
            set
            {
                selectedDevice = value;
                RaisePropertyChanged();
            }
        }
        #endregion

        #region 设备服务列表
        private List deviceServices;
        /// 
        /// 设备服务能力列表
        /// 
        public List DeviceServices
        {
            get
            {
                if (deviceServices == null)
                {
                    deviceServices = new List();
                }
                return deviceServices;
            }
            set
            {
                deviceServices = value;
                RaisePropertyChanged();
            }
        }

        private ServiceCapabilityDTO selectedService;

        /// 
        /// 选中设备服务
        /// 
        public ServiceCapabilityDTO SelectedService
        {
            get
            {
                if (selectedService == null)
                {
                    selectedService = new ServiceCapabilityDTO();
                }
                return selectedService;
            }
            set
            {
                selectedService = value;
                RaisePropertyChanged();
            }
        }
        #endregion

    }
} 
  

 

你可能感兴趣的:(物联网,NB-IoT,程序人生,NB-IoT项目实践)