【脑洞大赛】基于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、使用技术[*]网络通信相关技术(数据接口请求)
[*]WPF(UI框架)
[*]MvvmLight(MVVM框架)
[*]依赖注入
[*]简单缓存
[*]LiveCharts(图标框架)
[*]HandyControl(WPF组件框架)
[*]非对称双向认证(Https)
[*]AutoMapper(DTO转换框架)
4、开发环境与工具
[*]开发环境:Windows7 sp1、.Net Framework 4.7.2
[*]开发语言:C#
[*]开发工具:MicrosoftVisual Studio professional 2019(VS 2019)
5、功能介绍设备管理页面的主页面,红框区域内为设备统计,包含了对当前设备的设备类型、设备状态、设备的协议类型的相关统计信息,属于设备总体的一个统计信息。设备列表中展示的是当前的存在的设备,以卡片的方式展示出来,包括设备的名称、设备的型号、设备的编号等预览。显示设备的详细信息。设备的实时数据显示页面,能够动态实时请求道IoT平台上的设备下发的最近历史信息。云平台联动主页中的卡片为一卡片一设备,点击设备卡片,可以对设备进行联动模式控制,可支持三种联动模式,终端联控模式、自动调光模式和分段定时模式。 默认手动模式,可以通过手动直接下发指令到IoT平台,通过平台将命令通知对应的设备执行,点击控制按钮进行云平台挂载设备的开启和关闭。 用户可以通过点击切换至定时模式,设定时间后,将点击发送定时设备,等待设定的命令发送至IoT平台。 命令下发成功是接收到的反馈信息。 自动模式与手动模式的操作类似,用户通过开启和关闭实现对IoT平台上挂载的设备的执行模式的设定,关闭时,设备默认执行,为上一次的模式运行状态,开启时,变更为根据实际的自动条件进行自身状态的控制。 设备历史数据显示页面,主要功能为查询功能,用于显示从IoT平台获取到的当前设备对应的历史记录信息,可通过查询条件进行更加细致数据查找。 点击每条记录的操作列按钮,能够获取到该条记录的详细信息。 下图的页面为命令历史数据的主页面,默认显示第一个设备的相关历史数据,能够查询到多端给设备发送的相关命令指令历史信息。 通过点击每条记录末尾的数据明细,可以查看到当前命令记录的具体信息。 6、核心代码 PC端主要分为两个部分,一个是通过https请求双向认证获取到来自于IoT平台提供的相关Api接口的目标数据,将数据进行处理根据View的需求进行相关的ViewModel处理之后展示到页面中;一个是需要PC端与IoT平台上的挂载设备进行数据交互时,实现本地命令的发送,进而间接控制设备的数据响应。 鉴定权限代码如下:
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;
}
}
}
获取设备信息代码如下: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;
}
}
}
下发命令代码如下: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;
}
//设备服务调用
}
}
设备历史信息查询代码如下:
<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>
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);
}
}
}
}
<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:ComboBoxhc: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>
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);
}
}
}
}
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
}
}
【脑洞大赛】基于NB-IoT的智慧路灯监控系统(手机应用开发):https://mc.dfrobot.com.cn/thread-297186-1-1.html#pid423131
脑洞超量啊,看不完,不如直接来个视频吧
页:
[1]