4227| 1
|
[2019参赛作品] 【脑洞大赛】基于NB-IoT的智慧路灯监控系统(PC应用开发) |
作为IoT云平台的数据交互PC客户端,对平台的数据进行展示,实现本地与远程终端的数据交互,进而展现出依赖云平台的应用使用的具体场景,进一步展现云品台的优势。 1、项目结构 整个使用常规的传统的三层架构,同时引入MVVM架构模式,属于混合型架构设计,将各个层次之间实现理论解耦,提高了系统各个层次之间的独立性和可拓展性。 结构说明如下: HandyC.HW:项目实际入口,表现层,实际用户操作逻辑的输入输出部分。 HandyC.HW.ViewModels:与表现层与之对应的视图实体类部分,对用户交互逻辑的主要实现处理模块,同时在该项目中进行相关数据实体和视图实体的相互转换工作。 HandyC.HW.Data:用于处理来自于IoT平台的数据源,为业务层提供需求的数据结果。 HandyC.HW.Service:项目的实际业务逻辑处理,组织数据层提供的数据。 HandyC.HW.Tools:项目整体结构中需要使用到的基础辅助类集合,包括网络请求相关类,缓存,数据序列化和反序列化,特殊数据格式处理等。 对应测试项目与之对应,前缀为Test.*,此处忽略 2、系统组织架构 系统组织架构分为两个大的功能模块,平台监管以及数据采集两个模块,平台监管主要是对设备实时动态进行监管,数据采集,处理来自IOT云平台的历史相关数据并展示。 3、使用技术
4、开发环境与工具
5、功能介绍 设备管理页面的主页面,红框区域内为设备统计,包含了对当前设备的设备类型、设备状态、设备的协议类型的相关统计信息,属于设备总体的一个统计信息。设备列表中展示的是当前的存在的设备,以卡片的方式展示出来,包括设备的名称、设备的型号、设备的编号等预览。 显示设备的详细信息。 设备的实时数据显示页面,能够动态实时请求道IoT平台上的设备下发的最近历史信息。 云平台联动主页中的卡片为一卡片一设备,点击设备卡片,可以对设备进行联动模式控制,可支持三种联动模式,终端联控模式、自动调光模式和分段定时模式。 默认手动模式,可以通过手动直接下发指令到IoT平台,通过平台将命令通知对应的设备执行,点击控制按钮进行云平台挂载设备的开启和关闭。 用户可以通过点击切换至定时模式,设定时间后,将点击发送定时设备,等待设定的命令发送至IoT平台。 命令下发成功是接收到的反馈信息。 自动模式与手动模式的操作类似,用户通过开启和关闭实现对IoT平台上挂载的设备的执行模式的设定,关闭时,设备默认执行,为上一次的模式运行状态,开启时,变更为根据实际的自动条件进行自身状态的控制。 设备历史数据显示页面,主要功能为查询功能,用于显示从IoT平台获取到的当前设备对应的历史记录信息,可通过查询条件进行更加细致数据查找。 点击每条记录的操作列按钮,能够获取到该条记录的详细信息。 下图的页面为命令历史数据的主页面,默认显示第一个设备的相关历史数据,能够查询到多端给设备发送的相关命令指令历史信息。 通过点击每条记录末尾的数据明细,可以查看到当前命令记录的具体信息。 6、核心代码 PC端主要分为两个部分,一个是通过https请求双向认证获取到来自于IoT平台提供的相关Api接口的目标数据,将数据进行处理根据View的需求进行相关的ViewModel处理之后展示到页面中;一个是需要PC端与IoT平台上的挂载设备进行数据交互时,实现本地命令的发送,进而间接控制设备的数据响应。 鉴定权限代码如下:[mw_shl_code=csharp,true]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 { /// <summary> /// 鉴权数据处理类 /// </summary> public class Authentication:IAuthentication { private readonly string accessTokenName = "Authentication"; private ICacheAdapter cache; public Authentication(ICacheAdapter adapter) { cache = adapter; } /// <summary> /// 获取鉴权的数据实例 /// </summary> /// <param name="ErrorCallBack">异常时执行回调</param> /// <returns>权限信息</returns> public ApiAuthInfo GetApiAuth(Action<object> ErrorCallBack) { //判定缓存中是否存在用户项目信息 ApiAuthInfo apiAuthInfo = GetCertificateCache(); if (apiAuthInfo != null) { return apiAuthInfo; } //获取证书 var cer = AuthContext.SSLConfig.X509Certificate2; #region 设定当前请请求 Dictionary<string, string> dataDic = new Dictionary<string, string> { { "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<ApiAuthInfo>(requestMessage,cer); if (apiAuthInfo == null) { //处理异常信息 ErrorCallBack(HttpHelper.ApiException); return apiAuthInfo; } //添加实例类到缓存中 cache.Set(accessTokenName, apiAuthInfo,DateTime.Now.AddSeconds(apiAuthInfo.ExpiresIn)); return apiAuthInfo; } /// <summary> /// 刷新Token值-服务端异常 /// </summary> /// <param name="ErrorCallBack">异常时执行回调</param> /// <returns>权限信息</returns> public ApiAuthInfo RefreshApiAuth(Action<object> ErrorCallBack) { //判定缓存中是否存在用户项目信息 ApiAuthInfo apiAuthInfo = GetCertificateCache(); //若当前缓存中不存在鉴权 if (apiAuthInfo == null) { return null; } //获取证书 var cer = AuthContext.SSLConfig.X509Certificate2; #region 设定当前请请求 Dictionary<string, string> dataDic = new Dictionary<string, string> { {"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<ApiAuthInfo>(requestMessage, cer); if (apiAuthInfo == null) { //处理异常信息 ErrorCallBack(HttpHelper.ApiException); return apiAuthInfo; } //添加实例类到缓存中 cache.Set(accessTokenName, apiAuthInfo, DateTime.Now.AddSeconds(apiAuthInfo.ExpiresIn)); return apiAuthInfo; } /// <summary> ///刷新密钥 ///校验当前密钥是否过期 /// </summary> /// <returns>权限信息</returns> public ApiAuthInfo GetCertificateCache() { ApiAuthInfo apiAuth = cache.Get<ApiAuthInfo>(accessTokenName); return apiAuth; } } } [/mw_shl_code] 获取设备信息代码如下:[mw_shl_code=csharp,true]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 { /// <summary> /// 数据采集操作实体 /// </summary> public class DataCollection: IDataCollection { private IAuthentication _authentication; public DataCollection(IAuthentication authentication) { _authentication = authentication; } //查询单个设备信息 public QuerySingleDeviceInfoOutDTO QuerySingleDeviceInfo(string deviceId, Action<object> 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<string, string> headerDic = new Dictionary<string, string> { { "app_key",AuthContext.ClientInfo.AppId}, { "Authorization",$"{apiAuthInfo.TokenType} {apiAuthInfo.AccessToken}"} }; //Body Dictionary<string, string> dataDic = new Dictionary<string, string>(); 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<QuerySingleDeviceInfoOutDTO>(requestMessage, cer); if (result == null) { //处理异常信息 ErrorCallBack(HttpHelper.ApiException); return null; } return result; } //批量查询设备信息列表 public QueryBatchDevicesInfoOutDTO QueryBatchDevicesInfo(QueryBatchDevicesInfoInDTO filter, Action<object> 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<string, string> headerDic = new Dictionary<string, string> { { "app_key",AuthContext.ClientInfo.AppId}, { "Authorization",$"{apiAuthInfo.TokenType} {apiAuthInfo.AccessToken}"} }; //Body Dictionary<string, string> pathDic = new Dictionary<string, string>(); //遍历获取对应实体的所有当前类自身属性 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<string, string>(), 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<QueryBatchDevicesInfoOutDTO>(requestMessage, cer); if (result == null) { //处理异常信息 ErrorCallBack(HttpHelper.ApiException); return null; } return result; } //查询设备历史信息 public DeviceDataSource QueryDeviceDataHistory(QueryDeviceDataHistoryInDTO filter, Action<object> 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<string, string> headerDic = new Dictionary<string, string> { { "app_key",AuthContext.ClientInfo.AppId}, { "Authorization",$"{apiAuthInfo.TokenType} {apiAuthInfo.AccessToken}"} }; //Body Dictionary<string, string> pathDic = new Dictionary<string, string>(); //遍历获取对应实体的所有当前类自身属性 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<string, string>(), headerDic); //此处为智障代码切记小心 if (requestMessage.Content != null) { requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); } //获取证书 var cer = AuthContext.SSLConfig.X509Certificate2; var result = HttpHelper.GetResponse<DeviceDataSource>(requestMessage, cer); if (result == null) { //处理异常信息 ErrorCallBack(HttpHelper.ApiException); return null; } return result; } //查询影子历史数据信息 public DeviceDesiredSource QueryDeviceDesiredHistory(QueryDeviceDesiredHistoryInDTO filter, Action<object> 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<string, string> headerDic = new Dictionary<string, string> { { "app_key",AuthContext.ClientInfo.AppId}, { "Authorization",$"{apiAuthInfo.TokenType} {apiAuthInfo.AccessToken}"} }; //Body Dictionary<string, string> pathDic = new Dictionary<string, string>(); //遍历获取对应实体的所有当前类自身属性 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<string, string>(), headerDic); //此处为智障代码切记小心 if (requestMessage.Content != null) { requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); } //获取证书 var cer = AuthContext.SSLConfig.X509Certificate2; var result = HttpHelper.GetResponse<DeviceDesiredSource>(requestMessage, cer); if (result == null) { //处理异常信息 ErrorCallBack(HttpHelper.ApiException); return null; } return result; } //查询设备服务信息 public DeviceCapabilitySource QueryDeviceCapability(QueryDeviceCapabilitiesInDTO filter, Action<object> 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<string, string> headerDic = new Dictionary<string, string> { { "app_key",AuthContext.ClientInfo.AppId}, { "Authorization",$"{apiAuthInfo.TokenType} {apiAuthInfo.AccessToken}"} }; //Body Dictionary<string, string> pathDic = new Dictionary<string, string>(); //遍历获取对应实体的所有当前类自身属性 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<string, string>(), headerDic); //此处为智障代码切记小心 if (requestMessage.Content != null) { requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); } //获取证书 var cer = AuthContext.SSLConfig.X509Certificate2; var result = HttpHelper.GetResponse<DeviceCapabilitySource>(requestMessage, cer); if (result == null) { //处理异常信息 ErrorCallBack(HttpHelper.ApiException); return null; } return result; } } }[/mw_shl_code] 下发命令代码如下:[mw_shl_code=csharp,true]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 { /// <summary> /// 设备命令数据处理类 /// </summary> public class DeviceCommand: IDeviceCommand { private IAuthentication _authentication; public DeviceCommand(IAuthentication authentication) { _authentication = authentication; } //创建设备命令 public PostDeviceCommandOutDTO2 CreateDeviceCommand(PostDeviceCommandInDTO2 dataComand, Action<object> 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<string, string> headerDic = new Dictionary<string, string> { { "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<PostDeviceCommandOutDTO2>(requestMessage, cer); if (result == null) { //处理异常信息 ErrorCallBack(HttpHelper.ApiException); return null; } return result; } //查询设备命令 public QueryDeviceCommandOutDTO2 QueryDeviceCommand(QueryDeviceCommandInDTO2 filter, Action<object> 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<string, string> headerDic = new Dictionary<string, string> { { "app_key",AuthContext.ClientInfo.AppId}, { "Authorization",$"{apiAuthInfo.TokenType} {apiAuthInfo.AccessToken}"} }; //Body Dictionary<string, string> dataDic = new Dictionary<string, string>(); //Queries Dictionary<string, string> pathDic = new Dictionary<string, string>(); //遍历获取对应实体的所有当前类自身属性 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<QueryDeviceCommandOutDTO2>(requestMessage, cer); if (result == null) { //处理异常信息 ErrorCallBack(HttpHelper.ApiException); return null; } return result; } //修改设备命令 public ModifyDeviceCommandOutDTO ModifyDeviceCommand(ModifyDeviceCommandInDTO filter,string deviceCommandId, Action<object> 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<string, string> headerDic = new Dictionary<string, string> { { "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<ModifyDeviceCommandOutDTO>(requestMessage, cer); if (result == null) { //处理异常信息 ErrorCallBack(HttpHelper.ApiException); return null; } return result; } //查询特定设备命令状态 public DeviceCommandRespV4 QueryDeviceCommandStatus(string deviceId, string commandId, Action<object> 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<string, string> headerDic = new Dictionary<string, string> { { "app_key",AuthContext.ClientInfo.AppId}, { "Authorization",$"{apiAuthInfo.TokenType} {apiAuthInfo.AccessToken}"} }; //Body Dictionary<string, string> dataDic = new Dictionary<string, string>(); //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<DeviceCommandRespV4>(requestMessage, cer); if (result == null) { //处理异常信息 ErrorCallBack(HttpHelper.ApiException); return null; } return result; } //批量创建设备命令 //创建设备命令撤销任务 public CreateDeviceCmdCancelTaskOutDTO CreateDeviceCmdCancelTask(CreateDeviceCmdCancelTaskInDTO dataComand, Action<object> 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<string, string> headerDic = new Dictionary<string, string> { { "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<CreateDeviceCmdCancelTaskOutDTO>(requestMessage, cer); if (result == null) { //处理异常信息 ErrorCallBack(HttpHelper.ApiException); return null; } return result; } //查询设备命令撤销任务 public QueryDeviceCmdCancelTaskOutDTO2 QueryDeviceCommandTask(QueryDeviceCmdCancelTaskInDTO2 filter,Action<object> 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<string, string> headerDic = new Dictionary<string, string> { { "app_key",AuthContext.ClientInfo.AppId}, { "Authorization",$"{apiAuthInfo.TokenType} {apiAuthInfo.AccessToken}"} }; //Body Dictionary<string, string> dataDic = new Dictionary<string, string>(); //遍历获取对应实体的所有当前类自身属性 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<QueryDeviceCmdCancelTaskOutDTO2>(requestMessage, cer); if (result == null) { //处理异常信息 ErrorCallBack(HttpHelper.ApiException); return null; } return result; } //设备服务调用 } } [/mw_shl_code] 设备历史信息查询代码如下: [mw_shl_code=csharp,true]<Grid x:Class="HandyC.HW.Views.DeviceManage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mv="clr-namespace:HandyC.HW.ViewModels;assembly=HandyC.HW.ViewModels" xmlns:uc="clr-namespace:HandyC.HW.Views" xmlns:hc="https://handyorg.github.io/handycontrol" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" Margin="10" DataContext="{Binding DeviceManage, Mode=OneWay, Source={StaticResource Locator}}"> <Grid.RowDefinitions> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="auto"></RowDefinition> </Grid.RowDefinitions> <GroupBox Effect="{StaticResource EffectShadow2}" Grid.Row="0" Header="设备统计" Padding="10,10,0,10" Background="{DynamicResource RegionBrush}" Style="{DynamicResource GroupBoxStyle}"> <UniformGrid Rows="1"> <Border Padding="20,10" CornerRadius="2" Background="{DynamicResource BackgroundBrush}" Margin="30,0"> <DockPanel> <TextBlock Text="设备类型" DockPanel.Dock="Top" Margin="0,10" FontSize="14"></TextBlock> <TextBlock Text="{Binding DeviceSummary.DeviceTypes.Count}" Margin="20,0" FontSize="36" VerticalAlignment="Center" DockPanel.Dock="Left"></TextBlock> <ItemsControl DockPanel.Dock="Right" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" ItemsSource="{Binding DeviceSummary.DeviceTypes,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"> <ItemsControl.ItemTemplate> <DataTemplate> <UniformGrid Rows="1" HorizontalAlignment="Center"> <TextBlock Text="{Binding PropertyName, StringFormat=\{0\}:}" FontSize="10"></TextBlock> <TextBlock Text="{Binding Count}" FontSize="10"></TextBlock> </UniformGrid> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel></StackPanel> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl> </DockPanel> </Border> <Border Padding="20,10" CornerRadius="2" Background="{DynamicResource BackgroundBrush}" Margin="30,0"> <DockPanel> <TextBlock Text="设备状态" DockPanel.Dock="Top" Margin="0,10" FontSize="14"></TextBlock> <TextBlock Text="{Binding DeviceSummary.DeviceStatus.Count}" Margin="20,0" FontSize="36" VerticalAlignment="Center" DockPanel.Dock="Left"></TextBlock> <ItemsControl DockPanel.Dock="Right" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" ItemsSource="{Binding DeviceSummary.DeviceStatus,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"> <ItemsControl.ItemTemplate> <DataTemplate> <UniformGrid Rows="1" HorizontalAlignment="Center"> <TextBlock Text="{Binding PropertyName, StringFormat=\{0\}:}" FontSize="10"></TextBlock> <TextBlock Text="{Binding Count}" FontSize="10"></TextBlock> </UniformGrid> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel></StackPanel> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl> </DockPanel> </Border> <Border Padding="20,10" CornerRadius="2" Background="{DynamicResource BackgroundBrush}" Margin="30,0"> <DockPanel> <TextBlock Text="协议类型" DockPanel.Dock="Top" Margin="0,10" FontSize="14"></TextBlock> <TextBlock Text="{Binding DeviceSummary.DeviceProtocolType.Count}" Margin="20,0" FontSize="36" VerticalAlignment="Center" DockPanel.Dock="Left"></TextBlock> <ItemsControl DockPanel.Dock="Right" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" ItemsSource="{Binding DeviceSummary.DeviceProtocolType,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"> <ItemsControl.ItemTemplate> <DataTemplate> <UniformGrid Rows="1" HorizontalAlignment="Center"> <TextBlock Text="{Binding PropertyName, StringFormat=\{0\}:}" FontSize="10"></TextBlock> <TextBlock Text="{Binding Count}" FontSize="10"></TextBlock> </UniformGrid> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel></StackPanel> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl> </DockPanel> </Border> </UniformGrid> </GroupBox> <GroupBox Effect="{StaticResource EffectShadow2}" Grid.Row="1" Header="设备列表" Background="{DynamicResource RegionBrush}" Style="{DynamicResource GroupBoxStyle}"> <ItemsControl ItemsSource="{Binding DeviceInfos}" Margin="10"> <ItemsControl.ItemTemplate> <DataTemplate DataType="{x:Type mv:DeviceInfoViewModel}"> <uc:DeviceInfo DataContext="{Binding}"></uc:DeviceInfo> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <WrapPanel Orientation="Horizontal"></WrapPanel> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl> </GroupBox> </Grid>[/mw_shl_code] [mw_shl_code=csharp,true]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 { /// <summary> /// 设备管理视图实体 /// </summary> public class DeviceManageViewModel : ViewModelBase { private readonly IDeviceInfoService _deviceInfoService; public DeviceManageViewModel(IDeviceInfoService deviceInfo) { _deviceInfoService = deviceInfo; //获取初始化构造数据 InitialData(); } /// <summary> /// 初始化设定页面数据 /// </summary> 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<QuerySingleDeviceInfoOutDTO>, List<DeviceInfoViewModel>>(datas.Devices); DeviceSummary.GetSummaryData(DeviceInfos); } //关闭加载 Messenger.Default.Send(false, MessageToken.LoadingToken); }); ContextMenus = new List<ContextMenuViewModel> { new ContextMenuViewModel(new RelayCommand<DeviceInfoViewModel>(QueryDeviceInfo)) { Header="查看", IsEnable = true }, //new ContextMenuViewModel(new RelayCommand<DeviceInfoViewModel>(QueryDeviceInfo)) //{ // Header="编辑", // IsEnable = true //}, new ContextMenuViewModel(new RelayCommand<DeviceInfoViewModel>(QueryLastest)) { Header="动态", IsEnable = true } }; } /// <summary> /// 查询设备对应的最新数据 /// </summary> /// <param name="obj"></param> 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); } } /// <summary> /// 网络请求服务异常结果处理 /// </summary> /// <param name="obj"></param> 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<DeviceInfoViewModel> deviceInfos; /// <summary> /// 设备列表 /// </summary> public List<DeviceInfoViewModel> DeviceInfos { get { if (deviceInfos == null) { deviceInfos = new List<DeviceInfoViewModel>(); } return deviceInfos; } set { deviceInfos = value; RaisePropertyChanged(); } } private DeviceSummaryViewModel deviceSummary; /// <summary> /// 设备信息汇总 /// </summary> public DeviceSummaryViewModel DeviceSummary { get { if (deviceSummary == null) { deviceSummary = new DeviceSummaryViewModel(); } return deviceSummary; } set { deviceSummary = value; RaisePropertyChanged(); } } private List<ContextMenuViewModel> contextMenus; /// <summary> /// 设备信息菜单实体 /// </summary> public List<ContextMenuViewModel> ContextMenus { get { if (contextMenus == null) { contextMenus = new List<ContextMenuViewModel>(); } return contextMenus; } set { contextMenus = value; RaisePropertyChanged(); } } /// <summary> /// 查询设备详信息 /// </summary> /// <param name="entity">设备实体</param> private void QueryDeviceInfo(DeviceInfoViewModel entity) { if (entity != null) { Messenger.Default.Send(entity, MessageToken.NewDeviceDialog); } } } }[/mw_shl_code] [mw_shl_code=csharp,true]<GroupBox x:Class="HandyC.HW.Views.DataHistory" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:hc="https://handyorg.github.io/handycontrol" mc:Ignorable="d" Header="设备历史数据" Style="{DynamicResource GroupBoxStyle}" d:DesignHeight="450" d:DesignWidth="800" DataContext="{Binding DataHistory, Mode=OneWay, Source={StaticResource Locator}}"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <StackPanel Grid.Row="0"> <DockPanel Margin="0,10"> <hc:ComboBox hc:BorderElement.CornerRadius="2" Padding="3" hc:InfoElement.ContentHeight="34" hc:TitleElement.Title="设备名称:" hc:TitleElement.TitleAlignment="Left" hc:TitleElement.TitleWidth="Auto" IsEditable="False" hc:InfoElement.Placeholder="请选择设备名称" DockPanel.Dock="Left" Width="Auto" ItemsSource="{Binding Devices}" DisplayMemberPath="Name" SelectedValuePath="DeviceId" SelectedItem="{Binding SelectedDevice}" Style="{DynamicResource ComboBoxExtend}"></hc:ComboBox> <hc:ComboBox hc:BorderElement.CornerRadius="2" hc:InfoElement.ContentHeight="34" hc:TitleElement.TitleAlignment="Left" hc:TitleElement.TitleWidth="Auto" IsEditable="False" hc:TitleElement.Title="服务类型:" hc:InfoElement.Placeholder="请选择服务类型" DockPanel.Dock="Left" Width="Auto" ItemsSource="{Binding DeviceServices}" DisplayMemberPath="ServiceType" SelectedValuePath="ServiceId" SelectedItem="{Binding SelectedService}"></hc:ComboBox> <hc:SearchBar hc:BorderElement.CornerRadius="2" Margin="10,0,0,0" Command="{Binding SearchCmd}" Cursor="Hand"></hc:SearchBar> </DockPanel> </StackPanel> <DataGrid Effect="{StaticResource EffectShadow2}" Grid.Row="1" hc:BorderElement.CornerRadius="2" Background="{DynamicResource RegionBrush}" AutoGenerateColumns="False" ItemsSource="{Binding DeviceDataSource}"> <DataGrid.Columns> <DataGridTextColumn Header="设备标识" Binding="{Binding DeviceId}" IsReadOnly="True"/> <DataGridTextColumn Header="服务标识" Binding="{Binding ServiceId}" IsReadOnly="True"/> <DataGridTextColumn Header="光照(Lux)" Binding="{Binding SensorData.Illumination}" IsReadOnly="True"/> <DataGridTextColumn Header="电压(V)" Binding="{Binding SensorData.Voltage}" IsReadOnly="True"/> <DataGridTextColumn Header="采集时间" Binding="{Binding Timestamp}" IsReadOnly="True"/> <DataGridTemplateColumn Header="操作"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <Button Content="数据明细" Cursor="Hand" Command="{Binding SearchDataDetailsCmd}" CommandParameter="{Binding DataContext, RelativeSource={RelativeSource Self}}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> <Border Effect="{StaticResource EffectShadow2}" hc:BorderElement.CornerRadius="2" Margin="0,5,0,0" BorderThickness="0" Grid.Row="2" Background="{DynamicResource RegionBrush}"> <hc:Pagination MaxPageInterval="2" MaxPageCount="{Binding MaxPageCount,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" PageIndex="{Binding PageNo, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DataCountPerPage="{Binding PageSize, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> <hc:Interaction.Triggers> <hc:EventTrigger EventName="PageUpdated"> <hc:EventToCommand Command="{Binding PageChangedCmd}" PassEventArgsToCommand="True" /> </hc:EventTrigger> </hc:Interaction.Triggers> </hc:Pagination> </Border> </Grid> </GroupBox>[/mw_shl_code] [mw_shl_code=csharp,true]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 { /// <summary> /// DataHistory.xaml 的交互逻辑 /// </summary> public partial class DataHistory { public DataHistory() { InitializeComponent(); InitialMsg(); } private void InitialMsg() { //避免token值重名使用 this.Loaded += (e, arg) => { Messenger.Default.Register<DeviceDataViewModel>(this, MessageToken.NewDeviceDataDetails, NewDeviceDataDialog); }; this.Unloaded += (e, arg) => Messenger.Default.Unregister<DeviceDataViewModel>(this, MessageToken.NewDeviceDataDetails); } /// <summary> /// 显示数据信息明细 /// </summary> /// <param name="obj"></param> private void NewDeviceDataDialog(DeviceDataViewModel obj) { if (obj != null) { Dialog.Show(new DeviceDataInfo(obj), MessageToken.MainToken); } } } }[/mw_shl_code] [mw_shl_code=csharp,true]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 { /// <summary> /// 历史数据实体实体 /// </summary> public class DataHistoryViewModel : ViewModelBase { private readonly IDataCollectionService _collectionService; public DataHistoryViewModel(IDataCollectionService collectionService) { _collectionService = collectionService; InitialData(); } /// <summary> /// 初始化数据 /// </summary> private void InitialData() { Task.Factory.StartNew(() => { //获取设备信息 Devices = GetDevices(); //默认获取第一个设备的历史数据 if (Devices.Count > 0) { SelectedDevice = Devices.FirstOrDefault(); //获取设备服务列表 DeviceServices = GetDeviceServices(SelectedDevice); pageSize = 10;//默认设定为10 PageNo = 1;//设定默认起始页码 } }); //设定当前默认数据列表配置值 } /// <summary> /// 获取设备服务列表 /// </summary> /// <param name="selectedDevice">当前设备</param> /// <returns></returns> private List<ServiceCapabilityDTO> GetDeviceServices(DeviceInfoViewModel selectedDevice) { List<ServiceCapabilityDTO> services = new List<ServiceCapabilityDTO>(); List<DeviceCapabilityViewModel> 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<DeviceCapabilityDTO>, List<DeviceCapabilityViewModel>>(datas.DeviceCapabilities); } else { deviceCapabilitys = new List<DeviceCapabilityViewModel>(); } 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; } /// <summary> /// 获取当前设备列表信息 /// </summary> /// <returns></returns> private List<DeviceInfoViewModel> GetDevices() { List<DeviceInfoViewModel> 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<QuerySingleDeviceInfoOutDTO>, List<DeviceInfoViewModel>>(datas.Devices); } else { result = new List<DeviceInfoViewModel>(); } return result; } /// <summary> /// 网络请求服务异常结果处理 /// </summary> /// <param name="obj"></param> 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<DeviceInfoViewModel> devices; /// <summary> /// 设备集合 /// </summary> public List<DeviceInfoViewModel> Devices { get { if (devices == null) { devices = new List<DeviceInfoViewModel>(); } return devices; } set { devices = value; RaisePropertyChanged(); } } #endregion //Cmds private ICommand pageChangedCmd; /// <summary> /// 当前页变更命令 /// </summary> public ICommand PageChangedCmd { get { if (pageChangedCmd == null) { pageChangedCmd = new RelayCommand<object>(PageChanged); } return pageChangedCmd; } set => pageChangedCmd = value; } private ICommand searchCmd; public ICommand SearchCmd { get { if (searchCmd == null) { searchCmd = new RelayCommand(SearchData); } return searchCmd; } } /// <summary> /// 查询设备函数 /// </summary> 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 分页控件相关属性和函数 /// <summary> /// 当前页变更触发事件 /// </summary> /// <param name="obj"></param> 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); } /// <summary> /// 刷新当前数据列表 /// </summary> 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<IEnumerable<DeviceDataHistoryDTO>, List<DeviceDataViewModel>>(datas.DeviceDataHistoryDTOs).ToList(); } }); } /// <summary> /// 获取当前最大记录条数 /// </summary> private long GetMaxPageCount() { long pageCount; pageCount = TotalCount / PageSize; int result = Convert.ToInt32(TotalCount % PageSize); if (result != 0) { pageCount += 1; } return pageCount; } /// <summary> /// 查询的记录数量 /// </summary> private long totalCount; private long pageNo; private long pageSize; /// <summary> /// 最大显示记录数量 /// </summary> public long MaxPageCount { get => maxPageCount; set { maxPageCount = value; RaisePropertyChanged(); } } /// <summary> /// 查询的记录数量 /// </summary> public long TotalCount { get { return totalCount; } set { totalCount = value; RaisePropertyChanged(); } } /// <summary> /// 查询的页码 /// </summary> public long PageNo { get => pageNo; set { pageNo = value; RaisePropertyChanged(); } } /// <summary> /// 查询每页信息的数量 /// </summary> public long PageSize { get => pageSize; set { pageSize = value; RaisePropertyChanged(); } } #endregion #region 设备列表 private List<DeviceDataViewModel> deviceDataSource; private DeviceInfoViewModel selectedDevice; private long maxPageCount; /// <summary> /// 设备数据信息集合 /// </summary> public List<DeviceDataViewModel> DeviceDataSource { get { if (deviceDataSource == null) { deviceDataSource = new List<DeviceDataViewModel>(); } return deviceDataSource; } set { deviceDataSource = value; RaisePropertyChanged(); } } //选中项设备记录 public DeviceInfoViewModel SelectedDevice { get => selectedDevice; set { selectedDevice = value; RaisePropertyChanged(); } } #endregion #region 设备服务列表 private List<ServiceCapabilityDTO> deviceServices; /// <summary> /// 设备服务能力列表 /// </summary> public List<ServiceCapabilityDTO> DeviceServices { get { if (deviceServices == null) { deviceServices = new List<ServiceCapabilityDTO>(); } return deviceServices; } set { deviceServices = value; RaisePropertyChanged(); } } private ServiceCapabilityDTO selectedService; /// <summary> /// 选中设备服务 /// </summary> public ServiceCapabilityDTO SelectedService { get { if (selectedService == null) { selectedService = new ServiceCapabilityDTO(); } return selectedService; } set { selectedService = value; RaisePropertyChanged(); } } #endregion } }[/mw_shl_code] 【脑洞大赛】基于NB-IoT的智慧路灯监控系统(手机应用开发):https://mc.dfrobot.com.cn/thread-297186-1-1.html#pid423131 |
© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed