diff --git a/BPASmartClient.Helper/HttpRequestHelper.cs b/BPASmartClient.Helper/HttpRequestHelper.cs new file mode 100644 index 00000000..dd191933 --- /dev/null +++ b/BPASmartClient.Helper/HttpRequestHelper.cs @@ -0,0 +1,328 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; +namespace BPASmartClient.Helper +{ + /// + /// 该类实现客户端http 同步请求 + /// 支持环境 -.net4.0/-.net4.5 + /// 创建人:奉友福 + /// + public class HttpRequestHelper + { + #region 私有变量 + #endregion + + #region 公用函数 + /// + /// GET 同步请求 + /// 创建人:奉友福 + /// 创建时间:2020-11-19 + /// + /// 请求地址 + /// 超时时间设置,默认5秒 + public static string HttpGetRequest(string url, int _timeout = 2000) + { + string resultData = string.Empty; + + try + { + WebClient wc = new WebClient(); + byte[] bytes = wc.DownloadData(url); + string s = Encoding.UTF8.GetString(bytes); + return s; + } + catch (Exception e) + { + throw e; + } + return ""; + + try + { + var getrequest = HttpRequest.GetInstance().CreateHttpRequest(url, "GET", _timeout); + var getreponse = getrequest.GetResponse() as HttpWebResponse; + resultData = HttpRequest.GetInstance().GetHttpResponse(getreponse, "GET"); + } + catch (Exception) + { + throw; + } + return resultData; + } + /// + /// POST 同步请求 + /// 创建人:奉友福 + /// 创建时间:2020-11-19 + /// + /// 请求地址 + /// 请求数据 + /// + public static string HttpPostRequest(string url, string PostJsonData, int _timeout = 2000) + { + string resultData = string.Empty; + try + { + var postrequest = HttpRequest.GetInstance().CreateHttpRequest(url, "POST", _timeout, PostJsonData); + var postreponse = postrequest.GetResponse() as HttpWebResponse; + resultData = HttpRequest.GetInstance().GetHttpResponse(postreponse, "POST"); + } + catch (Exception ex) + { + return ex.Message; + } + return resultData; + } + + public static string HttpDeleteRequest(string url, string PostJsonData, int _timeout = 10000) + { + string resultData = string.Empty; + try + { + var deleteRequest = HttpRequest.CreateDeleteHttpRequest(url, PostJsonData, _timeout); + var deleteReponse = deleteRequest.GetResponse() as HttpWebResponse; + using (StreamReader reader = new StreamReader(deleteReponse.GetResponseStream(), Encoding.GetEncoding("UTF-8"))) + { + resultData = reader.ReadToEnd(); + } + } + catch (Exception ex) + { + } + return resultData; + } + + /// + /// GET 同步请求 + /// + /// 地址 + /// 头 + /// 内容 + /// + public static string GetHttpGetResponseWithHead(string url, HttpRequestHeader head, string headInfo) + { + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); + request.Method = "GET"; + request.ContentType = "application/json;charset=UTF-8"; + request.Timeout = 6000; + request.Headers.Set(head, headInfo); + StreamReader sr = null; + HttpWebResponse response = null; + Stream stream = null; + try + { + response = (HttpWebResponse)request.GetResponse(); + stream = response.GetResponseStream(); + sr = new StreamReader(stream, Encoding.GetEncoding("utf-8")); + var resultData = sr.ReadToEnd(); + return resultData; + } + catch (Exception ex) + { + Console.WriteLine(url + " 访问失败:" + ex.Message); + //return ex.Message; + } + finally + { + if (response != null) + { + response.Dispose(); + } + if (stream != null) + { + stream.Dispose(); + } + if (sr != null) + { + sr.Dispose(); + } + } + return null; + } + + + + /// + /// Post请求带Token + /// 2021-2-2 by dulf + /// + /// + /// + /// + /// + /// + public static string HttpPostResponseWithHead(string url, HttpRequestHeader head, string headInfo, string postParam, int Timeout = 6000) + { + string resultData = string.Empty; + try + { + var postrequest = WebRequest.Create(url) as HttpWebRequest; + postrequest.Timeout = Timeout; + postrequest.Method = "POST"; + postrequest.ContentType = "application/json;charset=UTF-8"; + postrequest.Headers.Set(head, headInfo); + byte[] data = Encoding.UTF8.GetBytes(postParam); + using (Stream reqStream = postrequest.GetRequestStream()) + { + reqStream.Write(data, 0, data.Length); + var postreponse = postrequest.GetResponse() as HttpWebResponse; + resultData = HttpRequest.GetInstance().GetHttpResponse(postreponse, "POST"); + reqStream.Close(); + } + return resultData; + } + catch (Exception ex) + { + Console.Write("请求异常:" + ex.Message); + } + return ""; + } + #endregion + + } + /// + /// HTTP请求类 + /// + public class HttpRequest + { + #region 私有变量 + /// + /// http请求超时时间设置 + /// 默认值:5秒 + /// + private static int Timeout = 5000; + #endregion + + #region 单例模式 + private static HttpRequest _HttpRequest = null; + public static HttpRequest GetInstance() + { + if (_HttpRequest == null) + { + _HttpRequest = new HttpRequest(); + } + return _HttpRequest; + } + private HttpRequest() + { + + } + #endregion + + #region 公用函数 + /// + /// 函数名称:创建http请求 + /// 创建人:奉友福 + /// 创建时间:2020-11-19 + /// 例如GET 请求: 地址 + "GET" + /// 例如POST请求: 地址 + "POST" + JSON + /// + /// http请求地址 + /// http请求方式:GET/POST + /// http请求附带数据 + /// + public HttpWebRequest CreateHttpRequest(string url, string requestType, int _timeout = 5000, params object[] strjson) + { + HttpWebRequest request = null; + const string get = "GET"; + const string post = "POST"; + Timeout = _timeout; + if (string.Equals(requestType, get, StringComparison.OrdinalIgnoreCase)) + { + request = CreateGetHttpRequest(url); + } + if (string.Equals(requestType, post, StringComparison.OrdinalIgnoreCase)) + { + request = CreatePostHttpRequest(url, strjson[0].ToString()); + } + return request; + } + /// + /// http获取数据 + /// + /// + /// + /// + public string GetHttpResponse(HttpWebResponse response, string requestType) + { + var resultData = string.Empty; + const string post = "POST"; + string encoding = "UTF-8"; + if (string.Equals(requestType, post, StringComparison.OrdinalIgnoreCase)) + { + encoding = response.ContentEncoding; + if (encoding == null || encoding.Length < 1) + encoding = "UTF-8"; + } + using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding))) + { + resultData = reader.ReadToEnd(); + } + return resultData; + } + #endregion + + #region 私有函数 + /// + /// http+GET请求 + /// + /// 请求地址 + /// 请求结果 + private static HttpWebRequest CreateGetHttpRequest(string url) + { + var getrequest = WebRequest.Create(url) as HttpWebRequest; + getrequest.Method = "GET"; + getrequest.Timeout = Timeout; + getrequest.ContentType = "application/json;charset=UTF-8"; + getrequest.Proxy = null; + getrequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; + return getrequest; + } + /// + /// http+POST请求 + /// + /// 请求地址 + /// + /// 请求结果 + private static HttpWebRequest CreatePostHttpRequest(string url, string postData) + { + var postrequest = WebRequest.Create(url) as HttpWebRequest; + //postrequest.KeepAlive = false; + postrequest.Timeout = Timeout; + postrequest.Method = "POST"; + postrequest.ContentType = "application/json;charset=UTF-8"; + //postrequest.ContentLength = postData.Length; + //postrequest.AllowWriteStreamBuffering = false; + //StreamWriter writer = new StreamWriter(postrequest.GetRequestStream(), Encoding.UTF8); + //writer.Write(postData); + //writer.Flush(); + byte[] data = Encoding.UTF8.GetBytes(postData); + using (Stream reqStream = postrequest.GetRequestStream()) + { + reqStream.Write(data, 0, data.Length); + reqStream.Close(); + } + return postrequest; + } + + public static HttpWebRequest CreateDeleteHttpRequest(string url, string postJson, int _timeout = 5000) + { + var deleteRequest = WebRequest.Create(url) as HttpWebRequest; + deleteRequest.Timeout = _timeout; + deleteRequest.Method = "DELETE"; + deleteRequest.ContentType = "application/json;charset=UTF-8"; + byte[] data = Encoding.UTF8.GetBytes(postJson); + using (Stream reqStream = deleteRequest.GetRequestStream()) + { + reqStream.Write(data, 0, data.Length); + reqStream.Close(); + } + return deleteRequest; + } + #endregion + } +} diff --git a/BPASmartClient.Helper/Tools.cs b/BPASmartClient.Helper/Tools.cs new file mode 100644 index 00000000..8d5379b3 --- /dev/null +++ b/BPASmartClient.Helper/Tools.cs @@ -0,0 +1,93 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.Helper +{ + /// + /// 工具 + /// + public class Tools + { + /// + /// 对象Json序列 + /// + /// 对象类型 + /// 对象实例 + /// + public static string JsonConvertTools(T obj) + { + string strvalue = JsonConvert.SerializeObject(obj); + return strvalue; + } + + /// + /// 对象反Json序列 + /// + /// 对象类型 + /// 对象序列化json字符串 + /// 返回对象实例 + public static T JsonToObjectTools(string jsonstring) + { + T obj = JsonConvert.DeserializeObject(jsonstring); + return obj; + } + + /// + /// DateTime --> long + /// + /// + /// + public static long ConvertDateTimeToLong(DateTime dt) + { + DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); + TimeSpan toNow = dt.Subtract(dtStart); + long timeStamp = toNow.Ticks; + timeStamp = long.Parse(timeStamp.ToString().Substring(0, timeStamp.ToString().Length - 4)); + return timeStamp; + } + + /// + /// long --> DateTime + /// + /// + /// + public static DateTime ConvertLongToDateTime(long d) + { + DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); + long lTime = long.Parse(d + "0000"); + TimeSpan toNow = new TimeSpan(lTime); + DateTime dtResult = dtStart.Add(toNow); + return dtResult; + } + + /// + /// 获取IP 地址 + /// + /// + public static string GetLocalIp() + { + //得到本机名 + string hostname = Dns.GetHostName(); + //解析主机名称或IP地址的system.net.iphostentry实例。 + IPHostEntry localhost = Dns.GetHostEntry(hostname); + if (localhost != null) + { + foreach (IPAddress item in localhost.AddressList) + { + //判断是否是内网IPv4地址 + if (item.AddressFamily == AddressFamily.InterNetwork) + { + return item.MapToIPv4().ToString(); + } + } + } + return "192.168.1.124"; + } + } +} diff --git a/BPASmartClient.IoT/BPASmartClient.IoT.csproj b/BPASmartClient.IoT/BPASmartClient.IoT.csproj index dbc15171..a3727742 100644 --- a/BPASmartClient.IoT/BPASmartClient.IoT.csproj +++ b/BPASmartClient.IoT/BPASmartClient.IoT.csproj @@ -4,4 +4,15 @@ net6.0 + + + + + + + + + + + diff --git a/BPASmartClient.IoT/Class1.cs b/BPASmartClient.IoT/Class1.cs deleted file mode 100644 index 1aa0de8c..00000000 --- a/BPASmartClient.IoT/Class1.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System; - -namespace BPASmartClient.IoT -{ - public class Class1 - { - } -} diff --git a/BPASmartClient.IoT/DataVClient.cs b/BPASmartClient.IoT/DataVClient.cs new file mode 100644 index 00000000..a76c28c8 --- /dev/null +++ b/BPASmartClient.IoT/DataVClient.cs @@ -0,0 +1,30 @@ +using System; + +namespace BPASmartClient.IoT +{ + /// + /// DataV客户端数据中心 + /// + public class DataVClient + { + #region 单例模式 + private volatile static DataVClient _Instance; + public static DataVClient GetInstance => _Instance ?? (_Instance = new DataVClient()); + #endregion + + #region 公有变量 + //DataV 服务地址 + public string DataVApiAddress { set; get; } + #endregion + + public DataVClient() + { + DataVApiAddress = System.Configuration.ConfigurationManager.AppSettings["DataVServiceUri"].ToString(); + } + + public void Start() + { + + } + } +} diff --git a/BPASmartClient.IoT/DataVReport.cs b/BPASmartClient.IoT/DataVReport.cs new file mode 100644 index 00000000..78e1017a --- /dev/null +++ b/BPASmartClient.IoT/DataVReport.cs @@ -0,0 +1,365 @@ +using BPASmartClient.Helper; +using BPASmartClient.IoT; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Security.Cryptography; +using System.Text; +using System.Threading; +using uPLibrary.Networking.M2Mqtt; +using uPLibrary.Networking.M2Mqtt.Messages; + +namespace BPASmartDatavDeviceClient.IoT +{ + /// + /// DataV客户端 + /// + public class DataVReport + { + #region 外部调用 + /// + /// 初始化IOT连接 + /// + public bool Initialize(string url,string clientId,string deviceId,ref string message) + { + if(string.IsNullOrEmpty(url))return false; + DeviceTable device; + if (!CreateLinks(url,clientId,deviceId, out device)) + { + message += $"客户端{clientId}设备{deviceId}阿里云上没有该设备。"; + return false; + } + IOT_Subscribe(BroadcastTopic);//订阅广播主题 + if (DatavDeviceClient.IsConnected) message += $"设备{device.devicename} {device.remark}阿里云连接成功."; + else message += $"设备{device.devicename} {device.remark}阿里云连接失败.不能上报业务信息"; + return DatavDeviceClient.IsConnected; + } + + /// + /// 获取连接状态 + /// + public bool GetIsConnected() + { + try + { + if (DatavDeviceClient == null || !DatavDeviceClient.IsConnected) + return false; + else return true; + } + catch (Exception ex) + { + return false; + throw; + } + } + + /// + /// 断开连接 + /// + public void Disconnect() + { + if (DatavDeviceClient != null) + { + DatavDeviceClient.Disconnect(); + } + } + + /// + /// 发布消息 + /// + /// + /// + public void IOT_Publish(string topic, string message) + { + var id = DatavDeviceClient.Publish(topic, Encoding.UTF8.GetBytes(message)); + } + + /// + /// 订阅主题 + /// + /// + public void IOT_Subscribe(string topic) + { + if (SubTopicList.Contains(topic)) + { + SubTopicList.Add(topic); + } + DatavDeviceClient.Subscribe(new string[] { topic }, new byte[] { 0 }); + } + #endregion + + #region 私有函数 + /// + /// 设置变量 + /// + /// + /// + /// + /// + private void SetValue(string _ProductKey, string _DeviceName, string _DeviceSecret, string _RegionId = "cn-shanghai") + { + ProductKey = _ProductKey; + DeviceName = _DeviceName; + DeviceSecret = _DeviceSecret; + RegionId = _RegionId; + PubTopic = "/sys/" + ProductKey + "/" + DeviceName + "/thing/event/property/post"; + SubTopic = "/sys/" + ProductKey + "/" + DeviceName + "/thing/event/property/set"; + UserPubTopic = "/" + ProductKey + "/" + DeviceName + "/user/update"; + UserSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/get"; + BroadcastTopic = "/broadcast/" + ProductKey + "/" + DeviceName + "_SetDevice"; + AlarmSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/AlarmMessage"; + LogsSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/ExceptionLogs"; + HeartbeatSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/HeartbeatAndState"; + TargetStatusSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/TargetStatus"; + ScreenShowPubTopic = "/" + ProductKey + "/" + DeviceName + "/user/ScreenShow"; + } + + /// + /// 创建连接 + /// + private bool CreateLinks(string url, string clientId, string deviceId, out DeviceTable device) + { + try + { + string json = HttpRequestHelper.HttpGetRequest($"{url}/api/Device/Query?clientId={clientId}&deviceId={deviceId}"); + JsonMsg> jsonMsg = Tools.JsonToObjectTools>>(json); + if (jsonMsg.obj != null && jsonMsg.obj.data != null) + { + device = jsonMsg.obj.data.FirstOrDefault(); + if (device == null) return false; + SetValue(device.productkey, device.devicename, device.devicesecret); + IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName()); + string _clientId = host.AddressList.FirstOrDefault( + ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).ToString(); + string t = Convert.ToString(DateTimeOffset.Now.ToUnixTimeMilliseconds()); + string signmethod = "hmacmd5"; + + Dictionary dict = new Dictionary(); + dict.Add("productKey", ProductKey); + dict.Add("deviceName", DeviceName); + dict.Add("clientId", _clientId); + dict.Add("timestamp", t); + + mqttUserName = DeviceName + "&" + ProductKey; + mqttPassword = IotSignUtils.sign(dict, DeviceSecret, signmethod); + mqttClientId = clientId + "|securemode=3,signmethod=" + signmethod + ",timestamp=" + t + "|"; + targetServer = ProductKey + ".iot-as-mqtt." + RegionId + ".aliyuncs.com"; + ConnectMqtt(targetServer, mqttClientId, mqttUserName, mqttPassword); + return true; + } + else + { + device = null; + return false; + } + } + catch (Exception ex) + { + device = null; + return false; + } + } + + /// + /// MQTT创建连接 + /// + /// + /// + /// + /// + private void ConnectMqtt(string targetServer, string mqttClientId, string mqttUserName, string mqttPassword) + { + DatavDeviceClient = new MqttClient(targetServer); + DatavDeviceClient.ProtocolVersion = MqttProtocolVersion.Version_3_1_1; + DatavDeviceClient.Connect(mqttClientId, mqttUserName, mqttPassword, false, 60); + DatavDeviceClient.MqttMsgPublishReceived += Client_MqttMsgPublishReceived; + DatavDeviceClient.ConnectionClosed += Client_ConnectionClosed; + } + + /// + /// MQTT 断开事件 + /// + /// + /// + private static void Client_ConnectionClosed(object sender, EventArgs e) + { + // 尝试重连 + _TryContinueConnect(); + } + + /// + /// 订阅数据接收 + /// + /// + /// + private static void Client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e) + { + string topic = e.Topic; + string message = Encoding.UTF8.GetString(e.Message); + if (DataVMessageAction != null) + { + DataVMessageAction.Invoke(topic, message); + } + } + + /// + /// 自动重连主体 + /// + private static void _TryContinueConnect() + { + Thread retryThread = new Thread(new ThreadStart(delegate + { + while (DatavDeviceClient == null || !DatavDeviceClient.IsConnected) + { + if (DatavDeviceClient.IsConnected) break; + + if (DatavDeviceClient == null) + { + DatavDeviceClient = new MqttClient(targetServer); + DatavDeviceClient.ProtocolVersion = MqttProtocolVersion.Version_3_1_1; + DatavDeviceClient.Connect(mqttClientId, mqttUserName, mqttPassword, false, 60); + DatavDeviceClient.MqttMsgPublishReceived += Client_MqttMsgPublishReceived; + DatavDeviceClient.ConnectionClosed += Client_ConnectionClosed; + if (DatavDeviceClient.IsConnected) + { + SubTopicList?.ForEach(par =>{DatavDeviceClient.Subscribe(new string[] { par }, new byte[] { 0 }); }); + } + Thread.Sleep(3000); + continue; + } + + try + { + DatavDeviceClient.Connect(mqttClientId, mqttUserName, mqttPassword, false, 60); + if (DatavDeviceClient.IsConnected) + { + SubTopicList?.ForEach(par => { DatavDeviceClient.Subscribe(new string[] { par }, new byte[] { 0 }); }); + UnConnectMqtt?.Invoke("重新连接阿里云MQTT成功!"); + } + } + catch (Exception ce) + { + UnConnectMqtt?.Invoke("重新连接阿里云MQTT失败!"); + } + // 如果还没连接不符合结束条件则睡2秒 + if (!DatavDeviceClient.IsConnected) + { + Thread.Sleep(2000); + } + } + })); + + retryThread.Start(); + } + #endregion + + #region 私有IOT连接变量 + private static string ProductKey = "grgpECHSL7q"; + private static string DeviceName = "hbldev"; + private static string DeviceSecret = "4ec120de0c866199183b22e2e3135aeb"; + private static string RegionId = "cn-shanghai"; + private static string mqttUserName = string.Empty; + private static string mqttPassword = string.Empty; + private static string mqttClientId = string.Empty; + private static string targetServer = string.Empty; + #endregion + + #region 公有变量 + /// + /// 设备消息数据回调 + /// + public static Action DataVMessageAction { get; set; } + /// + /// 重连事件 + /// + public static Action UnConnectMqtt { get; set; } + /// + /// 客户端 + /// + public static MqttClient DatavDeviceClient { get; set; } + /// + /// 当前设备 + /// + public DeviceTable deviceTable { get; set; } + #endregion + + #region 发布或订阅主题或URL地址 + /// + /// 属性发布消息主题 + /// + public static string PubTopic = "/" + ProductKey + "/" + DeviceName + "/user/update"; + /// + /// 属性接收消息主题 + /// + public static string SubTopic = "/" + ProductKey + "/" + DeviceName + "/user/get"; + /// + /// 自定义发布消息主题 + /// + public static string UserPubTopic = "/" + ProductKey + "/" + DeviceName + "/user/update"; + /// + /// 自定义接收消息主题 + /// + public static string UserSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/get"; + /// + /// 告警订阅主题 + /// + public static string AlarmSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/AlarmMessage"; + /// + /// 日志订阅主题 + /// + public static string LogsSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/ExceptionLogs"; + /// + /// 上下线订阅主题 + /// + public static string HeartbeatSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/HeartbeatAndState"; + /// + /// 属性状态主题 + /// + public static string TargetStatusSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/TargetStatus"; + /// + /// 大屏展示发布主题 + /// + public static string ScreenShowPubTopic = "/" + ProductKey + "/" + DeviceName + "/user/ScreenShow"; + /// + /// 广播主题 + /// + public static string BroadcastTopic = "/broadcast/" + "grgpECHSL7q" + "/" + DeviceName + "_SetDevice"; + /// + /// 订阅主题集合 + /// + public static List SubTopicList = new List(); + #endregion + } + + /// + /// Iot 设备上报 + /// + public class IotSignUtils + { + public static string sign(Dictionary param, + string deviceSecret, string signMethod) + { + string[] sortedKey = param.Keys.ToArray(); + Array.Sort(sortedKey); + + StringBuilder builder = new StringBuilder(); + foreach (var i in sortedKey) + { + builder.Append(i).Append(param[i]); + } + + byte[] key = Encoding.UTF8.GetBytes(deviceSecret); + byte[] signContent = Encoding.UTF8.GetBytes(builder.ToString()); + //这里根据signMethod动态调整,本例子硬编码了: 'hmacmd5' + var hmac = new HMACMD5(key); + byte[] hashBytes = hmac.ComputeHash(signContent); + + StringBuilder signBuilder = new StringBuilder(); + foreach (byte b in hashBytes) + signBuilder.AppendFormat("{0:x2}", b); + + return signBuilder.ToString(); + } + } +} diff --git a/BPASmartClient.IoT/Model/AlarmTable.cs b/BPASmartClient.IoT/Model/AlarmTable.cs new file mode 100644 index 00000000..66c0e205 --- /dev/null +++ b/BPASmartClient.IoT/Model/AlarmTable.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.IoT +{ + /// + /// 告警消息表 + /// + public class AlarmTable : BaseEntity + { + /// + /// 告警时间 + /// + public string AlarmTime { get; set; } + /// + /// 告警类型:1 轻微 2:一般 3 严重 + /// + public string AlarmType { get; set; } + /// + /// 告警消息 + /// + public string AlarmMessage { get; set; } + /// + /// 告警值 + /// + public string AlarmVla { get; set; } + /// + /// IP 地址 + /// + public string IP { get; set; } + } +} diff --git a/BPASmartClient.IoT/Model/BaseEntity.cs b/BPASmartClient.IoT/Model/BaseEntity.cs new file mode 100644 index 00000000..0cbff59d --- /dev/null +++ b/BPASmartClient.IoT/Model/BaseEntity.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.IoT +{ + /// + /// MongoDB基类 + /// + public abstract class BaseEntity + { + /// + /// ID + /// + public string Id { get; set; } + /// + /// 客户端 ID + /// + public string ClientId { get; set; } + /// + /// 设备 ID + /// + public string DeviceId { get; set; } + /// + /// 阿里云设备名称 + /// + public string devicename { get; set; } + /// + /// 状态 + /// + public string State { get; set; } + /// + /// 创建时间 + /// + public DateTime CreateTime { get; set; } + /// + /// 修改时间 + /// + public DateTime UpdateTime { get; set; } + } +} diff --git a/BPASmartClient.IoT/Model/CommandModel.cs b/BPASmartClient.IoT/Model/CommandModel.cs new file mode 100644 index 00000000..964e21bd --- /dev/null +++ b/BPASmartClient.IoT/Model/CommandModel.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.IoT +{ + /// + /// 命令实体类 + /// + public class CommandModel + { + /// + /// 设备名称 + /// + public string deviceName { get; set; } + /// + /// 命令名称:0 控制类 1 设置属性 2 通知信息类 + /// + public int CommandName { get; set; } + /// + /// 命令变量:执行变量 key为属性或时间 value为值或者消息 + /// + public Dictionary CommandValue { get; set; } + } +} diff --git a/BPASmartClient.IoT/Model/DeviceTable.cs b/BPASmartClient.IoT/Model/DeviceTable.cs new file mode 100644 index 00000000..e55d7ff5 --- /dev/null +++ b/BPASmartClient.IoT/Model/DeviceTable.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.IoT +{ + /// + /// 设备信息表 + /// + public class DeviceTable : BaseEntity + { + /// + /// 阿里云设备key + /// + public string productkey { get; set; } + /// + /// 阿里云设备secret + /// + public string devicesecret { get; set; } + /// + /// 客户端类型 + /// + public string devtype { get; set; } + /// + /// 经度 + /// + public string jd { get; set; } + /// + /// 维度 + /// + public string wd { get; set; } + /// + /// 备注 + /// + public string remark { get; set; } + } +} diff --git a/BPASmartClient.IoT/Model/IOT/CommandModel.cs b/BPASmartClient.IoT/Model/IOT/CommandModel.cs new file mode 100644 index 00000000..b48fea53 --- /dev/null +++ b/BPASmartClient.IoT/Model/IOT/CommandModel.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DataVAPI.Tool.IOT +{ + /// + /// 命令实体类 + /// + public class IOTCommandModel + { + /// + /// 设备名称 + /// + public string deviceName { get; set; } + /// + /// 命令名称:0 控制类 1 设置属性 2 通知信息类 + /// + public int CommandName { get; set; } + /// + /// 命令变量:执行变量 key为属性或时间 value为值或者消息 + /// + public Dictionary CommandValue { get; set; } + } +} diff --git a/BPASmartClient.IoT/Model/IOT/IOTDevModel.cs b/BPASmartClient.IoT/Model/IOT/IOTDevModel.cs new file mode 100644 index 00000000..b1186572 --- /dev/null +++ b/BPASmartClient.IoT/Model/IOT/IOTDevModel.cs @@ -0,0 +1,336 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DataVAPI.Tool.IOT +{ + /// + /// IOT Model + /// + public class IotModel + { + public string id { get; set; } = Guid.NewGuid().ToString(); + public string version { get; set; } = "1.0"; + public T @params { get; set; } + public string method { get; set; } = "thing.event.property.post"; + } + /// + /// IOT 接收数据Model + /// + public class ReceiveModel + { + /// + /// 设备详细信息 + /// + public DevBase deviceContext { get; set; } + /// + /// 设备属性 + /// + public ReceiveSXModel props { get; set; } + /// + /// 设备上下线状态 + /// + public Vls status { get; set; } + + } + /// + /// 接收数据Model + /// + public class ReceiveSXModel + { + /// + /// 告警消息 + /// + public Vls GJXX { get; set; } + /// + /// 扩展属性 + /// + public Vls KZSX { get; set; } + /// + /// 基本属性 + /// + public Vls JBSX { get; set; } + /// + /// 节点状态 + /// + public Vls NodeStatus { get; set; } + /// + /// 日志消息 + /// + public Vls SZXX { get; set; } + } + /// + /// IOT 设备属性 Model + /// + public class IOTDevSXModel + { + /// + /// 硬件状态 + /// + public string HardwareStatus { get; set; } + /// + /// 扩展属性 + /// + public string KZSX { get; set; } + /// + /// 基本属性 + /// + public string JBSX { get; set; } + /// + /// 节点状态 + /// + public string NodeStatus { get; set; } + /// + /// Model + /// + public IOTDevSXModel() + { + + } + /// + /// 序列化为JSON + /// + /// + public string Tojson() + { + try + { + IotModel iotModel = new IotModel { @params = this }; + string json = Tools.JsonConvertTools(iotModel); + return json; + } + catch (Exception ex) + { + return string.Empty; + } + } + /// + /// 设置基本属性 + /// + /// + /// + public void SetJBSX(DevSX devSX) + { + try + { + JBSX = Tools.JsonConvertTools(devSX); + } + catch (Exception ex) + { + JBSX = string.Empty; + } + } + /// + /// 设置基本属性状态 + /// + /// + /// + public void SetJBSXStatus(DevSXBase sXBase, bool Status) + { + try + { + if (sXBase == null) return; + DevSX dev = Tools.JsonToObjectTools(JBSX); + dev.data?.ForEach(x => + { + if (x.SXMC == sXBase.SXMC && x.SXLX == sXBase.SXLX) + { + x.SXStatus = Status; + } + }); + JBSX = Tools.JsonConvertTools(dev); + } + catch (Exception ex) + { + JBSX = string.Empty; + } + } + /// + /// 设置扩展属性 + /// + /// + public void SetKZSX(DevSX devSX) + { + try + { + KZSX = Tools.JsonConvertTools(devSX); + } + catch (Exception ex) + { + KZSX = string.Empty; + } + } + /// + /// 设置扩展属性状态 + /// + /// + /// + public void SetKZSXStatus(DevSXBase sXBase, bool Status) + { + try + { + if (sXBase == null) return; + DevSX dev = Tools.JsonToObjectTools(KZSX); + dev.data?.ForEach(x => + { + if (x.SXMC == sXBase.SXMC && x.SXLX == sXBase.SXLX) + { + x.SXStatus = Status; + } + }); + KZSX = Tools.JsonConvertTools(dev); + } + catch (Exception ex) + { + KZSX = string.Empty; + } + } + } + /// + /// 告警消息 + /// + public class AlarmMessage + { + public List data { get; set; } + } + /// + /// 告警Model + /// + public class AlarmModel : DeviceBase + { + /// + /// 告警程度:提示 一般 严重 + /// + public string AlarmCD + { + get { return _AlarmCD; } + set + { + _AlarmCD = value; + if (_AlarmCD == "提示") DeviceColor = new ALYColor { r = 13, g = 254, b = 73, a = 1 }; + else if (_AlarmCD == "一般") DeviceColor = new ALYColor { r = 245, g = 216, b = 13, a = 1 }; + else if (_AlarmCD == "严重") DeviceColor = new ALYColor { r = 245, g = 13, b = 13, a = 1 }; + } + } + private string _AlarmCD { get; set; } + /// + /// 颜色 + /// + public ALYColor DeviceColor { get; set; } + } + /// + /// 设备上报属性 + /// + public class DevSX + { + public List data { get; set; } + } + /// + /// 设备基本属性Model + /// + public class DevSXBase + { + /// + /// 属性名称 + /// + public string SXMC { get; set; } + /// + /// 属性类型 + /// + public string SXLX { get; set; } + /// + /// 属性状态 + /// + private bool _SXStatus { get; set; } + public bool SXStatus + { + get { return _SXStatus; } + set + { + _SXStatus = value; + if (_SXStatus) + { + SXZT = "正常"; + } + else + { + SXZT = "异常"; + } + } + } + private string _SXZT { get; set; } + /// + /// 属性状态:正常 异常 + /// + public string SXZT + { + get { return _SXZT; } + set + { + _SXZT = value; + if (_SXZT == "正常") + { + SXYC = new ALYColor { r = 13, g = 254, b = 73, a = 1 };//绿色 + SXYCMS = ""; + YCZT = ""; + ButtonText = ""; + ButtonYC = new ALYColor { r = 0, g = 0, b = 0, a = 0 }; + } + else if (_SXZT == "异常") + { + SXYC = new ALYColor { r = 245, g = 13, b = 13, a = 1 };//红色 + ButtonText = "详情"; + ButtonYC = new ALYColor { r = 48, g = 109, b = 201, a = 0.18 }; + } + } + } + /// + /// 属性异常描述 + /// + public string SXYCMS { get; set; } + public string YCZT { get; set; } + /// + /// 属性颜色 + /// + public ALYColor SXYC { get; set; } + /// + /// 按钮文字 + /// + public string ButtonText { get; set; } + /// + /// 按钮颜色 + /// + public ALYColor ButtonYC { get; set; } + public DevSXBase() + { + SXZT = ""; + SXYC = new ALYColor { r = 13, g = 254, b = 73, a = 1 };//绿色 + SXYCMS = ""; + YCZT = ""; + ButtonText = ""; + ButtonYC = new ALYColor { r = 0, g = 0, b = 0, a = 0 }; + } + } + + /// + /// 设备颜色 + /// + public class ALYColor + { + public int r { get; set; } + public int g { get; set; } + public int b { get; set; } + public double a { get; set; } + } + + /// + /// 变量 + /// + public class Vls + { + public long time { get; set; } + public string value { get; set; } + } +} diff --git a/BPASmartClient.IoT/Model/IOT/IOTDevServer.cs b/BPASmartClient.IoT/Model/IOT/IOTDevServer.cs new file mode 100644 index 00000000..98de2203 --- /dev/null +++ b/BPASmartClient.IoT/Model/IOT/IOTDevServer.cs @@ -0,0 +1,467 @@ + + +using BPASmartClient.Helper; +using BPASmartClient.IoT; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Security.Cryptography; +using System.Text; +using System.Threading; +using uPLibrary.Networking.M2Mqtt; +using uPLibrary.Networking.M2Mqtt.Messages; + +namespace DataVAPI.Tool.IOT +{ + /// + /// add fengyoufu + /// 黑菠萝科技有限公司 + /// IOT设备上报消息类 + /// + public class IOTDevServer + { + #region 私有IOT连接变量 + private static string ProductKey = "grgpECHSL7q"; + private static string DeviceName = "hbldev"; + private static string DeviceSecret = "4ec120de0c866199183b22e2e3135aeb"; + private static string RegionId = "cn-shanghai"; + private static string mqttUserName = string.Empty; + private static string mqttPassword = string.Empty; + private static string mqttClientId = string.Empty; + private static string targetServer = string.Empty; + #endregion + + #region 公有变量 + /// + /// 设备消息数据回调 + /// + public static Action DevIOTAction { get; set; } + /// + /// 重连事件 + /// + public static Action UNConnectMqtt { get; set; } + /// + /// 客户端 + /// + public static MqttClient client { get; set; } + #endregion + + #region 发布或订阅主题或URL地址 + /// + /// API 服务 + /// + private static string APIurl = "http://124.222.238.75:6002"; + /// + /// 属性发布消息主题 + /// + public static string PubTopic = "/" + ProductKey + "/" + DeviceName + "/user/update"; + /// + /// 属性接收消息主题 + /// + public static string SubTopic = "/" + ProductKey + "/" + DeviceName + "/user/get"; + /// + /// 自定义发布消息主题 + /// + public static string UserPubTopic = "/" + ProductKey + "/" + DeviceName + "/user/update"; + /// + /// 自定义接收消息主题 + /// + public static string UserSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/get"; + /// + /// 告警订阅主题 + /// + public static string AlarmSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/AlarmMessage"; + /// + /// 日志订阅主题 + /// + public static string LogsSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/ExceptionLogs"; + /// + /// 上下线订阅主题 + /// + public static string HeartbeatSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/HeartbeatAndState"; + /// + /// 属性状态主题 + /// + public static string TargetStatusSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/TargetStatus"; + /// + /// 大屏展示发布主题 + /// + public static string ScreenShowPubTopic = "/" + ProductKey + "/" + DeviceName + "/user/ScreenShow"; + /// + /// 广播主题 + /// + public static string BroadcastTopic = "/broadcast/" + "grgpECHSL7q" + "/" + DeviceName + "_SetDevice"; + /// + /// 订阅主题集合 + /// + public static List SubTopicList = new List(); + #endregion + + #region 单例模式 + private static IOTDevServer iot = null; + public static IOTDevServer GetInstance() + { + if (iot == null) { iot = new IOTDevServer(); } + return iot; + } + #endregion + + #region 公共调用阿里云连接或检测 + /// + /// 设置URL + /// + /// + public void SetUrl(string url = "http://124.222.238.75:6002") + { + APIurl = url; + } + + /// + /// 设置变量 + /// + /// + /// + /// + /// + public void Set(string _ProductKey, string _DeviceName, string _DeviceSecret, string _RegionId = "cn-shanghai") + { + ProductKey = _ProductKey; + DeviceName = _DeviceName; + DeviceSecret = _DeviceSecret; + RegionId = _RegionId; + PubTopic = "/sys/" + ProductKey + "/" + DeviceName + "/thing/event/property/post"; + SubTopic = "/sys/" + ProductKey + "/" + DeviceName + "/thing/event/property/set"; + UserPubTopic = "/" + ProductKey + "/" + DeviceName + "/user/update"; + UserSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/get"; + BroadcastTopic = "/broadcast/" + ProductKey + "/" + DeviceName + "_SetDevice"; + AlarmSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/AlarmMessage"; + LogsSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/ExceptionLogs"; + HeartbeatSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/HeartbeatAndState"; + TargetStatusSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/TargetStatus"; + ScreenShowPubTopic = "/" + ProductKey + "/" + DeviceName + "/user/ScreenShow"; + } + + /// + /// 创建连接 + /// + /// + public bool CreateLinks(int ClientId, out DeviceTable device) + { + try + { + //http://localhost:9092/api/Device/Query?chid=2 + string json = HttpRequestHelper.HttpGetRequest($"{APIurl}/api/Device/Query?clientId={ClientId}"); + JsonMsg> jsonMsg = Tools.JsonToObjectTools>>(json); + if (jsonMsg.obj != null && jsonMsg.obj.data!=null) + { + device = jsonMsg.obj.data.FirstOrDefault(); + if (device == null) return false; + + Set(device.productkey, device.devicename, device.devicesecret); + + IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName()); + string clientId = host.AddressList.FirstOrDefault( + ip => ip.AddressFamily == AddressFamily.InterNetwork).ToString(); + string t = Convert.ToString(DateTimeOffset.Now.ToUnixTimeMilliseconds()); + string signmethod = "hmacmd5"; + + Dictionary dict = new Dictionary(); + dict.Add("productKey", ProductKey); + dict.Add("deviceName", DeviceName); + dict.Add("clientId", clientId); + dict.Add("timestamp", t); + + mqttUserName = DeviceName + "&" + ProductKey; + mqttPassword = IotSignUtils.sign(dict, DeviceSecret, signmethod); + mqttClientId = clientId + "|securemode=3,signmethod=" + signmethod + ",timestamp=" + t + "|"; + targetServer = ProductKey + ".iot-as-mqtt." + RegionId + ".aliyuncs.com"; + ConnectMqtt(targetServer, mqttClientId, mqttUserName, mqttPassword); + return true; + } + else + { + device = null; + return false; + } + } + catch (Exception ex) + { + device = null; + return false; + } + } + + /// + /// 获取连接状态 + /// + public bool GetIsConnected() + { + try + { + if (client == null || !client.IsConnected) + return false; + else return true; + } + catch (Exception ex) + { + return false; + throw; + } + } + + /// + /// 断开连接 + /// + public void Disconnect() + { + if (client != null) + { + client.Disconnect(); + } + } + #endregion + + #region 公共发布或订阅函数 + /// + /// 发布消息 + /// + /// + /// + public void IOT_Publish(string topic, string message) + { + var id = client.Publish(topic, Encoding.UTF8.GetBytes(message)); + } + + /// + /// 订阅主题 + /// + /// + public void IOT_Subscribe(string topic) + { + if (SubTopicList.Contains(topic)) + { + SubTopicList.Add(topic); + } + client.Subscribe(new string[] { topic }, new byte[] { 0 }); + } + #endregion + + #region 私有函数 + /// + /// mQTT创建连接 + /// + /// + /// + /// + /// + private void ConnectMqtt(string targetServer, string mqttClientId, string mqttUserName, string mqttPassword) + { + client = new MqttClient(targetServer); + client.ProtocolVersion = MqttProtocolVersion.Version_3_1_1; + client.Connect(mqttClientId, mqttUserName, mqttPassword, false, 60); + client.MqttMsgPublishReceived += Client_MqttMsgPublishReceived; + client.ConnectionClosed += Client_ConnectionClosed; + } + + /// + /// MQTT 断开事件 + /// + /// + /// + private static void Client_ConnectionClosed(object sender, EventArgs e) + { + // 尝试重连 + _TryContinueConnect(); + } + + /// + /// 订阅数据接收 + /// + /// + /// + private static void Client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e) + { + string topic = e.Topic; + string message = Encoding.UTF8.GetString(e.Message); + if (DevIOTAction != null) + { + DevIOTAction.Invoke(topic, message); + } + } + + /// + /// 自动重连主体 + /// + private static void _TryContinueConnect() + { + Thread retryThread = new Thread(new ThreadStart(delegate + { + while (client == null || !client.IsConnected) + { + if (client.IsConnected) break; + + if (client == null) + { + client = new MqttClient(targetServer); + client.ProtocolVersion = MqttProtocolVersion.Version_3_1_1; + client.Connect(mqttClientId, mqttUserName, mqttPassword, false, 60); + client.MqttMsgPublishReceived += Client_MqttMsgPublishReceived; + client.ConnectionClosed += Client_ConnectionClosed; + if (client.IsConnected) + { + SubTopicList.ForEach(par => + { + client.Subscribe(new string[] { par }, new byte[] { 0 }); + }); + } + Thread.Sleep(3000); + continue; + } + + try + { + client.Connect(mqttClientId, mqttUserName, mqttPassword, false, 60); + if (client.IsConnected) + { + SubTopicList.ForEach(par => + { + client.Subscribe(new string[] { par }, new byte[] { 0 }); + }); + UNConnectMqtt?.Invoke("重新连接阿里云MQTT成功!"); + } + } + catch (Exception ce) + { + UNConnectMqtt?.Invoke("重新连接阿里云MQTT失败!"); + } + // 如果还没连接不符合结束条件则睡2秒 + if (!client.IsConnected) + { + Thread.Sleep(2000); + } + } + })); + + retryThread.Start(); + } + #endregion + } + + /// + /// Iot 设备上报 + /// + public class IotSignUtils + { + public static string sign(Dictionary param, + string deviceSecret, string signMethod) + { + string[] sortedKey = param.Keys.ToArray(); + Array.Sort(sortedKey); + + StringBuilder builder = new StringBuilder(); + foreach (var i in sortedKey) + { + builder.Append(i).Append(param[i]); + } + + byte[] key = Encoding.UTF8.GetBytes(deviceSecret); + byte[] signContent = Encoding.UTF8.GetBytes(builder.ToString()); + //这里根据signMethod动态调整,本例子硬编码了: 'hmacmd5' + var hmac = new HMACMD5(key); + byte[] hashBytes = hmac.ComputeHash(signContent); + + StringBuilder signBuilder = new StringBuilder(); + foreach (byte b in hashBytes) + signBuilder.AppendFormat("{0:x2}", b); + + return signBuilder.ToString(); + } + } + + /// + /// 工具 + /// + public class Tools + { + /// + /// 对象Json序列 + /// + /// 对象类型 + /// 对象实例 + /// + public static string JsonConvertTools(T obj) + { + string strvalue = JsonConvert.SerializeObject(obj); + return strvalue; + } + + /// + /// 对象反Json序列 + /// + /// 对象类型 + /// 对象序列化json字符串 + /// 返回对象实例 + public static T JsonToObjectTools(string jsonstring) + { + T obj = JsonConvert.DeserializeObject(jsonstring); + return obj; + } + + /// + /// DateTime --> long + /// + /// + /// + public static long ConvertDateTimeToLong(DateTime dt) + { + DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); + TimeSpan toNow = dt.Subtract(dtStart); + long timeStamp = toNow.Ticks; + timeStamp = long.Parse(timeStamp.ToString().Substring(0, timeStamp.ToString().Length - 4)); + return timeStamp; + } + + /// + /// long --> DateTime + /// + /// + /// + public static DateTime ConvertLongToDateTime(long d) + { + DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); + long lTime = long.Parse(d + "0000"); + TimeSpan toNow = new TimeSpan(lTime); + DateTime dtResult = dtStart.Add(toNow); + return dtResult; + } + + /// + /// 获取IP 地址 + /// + /// + public static string GetLocalIp() + { + //得到本机名 + string hostname = Dns.GetHostName(); + //解析主机名称或IP地址的system.net.iphostentry实例。 + IPHostEntry localhost = Dns.GetHostEntry(hostname); + if (localhost != null) + { + foreach (IPAddress item in localhost.AddressList) + { + //判断是否是内网IPv4地址 + if (item.AddressFamily == AddressFamily.InterNetwork) + { + return item.MapToIPv4().ToString(); + } + } + } + return "192.168.1.124"; + } + } + + +} diff --git a/BPASmartClient.IoT/Model/IOT/ScreenMonitorModel.cs b/BPASmartClient.IoT/Model/IOT/ScreenMonitorModel.cs new file mode 100644 index 00000000..21933f4e --- /dev/null +++ b/BPASmartClient.IoT/Model/IOT/ScreenMonitorModel.cs @@ -0,0 +1,275 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DataVAPI.Tool.IOT +{ + + /// + /// 大屏监视Model + /// + public class ScreenMonitorModel + { + /// + /// 服务商家数 + /// + public string TotalSales { get; set; } + /// + /// 现场运营设备状态 + /// + public OperatingDeviceStatus operatingDeviceStatus { get; set; } + /// + /// 通知消息 + /// + public InfoMessage infoMessage { get; set; } + /// + /// 返回JSON + /// + /// + public string ToJSON() + { + try + { + return Tools.JsonConvertTools(this); + } + catch (Exception ex) + { + return string.Empty; + } + } + /// + /// 序列化为对象 + /// + /// + /// + public ScreenMonitorModel JSONtoDX(string JSON) + { + try + { + return Tools.JsonToObjectTools(JSON); + } + catch (Exception ex) + { + return new ScreenMonitorModel(); + } + } + } + /// + /// 下订单统计 + /// + public class PlaceOrderCount + { + /// + /// 今日下单量统计 + /// + public string ToDayPlaceCount { get; set; } + /// + /// 本月下单量统计 + /// + public string MonthPlaceCount { get; set; } + /// + /// 本年下单量统计 + /// + public string YearPlaceCount { get; set; } + + } + /// + /// 制作流程 + /// + public class ProcessMessage + { + public List data { get; set; } + } + /// + /// 制作流程Model + /// + public class ProcessModel + { + /// + /// 告警程度:提示 一般 严重 + /// + private bool _IsMark { get; set; } + public bool IsMark + { + get { return _IsMark; } + set + { + _IsMark = value; + if (_IsMark) ProcessColor = new ALYColor { r = 253, g = 234, b = 1, a = 1 }; + else ProcessColor = new ALYColor { r = 151, g = 150, b = 140, a = 1 }; + } + } + /// + /// 流程名称 + /// + public string ProcessName { get; set; } + /// + /// 流程描述 + /// + public string ProcessMS { get; set; } + /// + /// 颜色 + /// + public ALYColor ProcessColor { get; set; } + public ProcessModel() + { + IsMark = false; + ProcessMS = string.Empty; + ProcessName = string.Empty; + } + + } + + /// + /// 通知消息 + /// + public class InfoMessage + { + public List data { get; set; } + + } + /// + /// 运营设备及状态 + /// + public class OperatingDeviceStatus + { + public List data { get; set; } + } + /// + /// 设备状态 + /// + public class DevStatus : DeviceBase + { + /// + /// 设备状态 + /// + public string DeviceZT + { + get { return _DeviceZT; } + set + { + _DeviceZT = value; + if (_DeviceZT == "在线") DeviceColor = new ALYColor { r = 13, g = 254, b = 73, a = 1 }; + else DeviceColor = new ALYColor { r = 249, g = 191, b = 0, a = 1 }; + } + } + private string _DeviceZT { get; set; } + /// + /// 是否有告警 + /// + public bool IsAlarm + { + get { return _IsAlarm; } + set + { + _IsAlarm = value; + if (_IsAlarm) AlarmColor = new ALYColor { r = 245, g = 13, b = 13, a = 1 }; + else AlarmColor = new ALYColor { r = 245, g = 13, b = 13, a = 0 }; + } + } + private bool _IsAlarm { get; set; } + + /// + /// 颜色 + /// + public ALYColor DeviceColor { get; set; } + /// + /// 告警颜色 + /// + public ALYColor AlarmColor { get; set; } + /// + /// 初始化 + /// + public DevStatus() + { + IsAlarm = false; + AlarmColor = new ALYColor { r = 245, g = 13, b = 13, a = 0 }; + DeviceColor = new ALYColor { r = 249, g = 191, b = 0, a = 1 }; + } + /// + /// 设置属性 + /// + /// + /// + /// + /// + /// + /// + public void SetTarget(string _deviceName, string _gmtCreate, string _DeviceMC, string _DeviceMS, string _DeviceSJ, string _DeviceZT) + { + deviceName = _deviceName; + gmtCreate = _gmtCreate; + DeviceMC = _DeviceMC; + DeviceMS = _DeviceMS; + DeviceSJ = _DeviceSJ; + DeviceZT = _DeviceZT; + } + /// + /// 状态 + /// + /// + public void SetStatus(string _DeviceZT) + { + DeviceSJ = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + DeviceZT = _DeviceZT; + } + } + /// + /// 设备基本属性 + /// + public class DeviceBase : DevBase + { + /// + /// 设备名称 + /// + public string DeviceMC { get; set; } + /// + /// 设备描述 + /// + public string DeviceMS { get; set; } + /// + /// 设备时间 + /// + public string DeviceSJ { get; set; } + /// + /// 设备状态:已处理 未处理 + /// + public string DeviceZT { get; set; } + } + /// + /// 设备基本信息 + /// + public class DevBase + { + /// + /// 唯一id + /// + public string id { get; set; } + /// + /// 设备key + /// + public string productKey { get; set; } + /// + /// 设备名称 + /// + public string deviceName { get; set; } + /// + /// gmtCreate + /// + public string gmtCreate { get; set; } + /// + /// 客户端ID + /// + public string clientId { get; set; } + + public DevBase() + { + id = Guid.NewGuid().ToString(); + } + } + + + +} diff --git a/BPASmartClient.IoT/Model/JsonMsg.cs b/BPASmartClient.IoT/Model/JsonMsg.cs new file mode 100644 index 00000000..8f1ee188 --- /dev/null +++ b/BPASmartClient.IoT/Model/JsonMsg.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.IoT +{ + /// + /// 返回消息 + /// + public class JsonMsg where T : class + { + /// + /// 状态码 + /// + public int code { get; set; } + + /// + /// 消息 + /// + public string msg { get; set; } + + /// + /// 描述 + /// + public string ms { get; set; } + + /// + /// 内容 + /// + public IOTData obj { get; set; } + + ///// + ///// 返回数据 + ///// + //public IOTData oTData { get; set; } + + /// + /// 图标 + /// + public int icon { get; set; } + + + public static JsonMsg OK(T obj, string msg = "接口名称", string mso = "调用接口成功") + { + string str = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 接口名称为“ {msg + "”调用成功,描述:" + mso + obj}"; + ConsoleColor currentForeColor = Console.ForegroundColor; + Console.ForegroundColor = ConsoleColor.Green; + Console.WriteLine(str); + Console.ForegroundColor = currentForeColor; + ; + return new JsonMsg() { code = 1, ms = mso, msg = "成功", obj = new IOTData { data = obj }, icon = 1}; + } + + public static JsonMsg Error(T obj, string msg = "接口名称", string mso = "调用接口成功失败") + { + string str = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 接口名称为“ {msg + "”调用失败,描述:" + mso + obj}"; + ConsoleColor currentForeColor = Console.ForegroundColor; + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine(str); + Console.ForegroundColor = currentForeColor; + return new JsonMsg() { code = 0, ms = mso, msg = "失败",icon = 1, obj = new IOTData { data = obj } }; + } + } + + public class IOTData where T : class + { + public T data { get; set; } + } +} diff --git a/BPASmartClient.IoT/Model/LargeScreenTable.cs b/BPASmartClient.IoT/Model/LargeScreenTable.cs new file mode 100644 index 00000000..10faa77a --- /dev/null +++ b/BPASmartClient.IoT/Model/LargeScreenTable.cs @@ -0,0 +1,14 @@ +namespace BPASmartClient.IoT +{ + /// + /// 大屏消息表 + /// + public class LargeScreenTable : BaseEntity + { + /// + /// Json值 + /// + public string json { get; set; } + } + +} diff --git a/BPASmartClient.IoT/Model/LogTable.cs b/BPASmartClient.IoT/Model/LogTable.cs new file mode 100644 index 00000000..7aec43c0 --- /dev/null +++ b/BPASmartClient.IoT/Model/LogTable.cs @@ -0,0 +1,29 @@ +namespace BPASmartClient.IoT +{ + /// + /// 日志表 + /// + public class LogTable : BaseEntity + { + /// + /// 日志时间 + /// + public string LogTime { get; set; } + /// + /// 日志类型:1 轻微 2:一般 3 严重 + /// + public string LogType { get; set; } + /// + /// 日志消息 + /// + public string LogMessage { get; set; } + /// + /// 日志值 + /// + public string LogVla { get; set; } + /// + /// IP 地址 + /// + public string IP { get; set; } + } +} diff --git a/BPASmartClient/App.config b/BPASmartClient/App.config index 6f8c7af3..aa86f0ed 100644 --- a/BPASmartClient/App.config +++ b/BPASmartClient/App.config @@ -15,9 +15,10 @@ + - +