Monitor.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. using allInOneMachine;
  2. using BroadcastModule;
  3. using centralController.advert;
  4. using db;
  5. using Monitor;
  6. using MySql.Data.MySqlClient;
  7. using NumMachine;
  8. using parkMonitor.language;
  9. using parkMonitor.model;
  10. using PLCS7;
  11. using System;
  12. using System.Collections.Generic;
  13. using System.Data;
  14. using System.Diagnostics;
  15. using System.Management;
  16. using System.Net;
  17. using System.Text;
  18. using System.Threading;
  19. using System.Threading.Tasks;
  20. using WebServer;
  21. namespace Monitor
  22. {
  23. public class Monitor : IMonitor
  24. {
  25. /// <summary>
  26. /// 监控模块单例
  27. /// </summary>
  28. public static Monitor ins { get; set; }
  29. /// <summary>
  30. /// 中控系统总状态
  31. /// </summary>
  32. public static bool globalStatus = false;
  33. /// <summary>
  34. /// 初始化步骤
  35. /// </summary>
  36. public static int initializeState = 0;
  37. /// <summary>
  38. /// PLC对象句柄
  39. /// </summary>
  40. public static AbstractPLCLinker PLC = null;
  41. public static string plcIPAddr { get; set; }
  42. public static int plcRack { get; set; }
  43. public static int plcSlot { get; set; }
  44. public static string[] plcDatablockConfig { get; set; }
  45. public static int plcTerminalCount { get; set; }
  46. public static int plcParkingSpaceCount { get; set; }
  47. public static int plcRefreshInterval { get; set; }
  48. public static MainBlockStru mainBlockInfo { get; set; }
  49. public static List<ParkingSpaceStru> parkingSpaceInfo { get; set; }
  50. /// <summary>
  51. /// 远程数据库操作句柄
  52. /// </summary>
  53. public static DBOperation remoteDBOper;
  54. /// <summary>
  55. /// 本地数据库操作句柄
  56. /// </summary>
  57. public static DBOperation localDBOper;
  58. /// <summary>
  59. /// 显示板操作对象句柄
  60. /// </summary>
  61. public static BroadcastLinker allInOneMachine;
  62. public static string allInOneMachineIP { get; set; }
  63. public static int allInOneMachinePort { get; set; }
  64. /// <summary>
  65. /// 号牌机操作句柄
  66. /// </summary>
  67. public static NumMachineLinker numMachineLinker;
  68. public static IntPtr flpHandle;
  69. /// <summary>
  70. /// 本地web操作句柄
  71. /// </summary>
  72. public static IWebServer webServer;
  73. public static int webPort { get; set; }
  74. /// <summary>
  75. /// 广告路径
  76. /// </summary>
  77. public static string advertPath { get; set; }
  78. public static AdvertManager advertMgr;
  79. /// <summary>
  80. /// 系统初始化器句柄
  81. /// </summary>
  82. internal static SystemInitializer sysInitializer;
  83. /// <summary>
  84. /// 系统关闭状态
  85. /// </summary>
  86. bool isClosing;
  87. /// <summary>
  88. /// 车库ID
  89. /// </summary>
  90. public static int garageID;
  91. /// <summary>
  92. /// 将显示在界面的提示字符串
  93. /// </summary>
  94. private static Queue<string> notificationQueue = new Queue<string>();
  95. private const int MAXLINES = 50;
  96. private void PLCUpdate()
  97. {
  98. int linkCount = 0;
  99. bool disconnected = false;
  100. while (!isClosing)
  101. {
  102. if (PLC != null)
  103. {
  104. if (PLC.isConnected)
  105. {
  106. if (disconnected) {disconnected = false; SetNotification("PLC已重新连接连接"); }
  107. linkCount = 0;
  108. List<object> received = PLC.ReadFromPLC(PLCDataType.terminal, 0);
  109. //首先获取所有终端信息
  110. try
  111. {
  112. //终端总数相同
  113. if (Terminal.Terminal.terminalInfo.Count == plcTerminalCount)
  114. {
  115. for (int i = 0; i < plcTerminalCount; i++)
  116. {
  117. //一旦发现差异立刻更新
  118. if (!Terminal.Terminal.terminalInfo[i].Equals(received[i]))
  119. {
  120. Terminal.Terminal.terminalInfo[i] = (TerminalStru)received[i];
  121. }
  122. }
  123. }
  124. else
  125. {
  126. //初始化终端信息列表
  127. Terminal.Terminal.terminalInfo.Clear();
  128. for (int i = 0; i < plcTerminalCount; i++)
  129. {
  130. Terminal.Terminal.terminalInfo.Add((TerminalStru)received[i]);
  131. Terminal.Terminal.termUsedMap.Add(((TerminalStru)received[i]).terminalID, false);
  132. }
  133. }
  134. }
  135. catch (Exception e) { Console.WriteLine("PLC监控终端数据," + e.Message); }
  136. //接下来获取中控监控信息
  137. try
  138. {
  139. received = PLC.ReadFromPLC(PLCDataType.central, 0);
  140. if (received.Count > 0 && !mainBlockInfo.Equals(received[0]))
  141. {
  142. mainBlockInfo = (MainBlockStru)received[0];
  143. }
  144. }
  145. catch (Exception e) { Console.WriteLine("PLC监控中控数据," + e.Message); }
  146. //最后获得所有车位信息
  147. try
  148. {
  149. received = PLC.ReadFromPLC(PLCDataType.parkingSpace, 0);
  150. //Console.WriteLine(parkingSpaceInfo.Count+","+ plcParkingSpaceCount);
  151. //车位总数相同
  152. if (parkingSpaceInfo.Count == plcParkingSpaceCount)
  153. {
  154. for (int i = 0; i < plcParkingSpaceCount; i++)
  155. {
  156. //一旦发现差异立刻更新
  157. if (!parkingSpaceInfo[i].Equals(received[i]))
  158. {
  159. parkingSpaceInfo[i] = (ParkingSpaceStru)received[i];
  160. }
  161. }
  162. }
  163. else
  164. {
  165. parkingSpaceInfo.Clear();
  166. for (int i = 0; i < plcParkingSpaceCount; i++)
  167. {
  168. parkingSpaceInfo.Add((ParkingSpaceStru)received[i]);
  169. }
  170. }
  171. }
  172. catch (Exception e) { Console.WriteLine("PLC监控车位数据," + e.Message); }
  173. }
  174. else
  175. {
  176. linkCount += 1;
  177. if (linkCount == 1)
  178. {
  179. disconnected = true;
  180. SetNotification("PLC掉线,请检查连接");
  181. }
  182. }
  183. }
  184. Thread.Sleep(500);
  185. }
  186. }
  187. /// <summary>
  188. /// CPU名
  189. /// </summary>
  190. /// <returns></returns>
  191. private static string getCPUName()
  192. {
  193. try
  194. {
  195. string str = string.Empty;
  196. ManagementClass mcCPU = new ManagementClass("Win32_Processor");
  197. ManagementObjectCollection mocCPU = mcCPU.GetInstances();
  198. foreach (ManagementObject m in mocCPU)
  199. {
  200. string name = m["Name"].ToString();
  201. return name;
  202. }
  203. }
  204. catch { }
  205. return "";
  206. }
  207. /// <summary>
  208. /// 操作系统版本
  209. /// </summary>
  210. private static string getOsVersion()
  211. {
  212. string str = "Windows 10";
  213. try
  214. {
  215. string hdId = string.Empty;
  216. ManagementClass hardDisk = new ManagementClass("Win32_OperatingSystem");
  217. ManagementObjectCollection hardDiskC = hardDisk.GetInstances();
  218. foreach (ManagementObject m in hardDiskC)
  219. {
  220. str = m["Name"].ToString().Split('|')[0].Replace("Microsoft", "").Trim();
  221. break;
  222. }
  223. }
  224. catch
  225. {
  226. }
  227. return str;
  228. }
  229. /// <summary>
  230. /// 显卡名
  231. /// </summary>
  232. private static string getGPUName()
  233. {
  234. string result = "";
  235. try
  236. {
  237. ManagementClass hardDisk = new ManagementClass("Win32_VideoController");
  238. ManagementObjectCollection hardDiskC = hardDisk.GetInstances();
  239. foreach (ManagementObject m in hardDiskC)
  240. {
  241. result = m["VideoProcessor"].ToString();
  242. break;
  243. }
  244. }
  245. catch
  246. {
  247. }
  248. return result;
  249. }
  250. /// <summary>
  251. /// 获取系统内存大小
  252. /// </summary>
  253. private static string getMenSize()
  254. {
  255. ManagementObjectSearcher searcher = new ManagementObjectSearcher(); //用于查询一些如系统信息的管理对象
  256. searcher.Query = new SelectQuery("Win32_PhysicalMemory", "", new string[] { "Capacity" });//设置查询条件
  257. ManagementObjectCollection collection = searcher.Get(); //获取内存容量
  258. ManagementObjectCollection.ManagementObjectEnumerator em = collection.GetEnumerator();
  259. long capacity = 0;
  260. while (em.MoveNext())
  261. {
  262. ManagementBaseObject baseObj = em.Current;
  263. if (baseObj.Properties["Capacity"].Value != null)
  264. {
  265. try
  266. {
  267. capacity += long.Parse(baseObj.Properties["Capacity"].Value.ToString());
  268. }
  269. catch
  270. {
  271. return "-GB";
  272. }
  273. }
  274. }
  275. int gb = 1024 * 1024 * 1024;
  276. return ((double)capacity / gb).ToString("0.0") + "GB";
  277. }
  278. //************************************ 公有方法 **********************************
  279. public Monitor(IntPtr flpHandle)
  280. {
  281. Monitor.flpHandle = flpHandle;
  282. parkingSpaceInfo = new List<ParkingSpaceStru>();
  283. mainBlockInfo = new MainBlockStru();
  284. }
  285. /// <summary>
  286. /// 获取提示信息
  287. /// </summary>
  288. /// <returns></returns>
  289. public string GetNotification()
  290. {
  291. StringBuilder notificationStr = new StringBuilder();
  292. lock (notificationQueue)
  293. {
  294. string[] strs = notificationQueue.ToArray();
  295. Array.Reverse(strs);
  296. for (int i = 0; i < strs.Length; i++)
  297. {
  298. notificationStr.Append(strs[i]);
  299. }
  300. //Queue<string>.Enumerator notiEnumer = notificationQueue.GetEnumerator();
  301. //while (notiEnumer.MoveNext())
  302. //{
  303. // notificationStr.Append(notiEnumer.Current);
  304. //}
  305. }
  306. return notificationStr.ToString();
  307. }
  308. /// <summary>
  309. /// 添加提示信息
  310. /// </summary>
  311. /// <param name="notification"></param>
  312. public static void SetNotification(string notification)
  313. {
  314. if (notification == "clear")
  315. {
  316. lock (notificationQueue)
  317. {
  318. notificationQueue.Clear();
  319. }
  320. return;
  321. }
  322. else
  323. {
  324. string time = DateTime.Now + "\r\n";
  325. string notificationStr = time + notification + "\r\n";
  326. lock (notificationQueue)
  327. {
  328. int count = notificationQueue.Count;
  329. if (count >= MAXLINES)
  330. {
  331. notificationQueue.Dequeue();
  332. }
  333. notificationQueue.Enqueue(notificationStr);
  334. }
  335. }
  336. }
  337. /// <summary>
  338. /// 返回系统信息字符串
  339. /// </summary>
  340. /// <returns></returns>
  341. public static string GetSysInfo()
  342. {
  343. string info = "";
  344. Language lng = Language.ins;
  345. try
  346. {
  347. string endl = "\r\n";
  348. info += endl + lng.autoPackSys + " " + lng.centralPort + endl + endl;
  349. info += lng.version + ":" + SysConst.version() + endl + endl;
  350. info += lng.hostNmae + ":" + Dns.GetHostName() + endl + endl;
  351. info += lng.os + ":" + getOsVersion() + endl + endl;
  352. info += lng.cpu + ":" + getCPUName() + endl + endl;
  353. info += lng.mem + ":" + getMenSize() + endl + endl;
  354. info += lng.gpu + ":" + getGPUName() + endl + endl;
  355. }
  356. catch (Exception) { }
  357. return info;
  358. }
  359. /// <summary>
  360. /// 返回停车记录信息
  361. /// </summary>
  362. /// <returns></returns>
  363. public static List<object[]> GetParkingRecords(string license = "", string startTime = "", string endTime = "")
  364. {
  365. DateTime now = DateTime.Now;
  366. List<object[]> result = new List<object[]>();
  367. string getParkingRecordsSql = "";
  368. if (startTime == "" || endTime == "")
  369. {
  370. DateTime yesterday = DateTime.Now - (new TimeSpan(1, 0, 0, 0));
  371. DateTime twoDaysAgo = DateTime.Now - (new TimeSpan(2, 0, 0, 0));
  372. getParkingRecordsSql = "select parkingRecordsID,userID,numberPlate,parkingSpaceID,realParkTime,realGetTime,receiptNum,parkingPrice,paymentStatus " +
  373. "from parkingrecords where numberPlate " + (license == "" ? "like '%" : "= '" + license) + "' and (realParkTime like '" + now.ToString("yyyy-MM-dd") + "%' or realParkTime like '" + yesterday.ToString("yyyy-MM-dd") + "%' or realParkTime like '" + twoDaysAgo.ToString("yyyy-MM-dd") + "%');";
  374. }
  375. else
  376. {
  377. getParkingRecordsSql = "select parkingRecordsID,userID,numberPlate,parkingSpaceID,realParkTime,realGetTime,receiptNum,parkingPrice,paymentStatus " +
  378. "from parkingrecords where numberPlate " + (license == "" ? "like '%" : "= '" + license) + "' and realParkTime >= '" + startTime + "' and realParkTime <= '" + endTime + "';";
  379. }
  380. if (localDBOper != null)
  381. {
  382. lock (localDBOper)
  383. {
  384. MySqlDataReader reader = localDBOper.Query(getParkingRecordsSql);
  385. try
  386. {
  387. //MySqlDataAdapter adapter = localDBOper.Display(getParkingRecordsSql);
  388. //DataSet ds = new DataSet();
  389. //adapter.Fill(ds);
  390. //DataTable dt = ds.Tables[0];
  391. //for (int i = 0; i < dt.Rows.Count; i++)
  392. //{
  393. // object[] objArray = new object[10];
  394. // for (int j = 0; j < dt.Columns.Count; j++)
  395. // {
  396. // objArray[j] = dt.Rows[i][j];
  397. // }
  398. // result.Add(objArray);
  399. //}
  400. //adapter.Dispose();
  401. while (reader != null && reader.Read())
  402. {
  403. if (reader.HasRows)
  404. {
  405. object[] temp = new object[reader.FieldCount];
  406. reader.GetValues(temp);
  407. result.Add(temp);
  408. }
  409. }
  410. }
  411. catch (Exception e) { Console.WriteLine(e.Message); }
  412. try
  413. {
  414. if (reader != null)
  415. {
  416. reader.Close();
  417. reader.Dispose();
  418. }
  419. }
  420. catch (Exception e) { Console.WriteLine(e.Message); }
  421. }
  422. }
  423. result.Reverse();
  424. return result;
  425. }
  426. /// <summary>
  427. /// 返回预约记录信息
  428. /// </summary>
  429. /// <returns></returns>
  430. public static List<object[]> GetOrderRecords()
  431. {
  432. return null;
  433. }
  434. /// <summary>
  435. /// 返回空闲正常车位数
  436. /// </summary>
  437. /// <param name="state">状态:0.空闲与保留,1.空闲,2.保留</param>
  438. /// <returns></returns>
  439. public int GetFreeSpaceCount(int state)
  440. {
  441. int freeSpaceCount = 0;
  442. int reservedSpaceCount = 0;
  443. if (parkingSpaceInfo != null)
  444. {
  445. foreach (ParkingSpaceStru psStru in parkingSpaceInfo)
  446. {
  447. if (psStru.spaceStatus != 1 && psStru.spaceStatus != 3)
  448. {
  449. freeSpaceCount++;
  450. if (psStru.spaceStatus == 2)
  451. reservedSpaceCount++;
  452. }
  453. }
  454. }
  455. switch (state)
  456. {
  457. case 0:
  458. return freeSpaceCount;
  459. case 1:
  460. return freeSpaceCount - reservedSpaceCount;
  461. case 2:
  462. return reservedSpaceCount;
  463. default:
  464. return freeSpaceCount;
  465. }
  466. }
  467. /// <summary>
  468. /// 暂未使用,查询本地数据库返回可预约车位数
  469. /// </summary>
  470. /// <returns></returns>
  471. public int GetBookableSpaceCount()
  472. {
  473. int bookableSpaceCount = 0;
  474. string bookableSpaceSql = "select currentBookableSpace from garageproperties where garageID = " + garageID + ";";
  475. if (localDBOper != null)
  476. {
  477. MySqlDataReader reader = localDBOper.Query(bookableSpaceSql);
  478. if (reader != null)
  479. {
  480. try
  481. {
  482. if (reader.Read() && reader.HasRows)
  483. {
  484. bookableSpaceCount = reader.GetInt32("currentBookableSpace");
  485. }
  486. }
  487. catch { }
  488. try
  489. {
  490. reader.Close();
  491. reader.Dispose();
  492. }
  493. catch { }
  494. }
  495. }
  496. return bookableSpaceCount;
  497. }
  498. /// <summary>
  499. /// 系统初始化,启动plc监控
  500. /// </summary>
  501. public void Start()
  502. {
  503. if (flpHandle != IntPtr.Zero)
  504. {
  505. //初始化系统
  506. if (sysInitializer == null)
  507. {
  508. sysInitializer = new SystemInitializer();
  509. }
  510. Task.Factory.StartNew(() =>
  511. {
  512. sysInitializer.Init(flpHandle);
  513. });
  514. //更新PLC数据
  515. Task.Factory.StartNew(() =>
  516. {
  517. PLCUpdate();
  518. });
  519. }
  520. }
  521. /// <summary>
  522. /// 系统停止
  523. /// </summary>
  524. public void Stop()
  525. {
  526. sysInitializer.Stop();
  527. }
  528. }
  529. //public class ParkingRecord
  530. //{
  531. // int parkingRecordsID;
  532. // int userID;
  533. // string numberPlate;
  534. // int parkingSpaceID;
  535. //}
  536. }