终端一体化运控平台
Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 

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