终端一体化运控平台
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

DataVClient.cs 17 KiB

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