终端一体化运控平台
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 

433 líneas
17 KiB

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