@@ -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 | |||
{ | |||
/// <summary> | |||
/// 该类实现客户端http 同步请求 | |||
/// 支持环境 -.net4.0/-.net4.5 | |||
/// 创建人:奉友福 | |||
/// </summary> | |||
public class HttpRequestHelper | |||
{ | |||
#region 私有变量 | |||
#endregion | |||
#region 公用函数 | |||
/// <summary> | |||
/// GET 同步请求 | |||
/// 创建人:奉友福 | |||
/// 创建时间:2020-11-19 | |||
/// </summary> | |||
/// <param name="url">请求地址</param> | |||
/// <returns>超时时间设置,默认5秒</returns> | |||
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; | |||
} | |||
/// <summary> | |||
/// POST 同步请求 | |||
/// 创建人:奉友福 | |||
/// 创建时间:2020-11-19 | |||
/// </summary> | |||
/// <param name="url">请求地址</param> | |||
/// <param name="PostJsonData">请求数据</param> | |||
/// <returns></returns> | |||
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; | |||
} | |||
/// <summary> | |||
/// GET 同步请求 | |||
/// </summary> | |||
/// <param name="url">地址</param> | |||
/// <param name="head">头</param> | |||
/// <param name="headInfo">内容</param> | |||
/// <returns></returns> | |||
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; | |||
} | |||
/// <summary> | |||
/// Post请求带Token | |||
/// 2021-2-2 by dulf | |||
/// </summary> | |||
/// <param name="url"></param> | |||
/// <param name="head"></param> | |||
/// <param name="headInfo"></param> | |||
/// <param name="postParam"></param> | |||
/// <returns></returns> | |||
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("请求<HttpPostResponseWithHead>异常:" + ex.Message); | |||
} | |||
return ""; | |||
} | |||
#endregion | |||
} | |||
/// <summary> | |||
/// HTTP请求类 | |||
/// </summary> | |||
public class HttpRequest | |||
{ | |||
#region 私有变量 | |||
/// <summary> | |||
/// http请求超时时间设置 | |||
/// 默认值:5秒 | |||
/// </summary> | |||
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 公用函数 | |||
/// <summary> | |||
/// 函数名称:创建http请求 | |||
/// 创建人:奉友福 | |||
/// 创建时间:2020-11-19 | |||
/// 例如GET 请求: 地址 + "GET" | |||
/// 例如POST请求: 地址 + "POST" + JSON | |||
/// </summary> | |||
/// <param name="url">http请求地址</param> | |||
/// <param name="requestType">http请求方式:GET/POST</param> | |||
/// <param name="strjson">http请求附带数据</param> | |||
/// <returns></returns> | |||
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; | |||
} | |||
/// <summary> | |||
/// http获取数据 | |||
/// </summary> | |||
/// <param name="response"></param> | |||
/// <param name="requestType"></param> | |||
/// <returns></returns> | |||
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 私有函数 | |||
/// <summary> | |||
/// http+GET请求 | |||
/// </summary> | |||
/// <param name="url">请求地址</param> | |||
/// <returns>请求结果</returns> | |||
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; | |||
} | |||
/// <summary> | |||
/// http+POST请求 | |||
/// </summary> | |||
/// <param name="url">请求地址</param> | |||
/// <param name="postData"></param> | |||
/// <returns>请求结果</returns> | |||
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 | |||
} | |||
} |
@@ -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 | |||
{ | |||
/// <summary> | |||
/// 工具 | |||
/// </summary> | |||
public class Tools | |||
{ | |||
/// <summary> | |||
/// 对象Json序列 | |||
/// </summary> | |||
/// <typeparam name="T">对象类型</typeparam> | |||
/// <param name="obj">对象实例</param> | |||
/// <returns></returns> | |||
public static string JsonConvertTools<T>(T obj) | |||
{ | |||
string strvalue = JsonConvert.SerializeObject(obj); | |||
return strvalue; | |||
} | |||
/// <summary> | |||
/// 对象反Json序列 | |||
/// </summary> | |||
/// <typeparam name="T">对象类型</typeparam> | |||
/// <param name="jsonstring">对象序列化json字符串</param> | |||
/// <returns>返回对象实例</returns> | |||
public static T JsonToObjectTools<T>(string jsonstring) | |||
{ | |||
T obj = JsonConvert.DeserializeObject<T>(jsonstring); | |||
return obj; | |||
} | |||
/// <summary> | |||
/// DateTime --> long | |||
/// </summary> | |||
/// <param name="dt"></param> | |||
/// <returns></returns> | |||
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; | |||
} | |||
/// <summary> | |||
/// long --> DateTime | |||
/// </summary> | |||
/// <param name="d"></param> | |||
/// <returns></returns> | |||
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; | |||
} | |||
/// <summary> | |||
/// 获取IP 地址 | |||
/// </summary> | |||
/// <returns></returns> | |||
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"; | |||
} | |||
} | |||
} |
@@ -4,4 +4,15 @@ | |||
<TargetFramework>net6.0</TargetFramework> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<PackageReference Include="M2Mqtt" Version="4.3.0" /> | |||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> | |||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\BPASmartClient.Business\BPASmartClient.Business.csproj" /> | |||
<ProjectReference Include="..\BPASmartClient.Helper\BPASmartClient.Helper.csproj" /> | |||
</ItemGroup> | |||
</Project> |
@@ -1,8 +0,0 @@ | |||
using System; | |||
namespace BPASmartClient.IoT | |||
{ | |||
public class Class1 | |||
{ | |||
} | |||
} |
@@ -0,0 +1,30 @@ | |||
using System; | |||
namespace BPASmartClient.IoT | |||
{ | |||
/// <summary> | |||
/// DataV客户端数据中心 | |||
/// </summary> | |||
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() | |||
{ | |||
} | |||
} | |||
} |
@@ -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 | |||
{ | |||
/// <summary> | |||
/// DataV客户端 | |||
/// </summary> | |||
public class DataVReport | |||
{ | |||
#region 外部调用 | |||
/// <summary> | |||
/// 初始化IOT连接 | |||
/// </summary> | |||
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; | |||
} | |||
/// <summary> | |||
/// 获取连接状态 | |||
/// </summary> | |||
public bool GetIsConnected() | |||
{ | |||
try | |||
{ | |||
if (DatavDeviceClient == null || !DatavDeviceClient.IsConnected) | |||
return false; | |||
else return true; | |||
} | |||
catch (Exception ex) | |||
{ | |||
return false; | |||
throw; | |||
} | |||
} | |||
/// <summary> | |||
/// 断开连接 | |||
/// </summary> | |||
public void Disconnect() | |||
{ | |||
if (DatavDeviceClient != null) | |||
{ | |||
DatavDeviceClient.Disconnect(); | |||
} | |||
} | |||
/// <summary> | |||
/// 发布消息 | |||
/// </summary> | |||
/// <param name="topic"></param> | |||
/// <param name="message"></param> | |||
public void IOT_Publish(string topic, string message) | |||
{ | |||
var id = DatavDeviceClient.Publish(topic, Encoding.UTF8.GetBytes(message)); | |||
} | |||
/// <summary> | |||
/// 订阅主题 | |||
/// </summary> | |||
/// <param name="topic"></param> | |||
public void IOT_Subscribe(string topic) | |||
{ | |||
if (SubTopicList.Contains(topic)) | |||
{ | |||
SubTopicList.Add(topic); | |||
} | |||
DatavDeviceClient.Subscribe(new string[] { topic }, new byte[] { 0 }); | |||
} | |||
#endregion | |||
#region 私有函数 | |||
/// <summary> | |||
/// 设置变量 | |||
/// </summary> | |||
/// <param name="_ProductKey"></param> | |||
/// <param name="_DeviceName"></param> | |||
/// <param name="_DeviceSecret"></param> | |||
/// <param name="_RegionId"></param> | |||
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"; | |||
} | |||
/// <summary> | |||
/// 创建连接 | |||
/// </summary> | |||
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<List<DeviceTable>> jsonMsg = Tools.JsonToObjectTools<JsonMsg<List<DeviceTable>>>(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<string, string> dict = new Dictionary<string, string>(); | |||
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; | |||
} | |||
} | |||
/// <summary> | |||
/// MQTT创建连接 | |||
/// </summary> | |||
/// <param name="targetServer"></param> | |||
/// <param name="mqttClientId"></param> | |||
/// <param name="mqttUserName"></param> | |||
/// <param name="mqttPassword"></param> | |||
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; | |||
} | |||
/// <summary> | |||
/// MQTT 断开事件 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
private static void Client_ConnectionClosed(object sender, EventArgs e) | |||
{ | |||
// 尝试重连 | |||
_TryContinueConnect(); | |||
} | |||
/// <summary> | |||
/// 订阅数据接收 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
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); | |||
} | |||
} | |||
/// <summary> | |||
/// 自动重连主体 | |||
/// </summary> | |||
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 公有变量 | |||
/// <summary> | |||
/// 设备消息数据回调 | |||
/// </summary> | |||
public static Action<string, string> DataVMessageAction { get; set; } | |||
/// <summary> | |||
/// 重连事件 | |||
/// </summary> | |||
public static Action<string> UnConnectMqtt { get; set; } | |||
/// <summary> | |||
/// 客户端 | |||
/// </summary> | |||
public static MqttClient DatavDeviceClient { get; set; } | |||
/// <summary> | |||
/// 当前设备 | |||
/// </summary> | |||
public DeviceTable deviceTable { get; set; } | |||
#endregion | |||
#region 发布或订阅主题或URL地址 | |||
/// <summary> | |||
/// 属性发布消息主题 | |||
/// </summary> | |||
public static string PubTopic = "/" + ProductKey + "/" + DeviceName + "/user/update"; | |||
/// <summary> | |||
/// 属性接收消息主题 | |||
/// </summary> | |||
public static string SubTopic = "/" + ProductKey + "/" + DeviceName + "/user/get"; | |||
/// <summary> | |||
/// 自定义发布消息主题 | |||
/// </summary> | |||
public static string UserPubTopic = "/" + ProductKey + "/" + DeviceName + "/user/update"; | |||
/// <summary> | |||
/// 自定义接收消息主题 | |||
/// </summary> | |||
public static string UserSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/get"; | |||
/// <summary> | |||
/// 告警订阅主题 | |||
/// </summary> | |||
public static string AlarmSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/AlarmMessage"; | |||
/// <summary> | |||
/// 日志订阅主题 | |||
/// </summary> | |||
public static string LogsSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/ExceptionLogs"; | |||
/// <summary> | |||
/// 上下线订阅主题 | |||
/// </summary> | |||
public static string HeartbeatSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/HeartbeatAndState"; | |||
/// <summary> | |||
/// 属性状态主题 | |||
/// </summary> | |||
public static string TargetStatusSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/TargetStatus"; | |||
/// <summary> | |||
/// 大屏展示发布主题 | |||
/// </summary> | |||
public static string ScreenShowPubTopic = "/" + ProductKey + "/" + DeviceName + "/user/ScreenShow"; | |||
/// <summary> | |||
/// 广播主题 | |||
/// </summary> | |||
public static string BroadcastTopic = "/broadcast/" + "grgpECHSL7q" + "/" + DeviceName + "_SetDevice"; | |||
/// <summary> | |||
/// 订阅主题集合 | |||
/// </summary> | |||
public static List<string> SubTopicList = new List<string>(); | |||
#endregion | |||
} | |||
/// <summary> | |||
/// Iot 设备上报 | |||
/// </summary> | |||
public class IotSignUtils | |||
{ | |||
public static string sign(Dictionary<string, string> 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(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,35 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.IoT | |||
{ | |||
/// <summary> | |||
/// 告警消息表 | |||
/// </summary> | |||
public class AlarmTable : BaseEntity | |||
{ | |||
/// <summary> | |||
/// 告警时间 | |||
/// </summary> | |||
public string AlarmTime { get; set; } | |||
/// <summary> | |||
/// 告警类型:1 轻微 2:一般 3 严重 | |||
/// </summary> | |||
public string AlarmType { get; set; } | |||
/// <summary> | |||
/// 告警消息 | |||
/// </summary> | |||
public string AlarmMessage { get; set; } | |||
/// <summary> | |||
/// 告警值 | |||
/// </summary> | |||
public string AlarmVla { get; set; } | |||
/// <summary> | |||
/// IP 地址 | |||
/// </summary> | |||
public string IP { get; set; } | |||
} | |||
} |
@@ -0,0 +1,43 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.IoT | |||
{ | |||
/// <summary> | |||
/// MongoDB基类 | |||
/// </summary> | |||
public abstract class BaseEntity | |||
{ | |||
/// <summary> | |||
/// ID | |||
/// </summary> | |||
public string Id { get; set; } | |||
/// <summary> | |||
/// 客户端 ID | |||
/// </summary> | |||
public string ClientId { get; set; } | |||
/// <summary> | |||
/// 设备 ID | |||
/// </summary> | |||
public string DeviceId { get; set; } | |||
/// <summary> | |||
/// 阿里云设备名称 | |||
/// </summary> | |||
public string devicename { get; set; } | |||
/// <summary> | |||
/// 状态 | |||
/// </summary> | |||
public string State { get; set; } | |||
/// <summary> | |||
/// 创建时间 | |||
/// </summary> | |||
public DateTime CreateTime { get; set; } | |||
/// <summary> | |||
/// 修改时间 | |||
/// </summary> | |||
public DateTime UpdateTime { get; set; } | |||
} | |||
} |
@@ -0,0 +1,27 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.IoT | |||
{ | |||
/// <summary> | |||
/// 命令实体类 | |||
/// </summary> | |||
public class CommandModel | |||
{ | |||
/// <summary> | |||
/// 设备名称 | |||
/// </summary> | |||
public string deviceName { get; set; } | |||
/// <summary> | |||
/// 命令名称:0 控制类 1 设置属性 2 通知信息类 | |||
/// </summary> | |||
public int CommandName { get; set; } | |||
/// <summary> | |||
/// 命令变量:执行变量 key为属性或时间 value为值或者消息 | |||
/// </summary> | |||
public Dictionary<string, string> CommandValue { get; set; } | |||
} | |||
} |
@@ -0,0 +1,39 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.IoT | |||
{ | |||
/// <summary> | |||
/// 设备信息表 | |||
/// </summary> | |||
public class DeviceTable : BaseEntity | |||
{ | |||
/// <summary> | |||
/// 阿里云设备key | |||
/// </summary> | |||
public string productkey { get; set; } | |||
/// <summary> | |||
/// 阿里云设备secret | |||
/// </summary> | |||
public string devicesecret { get; set; } | |||
/// <summary> | |||
/// 客户端类型 | |||
/// </summary> | |||
public string devtype { get; set; } | |||
/// <summary> | |||
/// 经度 | |||
/// </summary> | |||
public string jd { get; set; } | |||
/// <summary> | |||
/// 维度 | |||
/// </summary> | |||
public string wd { get; set; } | |||
/// <summary> | |||
/// 备注 | |||
/// </summary> | |||
public string remark { get; set; } | |||
} | |||
} |
@@ -0,0 +1,27 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace DataVAPI.Tool.IOT | |||
{ | |||
/// <summary> | |||
/// 命令实体类 | |||
/// </summary> | |||
public class IOTCommandModel | |||
{ | |||
/// <summary> | |||
/// 设备名称 | |||
/// </summary> | |||
public string deviceName { get; set; } | |||
/// <summary> | |||
/// 命令名称:0 控制类 1 设置属性 2 通知信息类 | |||
/// </summary> | |||
public int CommandName { get; set; } | |||
/// <summary> | |||
/// 命令变量:执行变量 key为属性或时间 value为值或者消息 | |||
/// </summary> | |||
public Dictionary<string, string> CommandValue { get; set; } | |||
} | |||
} |
@@ -0,0 +1,336 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace DataVAPI.Tool.IOT | |||
{ | |||
/// <summary> | |||
/// IOT Model | |||
/// </summary> | |||
public class IotModel<T> | |||
{ | |||
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"; | |||
} | |||
/// <summary> | |||
/// IOT 接收数据Model | |||
/// </summary> | |||
public class ReceiveModel | |||
{ | |||
/// <summary> | |||
/// 设备详细信息 | |||
/// </summary> | |||
public DevBase deviceContext { get; set; } | |||
/// <summary> | |||
/// 设备属性 | |||
/// </summary> | |||
public ReceiveSXModel props { get; set; } | |||
/// <summary> | |||
/// 设备上下线状态 | |||
/// </summary> | |||
public Vls status { get; set; } | |||
} | |||
/// <summary> | |||
/// 接收数据Model | |||
/// </summary> | |||
public class ReceiveSXModel | |||
{ | |||
/// <summary> | |||
/// 告警消息 | |||
/// </summary> | |||
public Vls GJXX { get; set; } | |||
/// <summary> | |||
/// 扩展属性 | |||
/// </summary> | |||
public Vls KZSX { get; set; } | |||
/// <summary> | |||
/// 基本属性 | |||
/// </summary> | |||
public Vls JBSX { get; set; } | |||
/// <summary> | |||
/// 节点状态 | |||
/// </summary> | |||
public Vls NodeStatus { get; set; } | |||
/// <summary> | |||
/// 日志消息 | |||
/// </summary> | |||
public Vls SZXX { get; set; } | |||
} | |||
/// <summary> | |||
/// IOT 设备属性 Model | |||
/// </summary> | |||
public class IOTDevSXModel | |||
{ | |||
/// <summary> | |||
/// 硬件状态 | |||
/// </summary> | |||
public string HardwareStatus { get; set; } | |||
/// <summary> | |||
/// 扩展属性 | |||
/// </summary> | |||
public string KZSX { get; set; } | |||
/// <summary> | |||
/// 基本属性 | |||
/// </summary> | |||
public string JBSX { get; set; } | |||
/// <summary> | |||
/// 节点状态 | |||
/// </summary> | |||
public string NodeStatus { get; set; } | |||
/// <summary> | |||
/// Model | |||
/// </summary> | |||
public IOTDevSXModel() | |||
{ | |||
} | |||
/// <summary> | |||
/// 序列化为JSON | |||
/// </summary> | |||
/// <returns></returns> | |||
public string Tojson() | |||
{ | |||
try | |||
{ | |||
IotModel<IOTDevSXModel> iotModel = new IotModel<IOTDevSXModel> { @params = this }; | |||
string json = Tools.JsonConvertTools(iotModel); | |||
return json; | |||
} | |||
catch (Exception ex) | |||
{ | |||
return string.Empty; | |||
} | |||
} | |||
/// <summary> | |||
/// 设置基本属性 | |||
/// </summary> | |||
/// <param name="devSX"></param> | |||
/// <returns></returns> | |||
public void SetJBSX(DevSX devSX) | |||
{ | |||
try | |||
{ | |||
JBSX = Tools.JsonConvertTools(devSX); | |||
} | |||
catch (Exception ex) | |||
{ | |||
JBSX = string.Empty; | |||
} | |||
} | |||
/// <summary> | |||
/// 设置基本属性状态 | |||
/// </summary> | |||
/// <param name="devSX"></param> | |||
/// <returns></returns> | |||
public void SetJBSXStatus(DevSXBase sXBase, bool Status) | |||
{ | |||
try | |||
{ | |||
if (sXBase == null) return; | |||
DevSX dev = Tools.JsonToObjectTools<DevSX>(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; | |||
} | |||
} | |||
/// <summary> | |||
/// 设置扩展属性 | |||
/// </summary> | |||
/// <param name="devSX"></param> | |||
public void SetKZSX(DevSX devSX) | |||
{ | |||
try | |||
{ | |||
KZSX = Tools.JsonConvertTools(devSX); | |||
} | |||
catch (Exception ex) | |||
{ | |||
KZSX = string.Empty; | |||
} | |||
} | |||
/// <summary> | |||
/// 设置扩展属性状态 | |||
/// </summary> | |||
/// <param name="devSX"></param> | |||
/// <returns></returns> | |||
public void SetKZSXStatus(DevSXBase sXBase, bool Status) | |||
{ | |||
try | |||
{ | |||
if (sXBase == null) return; | |||
DevSX dev = Tools.JsonToObjectTools<DevSX>(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; | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// 告警消息 | |||
/// </summary> | |||
public class AlarmMessage | |||
{ | |||
public List<AlarmModel> data { get; set; } | |||
} | |||
/// <summary> | |||
/// 告警Model | |||
/// </summary> | |||
public class AlarmModel : DeviceBase | |||
{ | |||
/// <summary> | |||
/// 告警程度:提示 一般 严重 | |||
/// </summary> | |||
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; } | |||
/// <summary> | |||
/// 颜色 | |||
/// </summary> | |||
public ALYColor DeviceColor { get; set; } | |||
} | |||
/// <summary> | |||
/// 设备上报属性 | |||
/// </summary> | |||
public class DevSX | |||
{ | |||
public List<DevSXBase> data { get; set; } | |||
} | |||
/// <summary> | |||
/// 设备基本属性Model | |||
/// </summary> | |||
public class DevSXBase | |||
{ | |||
/// <summary> | |||
/// 属性名称 | |||
/// </summary> | |||
public string SXMC { get; set; } | |||
/// <summary> | |||
/// 属性类型 | |||
/// </summary> | |||
public string SXLX { get; set; } | |||
/// <summary> | |||
/// 属性状态 | |||
/// </summary> | |||
private bool _SXStatus { get; set; } | |||
public bool SXStatus | |||
{ | |||
get { return _SXStatus; } | |||
set | |||
{ | |||
_SXStatus = value; | |||
if (_SXStatus) | |||
{ | |||
SXZT = "正常"; | |||
} | |||
else | |||
{ | |||
SXZT = "异常"; | |||
} | |||
} | |||
} | |||
private string _SXZT { get; set; } | |||
/// <summary> | |||
/// 属性状态:正常 异常 | |||
/// </summary> | |||
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 }; | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// 属性异常描述 | |||
/// </summary> | |||
public string SXYCMS { get; set; } | |||
public string YCZT { get; set; } | |||
/// <summary> | |||
/// 属性颜色 | |||
/// </summary> | |||
public ALYColor SXYC { get; set; } | |||
/// <summary> | |||
/// 按钮文字 | |||
/// </summary> | |||
public string ButtonText { get; set; } | |||
/// <summary> | |||
/// 按钮颜色 | |||
/// </summary> | |||
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 }; | |||
} | |||
} | |||
/// <summary> | |||
/// 设备颜色 | |||
/// </summary> | |||
public class ALYColor | |||
{ | |||
public int r { get; set; } | |||
public int g { get; set; } | |||
public int b { get; set; } | |||
public double a { get; set; } | |||
} | |||
/// <summary> | |||
/// 变量 | |||
/// </summary> | |||
public class Vls | |||
{ | |||
public long time { get; set; } | |||
public string value { get; set; } | |||
} | |||
} |
@@ -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 | |||
{ | |||
/// <summary> | |||
/// add fengyoufu | |||
/// 黑菠萝科技有限公司 | |||
/// IOT设备上报消息类 | |||
/// </summary> | |||
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 公有变量 | |||
/// <summary> | |||
/// 设备消息数据回调 | |||
/// </summary> | |||
public static Action<string, string> DevIOTAction { get; set; } | |||
/// <summary> | |||
/// 重连事件 | |||
/// </summary> | |||
public static Action<string> UNConnectMqtt { get; set; } | |||
/// <summary> | |||
/// 客户端 | |||
/// </summary> | |||
public static MqttClient client { get; set; } | |||
#endregion | |||
#region 发布或订阅主题或URL地址 | |||
/// <summary> | |||
/// API 服务 | |||
/// </summary> | |||
private static string APIurl = "http://124.222.238.75:6002"; | |||
/// <summary> | |||
/// 属性发布消息主题 | |||
/// </summary> | |||
public static string PubTopic = "/" + ProductKey + "/" + DeviceName + "/user/update"; | |||
/// <summary> | |||
/// 属性接收消息主题 | |||
/// </summary> | |||
public static string SubTopic = "/" + ProductKey + "/" + DeviceName + "/user/get"; | |||
/// <summary> | |||
/// 自定义发布消息主题 | |||
/// </summary> | |||
public static string UserPubTopic = "/" + ProductKey + "/" + DeviceName + "/user/update"; | |||
/// <summary> | |||
/// 自定义接收消息主题 | |||
/// </summary> | |||
public static string UserSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/get"; | |||
/// <summary> | |||
/// 告警订阅主题 | |||
/// </summary> | |||
public static string AlarmSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/AlarmMessage"; | |||
/// <summary> | |||
/// 日志订阅主题 | |||
/// </summary> | |||
public static string LogsSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/ExceptionLogs"; | |||
/// <summary> | |||
/// 上下线订阅主题 | |||
/// </summary> | |||
public static string HeartbeatSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/HeartbeatAndState"; | |||
/// <summary> | |||
/// 属性状态主题 | |||
/// </summary> | |||
public static string TargetStatusSubTopic = "/" + ProductKey + "/" + DeviceName + "/user/TargetStatus"; | |||
/// <summary> | |||
/// 大屏展示发布主题 | |||
/// </summary> | |||
public static string ScreenShowPubTopic = "/" + ProductKey + "/" + DeviceName + "/user/ScreenShow"; | |||
/// <summary> | |||
/// 广播主题 | |||
/// </summary> | |||
public static string BroadcastTopic = "/broadcast/" + "grgpECHSL7q" + "/" + DeviceName + "_SetDevice"; | |||
/// <summary> | |||
/// 订阅主题集合 | |||
/// </summary> | |||
public static List<string> SubTopicList = new List<string>(); | |||
#endregion | |||
#region 单例模式 | |||
private static IOTDevServer iot = null; | |||
public static IOTDevServer GetInstance() | |||
{ | |||
if (iot == null) { iot = new IOTDevServer(); } | |||
return iot; | |||
} | |||
#endregion | |||
#region 公共调用阿里云连接或检测 | |||
/// <summary> | |||
/// 设置URL | |||
/// </summary> | |||
/// <param name="url"></param> | |||
public void SetUrl(string url = "http://124.222.238.75:6002") | |||
{ | |||
APIurl = url; | |||
} | |||
/// <summary> | |||
/// 设置变量 | |||
/// </summary> | |||
/// <param name="_ProductKey"></param> | |||
/// <param name="_DeviceName"></param> | |||
/// <param name="_DeviceSecret"></param> | |||
/// <param name="_RegionId"></param> | |||
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"; | |||
} | |||
/// <summary> | |||
/// 创建连接 | |||
/// </summary> | |||
/// <returns></returns> | |||
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<List<DeviceTable>> jsonMsg = Tools.JsonToObjectTools<JsonMsg<List<DeviceTable>>>(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<string, string> dict = new Dictionary<string, string>(); | |||
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; | |||
} | |||
} | |||
/// <summary> | |||
/// 获取连接状态 | |||
/// </summary> | |||
public bool GetIsConnected() | |||
{ | |||
try | |||
{ | |||
if (client == null || !client.IsConnected) | |||
return false; | |||
else return true; | |||
} | |||
catch (Exception ex) | |||
{ | |||
return false; | |||
throw; | |||
} | |||
} | |||
/// <summary> | |||
/// 断开连接 | |||
/// </summary> | |||
public void Disconnect() | |||
{ | |||
if (client != null) | |||
{ | |||
client.Disconnect(); | |||
} | |||
} | |||
#endregion | |||
#region 公共发布或订阅函数 | |||
/// <summary> | |||
/// 发布消息 | |||
/// </summary> | |||
/// <param name="topic"></param> | |||
/// <param name="message"></param> | |||
public void IOT_Publish(string topic, string message) | |||
{ | |||
var id = client.Publish(topic, Encoding.UTF8.GetBytes(message)); | |||
} | |||
/// <summary> | |||
/// 订阅主题 | |||
/// </summary> | |||
/// <param name="topic"></param> | |||
public void IOT_Subscribe(string topic) | |||
{ | |||
if (SubTopicList.Contains(topic)) | |||
{ | |||
SubTopicList.Add(topic); | |||
} | |||
client.Subscribe(new string[] { topic }, new byte[] { 0 }); | |||
} | |||
#endregion | |||
#region 私有函数 | |||
/// <summary> | |||
/// mQTT创建连接 | |||
/// </summary> | |||
/// <param name="targetServer"></param> | |||
/// <param name="mqttClientId"></param> | |||
/// <param name="mqttUserName"></param> | |||
/// <param name="mqttPassword"></param> | |||
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; | |||
} | |||
/// <summary> | |||
/// MQTT 断开事件 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
private static void Client_ConnectionClosed(object sender, EventArgs e) | |||
{ | |||
// 尝试重连 | |||
_TryContinueConnect(); | |||
} | |||
/// <summary> | |||
/// 订阅数据接收 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
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); | |||
} | |||
} | |||
/// <summary> | |||
/// 自动重连主体 | |||
/// </summary> | |||
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 | |||
} | |||
/// <summary> | |||
/// Iot 设备上报 | |||
/// </summary> | |||
public class IotSignUtils | |||
{ | |||
public static string sign(Dictionary<string, string> 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(); | |||
} | |||
} | |||
/// <summary> | |||
/// 工具 | |||
/// </summary> | |||
public class Tools | |||
{ | |||
/// <summary> | |||
/// 对象Json序列 | |||
/// </summary> | |||
/// <typeparam name="T">对象类型</typeparam> | |||
/// <param name="obj">对象实例</param> | |||
/// <returns></returns> | |||
public static string JsonConvertTools<T>(T obj) | |||
{ | |||
string strvalue = JsonConvert.SerializeObject(obj); | |||
return strvalue; | |||
} | |||
/// <summary> | |||
/// 对象反Json序列 | |||
/// </summary> | |||
/// <typeparam name="T">对象类型</typeparam> | |||
/// <param name="jsonstring">对象序列化json字符串</param> | |||
/// <returns>返回对象实例</returns> | |||
public static T JsonToObjectTools<T>(string jsonstring) | |||
{ | |||
T obj = JsonConvert.DeserializeObject<T>(jsonstring); | |||
return obj; | |||
} | |||
/// <summary> | |||
/// DateTime --> long | |||
/// </summary> | |||
/// <param name="dt"></param> | |||
/// <returns></returns> | |||
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; | |||
} | |||
/// <summary> | |||
/// long --> DateTime | |||
/// </summary> | |||
/// <param name="d"></param> | |||
/// <returns></returns> | |||
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; | |||
} | |||
/// <summary> | |||
/// 获取IP 地址 | |||
/// </summary> | |||
/// <returns></returns> | |||
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"; | |||
} | |||
} | |||
} |
@@ -0,0 +1,275 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace DataVAPI.Tool.IOT | |||
{ | |||
/// <summary> | |||
/// 大屏监视Model | |||
/// </summary> | |||
public class ScreenMonitorModel | |||
{ | |||
/// <summary> | |||
/// 服务商家数 | |||
/// </summary> | |||
public string TotalSales { get; set; } | |||
/// <summary> | |||
/// 现场运营设备状态 | |||
/// </summary> | |||
public OperatingDeviceStatus operatingDeviceStatus { get; set; } | |||
/// <summary> | |||
/// 通知消息 | |||
/// </summary> | |||
public InfoMessage infoMessage { get; set; } | |||
/// <summary> | |||
/// 返回JSON | |||
/// </summary> | |||
/// <returns></returns> | |||
public string ToJSON() | |||
{ | |||
try | |||
{ | |||
return Tools.JsonConvertTools(this); | |||
} | |||
catch (Exception ex) | |||
{ | |||
return string.Empty; | |||
} | |||
} | |||
/// <summary> | |||
/// 序列化为对象 | |||
/// </summary> | |||
/// <param name="JSON"></param> | |||
/// <returns></returns> | |||
public ScreenMonitorModel JSONtoDX(string JSON) | |||
{ | |||
try | |||
{ | |||
return Tools.JsonToObjectTools<ScreenMonitorModel>(JSON); | |||
} | |||
catch (Exception ex) | |||
{ | |||
return new ScreenMonitorModel(); | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// 下订单统计 | |||
/// </summary> | |||
public class PlaceOrderCount | |||
{ | |||
/// <summary> | |||
/// 今日下单量统计 | |||
/// </summary> | |||
public string ToDayPlaceCount { get; set; } | |||
/// <summary> | |||
/// 本月下单量统计 | |||
/// </summary> | |||
public string MonthPlaceCount { get; set; } | |||
/// <summary> | |||
/// 本年下单量统计 | |||
/// </summary> | |||
public string YearPlaceCount { get; set; } | |||
} | |||
/// <summary> | |||
/// 制作流程 | |||
/// </summary> | |||
public class ProcessMessage | |||
{ | |||
public List<ProcessModel> data { get; set; } | |||
} | |||
/// <summary> | |||
/// 制作流程Model | |||
/// </summary> | |||
public class ProcessModel | |||
{ | |||
/// <summary> | |||
/// 告警程度:提示 一般 严重 | |||
/// </summary> | |||
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 }; | |||
} | |||
} | |||
/// <summary> | |||
/// 流程名称 | |||
/// </summary> | |||
public string ProcessName { get; set; } | |||
/// <summary> | |||
/// 流程描述 | |||
/// </summary> | |||
public string ProcessMS { get; set; } | |||
/// <summary> | |||
/// 颜色 | |||
/// </summary> | |||
public ALYColor ProcessColor { get; set; } | |||
public ProcessModel() | |||
{ | |||
IsMark = false; | |||
ProcessMS = string.Empty; | |||
ProcessName = string.Empty; | |||
} | |||
} | |||
/// <summary> | |||
/// 通知消息 | |||
/// </summary> | |||
public class InfoMessage | |||
{ | |||
public List<DeviceBase> data { get; set; } | |||
} | |||
/// <summary> | |||
/// 运营设备及状态 | |||
/// </summary> | |||
public class OperatingDeviceStatus | |||
{ | |||
public List<DevStatus> data { get; set; } | |||
} | |||
/// <summary> | |||
/// 设备状态 | |||
/// </summary> | |||
public class DevStatus : DeviceBase | |||
{ | |||
/// <summary> | |||
/// 设备状态 | |||
/// </summary> | |||
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; } | |||
/// <summary> | |||
/// 是否有告警 | |||
/// </summary> | |||
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; } | |||
/// <summary> | |||
/// 颜色 | |||
/// </summary> | |||
public ALYColor DeviceColor { get; set; } | |||
/// <summary> | |||
/// 告警颜色 | |||
/// </summary> | |||
public ALYColor AlarmColor { get; set; } | |||
/// <summary> | |||
/// 初始化 | |||
/// </summary> | |||
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 }; | |||
} | |||
/// <summary> | |||
/// 设置属性 | |||
/// </summary> | |||
/// <param name="_deviceName"></param> | |||
/// <param name="_gmtCreate"></param> | |||
/// <param name="_DeviceMC"></param> | |||
/// <param name="_DeviceMS"></param> | |||
/// <param name="_DeviceSJ"></param> | |||
/// <param name="_DeviceZT"></param> | |||
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; | |||
} | |||
/// <summary> | |||
/// 状态 | |||
/// </summary> | |||
/// <param name="_DeviceZT"></param> | |||
public void SetStatus(string _DeviceZT) | |||
{ | |||
DeviceSJ = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); | |||
DeviceZT = _DeviceZT; | |||
} | |||
} | |||
/// <summary> | |||
/// 设备基本属性 | |||
/// </summary> | |||
public class DeviceBase : DevBase | |||
{ | |||
/// <summary> | |||
/// 设备名称 | |||
/// </summary> | |||
public string DeviceMC { get; set; } | |||
/// <summary> | |||
/// 设备描述 | |||
/// </summary> | |||
public string DeviceMS { get; set; } | |||
/// <summary> | |||
/// 设备时间 | |||
/// </summary> | |||
public string DeviceSJ { get; set; } | |||
/// <summary> | |||
/// 设备状态:已处理 未处理 | |||
/// </summary> | |||
public string DeviceZT { get; set; } | |||
} | |||
/// <summary> | |||
/// 设备基本信息 | |||
/// </summary> | |||
public class DevBase | |||
{ | |||
/// <summary> | |||
/// 唯一id | |||
/// </summary> | |||
public string id { get; set; } | |||
/// <summary> | |||
/// 设备key | |||
/// </summary> | |||
public string productKey { get; set; } | |||
/// <summary> | |||
/// 设备名称 | |||
/// </summary> | |||
public string deviceName { get; set; } | |||
/// <summary> | |||
/// gmtCreate | |||
/// </summary> | |||
public string gmtCreate { get; set; } | |||
/// <summary> | |||
/// 客户端ID | |||
/// </summary> | |||
public string clientId { get; set; } | |||
public DevBase() | |||
{ | |||
id = Guid.NewGuid().ToString(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,71 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.IoT | |||
{ | |||
/// <summary> | |||
/// 返回消息 | |||
/// </summary> | |||
public class JsonMsg<T> where T : class | |||
{ | |||
/// <summary> | |||
/// 状态码 | |||
/// </summary> | |||
public int code { get; set; } | |||
/// <summary> | |||
/// 消息 | |||
/// </summary> | |||
public string msg { get; set; } | |||
/// <summary> | |||
/// 描述 | |||
/// </summary> | |||
public string ms { get; set; } | |||
/// <summary> | |||
/// 内容 | |||
/// </summary> | |||
public IOTData<T> obj { get; set; } | |||
///// <summary> | |||
///// 返回数据 | |||
///// </summary> | |||
//public IOTData<T> oTData { get; set; } | |||
/// <summary> | |||
/// 图标 | |||
/// </summary> | |||
public int icon { get; set; } | |||
public static JsonMsg<T> 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<T>() { code = 1, ms = mso, msg = "成功", obj = new IOTData<T> { data = obj }, icon = 1}; | |||
} | |||
public static JsonMsg<T> 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<T>() { code = 0, ms = mso, msg = "失败",icon = 1, obj = new IOTData<T> { data = obj } }; | |||
} | |||
} | |||
public class IOTData<T> where T : class | |||
{ | |||
public T data { get; set; } | |||
} | |||
} |
@@ -0,0 +1,14 @@ | |||
namespace BPASmartClient.IoT | |||
{ | |||
/// <summary> | |||
/// 大屏消息表 | |||
/// </summary> | |||
public class LargeScreenTable : BaseEntity | |||
{ | |||
/// <summary> | |||
/// Json值 | |||
/// </summary> | |||
public string json { get; set; } | |||
} | |||
} |
@@ -0,0 +1,29 @@ | |||
namespace BPASmartClient.IoT | |||
{ | |||
/// <summary> | |||
/// 日志表 | |||
/// </summary> | |||
public class LogTable : BaseEntity | |||
{ | |||
/// <summary> | |||
/// 日志时间 | |||
/// </summary> | |||
public string LogTime { get; set; } | |||
/// <summary> | |||
/// 日志类型:1 轻微 2:一般 3 严重 | |||
/// </summary> | |||
public string LogType { get; set; } | |||
/// <summary> | |||
/// 日志消息 | |||
/// </summary> | |||
public string LogMessage { get; set; } | |||
/// <summary> | |||
/// 日志值 | |||
/// </summary> | |||
public string LogVla { get; set; } | |||
/// <summary> | |||
/// IP 地址 | |||
/// </summary> | |||
public string IP { get; set; } | |||
} | |||
} |
@@ -15,9 +15,10 @@ | |||
<add key="ApolloUri" value="http://10.2.1.21:28080"/> | |||
<add key="OrderServiceUri" value="http://10.2.1.26:21527/order/"/> | |||
<add key="StockServiceUri" value="http://10.2.1.26:21527/stock/"/> | |||
<add key="DataVServiceUri" value="http://111.9.47.105:21527/datav"/> | |||
<add key="COM_Coffee" value="COM3"/> | |||
<add key="COM_Coffee" value="COM3"/> | |||
<add key="BAUD_Coffee" value="115200"/> | |||
<add key="COM_IceCream" value="COM12"/> | |||
<add key="BAUD_IceCream" value="9600"/> | |||