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

285 lines
9.8 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.Message;
  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. public DataVClient()
  23. {
  24. DataVApiAddress = System.Configuration.ConfigurationManager.AppSettings["DataVServiceUri"].ToString();
  25. ClientId = System.Configuration.ConfigurationManager.AppSettings["ClientId"].ToString();
  26. Initialize();
  27. }
  28. #endregion
  29. #region 公有变量
  30. /// <summary>
  31. /// DataV 服务地址
  32. /// </summary>
  33. public string DataVApiAddress { set; get; }
  34. /// <summary>
  35. /// 客户端ID
  36. /// </summary>
  37. public string ClientId { set; get; }
  38. /// <summary>
  39. /// MQTT上报集合
  40. /// </summary>
  41. public DataVReport DeviceDataV = new DataVReport();
  42. /// <summary>
  43. /// 大屏上报Model
  44. /// </summary>
  45. public DataVAPI.Tool.IOT.IOTDevSXModel iOTDevSXModel = new DataVAPI.Tool.IOT.IOTDevSXModel() { };
  46. /// <summary>
  47. /// 广播
  48. /// </summary>
  49. public string PubTopic = "/broadcast/" + "grgpECHSL7q" + "/" + "Transit_SetDevice";
  50. /// <summary>
  51. /// key值
  52. /// </summary>
  53. public Dictionary<string,string> keyValues = new Dictionary<string, string>();
  54. #endregion
  55. #region API调用
  56. /// <summary>
  57. /// 增加告警信息
  58. /// </summary>
  59. /// <param name="alarmTable"></param>
  60. /// <returns>返回ID</returns>
  61. public string HttpAddAlarm(AlarmTable alarmTable)
  62. {
  63. try
  64. {
  65. if (DeviceDataV != null && DeviceDataV.GetIsConnected())
  66. {
  67. alarmTable.ClientId = ClientId;
  68. alarmTable.devicename = DeviceDataV.deviceTable.devicename;
  69. DeviceDataV.IOT_Publish(PubTopic, Tools.JsonConvertTools(alarmTable));
  70. }
  71. }
  72. catch (Exception ex)
  73. {
  74. MessageLog.GetInstance.Show(ex.Message);
  75. }
  76. return alarmTable.KeyID;
  77. }
  78. /// <summary>
  79. /// 增加日志信息
  80. /// </summary>
  81. /// <param name="alarmTable"></param>
  82. /// <returns>返回ID</returns>
  83. public string HttpAddLog(LogTable logTable)
  84. {
  85. string id = string.Empty;
  86. try
  87. {
  88. if (DeviceDataV != null && DeviceDataV.GetIsConnected())
  89. {
  90. logTable.ClientId = ClientId;
  91. logTable.devicename = DeviceDataV.deviceTable.devicename;
  92. DeviceDataV.IOT_Publish(PubTopic, Tools.JsonConvertTools(logTable));
  93. }
  94. }
  95. catch (Exception ex)
  96. {
  97. MessageLog.GetInstance.Show(ex.Message);
  98. }
  99. return id;
  100. }
  101. #endregion
  102. #region 公用
  103. /// <summary>
  104. /// 释放
  105. /// </summary>
  106. public void Dispose()
  107. {
  108. ThreadManage.GetInstance().StopTask("DataV数据上报");
  109. }
  110. /// <summary>
  111. /// 初始化
  112. /// </summary>
  113. public void Initialize()
  114. {
  115. string message = string.Empty;
  116. if (DeviceDataV.Initialize(DataVApiAddress, ClientId, "", ref message))
  117. {
  118. DeviceDataV.DataVMessageAction += DevIOTActionHandler;
  119. MessageLog.GetInstance.Show($"客户端:【{ClientId}】,设备名称{DeviceDataV.deviceTable.devicename}阿里云连接成功");
  120. }
  121. else
  122. {
  123. MessageLog.GetInstance.ShowEx(message);
  124. }
  125. Plugin.GetInstance()?.GetPlugin<DeviceMgr>()?.GetDevices()?.ForEach(device =>
  126. {
  127. device.AddErrorAction+= AddErrorAction;
  128. device.DeleteErrorAction += DeleteErrorAction;
  129. });
  130. }
  131. /// <summary>
  132. /// 启动DataV数据上报
  133. /// </summary>
  134. public void Start()
  135. {
  136. ThreadManage.GetInstance().StartLong(new Action(() =>
  137. {
  138. if (DeviceDataV != null && DeviceDataV.GetIsConnected())
  139. {
  140. List<object> dataVNode = new List<object>();
  141. Plugin.GetInstance()?.GetPlugin<DeviceMgr>()?.GetDevices()?.ForEach(device =>
  142. {
  143. var obj = new
  144. {
  145. DeviceId = device.DeviceId.ToString(),
  146. devicename = DeviceDataV.deviceTable.devicename,
  147. Name = device.Name,
  148. DeviceType = device.DeviceType.ToString(),
  149. IsBusy = device.IsBusy ? "忙碌" : "空闲",
  150. IsBusyColor = device.IsBusy ? new ALYColor { r = 255, g = 0, b = 0, a = 1 } : new ALYColor { r = 51, g = 232, b = 34, a = 1 },
  151. IsHealth = device.IsHealth ? "健康" : "故障",
  152. IsHealthColor = !device.IsHealth ? new ALYColor { r = 255, g = 0, b = 0, a = 1 } : new ALYColor { r = 51, g = 232, b = 34, a = 1 },
  153. Status = device.Status.GetIOTStatus(),
  154. gjxx = device.GetError(),
  155. rzxx = device.GetLog(),
  156. VariableMonitor = device.GetVariableMonitor(),
  157. };
  158. dataVNode.Add(obj);
  159. });
  160. if (dataVNode.Count > 0)
  161. {
  162. iOTDevSXModel.NodeStatus = Tools.JsonConvertTools(new { data = dataVNode });
  163. DeviceDataV.IOT_Publish(DeviceDataV.PubTopic, iOTDevSXModel.Tojson());
  164. }
  165. }
  166. Thread.Sleep(3000);
  167. }), "DataV数据上报", true);
  168. }
  169. #endregion
  170. #region 私有
  171. /// <summary>
  172. /// 增加告警
  173. /// </summary>
  174. /// <param name="obj"></param>
  175. private void AddErrorAction(object obj)
  176. {
  177. string id = Guid.NewGuid().ToString();
  178. HttpAddAlarm(new AlarmTable
  179. {
  180. AlarmTime = GetPropertyValue(obj, "Time").ToString(),
  181. AlarmType = GetPropertyValue(obj, "Type").ToString(),
  182. AlarmMessage = GetPropertyValue(obj, "Text").ToString(),
  183. AlarmVla = "告警",
  184. KeyID = id,
  185. });
  186. keyValues[GetPropertyValue(obj, "Time").ToString() + GetPropertyValue(obj, "Type").ToString() + GetPropertyValue(obj, "Text").ToString()] =id ;
  187. }
  188. /// <summary>
  189. /// 删除告警
  190. /// </summary>
  191. /// <param name="obj"></param>
  192. private void DeleteErrorAction(object obj)
  193. {
  194. string message = GetPropertyValue(obj, "Time").ToString() + GetPropertyValue(obj, "Type").ToString() + GetPropertyValue(obj, "Text").ToString();
  195. if (keyValues.ContainsKey(message))
  196. {
  197. HttpAddAlarm(new AlarmTable
  198. {
  199. AlarmTime = GetPropertyValue(obj, "Time").ToString(),
  200. AlarmType = GetPropertyValue(obj, "Type").ToString(),
  201. AlarmMessage = GetPropertyValue(obj, "Text").ToString(),
  202. AlarmVla = "告警",
  203. KeyID = keyValues[message],
  204. State="n"
  205. });
  206. }
  207. }
  208. /// <summary>
  209. /// 接收云端消息
  210. /// </summary>
  211. /// <param name="topic"></param>
  212. /// <param name="message"></param>
  213. private void DevIOTActionHandler(string deviceId, string topic, string message)
  214. {
  215. if (DeviceDataV.BroadcastTopic == topic && !string.IsNullOrEmpty(message))//广播主题消息,将广播消息发送到相应客户端
  216. {
  217. IOTCommandModel iOTCommand = Tools.JsonToObjectTools<IOTCommandModel>(message);
  218. if (iOTCommand.deviceName == DeviceDataV.deviceTable.devicename)
  219. ActionManage.GetInstance.Send("IotBroadcast", iOTCommand);
  220. }
  221. }
  222. /// <summary>
  223. /// 获取某个对象中的属性值
  224. /// </summary>
  225. /// <param name="info"></param>
  226. /// <param name="field"></param>
  227. public object GetPropertyValue(object info, string field)
  228. {
  229. if (info == null) return null;
  230. Type t = info.GetType();
  231. IEnumerable<System.Reflection.PropertyInfo> property = from pi in t.GetProperties() where pi.Name.ToLower() == field.ToLower() select pi;
  232. return property.First().GetValue(info, null);
  233. }
  234. #endregion
  235. }
  236. //命令实体类
  237. public class IOTCommandModel
  238. {
  239. /// <summary>
  240. /// 设备名称
  241. /// </summary>
  242. public string deviceName
  243. {
  244. get;
  245. set;
  246. }
  247. /// <summary>
  248. /// 命令名称:0 控制类 1 设置属性 2 通知信息类
  249. /// </summary>
  250. public int CommandName
  251. {
  252. get;
  253. set;
  254. }
  255. /// <summary>
  256. /// 命令变量:执行变量 key为属性或时间 value为值或者消息
  257. /// </summary>
  258. public Dictionary<string, string> CommandValue
  259. {
  260. get;
  261. set;
  262. }
  263. }
  264. }