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

ProcessServer.cs 18 KiB

2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. using DataVApi.Order;
  2. using DataVAPI.Controllers;
  3. using DataVAPI.Model;
  4. using DataVAPI.ModelDataBus;
  5. using DataVAPI.Tool;
  6. using DataVAPI.Tool.IOT;
  7. using DataVAPI.Tool.控制台显示;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Linq;
  11. using System.Threading;
  12. namespace DataVAPI.UpAndDown
  13. {
  14. /// <summary>
  15. /// 上下线通知
  16. /// </summary>
  17. public class ProcessServer
  18. {
  19. /// <summary>
  20. /// 上报大屏总Model
  21. /// </summary>
  22. public ScreenMonitorModel devModel { get; set; }
  23. public DeviceController deviceController { get; set; }
  24. public LogController logController { get; set; }
  25. public ScreenController screenController { get; set; }
  26. public AlarmController alarmController { get; set; }
  27. public OrderProvider orderProvider { get; set; }
  28. public List<DevStatus> devStatuses { get; set; }=new List<DevStatus>();
  29. #region 不需要监听
  30. private static ProcessServer _instance;
  31. public static ProcessServer Instance
  32. {
  33. get
  34. {
  35. if (_instance == null)
  36. _instance = new ProcessServer();
  37. return _instance;
  38. }
  39. }
  40. public ProcessServer()
  41. {
  42. deviceController = new DeviceController();
  43. logController = new LogController();
  44. alarmController = new AlarmController();
  45. screenController = new ScreenController();
  46. orderProvider = new OrderProvider();
  47. }
  48. #endregion
  49. bool FistBOOL = false;
  50. /// <summary>
  51. /// 初始化
  52. /// </summary>
  53. public void Initialize()
  54. {
  55. devModel = new ScreenMonitorModel();
  56. devModel.operatingDeviceStatus = new OperatingDeviceStatus(); devModel.operatingDeviceStatus.data = new List<DevStatus>();//现场设备于状态
  57. devModel.infoMessage = new InfoMessage(); devModel.infoMessage.data = new List<DeviceBase>();//通知消息
  58. //加载店铺信息 //加载店铺信息
  59. LoadingShopInformation();
  60. //MQTT 数据接收处理
  61. ConsoleHelper.WriteInfoLine("尝试连接阿里云.");
  62. //设置变量
  63. IOTDevServer.GetInstance().Set(DataBus.ProductKey, DataBus.DeviceName, DataBus.DeviceSecret);
  64. IOTDevServer.GetInstance().SetSub(new List<string> { IOTDevServer.HeartbeatSubTopic, IOTDevServer.BroadcastTopic });
  65. if (IOTDevServer.GetInstance().CreateLinks(DataBus.ProductKey, DataBus.DeviceName, DataBus.DeviceSecret))
  66. {
  67. //订阅上下线
  68. Subscribe(IOTDevServer.HeartbeatSubTopic);
  69. //订阅主播消息
  70. Subscribe(IOTDevServer.BroadcastTopic);
  71. ConsoleHelper.WriteInfoLine($"阿里云【Transit】连接成功");
  72. }
  73. else
  74. {
  75. ConsoleHelper.WriteErrorLine($"阿里云【Transit】连接失败");
  76. }
  77. IOTDevServer.UNConnectMqtt += new Action<string>((o) => { ConsoleHelper.WriteSuccessLine(o); });
  78. IOTDevServer.DevIOTAction += DevIOTActionHandler;
  79. QueueTask();
  80. ConsoleHelper.WriteSuccessLine("开始接收数据,执行队列任务!");
  81. }
  82. /// <summary>
  83. /// 队列任务
  84. /// </summary>
  85. private void QueueTask()
  86. {
  87. Executer.GetInstance().Start(new Action(() =>
  88. {
  89. while (true)
  90. {
  91. try
  92. {
  93. if (!IOTDevServer.GetInstance().GetIsConnected())
  94. {
  95. if (IOTDevServer.GetInstance().CreateLinks(DataBus.ProductKey, DataBus.DeviceName, DataBus.DeviceSecret))
  96. {
  97. ConsoleHelper.WriteInfoLine($"阿里云【Transit】重新连接成功");
  98. //订阅上下线
  99. Subscribe(IOTDevServer.HeartbeatSubTopic);
  100. //订阅主播消息
  101. Subscribe(IOTDevServer.BroadcastTopic);
  102. }
  103. else
  104. {
  105. ConsoleHelper.WriteErrorLine($"阿里云【Transit】重新连接失败");
  106. }
  107. Thread.Sleep(360000);
  108. }
  109. }
  110. catch (Exception ex)
  111. {
  112. ConsoleHelper.WriteErrorLine(ex.Message);
  113. }
  114. }
  115. }), "阿里云重新连接");
  116. Executer.GetInstance().Start(new Action(() =>
  117. {
  118. while (true)
  119. {
  120. try
  121. {
  122. if (IOTDevServer.GetInstance().GetIsConnected())
  123. {
  124. SentData(null);
  125. //FindDataAlarm();
  126. Thread.Sleep(3000);
  127. }
  128. }
  129. catch (Exception ex)
  130. {
  131. ConsoleHelper.WriteErrorLine(ex.Message);
  132. }
  133. }
  134. }), "队列任务执行");
  135. }
  136. public void FindDataAlarm()
  137. {
  138. devModel?.operatingDeviceStatus.data?.ForEach(par =>
  139. {
  140. if (!string.IsNullOrEmpty(par.clientId))
  141. {
  142. par.IsAlarm = alarmController.QueryClientProcess(par.clientId);
  143. }
  144. });
  145. }
  146. /// <summary>
  147. /// 加载店铺信息
  148. /// </summary>
  149. /// <param name="clientId"></param>
  150. public void LoadingShopInformation(string clientId = "")
  151. {
  152. try
  153. {
  154. devStatuses = devModel.operatingDeviceStatus.data;
  155. ConsoleHelper.WriteSuccessLine("加载店铺集合中.");
  156. JsonMsg<List<DeviceTable>> jsonMsg = deviceController.Query("", "", DateTime.MinValue, DateTime.MinValue);
  157. if (jsonMsg?.obj?.data.Count > 0)
  158. {
  159. //if ((devStatuses.Count != devModel.operatingDeviceStatus.data.Count) || devStatuses.Count<=0)
  160. {
  161. devModel.operatingDeviceStatus.data.Clear();
  162. jsonMsg?.obj?.data?.ForEach(par =>
  163. {
  164. int chid = 0;
  165. try
  166. {
  167. chid = int.Parse(par.ClientId);
  168. }
  169. catch (Exception ex)
  170. {
  171. chid = 0;
  172. }
  173. if (chid > 0)
  174. {
  175. DevStatus devStatus = new DevStatus()
  176. {
  177. deviceName = par.devicename,
  178. gmtCreate = par.devicesecret,
  179. productKey = par.productkey,
  180. DeviceMC = par.devtype,
  181. DeviceMS = par.remark,
  182. DeviceSJ = par.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"),
  183. DeviceZT = "离线",
  184. clientId = par.ClientId,
  185. deviceId = par.DeviceId
  186. };
  187. ConsoleHelper.WriteSuccessLine($"加载设备.{par.devtype} {par.remark}");
  188. DevStatus dev= devStatuses?.Find(k => k.deviceName == par.devicename);
  189. if (dev != null && dev.DeviceZT == "在线") { devStatus.SetStatus(dev.DeviceZT); }
  190. devModel.operatingDeviceStatus.data.Insert(0, devStatus);
  191. if (dev != null && dev.DeviceZT == "在线")
  192. {
  193. OnOrOffline(dev.DeviceZT, devModel.operatingDeviceStatus.data, devStatus);
  194. }
  195. }
  196. });
  197. ConsoleHelper.WriteSuccessLine($"加载设备数[ {jsonMsg?.obj?.data?.Count} ]台...");
  198. }
  199. }
  200. else
  201. {
  202. ConsoleHelper.WriteSuccessLine("查询店铺集合为空.");
  203. }
  204. }
  205. catch (Exception ex)
  206. {
  207. ConsoleHelper.WriteErrorLine($"错误{ex.Message}");
  208. }
  209. }
  210. /// <summary>
  211. /// 订阅主题
  212. /// </summary>
  213. /// <param name="subscribe"></param>
  214. public void Subscribe(string subscribe)
  215. {
  216. IOTDevServer.GetInstance().IOT_Subscribe(subscribe);
  217. ConsoleHelper.WriteSuccessLine("订阅主题: " + subscribe);
  218. }
  219. public void Publish(string PubTopic, CommandModel command)
  220. {
  221. ConsoleHelper.WriteWarningLine("发送数据 " + PubTopic + Tools.JsonConvertTools<CommandModel>(command));
  222. IOTDevServer.GetInstance().IOT_Publish(PubTopic, Tools.JsonConvertTools<CommandModel>(command));
  223. }
  224. /// <summary>
  225. /// 更新内存集合
  226. /// </summary>
  227. /// <param name="receive"></param>
  228. public void SentData(ReceiveModel receiveModel)
  229. {
  230. try
  231. {
  232. if (receiveModel?.deviceContext != null && receiveModel?.status != null)//状态变更消息
  233. {
  234. devModel?.operatingDeviceStatus.data?.Find(par => par.deviceName == receiveModel.deviceContext.deviceName)?.SetStatus(receiveModel.status.value);
  235. //devModel?.infoMessage?.data?.Add(new DeviceBase { DeviceMC = receiveModel.deviceContext.deviceName, DeviceMS = $"设备{receiveModel.status.value}了!", DeviceSJ = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") });
  236. DevStatus dev = devModel?.operatingDeviceStatus.data?.Find(par => par.deviceName == receiveModel.deviceContext.deviceName);
  237. if (dev == null) { LoadingShopInformation(); }
  238. dev = devModel?.operatingDeviceStatus.data?.Find(par => par.deviceName == receiveModel.deviceContext.deviceName);
  239. if (dev != null)
  240. {
  241. logController.Create(new LogTable
  242. {
  243. devicename = receiveModel.deviceContext.deviceName,
  244. ClientId = dev.clientId,
  245. DeviceId = dev.deviceId,
  246. LogTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
  247. LogType = "提示",
  248. LogMessage = $"设备{receiveModel.status.value}了!",
  249. LogVla = "通知"
  250. });
  251. OnOrOffline(receiveModel.status.value, devModel.operatingDeviceStatus.data, dev);
  252. }
  253. else
  254. {
  255. LoadingShopInformation();
  256. }
  257. }
  258. //devModel.OrderLine = orderProvider.OrderLine(new DataVApi.Order.RequestModel.FullScreenBasic());
  259. //devModel.OrderDataState = orderProvider.GetAllOrderDataState(new DataVApi.Order.RequestModel.FullScreenInput());
  260. ////devModel.LocSale = orderProvider.GetLocSale();
  261. //object obj = orderProvider.OrderNumber(new DataVApi.Order.RequestModel.FullScreenBasic());
  262. //devModel.OrderNumber = Tools.JsonToObjectTools<OrderCount>(Tools.JsonConvertTools(obj));
  263. ScreenMonitorModel screen1Monitor = Tools.JsonToObjectTools<ScreenMonitorModel>(devModel.ToJSON());
  264. #region 1.设置data默认值
  265. //if (screen1Monitor.operatingDeviceStatus.data.Count == 0)
  266. //{
  267. // screen1Monitor.operatingDeviceStatus.data.Add(new DevStatus { DeviceMC = "", DeviceMS = "", DeviceSJ = "", deviceName = "", DeviceZT = "", gmtCreate = "" });
  268. //}
  269. //if (screen1Monitor.infoMessage.data.Count == 0)
  270. //{
  271. // screen1Monitor.infoMessage.data.Add(new DeviceBase { DeviceMC = "", DeviceMS = "", DeviceSJ = "" });
  272. //}
  273. #endregion
  274. string JSON = screen1Monitor.ToJSON();
  275. if (!string.IsNullOrEmpty(JSON))
  276. {
  277. //screenController.CreateOrUpdate(new LargeScreenTable() { json = JSON, devicename = "Transit", ClientId = "-10", DeviceId = "-10" });
  278. IOTDevServer.GetInstance().IOT_Publish(IOTDevServer.ScreenShowPubTopic, JSON);
  279. }
  280. //if (devModel.infoMessage.data != null && devModel.infoMessage.data.Count > 0)
  281. //{
  282. // List<DeviceBase> bases = devModel.infoMessage.data.ToList();
  283. // bases?.ForEach(par =>
  284. // {
  285. // if (string.IsNullOrEmpty(par.DeviceMC)) devModel.infoMessage.data.Remove(par);
  286. // if (!string.IsNullOrEmpty(par.DeviceSJ) && DateTime.Now.AddSeconds(-5) > DateTime.Parse(par.DeviceSJ))
  287. // {
  288. // devModel.infoMessage.data.Remove(par);
  289. // }
  290. // });
  291. //}
  292. }
  293. catch (Exception ex)
  294. {
  295. ConsoleHelper.WriteErrorLine($"错误{ex.Message}");
  296. }
  297. }
  298. /// <summary>
  299. /// 上下线调整
  300. /// </summary>
  301. /// <typeparam name="T"></typeparam>
  302. /// <param name="status"></param>
  303. /// <param name="list"></param>
  304. /// <param name="present"></param>
  305. /// <returns></returns>
  306. private static List<T> OnOrOffline<T>(string status, List<T> list, T present)
  307. {
  308. int now = list.IndexOf(present);
  309. switch (status)
  310. {
  311. case "离线":
  312. list.Remove(present);
  313. list.Add(present);
  314. break;
  315. default:
  316. //在线
  317. list.Remove(present);
  318. list.Insert(0, present);
  319. break;
  320. }
  321. return list;
  322. }
  323. /// <summary>
  324. /// list 位置交换
  325. /// </summary>
  326. /// <typeparam name="T"></typeparam>
  327. /// <param name="list"></param>
  328. /// <param name="index1"></param>
  329. /// <param name="index2"></param>
  330. /// <returns></returns>
  331. private static List<T> Swap<T>(List<T> list, int index1, int index2)
  332. {
  333. var temp = list[index1];
  334. list[index1] = list[index2];
  335. list[index2] = temp;
  336. return list;
  337. }
  338. /// <summary>
  339. /// MQTT 消息
  340. /// </summary>
  341. /// <param name="topic"></param>
  342. /// <param name="message"></param>
  343. private void DevIOTActionHandler(string topic, string message)
  344. {
  345. if (string.IsNullOrEmpty(topic)) return;
  346. if (topic == IOTDevServer.HeartbeatSubTopic)//上下线订阅主题
  347. {
  348. ReceiveModel receiveModel = Tools.JsonToObjectTools<ReceiveModel>(message);
  349. if (receiveModel != null && receiveModel.status != null)//上下线通知
  350. {
  351. if (receiveModel.deviceContext.deviceName != "Transit" && receiveModel.deviceContext.deviceName != "Transit_Test")
  352. {
  353. ConsoleHelper.WriteWarningLine("接收数据 " + topic + " 数据 " + message);
  354. SentData(receiveModel);
  355. }
  356. }
  357. }
  358. else if (topic == IOTDevServer.BroadcastTopic)//广播主题
  359. {
  360. if (message.Contains("AlarmType"))
  361. {
  362. AlarmTable alarm = Tools.JsonToObjectTools<AlarmTable>(message);
  363. if (alarm.State == "n")
  364. {
  365. AlarmTable al = alarmController.mg.QueryKeyID(alarm.KeyID);
  366. if (al != null)
  367. {
  368. alarmController.mg.Modify(al.Id, "State", "n");
  369. }
  370. }
  371. else
  372. {
  373. alarmController.Create(alarm);
  374. }
  375. FindDataAlarm();
  376. }
  377. else if (message.Contains("LogType"))
  378. {
  379. logController.Create(Tools.JsonToObjectTools<LogTable>(message));
  380. }
  381. else if (message == "刷新店铺列表")
  382. {
  383. LoadingShopInformation();
  384. }
  385. }
  386. //else if (topic == IOTDevServer.TargetStatusSubTopic)//属性变更
  387. //{
  388. // ReceiveModel rEmodel = Tools.JsonToObjectTools<ReceiveModel>(message);
  389. // string name= rEmodel.deviceContext.deviceName;
  390. // string status = rEmodel.props.NodeStatus.value;
  391. // string id = deviceController.QueryDeviceName(name)?.obj?.data?.ClientId;
  392. // screenController.CreateOrUpdate(new LargeScreenTable() { json = status, devicename = name, ClientId = id, DeviceId = "" });
  393. //}
  394. }
  395. }
  396. }