终端一体化运控平台
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

DataVClient.cs 15 KiB

2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. 
  2. using BPA.Message.Enum;
  3. using BPA.Message.IOT;
  4. using BPASmartClient.Business;
  5. using BPASmartClient.Device;
  6. using BPASmartClient.Helper;
  7. using BPASmartClient.IoT.Model;
  8. using BPASmartClient.Message;
  9. using BPASmartDatavDeviceClient.IoT;
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Linq;
  13. using System.Threading;
  14. namespace BPASmartClient.IoT
  15. {
  16. /// <summary>
  17. /// DataV客户端数据中心
  18. /// </summary>
  19. public class DataVClient
  20. {
  21. #region 单例模式
  22. public static DataVClient init = null;
  23. public static DataVClient GetInstance()
  24. {
  25. if (init == null)
  26. {
  27. init = new DataVClient();
  28. }
  29. return init;
  30. }
  31. /// <summary>
  32. /// 显示定义构造函数为私有,表示只允许自己实例化自己
  33. /// </summary>
  34. public DataVClient()
  35. {
  36. DataVApiAddress = System.Configuration.ConfigurationManager.AppSettings["DataVServiceUri"].ToString();
  37. ClientId = System.Configuration.ConfigurationManager.AppSettings["ClientId"].ToString();
  38. DeviceName = System.Configuration.ConfigurationManager.AppSettings["DeviceName"].ToString();
  39. ProductKey = System.Configuration.ConfigurationManager.AppSettings["ProductKey"].ToString();
  40. DeviceSecret = System.Configuration.ConfigurationManager.AppSettings["DeviceSecret"].ToString();
  41. StartupMode = System.Configuration.ConfigurationManager.AppSettings["StartupMode"].ToString();
  42. BroadcastPubTopic= System.Configuration.ConfigurationManager.AppSettings["BroadcastPubTopic"].ToString();
  43. }
  44. #endregion
  45. #region 公有变量
  46. public string StartupMode { set; get; }
  47. public string DeviceName { set; get; }
  48. public string ProductKey { set; get; }
  49. public string DeviceSecret { set; get; }
  50. public string BroadcastPubTopic { set; get; }
  51. /// <summary>
  52. /// DataV 服务地址
  53. /// </summary>
  54. public string DataVApiAddress { set; get; }
  55. /// <summary>
  56. /// 客户端ID
  57. /// </summary>
  58. public string ClientId { set; get; }
  59. /// <summary>
  60. /// MQTT上报集合
  61. /// </summary>
  62. public DataVReport DeviceDataV = new DataVReport();
  63. /// <summary>
  64. /// 大屏上报Model
  65. /// </summary>
  66. public DataVAPI.Tool.IOT.IOTDevSXModel iOTDevSXModel = new DataVAPI.Tool.IOT.IOTDevSXModel() { };
  67. /// <summary>
  68. /// key值
  69. /// </summary>
  70. public Dictionary<string,string> keyValues = new Dictionary<string, string>();
  71. #endregion
  72. #region API调用
  73. /// <summary>
  74. /// 增加告警信息
  75. /// </summary>
  76. /// <param name="alarmTable"></param>
  77. /// <returns>返回ID</returns>
  78. public string HttpAddAlarm(AlarmTable alarmTable)
  79. {
  80. try
  81. {
  82. if (DeviceDataV != null && DeviceDataV.GetIsConnected() && DeviceDataV.deviceTable != null)
  83. {
  84. alarmTable.ClientId = ClientId;
  85. alarmTable.devicename = DeviceDataV.deviceTable.devicename;
  86. DeviceDataV.IOT_Publish(BroadcastPubTopic, Tools.JsonConvertTools(alarmTable));
  87. }
  88. }
  89. catch (Exception ex)
  90. {
  91. MessageLog.GetInstance.Show(ex.Message);
  92. }
  93. return alarmTable.KeyID;
  94. }
  95. /// <summary>
  96. /// 增加日志信息
  97. /// </summary>
  98. /// <param name="alarmTable"></param>
  99. /// <returns>返回ID</returns>
  100. public string HttpAddLog(LogTable logTable)
  101. {
  102. string id = string.Empty;
  103. try
  104. {
  105. if (DeviceDataV != null && DeviceDataV.GetIsConnected() && DeviceDataV.deviceTable!=null)
  106. {
  107. logTable.ClientId = ClientId;
  108. logTable.devicename = DeviceDataV.deviceTable.devicename;
  109. DeviceDataV.IOT_Publish(BroadcastPubTopic, Tools.JsonConvertTools(logTable));
  110. }
  111. }
  112. catch (Exception ex)
  113. {
  114. MessageLog.GetInstance.Show(ex.Message);
  115. }
  116. return id;
  117. }
  118. #endregion
  119. #region 公用
  120. /// <summary>
  121. /// 释放
  122. /// </summary>
  123. public void Dispose()
  124. {
  125. ThreadManage.GetInstance().StopTask("DataV数据上报");
  126. }
  127. /// <summary>
  128. /// 初始化
  129. /// </summary>
  130. public void Initialize()
  131. {
  132. string message = string.Empty;
  133. if (StartupMode == "API")
  134. {
  135. if (DeviceDataV.Initialize(DataVApiAddress, ClientId, "", ref message))
  136. {
  137. ProductKey = DeviceDataV.deviceTable.productkey;
  138. DeviceName = DeviceDataV.deviceTable.devicename;
  139. DeviceSecret = DeviceDataV.deviceTable.devicesecret;
  140. DeviceDataV.DataVMessageAction += DevIOTActionHandler;
  141. MessageLog.GetInstance.Show($"客户端:【{ClientId}】,设备名称{DeviceName}阿里云连接成功");
  142. UpDataFile();
  143. }
  144. else
  145. {
  146. MessageLog.GetInstance.ShowEx(message);
  147. }
  148. }
  149. else
  150. {
  151. if (DeviceDataV.InitializeNo(ProductKey, DeviceName, DeviceSecret, ref message))
  152. {
  153. MessageLog.GetInstance.Show($"客户端:【{ClientId}】,设备名称{DeviceName}阿里云连接成功");
  154. UpDataFile();
  155. }
  156. else
  157. MessageLog.GetInstance.ShowEx(message);
  158. }
  159. Plugin.GetInstance()?.GetPlugin<DeviceMgr>()?.GetDevices()?.ForEach(device =>
  160. {
  161. device.AddErrorAction+= AddErrorAction;
  162. device.DeleteErrorAction += DeleteErrorAction;
  163. });
  164. }
  165. /// <summary>
  166. /// 启动DataV数据上报
  167. /// </summary>
  168. public void Start()
  169. {
  170. ThreadManage.GetInstance().StartLong(new Action(() =>
  171. {
  172. if (DeviceDataV != null && DeviceDataV.GetIsConnected() && DeviceDataV.deviceTable != null)
  173. {
  174. iOTDevSXModel.Device1=String.Empty;iOTDevSXModel.Device2=String.Empty;iOTDevSXModel.Device3 = String.Empty;
  175. List<object> dataVNode = new List<object>();
  176. Plugin.GetInstance()?.GetPlugin<DeviceMgr>()?.GetDevices()?.ForEach(device =>
  177. {
  178. var obj = new
  179. {
  180. DeviceId = device.DeviceId.ToString(),
  181. devicename = DeviceDataV.deviceTable.devicename,
  182. Name = device.Name,
  183. DeviceType = device.DeviceType.ToString(),
  184. IsBusy = device.IsBusy ? "忙碌" : "空闲",
  185. IsBusyColor = device.IsBusy ? new ALYColor { r = 255, g = 0, b = 0, a = 1 } : new ALYColor { r = 51, g = 232, b = 34, a = 1 },
  186. IsHealth = device.IsHealth ? "健康" : "故障",
  187. IsHealthColor = !device.IsHealth ? new ALYColor { r = 255, g = 0, b = 0, a = 1 } : new ALYColor { r = 51, g = 232, b = 34, a = 1 },
  188. Status = device.Status.GetIOTStatus(),
  189. gjxx = device.GetError(),
  190. rzxx = device.GetLog(),
  191. VariableMonitor = device.GetVariableMonitor(),
  192. };
  193. dataVNode.Add(obj);
  194. if (string.IsNullOrEmpty(iOTDevSXModel.Device1)) iOTDevSXModel.Device1 = $"[{device.Name}]:{(device.IsBusy ? "忙碌" : "空闲")}-{(device.IsHealth ? "健康" : "故障")}";
  195. else if (string.IsNullOrEmpty(iOTDevSXModel.Device2)) iOTDevSXModel.Device2 = $"[{device.Name}]:{(device.IsBusy ? "忙碌" : "空闲")}-{(device.IsHealth ? "健康" : "故障")}";
  196. else if (string.IsNullOrEmpty(iOTDevSXModel.Device3)) iOTDevSXModel.Device3 = $"[{device.Name}]:{(device.IsBusy ? "忙碌" : "空闲")}-{(device.IsHealth ? "健康" : "故障")}";
  197. });
  198. if (dataVNode.Count > 0)
  199. {
  200. iOTDevSXModel.NodeStatus = Tools.JsonConvertTools(new { data = dataVNode });
  201. DeviceDataV.IOT_Publish(DeviceDataV.PubTopic, iOTDevSXModel.Tojson());
  202. }
  203. }
  204. Thread.Sleep(3000);
  205. }), "DataV数据上报", true);
  206. }
  207. /// <summary>
  208. /// 文件上传请求
  209. /// </summary>
  210. public void UpDataFile()
  211. {
  212. try
  213. {
  214. if (DeviceDataV != null && DeviceDataV.GetIsConnected() && DeviceDataV.deviceTable != null)
  215. {
  216. FileUpload.FileRequest(DeviceDataV);
  217. }
  218. }
  219. catch (Exception ex)
  220. {
  221. MessageLog.GetInstance.Show(ex.Message);
  222. }
  223. }
  224. #endregion
  225. #region 私有
  226. /// <summary>
  227. /// 增加告警
  228. /// </summary>
  229. /// <param name="obj"></param>
  230. private void AddErrorAction(int Devid, object obj)
  231. {
  232. string id = Guid.NewGuid().ToString();
  233. HttpAddAlarm(new AlarmTable
  234. {
  235. AlarmTime = GetPropertyValue(obj, "Time").ToString(),
  236. AlarmType = GetPropertyValue(obj, "Type").ToString(),
  237. AlarmMessage = GetPropertyValue(obj, "Text").ToString(),
  238. AlarmVla = "告警",
  239. DeviceId = Devid.ToString(),
  240. KeyID = id,
  241. });
  242. keyValues[GetPropertyValue(obj, "Time").ToString() + GetPropertyValue(obj, "Type").ToString() + GetPropertyValue(obj, "Text").ToString()] =id ;
  243. MessageLog.GetInstance.AddDeviceAlarmLogShow(GetPropertyValue(obj, "Time").ToString() + GetPropertyValue(obj, "Type").ToString() + GetPropertyValue(obj, "Text").ToString(),id);
  244. }
  245. /// <summary>
  246. /// 删除告警
  247. /// </summary>
  248. /// <param name="obj"></param>
  249. private void DeleteErrorAction(int Devid, object obj)
  250. {
  251. string message = GetPropertyValue(obj, "Time").ToString() + GetPropertyValue(obj, "Type").ToString() + GetPropertyValue(obj, "Text").ToString();
  252. if (keyValues.ContainsKey(message))
  253. {
  254. HttpAddAlarm(new AlarmTable
  255. {
  256. AlarmTime = GetPropertyValue(obj, "Time").ToString(),
  257. AlarmType = GetPropertyValue(obj, "Type").ToString(),
  258. AlarmMessage = GetPropertyValue(obj, "Text").ToString(),
  259. AlarmVla = "告警",
  260. DeviceId= Devid.ToString(),
  261. KeyID = keyValues[message],
  262. State="n"
  263. });
  264. MessageLog.GetInstance.DeleteDeviceAlarmLogShow(message, keyValues[message]);
  265. }
  266. }
  267. /// <summary>
  268. /// 接收云端消息
  269. /// </summary>
  270. /// <param name="topic"></param>
  271. /// <param name="message"></param>
  272. private void DevIOTActionHandler(string deviceId, string topic, string message)
  273. {
  274. if (DeviceDataV.BroadcastTopic == topic && !string.IsNullOrEmpty(message))//广播主题消息,将广播消息发送到相应客户端
  275. {
  276. IOTCommandModel iOTCommand = Tools.JsonToObjectTools<IOTCommandModel>(message);
  277. if (iOTCommand.deviceName == DeviceDataV.deviceTable.devicename)
  278. ActionManage.GetInstance.Send("IotBroadcast", iOTCommand);
  279. }
  280. else if (DeviceDataV.FileUpLoadReplyTopic == topic)//文件请求上传响应Topic
  281. {
  282. FileUploadModelResult result = Tools.JsonToObjectTools<FileUploadModelResult>(message);
  283. if (result.code == 200)
  284. {
  285. string FileName = result.data?.fileName;
  286. string uploadId = result.data?.uploadId;
  287. FileUpload.SetUploadData(result.id,uploadId);
  288. FileUpload.FileSend(DeviceDataV, uploadId);
  289. MessageLog.GetInstance.Show($"请求上传【阿里云】成功,准备上传日志文件【HBL.LogDir{DateTime.Now.ToString("yyyy_M_d")}.log】");
  290. }
  291. else
  292. MessageLog.GetInstance.Show($"【HBL.LogDir{DateTime.Now.ToString("yyyy_M_d")}.log】请求上传【阿里云】失败,{result.message}");
  293. }
  294. else if (DeviceDataV.FileUpLoadSendReplyTopic == topic)//文件上传Topic
  295. {
  296. FileUploadModelResult result = Tools.JsonToObjectTools<FileUploadModelResult>(message);
  297. if (result.code == 200)
  298. {
  299. MessageLog.GetInstance.Show($"今日日志文件“HBL.LogDir{DateTime.Now.ToString("yyyy_M_d")}.log”更新上传【阿里云】成功");
  300. bool complete = result.data.complete;
  301. string uploadId = result.data?.uploadId;
  302. }else
  303. MessageLog.GetInstance.Show($"今日日志文件“HBL.LogDir{DateTime.Now.ToString("yyyy_M_d")}.log”更新上传【阿里云】失败,{result.message}");
  304. }
  305. else if (DeviceDataV.CancelFileUpLoadSendReplyTopic == topic)//取消文件上传Topic
  306. {
  307. FileUploadModelResult result = Tools.JsonToObjectTools<FileUploadModelResult>(message);
  308. }
  309. }
  310. /// <summary>
  311. /// 获取某个对象中的属性值
  312. /// </summary>
  313. /// <param name="info"></param>
  314. /// <param name="field"></param>
  315. public object GetPropertyValue(object info, string field)
  316. {
  317. if (info == null) return null;
  318. Type t = info.GetType();
  319. IEnumerable<System.Reflection.PropertyInfo> property = from pi in t.GetProperties() where pi.Name.ToLower() == field.ToLower() select pi;
  320. return property.First().GetValue(info, null);
  321. }
  322. #endregion
  323. }
  324. //命令实体类
  325. public class IOTCommandModel
  326. {
  327. /// <summary>
  328. /// 设备名称
  329. /// </summary>
  330. public string deviceName
  331. {
  332. get;
  333. set;
  334. }
  335. /// <summary>
  336. /// 命令名称:0 控制类 1 设置属性 2 通知信息类
  337. /// </summary>
  338. public int CommandName
  339. {
  340. get;
  341. set;
  342. }
  343. /// <summary>
  344. /// 命令变量:执行变量 key为属性或时间 value为值或者消息
  345. /// </summary>
  346. public Dictionary<string, string> CommandValue
  347. {
  348. get;
  349. set;
  350. }
  351. }
  352. }