终端一体化运控平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DataVClient.cs 15 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
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. }