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

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