终端一体化运控平台
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.
 
 
 

446 lines
18 KiB

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