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

371 lines
14 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. //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 = InternetInfo.BroadcastPubTopic;
  43. //BroadcastPubTopic = System.Configuration.ConfigurationManager.AppSettings["BroadcastPubTopic"].ToString();
  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. /// <summary>
  61. /// MQTT上报集合
  62. /// </summary>
  63. public DataVReport DeviceDataV = new DataVReport();
  64. /// <summary>
  65. /// 大屏上报Model
  66. /// </summary>
  67. public DataVAPI.Tool.IOT.IOTDevSXModel iOTDevSXModel = new DataVAPI.Tool.IOT.IOTDevSXModel() { };
  68. /// <summary>
  69. /// key值
  70. /// </summary>
  71. public Dictionary<string, string> keyValues = new Dictionary<string, string>();
  72. #endregion
  73. #region API调用
  74. /// <summary>
  75. /// 增加告警信息
  76. /// </summary>
  77. /// <param name="alarmTable"></param>
  78. /// <returns>返回ID</returns>
  79. public string HttpAddAlarm(AlarmTable alarmTable)
  80. {
  81. try
  82. {
  83. if (DeviceDataV != null && DeviceDataV.GetIsConnected() && DeviceDataV.deviceTable != null)
  84. {
  85. alarmTable.ClientId = ClientId;
  86. alarmTable.devicename = DeviceDataV.deviceTable.devicename;
  87. DeviceDataV.IOT_Publish(BroadcastPubTopic, Tools.JsonConvertTools(alarmTable));
  88. }
  89. }
  90. catch (Exception ex)
  91. {
  92. MessageLog.GetInstance.Show(ex.Message);
  93. }
  94. return alarmTable.KeyID;
  95. }
  96. /// <summary>
  97. /// 增加日志信息
  98. /// </summary>
  99. /// <param name="alarmTable"></param>
  100. /// <returns>返回ID</returns>
  101. public string HttpAddLog(LogTable logTable)
  102. {
  103. string id = string.Empty;
  104. try
  105. {
  106. if (DeviceDataV != null && DeviceDataV.GetIsConnected() && DeviceDataV.deviceTable != null)
  107. {
  108. logTable.ClientId = ClientId;
  109. logTable.devicename = DeviceDataV.deviceTable.devicename;
  110. DeviceDataV.IOT_Publish(BroadcastPubTopic, Tools.JsonConvertTools(logTable));
  111. }
  112. }
  113. catch (Exception ex)
  114. {
  115. MessageLog.GetInstance.Show(ex.Message);
  116. }
  117. return id;
  118. }
  119. #endregion
  120. #region 公用
  121. /// <summary>
  122. /// 释放
  123. /// </summary>
  124. public void Dispose()
  125. {
  126. ThreadManage.GetInstance().StopTask("DataV数据上报");
  127. }
  128. /// <summary>
  129. /// 初始化
  130. /// </summary>
  131. public void Initialize()
  132. {
  133. string message = string.Empty;
  134. if (StartupMode == "API")
  135. {
  136. if (DeviceDataV.Initialize(DataVApiAddress, ClientId, "", ref message))
  137. {
  138. ProductKey = DeviceDataV.deviceTable.productkey;
  139. DeviceName = DeviceDataV.deviceTable.devicename;
  140. DeviceSecret = DeviceDataV.deviceTable.devicesecret;
  141. DeviceDataV.DataVMessageAction += DevIOTActionHandler;
  142. MessageLog.GetInstance.Show($"客户端:【{ClientId}】,设备名称{DeviceName}阿里云连接成功");
  143. UpDataFile();
  144. }
  145. else
  146. {
  147. MessageLog.GetInstance.ShowEx(message);
  148. }
  149. }
  150. else
  151. {
  152. if (DeviceDataV.InitializeNo(ProductKey, DeviceName, DeviceSecret, ref message))
  153. {
  154. MessageLog.GetInstance.Show($"客户端:【{ClientId}】,设备名称{DeviceName}阿里云连接成功");
  155. DeviceDataV.DataVMessageAction += DevIOTActionHandler;
  156. UpDataFile();
  157. }
  158. else
  159. MessageLog.GetInstance.ShowEx(message);
  160. }
  161. Plugin.GetInstance()?.GetPlugin<DeviceMgr>()?.GetDevices()?.ForEach(device =>
  162. {
  163. device.AddErrorAction += AddErrorAction;
  164. device.DeleteErrorAction += DeleteErrorAction;
  165. });
  166. }
  167. /// <summary>
  168. /// 启动DataV数据上报
  169. /// </summary>
  170. public void Start()
  171. {
  172. ThreadManage.GetInstance().StartLong(new Action(() =>
  173. {
  174. if (DeviceDataV != null && DeviceDataV.GetIsConnected() && DeviceDataV.deviceTable != null)
  175. {
  176. iOTDevSXModel.Device1 = String.Empty; iOTDevSXModel.Device2 = String.Empty; iOTDevSXModel.Device3 = String.Empty;
  177. List<object> dataVNode = new List<object>();
  178. Plugin.GetInstance()?.GetPlugin<DeviceMgr>()?.GetDevices()?.ForEach(device =>
  179. {
  180. var obj = new
  181. {
  182. DeviceId = device.DeviceId.ToString(),
  183. devicename = DeviceDataV.deviceTable.devicename,
  184. Name = device.Name,
  185. DeviceType = device.DeviceType.ToString(),
  186. IsBusy = device.IsBusy ? "忙碌" : "空闲",
  187. IsBusyColor = device.IsBusy ? new ALYColor { r = 255, g = 0, b = 0, a = 1 } : new ALYColor { r = 51, g = 232, b = 34, a = 1 },
  188. IsHealth = device.IsHealth ? "健康" : "故障",
  189. IsHealthColor = !device.IsHealth ? new ALYColor { r = 255, g = 0, b = 0, a = 1 } : new ALYColor { r = 51, g = 232, b = 34, a = 1 },
  190. Status = device.Status.GetIOTStatus(),
  191. gjxx = device.GetError(),
  192. rzxx = device.GetLog(),
  193. VariableMonitor = device.GetVariableMonitor(),
  194. };
  195. dataVNode.Add(obj);
  196. if (string.IsNullOrEmpty(iOTDevSXModel.Device1)) iOTDevSXModel.Device1 = $"[{device.Name}]:{(device.IsBusy ? "忙碌" : "空闲")}-{(device.IsHealth ? "健康" : "故障")}";
  197. else if (string.IsNullOrEmpty(iOTDevSXModel.Device2)) iOTDevSXModel.Device2 = $"[{device.Name}]:{(device.IsBusy ? "忙碌" : "空闲")}-{(device.IsHealth ? "健康" : "故障")}";
  198. else if (string.IsNullOrEmpty(iOTDevSXModel.Device3)) iOTDevSXModel.Device3 = $"[{device.Name}]:{(device.IsBusy ? "忙碌" : "空闲")}-{(device.IsHealth ? "健康" : "故障")}";
  199. });
  200. if (dataVNode.Count > 0)
  201. {
  202. iOTDevSXModel.NodeStatus = Tools.JsonConvertTools(new { data = dataVNode });
  203. DeviceDataV.IOT_Publish(DeviceDataV.PubTopic, iOTDevSXModel.Tojson());
  204. }
  205. }
  206. Thread.Sleep(3000);
  207. }), "DataV数据上报", true);
  208. }
  209. /// <summary>
  210. /// 文件上传请求
  211. /// </summary>
  212. public void UpDataFile()
  213. {
  214. try
  215. {
  216. if (DeviceDataV != null && DeviceDataV.GetIsConnected() && DeviceDataV.deviceTable != null)
  217. {
  218. FileUpload.FileRequest(DeviceDataV);
  219. }
  220. }
  221. catch (Exception ex)
  222. {
  223. MessageLog.GetInstance.Show(ex.Message);
  224. }
  225. }
  226. #endregion
  227. #region 私有
  228. /// <summary>
  229. /// 增加告警
  230. /// </summary>
  231. /// <param name="obj"></param>
  232. private void AddErrorAction(int Devid, object obj)
  233. {
  234. string id = Guid.NewGuid().ToString();
  235. HttpAddAlarm(new AlarmTable
  236. {
  237. AlarmTime = GetPropertyValue(obj, "Time").ToString(),
  238. AlarmType = GetPropertyValue(obj, "Type").ToString(),
  239. AlarmMessage = GetPropertyValue(obj, "Text").ToString(),
  240. AlarmVla = "告警",
  241. DeviceId = Devid.ToString(),
  242. KeyID = id,
  243. });
  244. keyValues[GetPropertyValue(obj, "Time").ToString() + GetPropertyValue(obj, "Type").ToString() + GetPropertyValue(obj, "Text").ToString()] = id;
  245. //MessageLog.GetInstance.AddDeviceAlarmLogShow(GetPropertyValue(obj, "Time").ToString() + GetPropertyValue(obj, "Type").ToString() + GetPropertyValue(obj, "Text").ToString(),id);
  246. }
  247. /// <summary>
  248. /// 删除告警
  249. /// </summary>
  250. /// <param name="obj"></param>
  251. private void DeleteErrorAction(int Devid, object obj)
  252. {
  253. string message = GetPropertyValue(obj, "Time").ToString() + GetPropertyValue(obj, "Type").ToString() + GetPropertyValue(obj, "Text").ToString();
  254. if (keyValues.ContainsKey(message))
  255. {
  256. HttpAddAlarm(new AlarmTable
  257. {
  258. AlarmTime = GetPropertyValue(obj, "Time").ToString(),
  259. AlarmType = GetPropertyValue(obj, "Type").ToString(),
  260. AlarmMessage = GetPropertyValue(obj, "Text").ToString(),
  261. AlarmVla = "告警",
  262. DeviceId = Devid.ToString(),
  263. KeyID = keyValues[message],
  264. State = "n"
  265. });
  266. //MessageLog.GetInstance.DeleteDeviceAlarmLogShow(message, keyValues[message]);
  267. }
  268. }
  269. /// <summary>
  270. /// 接收云端消息
  271. /// </summary>
  272. /// <param name="topic"></param>
  273. /// <param name="message"></param>
  274. private void DevIOTActionHandler(string deviceId, string topic, string message)
  275. {
  276. if (DeviceDataV.BroadcastTopic == topic && !string.IsNullOrEmpty(message))//广播主题消息,将广播消息发送到相应客户端
  277. {
  278. IOTCommandModel iOTCommand = Tools.JsonToObjectTools<IOTCommandModel>(message);
  279. if (iOTCommand.deviceName == DeviceDataV.deviceTable.devicename)
  280. ActionManage.GetInstance.Send("IotBroadcast", iOTCommand);
  281. }
  282. else if (DeviceDataV.FileUpLoadReplyTopic == topic)//文件请求上传响应Topic
  283. {
  284. FileUploadModelResult result = Tools.JsonToObjectTools<FileUploadModelResult>(message);
  285. if (result.code == 200)
  286. {
  287. string FileName = result.data?.fileName;
  288. string uploadId = result.data?.uploadId;
  289. FileUpload.FileSend(DeviceDataV, uploadId, result.data.offset);
  290. //MessageLog.GetInstance.Show($"[阿里云上传]:请求上传云回执成功.");
  291. }
  292. else
  293. MessageLog.GetInstance.Show($"[阿里云上传]:请求上传云回执失败.原因:{result.message}");
  294. }
  295. else if (DeviceDataV.FileUpLoadSendReplyTopic == topic)//文件上传Topic
  296. {
  297. FileUploadModelResult result = Tools.JsonToObjectTools<FileUploadModelResult>(message);
  298. FileUpload.modelResult = result;
  299. }
  300. else if (DeviceDataV.CancelFileUpLoadSendReplyTopic == topic)//取消文件上传Topic
  301. {
  302. FileUploadModelResult result = Tools.JsonToObjectTools<FileUploadModelResult>(message);
  303. }
  304. }
  305. /// <summary>
  306. /// 获取某个对象中的属性值
  307. /// </summary>
  308. /// <param name="info"></param>
  309. /// <param name="field"></param>
  310. public object GetPropertyValue(object info, string field)
  311. {
  312. if (info == null) return null;
  313. Type t = info.GetType();
  314. IEnumerable<System.Reflection.PropertyInfo> property = from pi in t.GetProperties() where pi.Name.ToLower() == field.ToLower() select pi;
  315. return property.First().GetValue(info, null);
  316. }
  317. #endregion
  318. }
  319. //命令实体类
  320. public class IOTCommandModel
  321. {
  322. /// <summary>
  323. /// 设备名称
  324. /// </summary>
  325. public string deviceName
  326. {
  327. get;
  328. set;
  329. }
  330. /// <summary>
  331. /// 命令名称:0 控制类 1 设置属性 2 通知信息类
  332. /// </summary>
  333. public int CommandName
  334. {
  335. get;
  336. set;
  337. }
  338. /// <summary>
  339. /// 命令变量:执行变量 key为属性或时间 value为值或者消息
  340. /// </summary>
  341. public Dictionary<string, string> CommandValue
  342. {
  343. get;
  344. set;
  345. }
  346. }
  347. }