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.
 
 

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