Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

434 строки
18 KiB

  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. }