Explorar o código

从wpf切回winform

yc_t %!s(int64=6) %!d(string=hai) anos
pai
achega
33f532e8a1
Modificáronse 100 ficheiros con 7146 adicións e 190 borrados
  1. 187 0
      .gitignore
  2. 57 30
      PLCLinker/parkMonitor/server/NumMachine/NumMachine.cs
  3. 25 0
      NumMachineTest/NumMachineTest.sln
  4. 9 0
      NumMachineTest/NumMachineTest/App.xaml
  5. 17 0
      NumMachineTest/NumMachineTest/App.xaml.cs
  6. 15 0
      NumMachineTest/NumMachineTest/INumMachineLinker.cs
  7. 18 0
      NumMachineTest/NumMachineTest/MainWindow.xaml
  8. 41 0
      NumMachineTest/NumMachineTest/MainWindow.xaml.cs
  9. 811 0
      NumMachineTest/NumMachineTest/NumMachine.cs
  10. 112 0
      NumMachineTest/NumMachineTest/NumMachineTest.csproj
  11. 55 0
      NumMachineTest/NumMachineTest/Properties/AssemblyInfo.cs
  12. 71 0
      NumMachineTest/NumMachineTest/Properties/Resources.Designer.cs
  13. 4 7
      PLCLinker/parkMonitor/view/FormModbus/VideoCfg_Form.resx
  14. 30 0
      NumMachineTest/NumMachineTest/Properties/Settings.Designer.cs
  15. 0 0
      NumMachineTest/NumMachineTest/Properties/Settings.settings
  16. 0 0
      NumMachineTest/NumMachineTest/VzClientSDK.cs
  17. 71 0
      NumMachineTest/NumMachineTest/broadcastModule/broadcastModule.cs
  18. 0 0
      NumMachineTest/NumMachineTest/entity/AbstractMessage.cs
  19. 0 0
      NumMachineTest/NumMachineTest/sdk/HslCommunication.dll
  20. 0 0
      NumMachineTest/NumMachineTest/sdk/Newtonsoft.Json.dll
  21. 0 0
      NumMachineTest/NumMachineTest/sdk/VZ_Sdk.dll
  22. 0 0
      NumMachineTest/NumMachineTest/sdk/VzDrawsLib.dll
  23. 0 0
      NumMachineTest/NumMachineTest/sdk/VzLPRSDK.dll
  24. BIN=BIN
      NumMachineTest/NumMachineTest/sdk/broadcastDLL.dll
  25. 0 0
      NumMachineTest/NumMachineTest/sdk/iDecoders.dll
  26. BIN=BIN
      PLCLinker/.vs/PLCLinker/v15/.suo
  27. BIN=BIN
      PLCLinker/.vs/PLCLinker/v15/Server/sqlite3/storage.ide
  28. 849 0
      PLCLinker/NumMachineModel.cs
  29. 5 5
      PLCLinker/PLCLinker.sln
  30. 3 3
      PLCLinker/PLCLinker/App.config
  31. 5 5
      PLCLinker/PLCLinker/PLCLinker.csproj
  32. 87 62
      PLCLinker/PLCLinker/Program.cs
  33. BIN=BIN
      PLCLinker/PLCLinker/bin/Release/PLCLinker.exe
  34. 3 3
      PLCLinker/PLCLinker/bin/Release/PLCLinker.exe.config
  35. BIN=BIN
      PLCLinker/PLCLinker/bin/Release/PLCLinker.pdb
  36. BIN=BIN
      PLCLinker/PLCLinker/bin/Release/PLCS7.dll
  37. BIN=BIN
      PLCLinker/PLCLinker/bin/Release/PLCS7.pdb
  38. 1 1
      PLCLinker/PLCLinker/obj/Release/PLCLinker.csproj.CoreCompileInputs.cache
  39. 1 2
      PLCLinker/PLCLinker/obj/Release/PLCLinker.csproj.FileListAbsolute.txt
  40. BIN=BIN
      PLCLinker/PLCLinker/obj/Release/PLCLinker.csprojResolveAssemblyReference.cache
  41. BIN=BIN
      PLCLinker/PLCLinker/obj/Release/PLCLinker.exe
  42. BIN=BIN
      PLCLinker/PLCLinker/obj/Release/PLCLinker.pdb
  43. 1 1
      PLCLinker/PLCS7/PLCS7.cs
  44. 2 1
      PLCLinker/PLCS7/PLCS7.csproj
  45. BIN=BIN
      PLCLinker/PLCS7/bin/Release/PLCS7.dll
  46. BIN=BIN
      PLCLinker/PLCS7/bin/Release/PLCS7.pdb
  47. 1 1
      PLCLinker/PLCS7/obj/Release/PLCS7.csproj.CoreCompileInputs.cache
  48. BIN=BIN
      PLCLinker/PLCS7/obj/Release/PLCS7.dll
  49. BIN=BIN
      PLCLinker/PLCS7/obj/Release/PLCS7.pdb
  50. 47 0
      PLCLinker/ParkController/Form1.Designer.cs
  51. 20 0
      PLCLinker/ParkController/Form1.cs
  52. 0 0
      PLCLinker/ParkController/Form1.resx
  53. 82 0
      PLCLinker/ParkController/ParkController.csproj
  54. 22 0
      PLCLinker/ParkController/Program.cs
  55. 36 0
      PLCLinker/ParkController/Properties/AssemblyInfo.cs
  56. 71 0
      PLCLinker/ParkController/Properties/Resources.Designer.cs
  57. 4 7
      PLCLinker/parkMonitor/view/FormModbus/RuleCfg_Form.resx
  58. 30 0
      PLCLinker/ParkController/Properties/Settings.Designer.cs
  59. 7 0
      PLCLinker/ParkController/Properties/Settings.settings
  60. 9 0
      PLCLinker/WpfApp1/App.xaml
  61. 8 6
      PLCLinker/parkMonitor/App.xaml.cs
  62. 14 0
      PLCLinker/WpfApp1/Entry/MainEntry.cs
  63. 184 0
      PLCLinker/WpfApp1/Entry/SystemInitializer.cs
  64. 23 0
      PLCLinker/WpfApp1/MainWindow.xaml
  65. 59 0
      PLCLinker/WpfApp1/MainWindow.xaml.cs
  66. 16 0
      PLCLinker/WpfApp1/Monitor/IMonitor.cs
  67. 30 0
      PLCLinker/WpfApp1/Monitor/Monitor.cs
  68. 17 0
      PLCLinker/WpfApp1/NumMachine/INumMachineLinker.cs
  69. 885 0
      PLCLinker/WpfApp1/NumMachine/NumMachine.cs
  70. 2287 0
      PLCLinker/WpfApp1/NumMachine/VzClientSDK.cs
  71. 8 9
      PLCLinker/parkMonitor/Properties/AssemblyInfo.cs
  72. 63 0
      PLCLinker/WpfApp1/Properties/Resources.Designer.cs
  73. 4 7
      PLCLinker/parkMonitor/view/FormModbus/RVideoCfg_Form.resx
  74. 2 2
      PLCLinker/parkMonitor/Properties/Settings.Designer.cs
  75. 7 0
      PLCLinker/WpfApp1/Properties/Settings.settings
  76. 20 0
      PLCLinker/WpfApp1/SuperAdmin/ISuperAdmin.cs
  77. 31 0
      PLCLinker/WpfApp1/SuperAdmin/SuperAdmin.cs
  78. 18 0
      PLCLinker/WpfApp1/Terminal/ITerminalDisplay.cs
  79. 46 0
      PLCLinker/WpfApp1/Terminal/Terminal.cs
  80. 64 36
      PLCLinker/parkMonitor/server/WebThread/CentralForWebSocketServer.cs
  81. 24 0
      PLCLinker/WpfApp1/WebServer/IWebServer.cs
  82. 1 1
      PLCLinker/parkMonitor/server/WebThread/LazySingleton.cs
  83. 1 1
      PLCLinker/parkMonitor/server/WebThread/MultiSocketThread.cs
  84. 167 0
      PLCLinker/WpfApp1/WpfApp1.csproj
  85. 358 0
      PLCLinker/WpfApp1/entity/AbstractMessage.cs
  86. 0 0
      PLCLinker/WpfApp1/entity/Jsonhelper.cs
  87. BIN=BIN
      PLCLinker/WpfApp1/sdk/PLC/PLCS7.dll
  88. BIN=BIN
      PLCLinker/WpfApp1/sdk/PLC/S7.Net.dll
  89. 0 0
      PLCLinker/WpfApp1/sdk/VZ_Sdk/HslCommunication.dll
  90. 0 0
      PLCLinker/WpfApp1/sdk/VZ_Sdk/Newtonsoft.Json.dll
  91. 0 0
      PLCLinker/WpfApp1/sdk/VZ_Sdk/VZ_Sdk.dll
  92. 0 0
      PLCLinker/WpfApp1/sdk/VZ_Sdk/VzDrawsLib.dll
  93. 0 0
      PLCLinker/WpfApp1/sdk/VZ_Sdk/VzLPRSDK.dll
  94. 0 0
      PLCLinker/WpfApp1/sdk/VZ_Sdk/iDecoders.dll
  95. BIN=BIN
      PLCLinker/WpfApp1/sdk/broadcast/DUCP.dll
  96. BIN=BIN
      PLCLinker/WpfApp1/sdk/broadcast/broadcastDLL.dll
  97. BIN=BIN
      PLCLinker/WpfApp1/sdk/broadcast/msvcr120d.dll
  98. 0 0
      PLCLinker/WpfApp1/sdk/log4net/log4net.dll
  99. 0 0
      PLCLinker/WpfApp1/sdk/log4net/log4net.xml
  100. 0 0
      PLCLinker/WpfApp1/sdk/mysql/DatabaseDLL.dll

+ 187 - 0
.gitignore

@@ -0,0 +1,187 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.sln.docstates
+
+# Build results
+
+[Dd]ebug/
+[Rr]elease/
+x64/
+build/
+[Bb]in/
+[Oo]bj/
+
+# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
+!packages/*/build/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+*_i.c
+*_p.c
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.log
+*.scc
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+*.cachefile
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+*.ncrunch*
+.*crunch*.local.xml
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+# publish/
+
+# Publish Web Output
+*.Publish.xml
+
+# NuGet Packages Directory
+## TODO: If you have NuGet Package Restore enabled, uncomment the next line
+#packages/
+
+# Windows Azure Build Output
+csx
+*.build.csdef
+
+# Windows Store app package directory
+AppPackages/
+
+# Others
+sql/
+*.Cache
+ClientBin/
+[Ss]tyle[Cc]op.*
+~$*
+*~
+*.dbmdl
+*.[Pp]ublish.xml
+*.pfx
+*.publishsettings
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file to a newer
+# Visual Studio version. Backup files are not needed, because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+App_Data/*.mdf
+App_Data/*.ldf
+
+
+#LightSwitch generated files
+GeneratedArtifacts/
+_Pvt_Extensions/
+ModelManifest.xml
+
+# =========================
+# Windows detritus
+# =========================
+
+# Windows image file caches
+Thumbs.db
+ehthumbs.db
+
+# Folder config file
+Desktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Mac desktop service store files
+.DS_Store
+
+*.orig
+
+# =========================
+# java project
+.idea/
+.settings/
+.myeclipse/
+.mymetadata
+
+.vs
+/modbus_PLC_laser_test/新plc模拟.mbs
+#Ignore thumbnails created by Windows
+#Ignore files built by Visual Studio
+*.mbs
+*.config
+
+*.exe
+*.bak
+*.cache
+[Bb]in
+[Dd]ebug*/
+*.lib
+obj/
+[Rr]elease*/
+[Tt]est[Rr]esult*
+.vs/
+#Nuget packages folder
+packages/
+/parkMonitor/App.config
+/modbus_PLC_laser_test/新plc模拟.mbs

+ 57 - 30
PLCLinker/parkMonitor/server/NumMachine/NumMachine.cs

@@ -14,19 +14,16 @@ using System.Net;
 using parkMonitor.entity;
 using System.Diagnostics;
 using System.Threading.Tasks;
-using parkMonitor.model;
-using parkMonitor.viewModel.objectTree;
-using parkMonitor.server.uiLogServer;
 using System.Configuration;
-using parkMonitor.LOG;
+using parkMonitor.server.broadcastModule;
 
-namespace parkMonitor.server
+namespace MyNumMachineManager
 {
 
     /// <summary>
     /// 号牌机通信类
     /// </summary>
-    public partial class NumMachineLinker : Form, IEquipments
+    public partial class NumMachineLinker : Form, INumMachineLinker
     {
         /// <summary>
         /// 刷新时间间隔与个数
@@ -72,7 +69,6 @@ namespace parkMonitor.server
         {
             Control.CheckForIllegalCrossThreadCalls = false;
             InitializeComponent();
-
             Thread thread = new Thread(new ThreadStart(DateTimeInfo));
             thread.IsBackground = true;
             thread.Start(); //显示当前时间            
@@ -85,7 +81,7 @@ namespace parkMonitor.server
             {
                 filterRatio = Double.Parse(ConfigurationManager.AppSettings.Get("filterRatio"));
             }
-            catch (Exception) { UILogServer.ins.error("号牌机配置文件异常"); Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "号牌机配置文件异常"); }
+            catch (Exception) { Console.WriteLine("号牌机配置文件异常"); }
             //m_sAppPath = System.IO.Directory.GetCurrentDirectory();
         }
 
@@ -101,13 +97,13 @@ namespace parkMonitor.server
 
         private void FormSiemens_Load(object sender, EventArgs e)
         {
-            Thread thread = new Thread(new ThreadStart(DateTimeInfo));
-            thread.IsBackground = true;
-            thread.Start(); //显示当前时间            
+            //Thread thread = new Thread(new ThreadStart(DateTimeInfo));
+            //thread.IsBackground = true;
+            //thread.Start(); //显示当前时间            
 
-            VzClientSDK.VzLPRClient_Setup();
+            //VzClientSDK.VzLPRClient_Setup();
 
-            hwndMain = this.Handle;
+            //hwndMain = this.Handle;
             //m_sAppPath = System.IO.Directory.GetCurrentDirectory();
             //this.ShowInTaskbar = false;
             //this.Opacity = 0;
@@ -158,8 +154,7 @@ namespace parkMonitor.server
                     nmn.status = EnumNumberMachineStatus.Offline;
                     if (count == 1)
                     {
-                        Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "正在与ip为 " + nmn.ip + " 的号牌机 进行连接。");
-                        UILogServer.ins.info("正在与ip为 " + nmn.ip + " 的号牌机 进行连接。");
+                        Console.WriteLine("正在与ip为 " + nmn.ip + " 的号牌机 进行连接。");
                     }
                     Thread.Sleep(10000);
                 }
@@ -200,7 +195,7 @@ namespace parkMonitor.server
                                         int id = Int32.Parse(ConfigurationManager.AppSettings.Get(ipEnumer.Current.Key));
                                         ipIdMap.Add(ipEnumer.Current.Key, id);
                                     }
-                                    catch (Exception) { UILogServer.ins.log("读取号牌机编号映射失败,配置文件填写有误"); Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "读取号牌机编号映射失败"); }
+                                    catch (Exception) { Console.WriteLine("读取号牌机编号映射失败,配置文件填写有误"); }
                                 }
                             }
                         }
@@ -371,13 +366,11 @@ namespace parkMonitor.server
                         int temp = VzClientSDK.VzLPRClient_ImageSaveToJpeg(pImgFull, path, 50);
                         if (temp != -1)
                         {
-                            Log.WriteLog(LogType.NOT_DATABASE, LogFile.LOG, "号牌机" + ip + "已拍照,图片保存于 " + strFilePath);
-                            UILogServer.ins.info("号牌机" + ip + "已拍照,图片保存于 " + strFilePath);
+                            Console.WriteLine("号牌机" + ip + "已拍照,图片保存于 " + strFilePath);
                         }
                         else
                         {
-                            UILogServer.ins.info("图片保存失败");
-                            Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "图片保存失败");
+                            Console.WriteLine("图片保存失败");
                         }
                     }
                     snapshotDevHandle = -1;
@@ -402,7 +395,7 @@ namespace parkMonitor.server
                         id = Int32.Parse(ConfigurationManager.AppSettings.Get(strIP));
                         ipIdMap.Add(strIP, id);
                     }
-                    catch (Exception) { UILogServer.ins.error("读取号牌机编号映射失败,配置文件填写有误"); Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "读取号牌机编号映射失败"); }
+                    catch (Exception) { Console.WriteLine("读取号牌机编号映射失败,配置文件填写有误"); }
                 }
             }
             //检查设备是否存在
@@ -497,6 +490,18 @@ namespace parkMonitor.server
                                 if (ipIdMap.TryGetValue(node.ip, out node.id))
                                 {
                                     LicBuffer.Enqueue((NumberMachineNode)node.Clone());
+                                    if (node.id == 1)
+                                    {
+                                        Task.Factory.StartNew(() => {
+                                            if (BroadcastLinker.ins != null)
+                                            {
+                                                BroadcastLinker.ins.DispString(1, node.LicenseNum, 6);
+                                                BroadcastLinker.ins.AudioPlay(node.LicenseNum + ",入场");
+                                                Thread.Sleep(5000);
+                                                BroadcastLinker.ins.DispDownStr(1, 0);
+                                            }
+                                        });
+                                    }
                                 }
                             }
                         }
@@ -548,8 +553,22 @@ namespace parkMonitor.server
             {
                 if (!namePicMap.ContainsKey(pb.Name))
                 {
-                    flowLayoutPanel1.Controls.Add(pb);
+                    try
+                    {
+                        PictureBox temp = pb;
+                        //flowLayoutPanel1.Controls.Add(temp);
+                        if (flowLayoutPanel1.InvokeRequired)
+                        {
+                            flowLayoutPanel1.Invoke(new Action(() => { flowLayoutPanel1.Controls.Add(temp); }));
+                        }
+                        else
+                        {
+                            flowLayoutPanel1.Controls.Add(pb);
+                        }
+                    }
+                    catch (Exception e) { Console.WriteLine(e.Message); }
                     namePicMap.Add(pb.Name, pb);
+                    this.Show();
                     return true;
                 }
                 else
@@ -612,7 +631,6 @@ namespace parkMonitor.server
             {
                 Run();
             });
-
             //Task imgTest = Task.Factory.StartNew(() =>
             //{
             //    while (!isClosing)
@@ -765,15 +783,24 @@ namespace parkMonitor.server
                 }
                 else
                 {
-                    UILogServer.ins.error("参数错误,图片未保存");
-                    Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "参数错误,图片未保存");
+                    Console.WriteLine("参数错误,图片未保存");
                 }
             }
 
         }
+
+        public void GetLicensePlate()
+        {
+            throw new NotImplementedException();
+        }
+
+        public void GetImage()
+        {
+            throw new NotImplementedException();
+        }
     }
 
-    public class NumMachineManager : IEquipments
+    public class NumMachineManager
     {
         public static NumMachineLinker ins;
         public AbstractMessage GetMessage()
@@ -795,8 +822,8 @@ namespace parkMonitor.server
 
         public void Start()
         {
-            Task.Factory.StartNew(() =>
-            {
+            //Task.Factory.StartNew(() =>
+            //{
                 ins = new NumMachineLinker();
                 Task.Factory.StartNew(() =>
                 {
@@ -805,8 +832,8 @@ namespace parkMonitor.server
                     //ins.ShowDialog();
                 });
                 //ins.WindowState = FormWindowState.Minimized;
-                ins.Hide();
-            });
+                //ins.Hide();
+            //});
         }
 
         public void Stop()

+ 25 - 0
NumMachineTest/NumMachineTest.sln

@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27130.2026
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NumMachineTest", "NumMachineTest\NumMachineTest.csproj", "{AD38F4AE-F726-4118-9F14-8BD651A4B1DE}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{AD38F4AE-F726-4118-9F14-8BD651A4B1DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{AD38F4AE-F726-4118-9F14-8BD651A4B1DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{AD38F4AE-F726-4118-9F14-8BD651A4B1DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{AD38F4AE-F726-4118-9F14-8BD651A4B1DE}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {C02A3765-8405-462A-9A8A-E61D55849939}
+	EndGlobalSection
+EndGlobal

+ 9 - 0
NumMachineTest/NumMachineTest/App.xaml

@@ -0,0 +1,9 @@
+<Application x:Class="NumMachineTest.App"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:local="clr-namespace:NumMachineTest"
+             StartupUri="MainWindow.xaml">
+    <Application.Resources>
+         
+    </Application.Resources>
+</Application>

+ 17 - 0
NumMachineTest/NumMachineTest/App.xaml.cs

@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace NumMachineTest
+{
+    /// <summary>
+    /// App.xaml 的交互逻辑
+    /// </summary>
+    public partial class App : Application
+    {
+    }
+}

+ 15 - 0
NumMachineTest/NumMachineTest/INumMachineLinker.cs

@@ -0,0 +1,15 @@
+namespace MyNumMachineManager
+{
+	public interface INumMachineLinker
+	{
+		void GetLicensePlate();
+
+		void GetImage();
+
+		void Start();
+
+		void Stop();
+	}
+
+}
+

+ 18 - 0
NumMachineTest/NumMachineTest/MainWindow.xaml

@@ -0,0 +1,18 @@
+<Window x:Class="NumMachineTest.MainWindow"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:wfh="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
+        xmlns:wfc="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
+        xmlns:local="clr-namespace:NumMachineTest"
+        mc:Ignorable="d"
+        Title="MainWindow" Height="700" Width="1200" Closed="win_Closed" WindowStartupLocation="CenterScreen">
+    <Grid>
+        <WindowsFormsHost x:Name="form1" HorizontalAlignment="Left" Height="500" Margin="10,65,0,0" VerticalAlignment="Top" Width="750">
+            <wfc:FlowLayoutPanel x:Name="flowLayoutPanel1">
+
+            </wfc:FlowLayoutPanel>
+        </WindowsFormsHost>
+    </Grid>
+</Window>

+ 41 - 0
NumMachineTest/NumMachineTest/MainWindow.xaml.cs

@@ -0,0 +1,41 @@
+using MyNumMachineManager;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Interop;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace NumMachineTest
+{
+    /// <summary>
+    /// MainWindow.xaml 的交互逻辑
+    /// </summary>
+    public partial class MainWindow : Window
+    {
+        NumMachineLinker nml;
+        public MainWindow()
+        {
+            InitializeComponent();
+            IntPtr flpHandle = flowLayoutPanel1.Handle;
+            nml = new NumMachineLinker(flpHandle);
+            nml.Start();
+        }
+
+        private void win_Closed(object sender, EventArgs e)
+        {
+            if (nml != null) { nml.Stop(); }
+            Close();
+            System.Environment.Exit(0);
+        }
+    }
+}

+ 811 - 0
NumMachineTest/NumMachineTest/NumMachine.cs

@@ -0,0 +1,811 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Windows.Forms;
+using HslCommunication;
+using HslCommunication.ModBus;
+using System.Threading;
+using System.Collections;
+using HslCommunication.Controls;
+using VzClientSDKDemo;
+using System.Runtime.InteropServices;
+using System.IO;
+using System.Net;
+using parkMonitor.entity;
+using System.Diagnostics;
+using System.Threading.Tasks;
+using System.Configuration;
+using parkMonitor.server.broadcastModule;
+
+namespace MyNumMachineManager
+{
+
+    /// <summary>
+    /// 号牌机通信类
+    /// </summary>
+    public partial class NumMachineLinker : INumMachineLinker
+    {
+        /// <summary>
+        /// 刷新时间间隔与个数
+        /// </summary>
+        public const int REFRESHINGTIME = 500, FILTERINGNUMBER = 8;
+        ///<summary>通过设备句柄访问pic;链接时add,系统关闭时remove</summary>
+        private static Dictionary<int, IntPtr> devPicMap = new Dictionary<int, IntPtr>();
+        ///<summary>通过名字获取pic对象;创建pic时add,系统关闭remove</summary>
+        private static Dictionary<string, IntPtr> namePicMap = new Dictionary<string, IntPtr>();
+        ///<summary>通过ip获取设备id;产生ip时创建</summary>
+        private static Dictionary<string, int> ipIdMap = new Dictionary<string, int>();
+        ///<summary>通过ip获取设备句柄;产生句柄时创建</summary>
+        private static Dictionary<string, int> ipHandleMap = new Dictionary<string, int>();
+        /// <summary>句柄到号牌回调映射</summary>
+        private static Dictionary<int, VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK> handleCallbackMap = new Dictionary<int, VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK>();
+        ///<summary>号牌队列</summary>
+        private static Queue<NumberMachineNode> LicBuffer = new Queue<NumberMachineNode>();
+        ///<summary>计数Map</summary>
+        private static Dictionary<string, Dictionary<NumberMachineNode, int>> filterMap = new Dictionary<string, Dictionary<NumberMachineNode, int>>();
+        /// <summary>筛选计数</summary>
+        private static int filterCount = 0;
+        private static double filterRatio = 0.7;
+        /// <summary>系统关闭</summary>
+        private static bool isClosing = false;
+        /// <summary>开启拍照的设备</summary>
+        private static int snapshotDevHandle = -1;
+        /// <summary>允许无号牌时拍照</summary>
+        private static bool enableEmptySnapshot = true;
+
+        private static NumberMachineMessage nmMsg = new NumberMachineMessage();
+        private static VzClientSDK.VZLPRC_FIND_DEVICE_CALLBACK_EX find_DeviceCB = null;
+        private const int MSG_PLATE_INFO = 0x901;
+        private const int MSG_DEVICE_INFO = 0x902;
+        /// <summary>
+        /// 用于消息传递机制
+        /// </summary>
+        //public static IntPtr hwndMain;
+
+        public static IntPtr flowLayoutPanel1;
+
+        public static ToolStripStatusLabel timeLabel;
+        /// <summary>
+        /// 号牌机类构造函数
+        /// </summary>
+        public NumMachineLinker(IntPtr flpHandle)
+        {
+            //Control.CheckForIllegalCrossThreadCalls = false;
+            //Thread thread = new Thread(new ThreadStart(DateTimeInfo));
+            //thread.IsBackground = true;
+            //thread.Start(); //显示当前时间            
+            flowLayoutPanel1 = flpHandle;
+
+            
+
+            //timeLabel = new ToolStripStatusLabel();
+
+            try
+            {
+                VzClientSDK.VzLPRClient_Setup();
+                filterRatio = Double.Parse(ConfigurationManager.AppSettings.Get("filterRatio"));
+            }
+            catch (Exception e) { Console.WriteLine(e.Message+",号牌机配置文件异常"); }
+            //m_sAppPath = System.IO.Directory.GetCurrentDirectory();
+        }
+
+        /// <summary>
+        /// 定义时钟委托
+        /// </summary>
+        public delegate void SetDateTime();
+
+        /// <summary>
+        /// 实时采集
+        /// </summary>
+        public delegate void Begin_Read();
+
+        private void FormSiemens_Load(object sender, EventArgs e)
+        {
+            //Thread thread = new Thread(new ThreadStart(DateTimeInfo));
+            //thread.IsBackground = true;
+            //thread.Start(); //显示当前时间            
+
+            //VzClientSDK.VzLPRClient_Setup();
+
+            //hwndMain = this.Handle;
+            //m_sAppPath = System.IO.Directory.GetCurrentDirectory();
+            //this.ShowInTaskbar = false;
+            //this.Opacity = 0;
+
+        }
+
+        private void FormSiemens_FormClosing(object sender, FormClosingEventArgs e)
+        {
+            Stop();
+        }
+
+        private void DateTimeInfo()
+        {
+            try
+            {
+                while (!isClosing)
+                {
+                    SetDateTime setDate = new SetDateTime(
+                    delegate
+                    {
+                        timeLabel.Text = DateTime.Now.ToString();
+                    });
+                    setDate();
+                    Thread.Sleep(1000);
+                }
+                // ReSharper disable once FunctionNeverReturns
+            }
+            catch (Exception e) { Debug.Print(e.StackTrace); }
+        }
+
+        //******************************************************************************************************************
+        private void UpdateStatus(NumberMachineNode nmn)
+        {
+            //提示次数计数
+            int count = 0;
+            while (!isClosing)
+            {
+                if (GetStatus(nmn.ip) == 1)
+                {
+                    nmn.status = EnumNumberMachineStatus.Normal;
+                    count = 0;
+                }
+                else
+                {
+                    count++;
+                    //号牌机断线写日志
+                    nmn.status = EnumNumberMachineStatus.Offline;
+                    if (count == 1)
+                    {
+                        Console.WriteLine("正在与ip为 " + nmn.ip + " 的号牌机 进行连接。");
+                    }
+                    Thread.Sleep(10000);
+                }
+                Thread.Sleep(REFRESHINGTIME);
+            }
+        }
+
+        private void Run()
+        {
+            try
+            {
+                while (!isClosing)
+                {
+                    Thread.Sleep(REFRESHINGTIME);
+                    //定时返回号牌
+                    lock (devPicMap)
+                    {
+                        Dictionary<int, IntPtr>.Enumerator devEnumer = devPicMap.GetEnumerator();
+                        while (devEnumer.MoveNext())
+                        {
+                            ActivateSnap(devEnumer.Current.Key);
+                            //Debug.WriteLine(lv.data.Count.ToString()+":\n"+ lv.data[lv.data.Count-1].LicenseNum+ lv.data[lv.data.Count - 1].TimeRecord);
+                        }
+                    }
+                    //读取设备ip与id映射关系
+                    lock (ipHandleMap)
+                    {
+                        Dictionary<string, int>.Enumerator ipEnumer = ipHandleMap.GetEnumerator();
+                        while (ipEnumer.MoveNext())
+                        {
+                            //映射关系不存在则读取配置文件
+                            lock (ipIdMap)
+                            {
+                                if (ipEnumer.Current.Key != null && !ipIdMap.ContainsKey(ipEnumer.Current.Key))
+                                {
+                                    try
+                                    {
+                                        int id = Int32.Parse(ConfigurationManager.AppSettings.Get(ipEnumer.Current.Key));
+                                        ipIdMap.Add(ipEnumer.Current.Key, id);
+                                    }
+                                    catch (Exception) { Console.WriteLine("读取号牌机编号映射失败,配置文件填写有误"); }
+                                }
+                            }
+                        }
+                    }
+                    lock (LicBuffer)
+                    {
+                        //删除已停好车的号牌
+                        for (int i = 0; i < LicBuffer.Count; i++)
+                        {
+                            NumberMachineNode n = (NumberMachineNode)LicBuffer.Dequeue().Clone();
+                            if (n.ip != "")
+                            {
+                                LicBuffer.Enqueue((NumberMachineNode)n.Clone());
+                            }
+                        }
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                Debug.WriteLine(ex.ToString());
+            }
+        }
+
+        ///<summary>寻找设备回调函数</summary>
+        private void FIND_DEVICE_CALLBACK_EX(string pStrDevName, string pStrIPAddr, ushort usPort1, ushort usPort2, uint SL, uint SH, string netmask, string gateway, IntPtr pUserData)
+        {
+            string pStrDev = pStrIPAddr.ToString() + ":" + usPort1.ToString();
+            string serialNO = SL.ToString() + ":" + SH.ToString() + ":" + netmask + ":" + gateway;
+
+            VzClientSDK.VZ_LPR_DEVICE_INFO device_info = new VzClientSDK.VZ_LPR_DEVICE_INFO();
+            device_info.device_ip = pStrDev;
+            device_info.serial_no = serialNO;
+            DeviceLink(pStrDev, serialNO);
+        }
+
+        ///<summary>与设备连接,启动更新设备状态线程,输出视频</summary>
+        private void DeviceLink(string pStrDev, string serialNO)
+        {
+            IPEndPoint ipe;
+            GetIpEndPoint(pStrDev, out ipe);
+            string ip = ipe.Address.ToString();
+            if (ipHandleMap.ContainsKey(ip))
+            {
+                //MessageBox.Show("设备已分配句柄");
+                return;
+            }
+            int handle = 0;
+            //找到设备,加入list
+            NumberMachineNode node = new NumberMachineNode(ip, 0, "", "", 1);
+            nmMsg.data.Add(node);
+            handle = VzClientSDK.VzLPRClient_Open(ip, (ushort)80, "admin", "admin");
+            Task.Factory.StartNew(() =>
+            {
+                UpdateStatus(node);
+            });
+            if (handle == 0)
+            {
+                return;
+            }
+
+            VzClientSDK.VzLPRClient_SetVideoEncodeType(handle, 0);
+            //将句柄加入
+            lock (ipHandleMap)
+            {
+                ipHandleMap.Add(ip, handle);
+            }
+            //MessageBox.Show("摄像头打开成功");
+            lock (handleCallbackMap)
+            {
+                handleCallbackMap.Add(handle, null);
+            }
+            //链接句柄到新PictureBox
+            VideoOutput(handle);
+        }
+
+        ///<summary>视频输出</summary>
+        private void VideoOutput(int handle)
+        {
+            try
+            {
+                lock (devPicMap)
+                {
+                    lock (handleCallbackMap)
+                    {
+                        ////存在设备则复位并在原pic上输出
+                        //if (devPicMap.ContainsKey(handle))
+                        //{
+                        //    VzClientSDK.VzLPRClient_SetPlateInfoCallBack(handle, null, IntPtr.Zero, 0);
+                        //    IntPtr pic;
+                        //    if (devPicMap.TryGetValue(handle, out pic) && handleCallbackMap.ContainsKey(handle))
+                        //    {
+                        //        int playHandle = VzClientSDK.VzLPRClient_StartRealPlay(handle, pic);
+                        //        // 设置车牌识别结果回调
+                        //        handleCallbackMap[handle] = new VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK(OnPlateResult);
+                        //        VzClientSDK.VzLPRClient_SetPlateInfoCallBack(handle, handleCallbackMap[handle], IntPtr.Zero, 1);
+                        //        //m_PlateResultCB = new VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK(OnPlateResult);
+                        //        //VzClientSDK.VzLPRClient_SetPlateInfoCallBack(handle, m_PlateResultCB, IntPtr.Zero, 1);
+                        //        //VzClientSDK.VzLPRClient_StopRealPlay(handle);
+                        //    }
+                        //}
+                        //else//否则找一个空位加pic
+                        {
+                            for (int i = 0; i < 20; i++)
+                            {
+                                string str = "PictureBox" + Convert.ToString(i);
+                                //该名称对应控件不存在,则创建并链接pic
+                                lock (namePicMap)
+                                {
+                                    if (!namePicMap.ContainsKey(str) && handleCallbackMap.ContainsKey(handle))
+                                    {
+                                        IntPtr pic;
+                                        if (CreatePic(i, out pic))
+                                        {
+                                            devPicMap.Add(handle, pic);
+                                            //ipIdMap.Add(Get_IP(handle), i);
+                                            VzClientSDK.VzLPRClient_SetPlateInfoCallBack(handle, null, IntPtr.Zero, 0);
+                                            Console.WriteLine(handle+","+pic.ToString());
+                                            int playHandle = VzClientSDK.VzLPRClient_StartRealPlay(handle, pic);
+                                            // 设置车牌识别结果回调
+                                            handleCallbackMap[handle] = new VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK(OnPlateResult);
+                                            VzClientSDK.VzLPRClient_SetPlateInfoCallBack(handle, handleCallbackMap[handle], IntPtr.Zero, 1);
+                                            //m_PlateResultCB = new VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK(OnPlateResult);
+                                            //VzClientSDK.VzLPRClient_SetPlateInfoCallBack(handle, m_PlateResultCB, IntPtr.Zero, 1);
+                                            //VzClientSDK.VzLPRClient_StopRealPlay(handle);
+                                            break;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            catch (Exception e)
+            {
+                Debug.WriteLine(e.Message+",jumped out");
+            }
+        }
+
+        ///<summary>号牌信息回调</summary>
+        private int OnPlateResult(int handle, IntPtr pUserData,
+                                                IntPtr pResult, uint uNumPlates,
+                                                VzClientSDK.VZ_LPRC_RESULT_TYPE eResultType,
+                                                IntPtr pImgFull,
+                                                IntPtr pImgPlateClip)
+        {
+            if (eResultType != VzClientSDK.VZ_LPRC_RESULT_TYPE.VZ_LPRC_RESULT_REALTIME)
+            {
+                VzClientSDK.TH_PlateResult result = (VzClientSDK.TH_PlateResult)Marshal.PtrToStructure(pResult, typeof(VzClientSDK.TH_PlateResult));
+                string strLicense = (new string(result.license)).Split('\0')[0];
+
+                VzClientSDK.VZ_LPR_MSG_PLATE_INFO plateInfo = new VzClientSDK.VZ_LPR_MSG_PLATE_INFO();
+                plateInfo.plate = strLicense;
+                SetDetail(plateInfo, Get_IP(handle));
+
+                //根据setMessage中通过id信息找到的handle保存图片
+                if (handle == snapshotDevHandle)
+                {
+                    if (enableEmptySnapshot || !strLicense.Contains("_无_"))
+                    {
+                        string strFilePath = ConfigurationManager.AppSettings["LogPath"] + DateTime.Now.ToString("yyyyMMdd") + "\\";
+                        if (!Directory.Exists(strFilePath))
+                        {
+                            Directory.CreateDirectory(strFilePath);
+                        }
+                        string ip = Get_IP(handle);
+                        string path = strFilePath + ip + "-" + DateTime.Now.ToString("hh_mm_ss") + ".jpg";
+                        int temp = VzClientSDK.VzLPRClient_ImageSaveToJpeg(pImgFull, path, 50);
+                        if (temp != -1)
+                        {
+                            Console.WriteLine("号牌机" + ip + "已拍照,图片保存于 " + strFilePath);
+                        }
+                        else
+                        {
+                            Console.WriteLine("图片保存失败");
+                        }
+                    }
+                    snapshotDevHandle = -1;
+                }
+            }
+
+            return 0;
+        }
+
+        ///<summary>记录车牌,时间,状态信息;刷新本地entity,并且入buffer</summary>
+        private void SetDetail(VzClientSDK.VZ_LPR_MSG_PLATE_INFO plateInformation, string strIP)
+        {
+            int stat = GetStatus(strIP);
+            bool found = false;
+            int id = 0;
+            lock (ipIdMap)
+            {
+                if (!ipIdMap.ContainsKey(strIP))
+                {
+                    try
+                    {
+                        id = Int32.Parse(ConfigurationManager.AppSettings.Get(strIP));
+                        ipIdMap.Add(strIP, id);
+                    }
+                    catch (Exception) { Console.WriteLine("读取号牌机编号映射失败,配置文件填写有误"); }
+                }
+            }
+            //检查设备是否存在
+            foreach (NumberMachineNode nmn in nmMsg.data)
+            {
+                //相同设备
+                if (nmn.ip == strIP)
+                {
+                    found = true;
+                    //号牌不为空
+                    if (!(plateInformation.plate.Contains("_无_")))
+                    {
+                        nmn.SetLic(strIP, nmn.id, plateInformation.plate, DateTime.Now.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss"), GetStatus(strIP));
+                        FilterLic(strIP, (NumberMachineNode)nmn.Clone());
+                    }
+                    //号牌为空
+                    else
+                    {
+                        nmn.SetLic(strIP, nmn.id, "", "", GetStatus(strIP));
+                    }
+                }
+            }
+            //新设备
+            if (!found)
+            {
+                lock (ipIdMap)
+                {
+                    if (!(plateInformation.plate.Contains("_无_")) && ipIdMap.TryGetValue(strIP, out id))
+                    {
+                        NumberMachineNode nmn = new NumberMachineNode(strIP, id, plateInformation.plate, DateTime.Now.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss"), GetStatus(strIP));
+                        NumberMachineNode nmnc = (NumberMachineNode)nmn.Clone();
+                        nmMsg.data.Add(nmnc);
+                        FilterLic(strIP, nmnc);
+                    }
+                    else
+                    {
+                        nmMsg.data.Add(new NumberMachineNode(strIP, id, "", "", GetStatus(strIP)));
+                    }
+                }
+            }
+        }
+
+        ///<summary>筛选号牌</summary>
+        private void FilterLic(string ip, NumberMachineNode nmn)
+        {
+            Dictionary<NumberMachineNode, int> filter;
+            //该filter不存在则创建
+            if (!filterMap.ContainsKey(ip))
+            {
+                filter = new Dictionary<NumberMachineNode, int>();
+                filterMap.Add(ip, filter);
+            }
+            //计数器异常
+            else if (!filterMap.TryGetValue(ip, out filter))
+            {
+                return;
+            }
+
+            //filter计数
+            int count = 0;
+            if (filter.ContainsKey(nmn) && filter.TryGetValue(nmn, out count))//存在则数量+1
+            {
+                filter[nmn] = count + 1;
+            }
+            else//不存在则计数1
+            {
+                filter.Add(nmn, 1);
+            }
+
+            //计算总数
+            filterCount = 0;
+            Dictionary<NumberMachineNode, int>.Enumerator countEnumer = filter.GetEnumerator();
+            while (countEnumer.MoveNext())
+            {
+                filterCount += countEnumer.Current.Value;
+            }
+
+            //达到计数限制,计算众数是否达标,达标则入队
+            if (filterCount >= FILTERINGNUMBER)
+            {
+                lock (LicBuffer)
+                {
+                    Dictionary<NumberMachineNode, int>.Enumerator enumer = filter.GetEnumerator();
+                    while (enumer.MoveNext())
+                    {
+                        //遍历,筛到号牌则入队
+                        if (enumer.Current.Value >= (int)(filterCount * filterRatio) && enumer.Current.Key != null && !LicBuffer.Contains(enumer.Current.Key))
+                        {
+                            if (nmMsg.aNode == null || nmMsg.aNode.LicenseNum == null || nmMsg.aNode.LicenseNum != enumer.Current.Key.LicenseNum)
+                            {
+                                NumberMachineNode node = (NumberMachineNode)enumer.Current.Key.Clone();
+                                if (ipIdMap.TryGetValue(node.ip, out node.id))
+                                {
+                                    LicBuffer.Enqueue((NumberMachineNode)node.Clone());
+                                    if (node.id == 1)
+                                    {
+                                        Task.Factory.StartNew(() => {
+                                            if (BroadcastLinker.ins != null)
+                                            {
+                                                BroadcastLinker.ins.DispString(1, node.LicenseNum, 6);
+                                                BroadcastLinker.ins.AudioPlay(node.LicenseNum + ",入场");
+                                                Thread.Sleep(5000);
+                                                BroadcastLinker.ins.DispDownStr(1, 0);
+                                            }
+                                        });
+                                    }
+                                }
+                            }
+                        }
+                    };
+                    filterCount = 0;
+                    filter.Clear();
+                }
+            }
+        }
+
+        ///<summary>停止播放与设备句柄关联的视频</summary>
+        private void StopPlay(int handleInput)
+        {
+            if (handleInput != 0)
+            {
+                int ret = VzClientSDK.VzLPRClient_StopRealPlay(handleInput);
+            }
+        }
+
+        ///<summary>强制获取号牌</summary>
+        private void ActivateSnap(int handle)
+        {
+            if (handle > 0)
+            {
+                VzClientSDK.VzLPRClient_ForceTrigger(handle);
+            }
+
+        }
+
+        ///<summary>ip+port字符串转ipe</summary>
+        private void GetIpEndPoint(string ipp, out IPEndPoint ipe)
+        {
+            IPAddress myIP = IPAddress.Parse(ipp.Remove(ipp.LastIndexOf(':')) + "");
+            string myPort = ipp.Substring(ipp.IndexOf(':') + 1);
+            ipe = new IPEndPoint(myIP, int.Parse(myPort));
+        }
+
+        ///<summary>创建新pic并记录在picNameMap</summary>
+        private bool CreatePic(int index, out IntPtr pic)
+        {
+            pic = IntPtr.Zero;
+            PictureBox pb = new PictureBox
+            {
+                Width = 500,
+                Height = 400,
+                Bounds = new System.Drawing.Rectangle(0, 0, 500, 400),
+                Name = "PictureBox" + Convert.ToString(index)
+            };
+            lock (namePicMap)
+            {
+                if (!namePicMap.ContainsKey(pb.Name))
+                {
+                    PictureBox temp = pb;
+                    IntPtr picHandle = IntPtr.Zero;
+                    try
+                    {
+                        Control flp = Control.FromHandle(flowLayoutPanel1);
+                        
+                        //Control.FromHandle(flowLayoutPanel1).Controls.Add(temp);
+                        if (flp.InvokeRequired)
+                        {
+                            flp.Invoke(new Action(() => { flp.Controls.Add(temp); picHandle = temp.Handle; }));
+                        }
+                        else
+                        {
+                            flp.Controls.Add(pb);
+                        }
+                    }
+                    catch (Exception e) { Console.WriteLine(e.Message); }
+                    namePicMap.Add(pb.Name, picHandle);
+                    pic = picHandle;
+                    Console.WriteLine(picHandle.ToString());
+                    return true;
+                }
+                else
+                    return false;
+            }
+        }
+
+        ///<summary>更新设备状态</summary>
+        private int GetStatus(string devIP)
+        {
+            int myHandle;
+            byte stat = 0;
+            if (ipHandleMap.TryGetValue(devIP, out myHandle))
+            {
+                VzClientSDK.VzLPRClient_IsConnected(myHandle, ref stat);
+                return stat;
+            }
+            return -1;
+        }
+
+        private string Get_IP(int lprHandle)
+        {
+            byte[] strDecIP = new byte[32];
+            int max_count = 32;
+            int ret = VzClientSDK.VzLPRClient_GetDeviceIP(lprHandle, ref strDecIP[0], max_count);
+            string strIP = System.Text.Encoding.Default.GetString(strDecIP);
+            strIP = strIP.TrimEnd('\0');
+            return strIP;
+        }
+
+        private bool NodeValidation(NumberMachineNode node)
+        {
+            return (node != null && node.ip != null && node.ip != "" && node.ip != "used" && node.LicenseNum != null && node.LicenseNum != "") ? true : false;
+        }
+
+        /// <summary>
+        /// 系统启动
+        /// </summary>
+        public void Start()
+        {
+
+            Task.Factory.StartNew(() =>
+            {
+                isClosing = false;
+
+                try
+                {
+                    VzClientSDK.VZLPRClient_StopFindDevice();
+
+                    find_DeviceCB = new VzClientSDK.VZLPRC_FIND_DEVICE_CALLBACK_EX(FIND_DEVICE_CALLBACK_EX);
+                    int ret = VzClientSDK.VZLPRClient_StartFindDeviceEx(find_DeviceCB, IntPtr.Zero);
+                }
+                catch (Exception ex)
+                {
+                    Debug.WriteLine(ex.ToString());
+                }
+            });
+
+            Task.Factory.StartNew(() =>
+            {
+                Run();
+            });
+            //Task imgTest = Task.Factory.StartNew(() =>
+            //{
+            //    while (!isClosing)
+            //    {
+            //        Command cmd = new Command
+            //        {
+            //            id = 1
+            //        };
+            //        SetMessage(cmd);
+            //        Thread.Sleep(30000);
+            //        Command cmd2 = new Command
+            //        {
+            //            id = 2
+            //        };
+            //        SetMessage(cmd2);
+            //        Thread.Sleep(30000);
+            //    }
+            //});
+
+        }
+
+        /// <summary>
+        /// 系统关闭
+        /// </summary>
+        public void Stop()
+        {
+            VzClientSDK.VZLPRClient_StopFindDevice();
+            lock (devPicMap)
+            {
+                Dictionary<int, IntPtr>.Enumerator enumer = devPicMap.GetEnumerator();
+                while (enumer.MoveNext())
+                {
+                    if (enumer.Current.Key != 0)
+                    {
+                        StopPlay(enumer.Current.Key);
+                        VzClientSDK.VzLPRClient_Close(enumer.Current.Key);
+                        //flowLayoutPanel1.Controls.Remove(enumer.Current.Value);
+                    }
+                }
+                isClosing = true;
+                devPicMap.Clear();
+            }
+            lock (namePicMap) { namePicMap.Clear(); }
+            lock (ipIdMap) { ipIdMap.Clear(); }
+            lock (ipHandleMap) { ipHandleMap.Clear(); }
+            //this.Close();
+        }
+
+        /// <summary>
+        /// 监控线程获取号牌机信息,核心线程获取号牌信息
+        /// </summary>
+        public AbstractMessage GetMessage()
+        {
+            lock (LicBuffer)
+            {
+                //准备输出的数据中存在非法Node,且LicBuffer可出队产生一个合法Node,则替换该非法Node
+                if (!NodeValidation(nmMsg.aNode))
+                {
+                    for (int i = 0; i < LicBuffer.Count; i++)
+                    {
+                        NumberMachineNode n = LicBuffer.Dequeue();
+                        if (NodeValidation(n))
+                        {
+                            if (nmMsg.aNode != null && nmMsg.aNode.ip != null)
+                            {
+                                LicBuffer.Enqueue((NumberMachineNode)nmMsg.aNode.Clone());
+                            }
+                            nmMsg.aNode = n;
+                            break;
+                        }
+                        else
+                        {
+                            LicBuffer.Enqueue(n);
+                        }
+                    }
+                    //遍历licBuffer后仍不合法,则丢入队列,将node置为null
+                    if (!NodeValidation(nmMsg.aNode))
+                    {
+                        if (nmMsg.aNode != null && nmMsg.aNode.ip != null)
+                        {
+                            LicBuffer.Enqueue((NumberMachineNode)nmMsg.aNode.Clone());
+                        }
+                        nmMsg.aNode = null;
+                    }
+                }
+            }
+            return nmMsg;
+        }
+
+        /// <summary>
+        /// 一次停车流程完成时调用该方法,发送已完成车辆号牌信息
+        /// </summary>
+        /// <param name="message">已完成车辆的号牌相关信息存于message的aNode中,用于标记需清空的号牌</param>
+        public void SetMessage(AbstractMessage message)
+        {
+            if (message.GetType().Equals(typeof(NumberMachineMessage)))
+            {
+                NumberMachineNode n = ((NumberMachineMessage)message).aNode;
+                lock (LicBuffer)
+                {
+                    //输入号牌格式无误
+                    if (n != null && n.ip != null && n.ip == "")
+                    {
+                        //与类成员变量中aNode号牌相同,将其ip复位表示已使用,重新入队等待清除
+                        if (nmMsg != null && nmMsg.aNode != null && nmMsg.aNode.LicenseNum == n.LicenseNum)
+                        {
+                            nmMsg.aNode.ip = "";
+                            LicBuffer.Enqueue((NumberMachineNode)nmMsg.aNode.Clone());
+                            nmMsg.aNode = null;
+                        }
+                        //搜索号牌队列,将相应号牌置空,准备清除
+                        else
+                        {
+                            for (int i = 0; i < LicBuffer.Count; i++)
+                            {
+                                NumberMachineNode temp = LicBuffer.Dequeue();
+                                //已匹配上,ip置空
+                                if (temp.LicenseNum == n.LicenseNum)
+                                {
+                                    temp.ip = "";
+                                    LicBuffer.Enqueue(temp);
+                                    break;
+                                }
+                                LicBuffer.Enqueue(temp);
+                            }
+                        }
+                    }
+                }
+            }
+            //传入异常号牌,根据ip找到handle,改变snapshotDevHandle的值在回调函数中截图
+            if (message.GetType().Equals(typeof(Command)))
+            {
+                Command cmd = (Command)message;
+                if (cmd != null && cmd.id != 0)
+                {
+                    lock (ipIdMap)
+                    {
+                        Dictionary<string, int>.Enumerator enumerator = ipIdMap.GetEnumerator();
+                        while (enumerator.MoveNext())
+                        {
+                            // if (enumerator.Current.Value == cmd.id && ipHandleMap.TryGetValue(enumerator.Current.Key, out int handle))
+                            int handle = 0;
+                            if (enumerator.Current.Value == cmd.id && ipHandleMap.TryGetValue(enumerator.Current.Key, out handle))
+                            {
+                                snapshotDevHandle = handle;
+                                break;
+                            }
+                        }
+                    }
+                }
+                else
+                {
+                    Console.WriteLine("参数错误,图片未保存");
+                }
+            }
+        }
+
+        public void GetLicensePlate()
+        {
+            throw new NotImplementedException();
+        }
+
+        public void GetImage()
+        {
+            throw new NotImplementedException();
+        }
+    }
+
+}

+ 112 - 0
NumMachineTest/NumMachineTest/NumMachineTest.csproj

@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{AD38F4AE-F726-4118-9F14-8BD651A4B1DE}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <RootNamespace>NumMachineTest</RootNamespace>
+    <AssemblyName>NumMachineTest</AssemblyName>
+    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <WarningLevel>4</WarningLevel>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="broadcastDLL">
+      <HintPath>sdk\broadcastDLL.dll</HintPath>
+    </Reference>
+    <Reference Include="HslCommunication">
+      <HintPath>sdk\HslCommunication.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Configuration" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xaml">
+      <RequiredTargetFramework>4.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="WindowsBase" />
+    <Reference Include="PresentationCore" />
+    <Reference Include="PresentationFramework" />
+    <Reference Include="WindowsFormsIntegration" />
+  </ItemGroup>
+  <ItemGroup>
+    <ApplicationDefinition Include="App.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </ApplicationDefinition>
+    <Compile Include="broadcastModule\broadcastModule.cs" />
+    <Compile Include="entity\AbstractMessage.cs" />
+    <Compile Include="INumMachineLinker.cs" />
+    <Compile Include="NumMachine.cs" />
+    <Compile Include="VzClientSDK.cs" />
+    <Page Include="MainWindow.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Compile Include="App.xaml.cs">
+      <DependentUpon>App.xaml</DependentUpon>
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="MainWindow.xaml.cs">
+      <DependentUpon>MainWindow.xaml</DependentUpon>
+      <SubType>Code</SubType>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>

+ 55 - 0
NumMachineTest/NumMachineTest/Properties/AssemblyInfo.cs

@@ -0,0 +1,55 @@
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("NumMachineTest")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("NumMachineTest")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+//若要开始生成可本地化的应用程序,请设置
+//.csproj 文件中的 <UICulture>CultureYouAreCodingWith</UICulture>
+//例如,如果您在源文件中使用的是美国英语,
+//使用的是美国英语,请将 <UICulture> 设置为 en-US。  然后取消
+//对以下 NeutralResourceLanguage 特性的注释。  更新
+//以下行中的“en-US”以匹配项目文件中的 UICulture 设置。
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly: ThemeInfo(
+    ResourceDictionaryLocation.None, //主题特定资源词典所处位置
+                                     //(未在页面中找到资源时使用,
+                                     //或应用程序资源字典中找到时使用)
+    ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置
+                                              //(未在页面中找到资源时使用,
+                                              //、应用程序或任何主题专用资源字典中找到时使用)
+)]
+
+
+// 程序集的版本信息由下列四个值组成: 
+//
+//      主版本
+//      次版本
+//      生成号
+//      修订号
+//
+// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
+// 方法是按如下所示使用“*”: :
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 71 - 0
NumMachineTest/NumMachineTest/Properties/Resources.Designer.cs

@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     此代码由工具生成。
+//     运行时版本: 4.0.30319.42000
+//
+//     对此文件的更改可能导致不正确的行为,如果
+//     重新生成代码,则所做更改将丢失。
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace NumMachineTest.Properties
+{
+
+
+    /// <summary>
+    ///   强类型资源类,用于查找本地化字符串等。
+    /// </summary>
+    // 此类是由 StronglyTypedResourceBuilder
+    // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
+    // 若要添加或删除成员,请编辑 .ResX 文件,然后重新运行 ResGen
+    // (以 /str 作为命令选项),或重新生成 VS 项目。
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources
+    {
+
+        private static global::System.Resources.ResourceManager resourceMan;
+
+        private static global::System.Globalization.CultureInfo resourceCulture;
+
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources()
+        {
+        }
+
+        /// <summary>
+        ///   返回此类使用的缓存 ResourceManager 实例。
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager
+        {
+            get
+            {
+                if ((resourceMan == null))
+                {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NumMachineTest.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+
+        /// <summary>
+        ///   覆盖当前线程的 CurrentUICulture 属性
+        ///   使用此强类型的资源类的资源查找。
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture
+        {
+            get
+            {
+                return resourceCulture;
+            }
+            set
+            {
+                resourceCulture = value;
+            }
+        }
+    }
+}

+ 4 - 7
PLCLinker/parkMonitor/view/FormModbus/VideoCfg_Form.resx

@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <root>
   <!-- 
     Microsoft ResX Schema 
@@ -46,7 +46,7 @@
     
     mimetype: application/x-microsoft.net.object.binary.base64
     value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : System.Serialization.Formatters.Binary.BinaryFormatter
             : and then encoded with base64 encoding.
     
     mimetype: application/x-microsoft.net.object.soap.base64
@@ -60,7 +60,6 @@
             : and then encoded with base64 encoding.
     -->
   <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
     <xsd:element name="root" msdata:IsDataSet="true">
       <xsd:complexType>
         <xsd:choice maxOccurs="unbounded">
@@ -69,10 +68,9 @@
               <xsd:sequence>
                 <xsd:element name="value" type="xsd:string" minOccurs="0" />
               </xsd:sequence>
-              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
               <xsd:attribute name="type" type="xsd:string" />
               <xsd:attribute name="mimetype" type="xsd:string" />
-              <xsd:attribute ref="xml:space" />
             </xsd:complexType>
           </xsd:element>
           <xsd:element name="assembly">
@@ -87,10 +85,9 @@
                 <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                 <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
               </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
               <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
               <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-              <xsd:attribute ref="xml:space" />
             </xsd:complexType>
           </xsd:element>
           <xsd:element name="resheader">

+ 30 - 0
NumMachineTest/NumMachineTest/Properties/Settings.Designer.cs

@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace NumMachineTest.Properties
+{
+
+
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+    {
+
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+        public static Settings Default
+        {
+            get
+            {
+                return defaultInstance;
+            }
+        }
+    }
+}

PLCLinker/parkMonitor/Properties/Settings.settings → NumMachineTest/NumMachineTest/Properties/Settings.settings


PLCLinker/parkMonitor/server/NumMachine/VzClientSDK.cs → NumMachineTest/NumMachineTest/VzClientSDK.cs


+ 71 - 0
NumMachineTest/NumMachineTest/broadcastModule/broadcastModule.cs

@@ -0,0 +1,71 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using BroadcastModule;
+
+namespace parkMonitor.server.broadcastModule
+{
+    public class BroadcastLinker
+    {
+        public static BroadcastBoard ins;
+        static string ip;
+        static int port;
+
+        /// <summary>
+        /// 初始化单例
+        /// </summary>
+        public static void Start()
+        {
+            Task.Factory.StartNew(() =>
+            {
+                try
+                {
+                    ip = ConfigurationManager.AppSettings["broadcastIP"];
+                    port = Int32.Parse(ConfigurationManager.AppSettings["broadcastPort"]);
+                    ins = new BroadcastBoard(ip, port);
+                    ins.Refresh();
+                    ins.AudioPlay("欢迎光临");
+                    ins.DownloadString(0, "欢迎光临", 0);
+                    ins.DownloadString(1, "智象停车", 0);
+                    ins.DownloadString(2, "date", 0);
+                    ins.DownloadString(3, "time", 0);
+                    ins.DispDownStr(0, 0);
+                    ins.DispDownStr(1, 0);
+                    ins.DispDownStr(2, 0);
+                    ins.DispDownStr(3, 0);
+                }
+                catch (Exception e) { Console.WriteLine(e.Message); ins = null; }
+            });
+        }
+
+        public static void dispForAWhile(int winID, string str, int delay, bool switchToOrigin)
+        {
+            if (ins != null)
+            {
+                ins.DispString(winID, str, 10);
+                Task.Factory.StartNew(() =>
+                {
+                    if (switchToOrigin)
+                    {
+                        Thread.Sleep(delay * 1000);
+                        OriginState();
+                    }
+                });
+            }
+        }
+        public static void OriginState()
+        {
+            if (ins != null)
+            {
+                ins.DispDownStr(0, 0);
+                ins.DispDownStr(1, 0);
+                ins.DispDownStr(2, 0);
+                ins.DispDownStr(3, 0);
+            }
+        }
+    }
+}

PLCLinker/parkMonitor/entity/AbstractMessage.cs → NumMachineTest/NumMachineTest/entity/AbstractMessage.cs


PLCLinker/parkMonitor/bin/Debug/HslCommunication.dll → NumMachineTest/NumMachineTest/sdk/HslCommunication.dll


PLCLinker/parkMonitor/bin/Debug/Newtonsoft.Json.dll → NumMachineTest/NumMachineTest/sdk/Newtonsoft.Json.dll


PLCLinker/parkMonitor/bin/Debug/VZ_Sdk.dll → NumMachineTest/NumMachineTest/sdk/VZ_Sdk.dll


PLCLinker/parkMonitor/bin/Debug/VzDrawsLib.dll → NumMachineTest/NumMachineTest/sdk/VzDrawsLib.dll


PLCLinker/parkMonitor/bin/Debug/VzLPRSDK.dll → NumMachineTest/NumMachineTest/sdk/VzLPRSDK.dll


BIN=BIN
NumMachineTest/NumMachineTest/sdk/broadcastDLL.dll


PLCLinker/parkMonitor/bin/Debug/iDecoders.dll → NumMachineTest/NumMachineTest/sdk/iDecoders.dll


BIN=BIN
PLCLinker/.vs/PLCLinker/v15/.suo


BIN=BIN
PLCLinker/.vs/PLCLinker/v15/Server/sqlite3/storage.ide


+ 849 - 0
PLCLinker/NumMachineModel.cs

@@ -0,0 +1,849 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Windows.Forms;
+using HslCommunication;
+using HslCommunication.ModBus;
+using System.Threading;
+using System.Collections;
+using HslCommunication.Controls;
+using VzClientSDKDemo;
+using System.Runtime.InteropServices;
+using System.IO;
+using System.Net;
+using parkMonitor.entity;
+using System.Diagnostics;
+using System.Threading.Tasks;
+using parkMonitor.model;
+using parkMonitor.viewModel.objectTree;
+using parkMonitor.server.uiLogServer;
+using System.Configuration;
+using parkMonitor.LOG;
+using parkMonitor.Database2;
+
+namespace parkMonitor.server
+{
+
+    /// <summary>
+    /// 号牌机通信类
+    /// </summary>
+    public partial class NumMachineLinker : Form, IEquipments
+    {
+        /// <summary>
+        /// 刷新时间间隔与个数
+        /// </summary>
+        public const int REFRESHINGTIME = 200, FILTERINGNUMBER = 20;
+        ///<summary>通过设备句柄访问pic;链接时add,系统关闭时remove</summary>
+        private static Dictionary<int, PictureBox> devPicMap = new Dictionary<int, PictureBox>();
+        ///<summary>通过名字获取pic对象;创建pic时add,系统关闭remove</summary>
+        private static Dictionary<string, PictureBox> namePicMap = new Dictionary<string, PictureBox>();
+        ///<summary>通过ip获取设备id;产生ip时创建</summary>
+        private static Dictionary<string, int> ipIdMap = new Dictionary<string, int>();
+        ///<summary>通过ip获取设备句柄;产生句柄时创建</summary>
+        private static Dictionary<string, int> ipHandleMap = new Dictionary<string, int>();
+        /// <summary>句柄到号牌回调映射</summary>
+        private static Dictionary<int, VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK> handleCallbackMap = new Dictionary<int, VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK>();
+        ///<summary>号牌队列</summary>
+        private static Queue<NumberMachineNode> LicBuffer = new Queue<NumberMachineNode>();
+        ///<summary>计数Map</summary>
+        private static Dictionary<string, Dictionary<NumberMachineNode, int>> filterMap = new Dictionary<string, Dictionary<NumberMachineNode, int>>();
+        /// <summary>号牌机编号与激活计数</summary>
+        private Dictionary<int, int> idCountMap = new Dictionary<int, int>();
+        /// <summary>筛选计数</summary>
+        private static int filterCount = 0;
+        private static double filterRatio = 0.7;
+        /// <summary>系统关闭</summary>
+        private static bool isClosing = false;
+        /// <summary>开启拍照的设备</summary>
+        private static int snapshotDevHandle = -1;
+        /// <summary>允许无号牌时拍照</summary>
+        private static bool enableEmptySnapshot = true;
+
+        private static NumberMachineMessage nmMsg = new NumberMachineMessage();
+        private static VzClientSDK.VZLPRC_FIND_DEVICE_CALLBACK_EX find_DeviceCB = null;
+        private const int MSG_PLATE_INFO = 0x901;
+        private const int MSG_DEVICE_INFO = 0x902;
+        /// <summary>
+        /// 用于消息传递机制
+        /// </summary>
+        public static IntPtr hwndMain;
+
+        /// <summary>
+        /// 号牌机类构造函数
+        /// </summary>
+        public NumMachineLinker()
+        {
+            Control.CheckForIllegalCrossThreadCalls = false;
+            InitializeComponent();
+
+            Thread thread = new Thread(new ThreadStart(DateTimeInfo));
+            thread.IsBackground = true;
+            thread.Start(); //显示当前时间            
+
+            VzClientSDK.VzLPRClient_Setup();
+
+            hwndMain = this.Handle;
+
+            try
+            {
+                filterRatio = Double.Parse(ConfigurationManager.AppSettings.Get("filterRatio"));
+            }
+            catch (Exception) { UILogServer.ins.error("号牌机配置文件异常"); Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "号牌机配置文件异常"); }
+            //m_sAppPath = System.IO.Directory.GetCurrentDirectory();
+        }
+
+        /// <summary>
+        /// 定义时钟委托
+        /// </summary>
+        public delegate void SetDateTime();
+
+        /// <summary>
+        /// 实时采集
+        /// </summary>
+        public delegate void Begin_Read();
+
+        private void FormSiemens_Load(object sender, EventArgs e)
+        {
+            Thread thread = new Thread(new ThreadStart(DateTimeInfo));
+            thread.IsBackground = true;
+            thread.Start(); //显示当前时间            
+
+            VzClientSDK.VzLPRClient_Setup();
+
+            hwndMain = this.Handle;
+            //m_sAppPath = System.IO.Directory.GetCurrentDirectory();
+            //this.ShowInTaskbar = false;
+            //this.Opacity = 0;
+
+        }
+
+        private void FormSiemens_FormClosing(object sender, FormClosingEventArgs e)
+        {
+            Stop();
+        }
+
+        private void DateTimeInfo()
+        {
+            try
+            {
+                while (!isClosing)
+                {
+                    SetDateTime setDate = new SetDateTime(
+                    delegate
+                    {
+                        toolStripStatusLabel2.Text = DateTime.Now.ToString();
+                    });
+                    setDate();
+                    Thread.Sleep(1000);
+                }
+                // ReSharper disable once FunctionNeverReturns
+            }
+            catch (Exception e) { Debug.Print(e.StackTrace); }
+
+        }
+
+        //******************************************************************************************************************
+        private void UpdateStatus(NumberMachineNode nmn)
+        {
+            //提示次数计数
+            int count = 0;
+            while (!isClosing)
+            {
+                if (GetStatus(nmn.ip) == 1)
+                {
+                    nmn.status = EnumNumberMachineStatus.Normal;
+                    count = 0;
+                }
+                else
+                {
+                    count++;
+                    //号牌机断线写日志
+                    nmn.status = EnumNumberMachineStatus.Offline;
+                    if (count == 1)
+                    {
+                        Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "正在与ip为 " + nmn.ip + " 的号牌机 进行连接。");
+                        UILogServer.ins.info("正在与ip为 " + nmn.ip + " 的号牌机 进行连接。");
+                    }
+                    else if (count == 30)
+                    {
+                        nmMsg.data.Remove(nmn);
+                    }
+                    Thread.Sleep(10000);
+                }
+                Thread.Sleep(REFRESHINGTIME);
+            }
+        }
+
+        private void Run()
+        {
+            try
+            {
+                while (!isClosing)
+                {
+                    Thread.Sleep(REFRESHINGTIME);
+                    //定时更新号牌
+                    lock (devPicMap)
+                    {
+                        Dictionary<int, PictureBox>.Enumerator devEnumer = devPicMap.GetEnumerator();
+                        while (devEnumer.MoveNext())
+                        {
+                            ActivateSnap(devEnumer.Current.Key);
+                            //Debug.WriteLine(lv.data.Count.ToString()+":\n"+ lv.data[lv.data.Count-1].LicenseNum+ lv.data[lv.data.Count - 1].TimeRecord);
+                        }
+                    }
+                    ////根据指令返回号牌
+                    //for (int i = 1; i <= idCountMap.Count; i++)
+                    //{
+                    //    int count = 0;
+                    //    if (idCountMap.TryGetValue(i, out count) && count <= FILTERINGNUMBER)
+                    //    {
+                    //        idCountMap[i] += 1;
+                    //        Dictionary<string, int>.Enumerator ipEnumer = ipIdMap.GetEnumerator();
+                    //        while (ipEnumer.MoveNext())
+                    //        {
+                    //            int handle = 0;
+                    //            if (ipEnumer.Current.Value == i && ipHandleMap.TryGetValue(ipEnumer.Current.Key, out handle))
+                    //            {
+                    //                ActivateSnap(handle);
+                    //            }
+                    //        }
+                    //    }
+                    //}
+
+                    //读取设备ip与id映射关系
+                    lock (ipHandleMap)
+                    {
+                        Dictionary<string, int>.Enumerator ipEnumer = ipHandleMap.GetEnumerator();
+                        while (ipEnumer.MoveNext())
+                        {
+                            //映射关系不存在则读取配置文件
+                            lock (ipIdMap)
+                            {
+                                if (ipEnumer.Current.Key != null && !ipIdMap.ContainsKey(ipEnumer.Current.Key))
+                                {
+                                    try
+                                    {
+                                        int id = Int32.Parse(ConfigurationManager.AppSettings.Get(ipEnumer.Current.Key));
+                                        ipIdMap.Add(ipEnumer.Current.Key, id);
+                                        idCountMap.Add(id, FILTERINGNUMBER);
+                                    }
+                                    catch (Exception) { UILogServer.ins.log("读取号牌机编号映射失败,配置文件填写有误"); Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "读取号牌机编号映射失败"); }
+                                }
+                            }
+                        }
+                    }
+                    lock (LicBuffer)
+                    {
+                        //删除已停好车的号牌
+                        for (int i = 0; i < LicBuffer.Count; i++)
+                        {
+                            NumberMachineNode n = (NumberMachineNode)LicBuffer.Dequeue().Clone();
+                            if (n.ip != "")
+                            {
+                                LicBuffer.Enqueue((NumberMachineNode)n.Clone());
+                            }
+                        }
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                Debug.WriteLine(ex.ToString());
+            }
+        }
+
+        ///<summary>寻找设备回调函数</summary>
+        private void FIND_DEVICE_CALLBACK_EX(string pStrDevName, string pStrIPAddr, ushort usPort1, ushort usPort2, uint SL, uint SH, string netmask, string gateway, IntPtr pUserData)
+        {
+            string pStrDev = pStrIPAddr.ToString() + ":" + usPort1.ToString();
+            string serialNO = SL.ToString() + ":" + SH.ToString() + ":" + netmask + ":" + gateway;
+
+            VzClientSDK.VZ_LPR_DEVICE_INFO device_info = new VzClientSDK.VZ_LPR_DEVICE_INFO();
+            device_info.device_ip = pStrDev;
+            device_info.serial_no = serialNO;
+            DeviceLink(pStrDev, serialNO);
+        }
+
+        ///<summary>与设备连接,启动更新设备状态线程,输出视频</summary>
+        private void DeviceLink(string pStrDev, string serialNO)
+        {
+            IPEndPoint ipe;
+            GetIpEndPoint(pStrDev, out ipe);
+            string ip = ipe.Address.ToString();
+            if (ipHandleMap.ContainsKey(ip))
+            {
+                //MessageBox.Show("设备已分配句柄");
+                return;
+            }
+            int handle = 0;
+            //找到设备,加入list
+            NumberMachineNode node = new NumberMachineNode(ip, 0, "", "", 1);
+            nmMsg.data.Add(node);
+            handle = VzClientSDK.VzLPRClient_Open(ip, (ushort)80, "admin", "admin");
+            Task.Factory.StartNew(() =>
+            {
+                UpdateStatus(node);
+            });
+            if (handle == 0)
+            {
+                return;
+            }
+
+            VzClientSDK.VzLPRClient_SetVideoEncodeType(handle, 0);
+            //将句柄加入
+            lock (ipHandleMap)
+            {
+                ipHandleMap.Add(ip, handle);
+            }
+            //MessageBox.Show("摄像头打开成功");
+            lock (handleCallbackMap)
+            {
+                handleCallbackMap.Add(handle, null);
+            }
+            //链接句柄到新PictureBox
+            VideoOutput(handle);
+        }
+
+        ///<summary>视频输出</summary>
+        private void VideoOutput(int handle)
+        {
+            try
+            {
+                lock (devPicMap)
+                {
+                    lock (handleCallbackMap)
+                    {
+                        //存在设备则复位并在原pic上输出
+                        if (devPicMap.ContainsKey(handle))
+                        {
+                            VzClientSDK.VzLPRClient_SetPlateInfoCallBack(handle, null, IntPtr.Zero, 0);
+                            PictureBox pic;
+                            if (devPicMap.TryGetValue(handle, out pic) && handleCallbackMap.ContainsKey(handle))
+                            {
+                                int playHandle = VzClientSDK.VzLPRClient_StartRealPlay(handle, pic.Handle);
+                                // 设置车牌识别结果回调
+                                handleCallbackMap[handle] = new VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK(OnPlateResult);
+                                VzClientSDK.VzLPRClient_SetPlateInfoCallBack(handle, handleCallbackMap[handle], IntPtr.Zero, 1);
+                                //m_PlateResultCB = new VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK(OnPlateResult);
+                                //VzClientSDK.VzLPRClient_SetPlateInfoCallBack(handle, m_PlateResultCB, IntPtr.Zero, 1);
+                                //VzClientSDK.VzLPRClient_StopRealPlay(handle);
+                            }
+                        }
+                        else//否则找一个空位加pic
+                        {
+                            for (int i = 0; i < 20; i++)
+                            {
+                                string str = "PictureBox" + Convert.ToString(i);
+                                //该名称对应控件不存在,则创建并链接pic
+                                lock (namePicMap)
+                                {
+                                    if (!namePicMap.ContainsKey(str) && handleCallbackMap.ContainsKey(handle))
+                                    {
+                                        PictureBox pic;
+                                        if (CreatePic(i, out pic))
+                                        {
+                                            devPicMap.Add(handle, pic);
+                                            //ipIdMap.Add(Get_IP(handle), i);
+                                            VzClientSDK.VzLPRClient_SetPlateInfoCallBack(handle, null, IntPtr.Zero, 0);
+                                            int playHandle = VzClientSDK.VzLPRClient_StartRealPlay(handle, pic.Handle);
+                                            // 设置车牌识别结果回调
+                                            handleCallbackMap[handle] = new VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK(OnPlateResult);
+                                            VzClientSDK.VzLPRClient_SetPlateInfoCallBack(handle, handleCallbackMap[handle], IntPtr.Zero, 1);
+                                            //m_PlateResultCB = new VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK(OnPlateResult);
+                                            //VzClientSDK.VzLPRClient_SetPlateInfoCallBack(handle, m_PlateResultCB, IntPtr.Zero, 1);
+                                            //VzClientSDK.VzLPRClient_StopRealPlay(handle);
+                                            break;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            catch (Exception)
+            {
+                Debug.WriteLine("jumped out");
+            }
+        }
+
+        ///<summary>号牌信息回调</summary>
+        private int OnPlateResult(int handle, IntPtr pUserData,
+                                                IntPtr pResult, uint uNumPlates,
+                                                VzClientSDK.VZ_LPRC_RESULT_TYPE eResultType,
+                                                IntPtr pImgFull,
+                                                IntPtr pImgPlateClip)
+        {
+            if (eResultType != VzClientSDK.VZ_LPRC_RESULT_TYPE.VZ_LPRC_RESULT_REALTIME)
+            {
+                VzClientSDK.TH_PlateResult result = (VzClientSDK.TH_PlateResult)Marshal.PtrToStructure(pResult, typeof(VzClientSDK.TH_PlateResult));
+                string strLicense = (new string(result.license)).Split('\0')[0];
+
+                VzClientSDK.VZ_LPR_MSG_PLATE_INFO plateInfo = new VzClientSDK.VZ_LPR_MSG_PLATE_INFO();
+                plateInfo.plate = strLicense;
+                SetDetail(plateInfo, Get_IP(handle));
+
+                //根据setMessage中通过id信息找到的handle保存图片
+                if (handle == snapshotDevHandle)
+                {
+                    if (enableEmptySnapshot || !strLicense.Contains("_无_"))
+                    {
+                        string strFilePath = ConfigurationManager.AppSettings["LogPath"] + DateTime.Now.ToString("yyyyMMdd") + "\\";
+                        if (!Directory.Exists(strFilePath))
+                        {
+                            Directory.CreateDirectory(strFilePath);
+                        }
+                        string ip = Get_IP(handle);
+                        string path = strFilePath + ip + "-" + DateTime.Now.ToString("hh_mm_ss") + ".jpg";
+                        int temp = VzClientSDK.VzLPRClient_ImageSaveToJpeg(pImgFull, path, 50);
+                        if (temp != -1)
+                        {
+                            Log.WriteLog(LogType.NOT_DATABASE, LogFile.LOG, "号牌机" + ip + "已拍照,图片保存于 " + strFilePath);
+                            UILogServer.ins.info("号牌机" + ip + "已拍照,图片保存于 " + strFilePath);
+                        }
+                        else
+                        {
+                            UILogServer.ins.info("图片保存失败");
+                            Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "图片保存失败");
+                        }
+                    }
+                    snapshotDevHandle = -1;
+                }
+            }
+
+            return 0;
+        }
+
+        ///<summary>记录车牌,时间,状态信息;刷新本地entity,并且入buffer</summary>
+        private void SetDetail(VzClientSDK.VZ_LPR_MSG_PLATE_INFO plateInformation, string strIP)
+        {
+            int stat = GetStatus(strIP);
+            bool found = false;
+            int id = 0;
+            lock (ipIdMap)
+            {
+                if (!ipIdMap.ContainsKey(strIP))
+                {
+                    try
+                    {
+                        id = Int32.Parse(ConfigurationManager.AppSettings.Get(strIP));
+                        ipIdMap.Add(strIP, id);
+                        idCountMap.Add(id, FILTERINGNUMBER);
+                    }
+                    catch (Exception) { UILogServer.ins.error("读取号牌机编号映射失败,配置文件填写有误"); Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "读取号牌机编号映射失败"); }
+                }
+            }
+            //检查设备是否存在
+            foreach (NumberMachineNode nmn in nmMsg.data)
+            {
+                //相同设备
+                if (nmn.ip == strIP)
+                {
+                    found = true;
+                    //号牌不为空
+                    if (!(plateInformation.plate.Contains("_无_")))
+                    {
+                        nmn.SetLic(strIP, nmn.id, plateInformation.plate, DateTime.Now.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss"), GetStatus(strIP));
+                        FilterLic(strIP, (NumberMachineNode)nmn.Clone());
+                    }
+                    //号牌为空
+                    else
+                    {
+                        nmn.SetLic(strIP, nmn.id, "", "", GetStatus(strIP));
+                        FilterLic(strIP, null);
+                    }
+                }
+            }
+            //新设备
+            if (!found)
+            {
+                lock (ipIdMap)
+                {
+                    if (!(plateInformation.plate.Contains("_无_")) && ipIdMap.TryGetValue(strIP, out id))
+                    {
+                        NumberMachineNode nmn = new NumberMachineNode(strIP, id, plateInformation.plate, DateTime.Now.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss"), GetStatus(strIP));
+                        NumberMachineNode nmnc = (NumberMachineNode)nmn.Clone();
+                        nmMsg.data.Add(nmnc);
+                        FilterLic(strIP, nmnc);
+                    }
+                    else
+                    {
+                        nmMsg.data.Add(new NumberMachineNode(strIP, id, "", "", GetStatus(strIP)));
+                        FilterLic(strIP, null);
+                    }
+                }
+            }
+        }
+
+        ///<summary>筛选号牌</summary>
+        private void FilterLic(string ip, NumberMachineNode nmn)
+        {
+            int id = 0, activeCount = 0;
+            if (ipIdMap.TryGetValue(ip, out id) && idCountMap.TryGetValue(id, out activeCount) && activeCount < FILTERINGNUMBER)
+            {
+                Dictionary<NumberMachineNode, int> filter;
+                //该filter不存在则创建
+                if (!filterMap.ContainsKey(ip))
+                {
+                    filter = new Dictionary<NumberMachineNode, int>();
+                    filterMap.Add(ip, filter);
+                }
+                else if (!filterMap.TryGetValue(ip, out filter))//计数器异常
+                {
+                    return;
+                }
+                else if (activeCount == 0) //刚接到拍摄命令
+                {
+                    filter.Clear();
+                }
+
+                //激活次数统计
+                idCountMap[id] = activeCount + 1;
+
+                //filter计数
+                int count = 0;
+                if (nmn == null)
+                {
+                    if (activeCount >= FILTERINGNUMBER - 1)
+                    {
+                        UILogServer.ins.error("本轮未扫描到号牌,请重新点击按钮停车");
+                        string context = System.DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ":" + "号牌未扫描到,请重发指令";
+                        string sql = "insert into messagequeue(userID,context,messageType) values (1,'" + context + "',1)";
+                        List<string> strs = new List<string>();
+                        strs.Add(sql);
+                        DBOperation.InsertMessageQueue(EntityForCore.remoteBQ, strs);
+                    }
+                    return;
+                }
+                else if (filter.ContainsKey(nmn) && filter.TryGetValue(nmn, out count))//存在则数量+1
+                {
+                    filter[nmn] = count + 1;
+                }
+                else//不存在则计数1
+                {
+                    filter.Add(nmn, 1);
+                }
+
+                //计算总数
+                filterCount = 0;
+                Dictionary<NumberMachineNode, int>.Enumerator countEnumer = filter.GetEnumerator();
+                while (countEnumer.MoveNext())
+                {
+                    filterCount += countEnumer.Current.Value;
+                }
+
+                //达到计数限制,计算众数是否达标,达标则入队
+                if (filterCount >= FILTERINGNUMBER)
+                {
+                    lock (LicBuffer)
+                    {
+                        Dictionary<NumberMachineNode, int>.Enumerator enumer = filter.GetEnumerator();
+                        int maxCount = 0;
+                        NumberMachineNode node = null;
+                        while (enumer.MoveNext())
+                        {
+                            ////遍历,计数达标且队列中无此号牌
+                            //if (enumer.Current.Value >= (int)(filterCount * filterRatio) && enumer.Current.Key != null && !LicBuffer.Contains(enumer.Current.Key))
+                            //找到最大计数及相应号牌信息
+                            if (enumer.Current.Value >= maxCount && enumer.Current.Key != null && !LicBuffer.Contains(enumer.Current.Key))
+                            {
+                                //输出节点为空或与该号牌不同
+                                if (nmMsg.aNode == null || nmMsg.aNode.LicenseNum == null || nmMsg.aNode.LicenseNum != enumer.Current.Key.LicenseNum)
+                                {
+                                    maxCount = enumer.Current.Value;
+                                    node = (NumberMachineNode)enumer.Current.Key.Clone();
+                                }
+                            }
+                        };
+                        //将相应号牌信息存入队列
+                        if (node != null && ipIdMap.TryGetValue(node.ip, out node.id))
+                        {
+                            LicBuffer.Enqueue((NumberMachineNode)node.Clone());
+                        }
+                        filterCount = 0;
+                        filter.Clear();
+                    }
+                }
+            }
+        }
+
+        ///<summary>停止播放与设备句柄关联的视频</summary>
+        private void StopPlay(int handleInput)
+        {
+            if (handleInput != 0)
+            {
+                int ret = VzClientSDK.VzLPRClient_StopRealPlay(handleInput);
+            }
+        }
+
+        ///<summary>强制获取号牌</summary>
+        private void ActivateSnap(int handle)
+        {
+            if (handle > 0)
+            {
+                VzClientSDK.VzLPRClient_ForceTrigger(handle);
+            }
+
+        }
+
+        ///<summary>ip+port字符串转ipe</summary>
+        private void GetIpEndPoint(string ipp, out IPEndPoint ipe)
+        {
+            IPAddress myIP = IPAddress.Parse(ipp.Remove(ipp.LastIndexOf(':')) + "");
+            string myPort = ipp.Substring(ipp.IndexOf(':') + 1);
+            ipe = new IPEndPoint(myIP, int.Parse(myPort));
+        }
+
+        ///<summary>创建新pic并记录在picNameMap</summary>
+        private bool CreatePic(int index, out PictureBox pb)
+        {
+            pb = new PictureBox
+            {
+                Width = 230,
+                Height = 180,
+                AutoSize = false,
+                Name = "PictureBox" + Convert.ToString(index)
+            };
+            lock (namePicMap)
+            {
+                if (!namePicMap.ContainsKey(pb.Name))
+                {
+                    flowLayoutPanel1.Controls.Add(pb);
+                    namePicMap.Add(pb.Name, pb);
+                    return true;
+                }
+                else
+                    return false;
+            }
+        }
+
+        ///<summary>更新设备状态</summary>
+        private int GetStatus(string devIP)
+        {
+            int myHandle;
+            byte stat = 0;
+            if (ipHandleMap.TryGetValue(devIP, out myHandle))
+            {
+                VzClientSDK.VzLPRClient_IsConnected(myHandle, ref stat);
+                return stat;
+            }
+            return -1;
+        }
+
+        private string Get_IP(int lprHandle)
+        {
+            byte[] strDecIP = new byte[32];
+            int max_count = 32;
+            int ret = VzClientSDK.VzLPRClient_GetDeviceIP(lprHandle, ref strDecIP[0], max_count);
+            string strIP = System.Text.Encoding.Default.GetString(strDecIP);
+            strIP = strIP.TrimEnd('\0');
+            return strIP;
+        }
+
+        private bool NodeValidation(NumberMachineNode node)
+        {
+            return (node != null && node.ip != null && node.ip != "" && node.ip != "used" && node.LicenseNum != null && node.LicenseNum != "") ? true : false;
+        }
+
+        /// <summary>
+        /// 系统启动
+        /// </summary>
+        public void Start()
+        {
+
+            Task.Factory.StartNew(() =>
+            {
+                isClosing = false;
+
+                try
+                {
+                    VzClientSDK.VZLPRClient_StopFindDevice();
+
+                    find_DeviceCB = new VzClientSDK.VZLPRC_FIND_DEVICE_CALLBACK_EX(FIND_DEVICE_CALLBACK_EX);
+                    int ret = VzClientSDK.VZLPRClient_StartFindDeviceEx(find_DeviceCB, IntPtr.Zero);
+                }
+                catch (Exception ex)
+                {
+                    Debug.WriteLine(ex.ToString());
+                }
+            });
+
+            Task.Factory.StartNew(() =>
+            {
+                Run();
+            });
+
+            //Task imgTest = Task.Factory.StartNew(() =>
+            //{
+            //    while (!isClosing)
+            //    {
+            //        Command cmd = new Command
+            //        {
+            //            id = 1
+            //        };
+            //        SetMessage(cmd);
+            //        Thread.Sleep(30000);
+            //        Command cmd2 = new Command
+            //        {
+            //            id = 2
+            //        };
+            //        SetMessage(cmd2);
+            //        Thread.Sleep(30000);
+            //    }
+            //});
+
+        }
+
+        /// <summary>
+        /// 系统关闭
+        /// </summary>
+        public void Stop()
+        {
+            VzClientSDK.VZLPRClient_StopFindDevice();
+            lock (devPicMap)
+            {
+                Dictionary<int, PictureBox>.Enumerator enumer = devPicMap.GetEnumerator();
+                while (enumer.MoveNext())
+                {
+                    if (enumer.Current.Key != 0)
+                    {
+                        StopPlay(enumer.Current.Key);
+                        VzClientSDK.VzLPRClient_Close(enumer.Current.Key);
+                        flowLayoutPanel1.Controls.Remove(enumer.Current.Value);
+                    }
+                }
+                isClosing = true;
+                devPicMap.Clear();
+            }
+            lock (namePicMap) { namePicMap.Clear(); }
+            lock (ipIdMap) { ipIdMap.Clear(); }
+            lock (ipHandleMap) { ipHandleMap.Clear(); }
+            //this.Close();
+        }
+
+        /// <summary>
+        /// 监控线程获取号牌机信息,核心线程获取号牌信息
+        /// </summary>
+        public AbstractMessage GetMessage()
+        {
+            lock (LicBuffer)
+            {
+                //准备输出的数据中存在非法Node,且LicBuffer可出队产生一个合法Node,则替换该非法Node
+                if (!NodeValidation(nmMsg.aNode))
+                {
+                    for (int i = 0; i < LicBuffer.Count; i++)
+                    {
+                        NumberMachineNode n = LicBuffer.Dequeue();
+                        if (NodeValidation(n))
+                        {
+                            if (nmMsg.aNode != null && nmMsg.aNode.ip != null)
+                            {
+                                LicBuffer.Enqueue((NumberMachineNode)nmMsg.aNode.Clone());
+                            }
+                            nmMsg.aNode = n;
+                            break;
+                        }
+                        else
+                        {
+                            LicBuffer.Enqueue(n);
+                        }
+                    }
+                    //遍历licBuffer后仍不合法,则丢入队列,将node置为null
+                    if (!NodeValidation(nmMsg.aNode))
+                    {
+                        if (nmMsg.aNode != null && nmMsg.aNode.ip != null)
+                        {
+                            LicBuffer.Enqueue((NumberMachineNode)nmMsg.aNode.Clone());
+                        }
+                        nmMsg.aNode = null;
+                    }
+                }
+            }
+            return nmMsg;
+        }
+
+        /// <summary>
+        /// 一次停车流程完成时调用该方法,发送已完成车辆号牌信息
+        /// </summary>
+        /// <param name="message">已完成车辆的号牌相关信息存于message的aNode中,用于标记需清空的号牌</param>
+        public void SetMessage(AbstractMessage message)
+        {
+            if (message.GetType().Equals(typeof(NumberMachineMessage)))
+            {
+                NumberMachineNode n = ((NumberMachineMessage)message).aNode;
+                lock (LicBuffer)
+                {
+                    //输入号牌格式无误
+                    if (n != null && n.ip != null && n.ip == "")
+                    {
+                        //与类成员变量中aNode号牌相同,将其ip复位表示已使用,重新入队等待清除
+                        if (nmMsg != null && nmMsg.aNode != null && nmMsg.aNode.LicenseNum == n.LicenseNum)
+                        {
+                            nmMsg.aNode.ip = "";
+                            LicBuffer.Enqueue((NumberMachineNode)nmMsg.aNode.Clone());
+                            nmMsg.aNode = null;
+                        }
+                        //搜索号牌队列,将相应号牌置空,准备清除
+                        else
+                        {
+                            for (int i = 0; i < LicBuffer.Count; i++)
+                            {
+                                NumberMachineNode temp = LicBuffer.Dequeue();
+                                //已匹配上,ip置空
+                                if (temp.LicenseNum == n.LicenseNum)
+                                {
+                                    temp.ip = "";
+                                    LicBuffer.Enqueue(temp);
+                                    break;
+                                }
+                                LicBuffer.Enqueue(temp);
+                            }
+                        }
+                    }
+                }
+            }
+            //传入指令,根据ip找到handle,改变snapshotDevHandle的值在回调函数中截图
+            if (message.GetType().Equals(typeof(Command)))
+            {
+                Command cmd = (Command)message;
+                if (cmd != null && cmd.id != 0)
+                {
+                    //按动按钮启动号牌机扫描
+                    if (cmd.manual)
+                    {
+                        lock (idCountMap)
+                        {
+                            if (idCountMap.ContainsKey(cmd.id))
+                            {
+                                idCountMap[cmd.id] = 0;
+                            }
+                        }
+                    }
+                    else
+                    {
+                        lock (ipIdMap)
+                        {
+                            Dictionary<string, int>.Enumerator enumerator = ipIdMap.GetEnumerator();
+                            while (enumerator.MoveNext())
+                            {
+                                // if (enumerator.Current.Value == cmd.id && ipHandleMap.TryGetValue(enumerator.Current.Key, out int handle))
+                                int handle = 0;
+                                if (enumerator.Current.Value == cmd.id && ipHandleMap.TryGetValue(enumerator.Current.Key, out handle))
+                                {
+                                    snapshotDevHandle = handle;
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
+                else
+                {
+                    UILogServer.ins.error("参数错误,图片未保存");
+                    Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "参数错误,图片未保存");
+                }
+            }
+
+        }
+    }
+}

+ 5 - 5
PLCLinker/PLCLinker.sln

@@ -11,7 +11,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "centralController", "centra
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "socketTest", "socketTest\socketTest.csproj", "{9AB6542B-0FD8-4ED2-8484-CC7F8C23C67D}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "parkMonitor", "parkMonitor\parkMonitor.csproj", "{DD3DCAB1-41A7-4EED-ADEE-9E4BBCE6B4C0}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfApp1", "WpfApp1\WpfApp1.csproj", "{4B52BB18-B89A-47C0-A20C-27FF628437FE}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -35,10 +35,10 @@ Global
 		{9AB6542B-0FD8-4ED2-8484-CC7F8C23C67D}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{9AB6542B-0FD8-4ED2-8484-CC7F8C23C67D}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{9AB6542B-0FD8-4ED2-8484-CC7F8C23C67D}.Release|Any CPU.Build.0 = Release|Any CPU
-		{DD3DCAB1-41A7-4EED-ADEE-9E4BBCE6B4C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{DD3DCAB1-41A7-4EED-ADEE-9E4BBCE6B4C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{DD3DCAB1-41A7-4EED-ADEE-9E4BBCE6B4C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{DD3DCAB1-41A7-4EED-ADEE-9E4BBCE6B4C0}.Release|Any CPU.Build.0 = Release|Any CPU
+		{4B52BB18-B89A-47C0-A20C-27FF628437FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{4B52BB18-B89A-47C0-A20C-27FF628437FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{4B52BB18-B89A-47C0-A20C-27FF628437FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{4B52BB18-B89A-47C0-A20C-27FF628437FE}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 3 - 3
PLCLinker/PLCLinker/App.config

@@ -1,6 +1,6 @@
-<?xml version="1.0" encoding="utf-8" ?>
+<?xml version="1.0" encoding="utf-8"?>
 <configuration>
     <startup> 
-        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
     </startup>
-</configuration>
+</configuration>

+ 5 - 5
PLCLinker/PLCLinker/PLCLinker.csproj

@@ -8,9 +8,10 @@
     <OutputType>Exe</OutputType>
     <RootNamespace>PLCLinker</RootNamespace>
     <AssemblyName>PLCLinker</AssemblyName>
-    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+    <TargetFrameworkProfile />
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -33,11 +34,10 @@
   </PropertyGroup>
   <ItemGroup>
     <Reference Include="PLCS7">
-      <HintPath>..\PLCS7\bin\Debug\PLCS7.dll</HintPath>
+      <HintPath>..\..\resources\PLCS7.dll</HintPath>
     </Reference>
-    <Reference Include="S7.Net, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d5812d469e84c693, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\PLCS7\bin\Debug\S7.Net.dll</HintPath>
+    <Reference Include="S7.Net">
+      <HintPath>..\..\resources\S7.Net.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />

+ 87 - 62
PLCLinker/PLCLinker/Program.cs

@@ -3,6 +3,9 @@ using S7.Net;
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Reflection;
 using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
@@ -13,76 +16,98 @@ namespace PLCTest
     {
         static void Main(string[] args)
         {
-            AbstractPLCLinker pl = new PLCLinker(CpuType.S71500, "192.168.0.1", 0, 1, 18, 22, 20, 6, 200);
-            Random rnd = new Random();
-            Task t = Task.Factory.StartNew(() =>
+            //AbstractPLCLinker pl = new PLCLinker(CpuType.S71500, "192.168.0.1", 0, 1, 18, 22, 20, 6, 200);
+            //Random rnd = new Random();
+            //Task t = Task.Factory.StartNew(() =>
+            //{
+            //    while (true)
+            //    {
+            //        //parkingSpaceDBTest(pl, rnd);
+            //        terminalDBTest(pl, rnd);
+            //        Thread.Sleep(500);
+            //    }
+            //});
+            //t.Wait();
+
+            try
             {
-                while (true)
-                {
-                    //parkingSpaceDBTest(pl, rnd);
-                    terminalDBTest(pl, rnd);
-                    Thread.Sleep(500);
-                }
-            });
-            t.Wait();
+                TcpClient client = new TcpClient();
+                client.Connect("www.baidu.com", 80);
+                string ip = ((IPEndPoint)client.Client.LocalEndPoint).Address.ToString();
+                client.Close();
+                Console.WriteLine(ip.ToString());
+            }
+            catch (Exception e) { Console.WriteLine("wrong ipAddr"); }
+
+        //Assembly assembly = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory+"PLCS7.dll");
+        //Type t = assembly.GetType("PLCS7.PLCLinker");
+        //object[] constructorParams = new object[] { S7.Net.CpuType.S71500, "192.168.0.1", 0, 1, 18, 22, 20, 6, 200 };
+        //if (t != null)
+        //{
+        //    //object instance = assembly.CreateInstance("PLCS7.PLCLinker",false,BindingFlags.CreateInstance,null,constructorParams,null,null);
+        //    object instance = Activator.CreateInstance(t,constructorParams);
+        //    AbstractPLCLinker plc = instance as AbstractPLCLinker;
+        //    Console.WriteLine(plc.isConnected);
+        //}
+        Console.ReadLine();
         }
-        public static void parkingSpaceDBTest(AbstractPLCLinker pl, Random rnd)
+    public static void parkingSpaceDBTest(AbstractPLCLinker pl, Random rnd)
+    {
+        if (!pl.isConnected) { pl.PLCConnect(); }
+        else
         {
-            if (!pl.isConnected) { pl.PLCConnect(); }
-            else
+            //读车位表信息
+            List<object> psList = pl.ReadFromPLC(PLCDataType.parkingSpace, 1);
+            psList.AddRange(pl.ReadFromPLC(PLCDataType.parkingSpace, 2));
+            foreach (var ps in psList)
             {
-                //读车位表信息
-                List<object> psList = pl.ReadFromPLC(PLCDataType.parkingSpace, 1);
-                psList.AddRange(pl.ReadFromPLC(PLCDataType.parkingSpace, 2));
-                foreach (var ps in psList)
-                {
-                    Console.WriteLine(((ParkingSpaceStru)ps).ToString());
-                }
-                //写入车位状态信息
-                ParkingSpaceStru pss = new ParkingSpaceStru
-                {
-                    parkingSpace = (short)rnd.Next(1, 3),
-                    spaceStatus = (short)rnd.Next(0, 3)
-                };
-                pl.WriteToPLC(pss, PLCDataType.central);
-                Console.WriteLine("写入状态值");
+                Console.WriteLine(((ParkingSpaceStru)ps).ToString());
             }
+            //写入车位状态信息
+            ParkingSpaceStru pss = new ParkingSpaceStru
+            {
+                parkingSpace = (short)rnd.Next(1, 3),
+                spaceStatus = (short)rnd.Next(0, 3)
+            };
+            pl.WriteToPLC(pss, PLCDataType.central);
+            Console.WriteLine("写入状态值");
         }
+    }
 
-        public static void terminalDBTest(AbstractPLCLinker pl, Random rnd)
+    public static void terminalDBTest(AbstractPLCLinker pl, Random rnd)
+    {
+        if (!pl.isConnected) { pl.PLCConnect(); }
+        else
         {
-            if (!pl.isConnected) { pl.PLCConnect(); }
-            else
-            { 
-                //读终端块数据
-                List<object> tList = pl.ReadFromPLC(PLCDataType.terminal, 1);
-                foreach (var term in tList)
-                {
-                    Console.WriteLine(((TerminalStru)term).ToString());
-                }
-                //模拟中控写数据
-                TerminalStru tsCentral = new TerminalStru
-                {
-                    terminalID = 1,
-                    paymentStatus = (short)rnd.Next(100, 999),
-                    licVerification = -1,
-                    parkingFee = (short)rnd.Next(100, 999),
-                    userType = (short)rnd.Next(100, 999)
-                };
-                //模拟终端写数据
-                TerminalStru tsTerminal = new TerminalStru
-                {
-                    terminalID = 1,
-                    terminalStatus = (short)rnd.Next(100, 999),
-                    btnStatus = (short)rnd.Next(100, 999),
-                    licenseCodeA = (short)rnd.Next(100, 999),
-                    licenseCodeB = -1,
-                    licenseCodeC = (short)rnd.Next(100, 999),
-                    receiptNum = (short)rnd.Next(100, 999)
-                };
-                //pl.WriteToPLC(tsCentral, PLCDataType.central);
-                pl.WriteToPLC(tsTerminal, PLCDataType.terminal);
+            //读终端块数据
+            List<object> tList = pl.ReadFromPLC(PLCDataType.terminal, 1);
+            foreach (var term in tList)
+            {
+                Console.WriteLine(((TerminalStru)term).ToString());
             }
+            //模拟中控写数据
+            TerminalStru tsCentral = new TerminalStru
+            {
+                terminalID = 1,
+                paymentStatus = (short)rnd.Next(100, 999),
+                licVerification = -1,
+                parkingFee = (short)rnd.Next(100, 999),
+                userType = (short)rnd.Next(100, 999)
+            };
+            //模拟终端写数据
+            TerminalStru tsTerminal = new TerminalStru
+            {
+                terminalID = 1,
+                terminalStatus = (short)rnd.Next(100, 999),
+                btnStatus = (short)rnd.Next(100, 999),
+                licenseCodeA = (short)rnd.Next(100, 999),
+                licenseCodeB = -1,
+                licenseCodeC = (short)rnd.Next(100, 999),
+                receiptNum = (short)rnd.Next(100, 999)
+            };
+            //pl.WriteToPLC(tsCentral, PLCDataType.central);
+            pl.WriteToPLC(tsTerminal, PLCDataType.terminal);
         }
-        }
+    }
+}
 }

BIN=BIN
PLCLinker/PLCLinker/bin/Release/PLCLinker.exe


+ 3 - 3
PLCLinker/PLCLinker/bin/Release/PLCLinker.exe.config

@@ -1,6 +1,6 @@
-<?xml version="1.0" encoding="utf-8" ?>
+<?xml version="1.0" encoding="utf-8"?>
 <configuration>
     <startup> 
-        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
     </startup>
-</configuration>
+</configuration>

BIN=BIN
PLCLinker/PLCLinker/bin/Release/PLCLinker.pdb


BIN=BIN
PLCLinker/PLCLinker/bin/Release/PLCS7.dll


BIN=BIN
PLCLinker/PLCLinker/bin/Release/PLCS7.pdb


+ 1 - 1
PLCLinker/PLCLinker/obj/Release/PLCLinker.csproj.CoreCompileInputs.cache

@@ -1 +1 @@
-bc88ed63d13083557ce9673451090a0e191a41b4
+2f2a2cff2026c14e7b20a0582a7d3320ceed58c6

+ 1 - 2
PLCLinker/PLCLinker/obj/Release/PLCLinker.csproj.FileListAbsolute.txt

@@ -1,10 +1,9 @@
+E:\superScene\智能停车项目\智能停车项目v2.0\PLCLinker\PLCLinker\obj\Release\PLCLinker.csproj.CoreCompileInputs.cache
 E:\superScene\智能停车项目\智能停车项目v2.0\PLCLinker\PLCLinker\bin\Release\PLCLinker.exe.config
 E:\superScene\智能停车项目\智能停车项目v2.0\PLCLinker\PLCLinker\bin\Release\PLCLinker.exe
 E:\superScene\智能停车项目\智能停车项目v2.0\PLCLinker\PLCLinker\bin\Release\PLCLinker.pdb
 E:\superScene\智能停车项目\智能停车项目v2.0\PLCLinker\PLCLinker\bin\Release\PLCS7.dll
 E:\superScene\智能停车项目\智能停车项目v2.0\PLCLinker\PLCLinker\bin\Release\S7.Net.dll
-E:\superScene\智能停车项目\智能停车项目v2.0\PLCLinker\PLCLinker\bin\Release\PLCS7.pdb
-E:\superScene\智能停车项目\智能停车项目v2.0\PLCLinker\PLCLinker\obj\Release\PLCLinker.csproj.CoreCompileInputs.cache
 E:\superScene\智能停车项目\智能停车项目v2.0\PLCLinker\PLCLinker\obj\Release\PLCLinker.exe
 E:\superScene\智能停车项目\智能停车项目v2.0\PLCLinker\PLCLinker\obj\Release\PLCLinker.pdb
 E:\superScene\智能停车项目\智能停车项目v2.0\PLCLinker\PLCLinker\obj\Release\PLCLinker.csprojResolveAssemblyReference.cache

BIN=BIN
PLCLinker/PLCLinker/obj/Release/PLCLinker.csprojResolveAssemblyReference.cache


BIN=BIN
PLCLinker/PLCLinker/obj/Release/PLCLinker.exe


BIN=BIN
PLCLinker/PLCLinker/obj/Release/PLCLinker.pdb


+ 1 - 1
PLCLinker/PLCS7/PLCS7.cs

@@ -12,7 +12,7 @@ using System.Timers;
 
 namespace PLCS7
 {
-    interface IPLCS7
+    public interface IPLCS7
     {
         bool PLCConnect();
         void PLCDisconnect();

+ 2 - 1
PLCLinker/PLCS7/PLCS7.csproj

@@ -9,8 +9,9 @@
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <RootNamespace>PLCS7</RootNamespace>
     <AssemblyName>PLCS7</AssemblyName>
-    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
+    <TargetFrameworkProfile />
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>

BIN=BIN
PLCLinker/PLCS7/bin/Release/PLCS7.dll


BIN=BIN
PLCLinker/PLCS7/bin/Release/PLCS7.pdb


+ 1 - 1
PLCLinker/PLCS7/obj/Release/PLCS7.csproj.CoreCompileInputs.cache

@@ -1 +1 @@
-11619de1b15775019fd1de669bf914c94e290e9f
+cc05f1a35fab18bffcd16693ec42e7effb9ede7d

BIN=BIN
PLCLinker/PLCS7/obj/Release/PLCS7.dll


BIN=BIN
PLCLinker/PLCS7/obj/Release/PLCS7.pdb


+ 47 - 0
PLCLinker/ParkController/Form1.Designer.cs

@@ -0,0 +1,47 @@
+namespace ParkController
+{
+    partial class Form1
+    {
+        /// <summary>
+        /// 必需的设计器变量。
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// 清理所有正在使用的资源。
+        /// </summary>
+        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows 窗体设计器生成的代码
+
+        /// <summary>
+        /// 设计器支持所需的方法 - 不要修改
+        /// 使用代码编辑器修改此方法的内容。
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.SuspendLayout();
+            // 
+            // Form1
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(644, 360);
+            this.Name = "Form1";
+            this.Text = "Form1";
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+    }
+}
+

+ 20 - 0
PLCLinker/ParkController/Form1.cs

@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace ParkController
+{
+    public partial class Form1 : Form
+    {
+        public Form1()
+        {
+            InitializeComponent();
+        }
+    }
+}

PLCLinker/parkMonitor/controlPanel/ControlPanel.resx → PLCLinker/ParkController/Form1.resx


+ 82 - 0
PLCLinker/ParkController/ParkController.csproj

@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{78435D52-0B74-4BE5-9E3D-F29B61CC7B04}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <RootNamespace>ParkController</RootNamespace>
+    <AssemblyName>ParkController</AssemblyName>
+    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Deployment" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Form1.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Form1.Designer.cs">
+      <DependentUpon>Form1.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <EmbeddedResource Include="Form1.resx">
+      <DependentUpon>Form1.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>

+ 22 - 0
PLCLinker/ParkController/Program.cs

@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace ParkController
+{
+    static class Program
+    {
+        /// <summary>
+        /// 应用程序的主入口点。
+        /// </summary>
+        [STAThread]
+        static void Main()
+        {
+            Application.EnableVisualStyles();
+            Application.SetCompatibleTextRenderingDefault(false);
+            Application.Run(new Form1());
+        }
+    }
+}

+ 36 - 0
PLCLinker/ParkController/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("ParkController")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("ParkController")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("78435d52-0b74-4be5-9e3d-f29b61cc7b04")]
+
+// 程序集的版本信息由下列四个值组成: 
+//
+//      主版本
+//      次版本
+//      生成号
+//      修订号
+//
+// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
+// 方法是按如下所示使用“*”: :
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 71 - 0
PLCLinker/ParkController/Properties/Resources.Designer.cs

@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     此代码由工具生成。
+//     运行时版本: 4.0.30319.42000
+//
+//     对此文件的更改可能导致不正确的行为,如果
+//     重新生成代码,则所做更改将丢失。
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace ParkController.Properties
+{
+
+
+    /// <summary>
+    ///   强类型资源类,用于查找本地化字符串等。
+    /// </summary>
+    // 此类是由 StronglyTypedResourceBuilder
+    // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
+    // 若要添加或删除成员,请编辑 .ResX 文件,然后重新运行 ResGen
+    // (以 /str 作为命令选项),或重新生成 VS 项目。
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources
+    {
+
+        private static global::System.Resources.ResourceManager resourceMan;
+
+        private static global::System.Globalization.CultureInfo resourceCulture;
+
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources()
+        {
+        }
+
+        /// <summary>
+        ///   返回此类使用的缓存 ResourceManager 实例。
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager
+        {
+            get
+            {
+                if ((resourceMan == null))
+                {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ParkController.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+
+        /// <summary>
+        ///   覆盖当前线程的 CurrentUICulture 属性
+        ///   使用此强类型的资源类的资源查找。
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture
+        {
+            get
+            {
+                return resourceCulture;
+            }
+            set
+            {
+                resourceCulture = value;
+            }
+        }
+    }
+}

+ 4 - 7
PLCLinker/parkMonitor/view/FormModbus/RuleCfg_Form.resx

@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <root>
   <!-- 
     Microsoft ResX Schema 
@@ -46,7 +46,7 @@
     
     mimetype: application/x-microsoft.net.object.binary.base64
     value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : System.Serialization.Formatters.Binary.BinaryFormatter
             : and then encoded with base64 encoding.
     
     mimetype: application/x-microsoft.net.object.soap.base64
@@ -60,7 +60,6 @@
             : and then encoded with base64 encoding.
     -->
   <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
     <xsd:element name="root" msdata:IsDataSet="true">
       <xsd:complexType>
         <xsd:choice maxOccurs="unbounded">
@@ -69,10 +68,9 @@
               <xsd:sequence>
                 <xsd:element name="value" type="xsd:string" minOccurs="0" />
               </xsd:sequence>
-              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
               <xsd:attribute name="type" type="xsd:string" />
               <xsd:attribute name="mimetype" type="xsd:string" />
-              <xsd:attribute ref="xml:space" />
             </xsd:complexType>
           </xsd:element>
           <xsd:element name="assembly">
@@ -87,10 +85,9 @@
                 <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                 <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
               </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
               <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
               <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-              <xsd:attribute ref="xml:space" />
             </xsd:complexType>
           </xsd:element>
           <xsd:element name="resheader">

+ 30 - 0
PLCLinker/ParkController/Properties/Settings.Designer.cs

@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace ParkController.Properties
+{
+
+
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+    {
+
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+        public static Settings Default
+        {
+            get
+            {
+                return defaultInstance;
+            }
+        }
+    }
+}

+ 7 - 0
PLCLinker/ParkController/Properties/Settings.settings

@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>

+ 9 - 0
PLCLinker/WpfApp1/App.xaml

@@ -0,0 +1,9 @@
+<Application x:Class="WpfApp1.App"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:local="clr-namespace:WpfApp1"
+             StartupUri="MainWindow.xaml">
+    <Application.Resources>
+         
+    </Application.Resources>
+</Application>

+ 8 - 6
PLCLinker/parkMonitor/App.xaml.cs

@@ -6,10 +6,12 @@ using System.Linq;
 using System.Threading.Tasks;
 using System.Windows;
 
-namespace parkMonitor {
-	/// <summary>
-	/// App.xaml 的交互逻辑
-	/// </summary>
-	public partial class App : Application {
-	}
+namespace WpfApp1
+{
+    /// <summary>
+    /// App.xaml 的交互逻辑
+    /// </summary>
+    public partial class App : Application
+    {
+    }
 }

+ 14 - 0
PLCLinker/WpfApp1/Entry/MainEntry.cs

@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace WpfApp1.Entry
+{
+    public class MainEntry
+    {
+
+    }
+
+}

+ 184 - 0
PLCLinker/WpfApp1/Entry/SystemInitializer.cs

@@ -0,0 +1,184 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using BroadcastModule;
+using DatabaseDLL;
+using NumMachine;
+using parkMonitor.tools;
+using PLCS7;
+using S7.Net;
+using WebServer;
+
+namespace WpfApp1.Entry
+{
+    public class SystemInitializer
+    {
+        /// <summary>
+        /// 中控系统总状态
+        /// </summary>
+        public static bool globalStatus = false;
+        /// <summary>
+        /// 初始化步骤
+        /// </summary>
+        public static int initializeState = 0;
+        /// <summary>
+        /// PLC对象句柄
+        /// </summary>
+        public static AbstractPLCLinker PLC = null;
+        public static string plcIPAddr { get; set; }
+        public static int plcRack { get; set; }
+        public static int plcSlot { get; set; }
+        public static string[] plcDatablockConfig { get; set; }
+        public static int plcTerminalCount { get; set; }
+        public static int plcParkingSpaceCount { get; set; }
+        public static int plcRefreshInterval { get; set; }
+        /// <summary>
+        /// 远程数据库操作句柄
+        /// </summary>
+        public static DBOperation remoteDBOper;
+        /// <summary>
+        /// 本地数据库操作句柄
+        /// </summary>
+        public static DBOperation localDBOper;
+        /// <summary>
+        /// 显示板操作对象句柄
+        /// </summary>
+        public static BroadcastBoard allInOneMachine;
+        public static string allInOneMachineIP { get; set; }
+        public static int allInOneMachinePort { get; set; }
+        public static INumMachineLinker numMachineLinker;
+
+        public static IWebServer webServer;
+        public static int webPort { get; set; }
+        /// <summary>
+        /// 初始化各模块
+        /// </summary>
+        /// <returns></returns>
+        public static void Init(IntPtr flpHandle)
+        {
+            bool initStatus = false;
+            int retryCount = 0;
+            string remoteDBConnStr, localDBConnStr;
+            int DBtimeout;
+            int garageID;
+            MyTimer mt = new MyTimer();
+            mt.StartTiming();
+            try
+            {
+                retryCount = Convert.ToInt32(ConfigurationManager.AppSettings.Get("retryCount"));
+                //数据库
+                remoteDBConnStr = ConfigurationManager.AppSettings.Get("remoteDBConnStr");
+                localDBConnStr = ConfigurationManager.AppSettings.Get("localDBConnStr");
+                DBtimeout = Convert.ToInt32(ConfigurationManager.AppSettings.Get("DBtimeout"));
+                //plc
+                plcIPAddr = ConfigurationManager.AppSettings.Get("plcIpAddress");
+                plcRack = Convert.ToInt32(ConfigurationManager.AppSettings.Get("plcRack"));
+                plcSlot = Convert.ToInt32(ConfigurationManager.AppSettings.Get("plcSlot"));
+                plcDatablockConfig = ConfigurationManager.AppSettings.Get("plcDatablockId").Split(',');
+                plcTerminalCount = Convert.ToInt32(ConfigurationManager.AppSettings.Get("plcTerminalCount"));
+                plcParkingSpaceCount = Convert.ToInt32(ConfigurationManager.AppSettings.Get("plcParkingSpaceCount"));
+                plcRefreshInterval = Convert.ToInt32(ConfigurationManager.AppSettings.Get("plcRefreshInterval"));
+                //显示屏
+                allInOneMachineIP = ConfigurationManager.AppSettings.Get("allInOneMachineIP");
+                allInOneMachinePort = Convert.ToInt32(ConfigurationManager.AppSettings.Get("allInOneMachinePort"));
+                //webServer端口
+                webPort = Convert.ToInt32(ConfigurationManager.AppSettings.Get("webPort"));
+
+                garageID = Convert.ToInt32(ConfigurationManager.AppSettings.Get("garageID"));
+                //配置文件读取结束,进入状态1
+                initializeState = 1;
+                initStatus = true;
+            }
+            catch (Exception e) { Console.WriteLine("初始化," + e.Message); return; }
+
+            initStatus = initStatus && PLCInit(retryCount);
+            //PLC初始化结束,进入状态2
+            if (!initStatus) { return; }
+            else { initializeState = 2;}
+
+            //初始化数据库对象
+            remoteDBOper = new DBOperation(remoteDBConnStr, DBtimeout);
+            localDBOper = new DBOperation(localDBConnStr, DBtimeout);
+            initStatus = initStatus && remoteDBOper.InitConnPooling(10);
+            initStatus = initStatus && localDBOper.InitConnPooling(10);
+            //数据库初始化结束,进入状态3
+            if (!initStatus) { return; }
+            else { initializeState = 3; }
+
+            //初始化web对象
+            webServer = new CentralForWeb();
+            initStatus = initStatus && webServer.Start(webPort);
+            //webServer初始化结束,进入状态4
+            if (!initStatus) { return; }
+            else { initializeState = 4; }
+
+            //初始化号牌机对象
+            numMachineLinker = new NumMachineLinker(flpHandle);
+            numMachineLinker.Start();
+            //初始化显示板对象,显示板udp面向无连接
+            allInOneMachine = new BroadcastBoard(allInOneMachineIP, allInOneMachinePort);
+            allInOneMachine.Refresh();
+            //系统初始化结束,进入状态5
+            if (!initStatus) { return; }
+            else { initializeState = 5; }
+            mt.EndTiming();
+            Console.WriteLine("初始化耗时:"+mt.GetInterval().TotalSeconds);
+            switch(initializeState){
+                case 0:
+                    Console.WriteLine("配置文件读写异常");
+                    break;
+                case 1:
+                    Console.WriteLine("PLC初始化异常");
+                    break;
+                case 2:
+                    Console.WriteLine("数据库初始化异常");
+                    break;
+                case 3:
+                    Console.WriteLine("webServer初始化异常");
+                    break;
+                case 4:
+                    Console.WriteLine("其他异常");
+                    break;
+                case 5:
+                    Console.WriteLine("初始化成功");
+                    break;
+            }
+        }
+
+        public static bool PLCInit(int retryCount)
+        {
+            int temp = retryCount;
+            //初始化PLC对象
+            while (temp-- > 0)
+            {
+                if (PLC == null)
+                {
+                    PLC = new PLCLinker(CpuType.S71500, plcIPAddr, (short)plcRack, (short)plcSlot, 
+                        Int32.Parse(plcDatablockConfig[0]), Int32.Parse(plcDatablockConfig[1]), Int32.Parse(plcDatablockConfig[2]), 
+                        plcTerminalCount, plcParkingSpaceCount);
+                }
+                else if (PLC.isConnected)
+                {
+                    return true;
+                }
+                else { PLC.PLCConnect(); }
+            }
+            return false;
+        }
+
+        public static void Stop()
+        {
+            //关闭号牌机
+            if (numMachineLinker != null) { numMachineLinker.Stop();}
+            //关闭webServer
+            if (webServer != null) { webServer.Stop();}
+            //关闭数据库
+            if (remoteDBOper != null) {remoteDBOper.DBClose(); }
+            if (localDBOper != null) {localDBOper.DBClose(); }
+        }
+
+    }
+}

+ 23 - 0
PLCLinker/WpfApp1/MainWindow.xaml

@@ -0,0 +1,23 @@
+<Window
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:wfh="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
+        xmlns:wfc="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
+        xmlns:local="clr-namespace:WpfApp1"
+        xmlns:PLCS7="clr-namespace:PLCS7;assembly=PLCS7" x:Class="WpfApp1.MainWindow"
+        mc:Ignorable="d"
+        Title="MainWindow" Height="700" Width="1200" Closed="win_Closed">
+    <Grid Margin="0,0,-8,-20">
+        <WindowsFormsHost x:Name="form1" HorizontalAlignment="Left" Height="500" Margin="10,65,0,0" VerticalAlignment="Top" Width="750">
+            <wfc:FlowLayoutPanel x:Name="flowLayoutPanel1"/>
+        </WindowsFormsHost>
+        <Button x:Name="GetNum" Content="生成号牌" HorizontalAlignment="Left" Margin="886,138,0,0" VerticalAlignment="Top" Width="64" Height="36" Click="GetNum_Click"/>
+        <TextBox x:Name="NumMachineId" HorizontalAlignment="Left" Height="47" Margin="812,65,0,0" TextWrapping="Wrap" Text="input id" VerticalAlignment="Top" Width="76">
+
+        </TextBox>
+        <TextBox x:Name="License" HorizontalAlignment="Left" Height="47" Margin="941,65,0,0" TextWrapping="Wrap" Text="result" VerticalAlignment="Top" Width="76"/>
+
+    </Grid>
+</Window>

+ 59 - 0
PLCLinker/WpfApp1/MainWindow.xaml.cs

@@ -0,0 +1,59 @@
+using NumMachine;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using WpfApp1.Entry;
+
+namespace WpfApp1
+{
+    /// <summary>
+    /// MainWindow.xaml 的交互逻辑
+    /// </summary>
+    public partial class MainWindow : Window
+    {
+        public MainWindow()
+        {
+            InitializeComponent();
+            IntPtr flpHandle = flowLayoutPanel1.Handle;
+            SystemInitializer.Init(flpHandle);
+        }
+
+        private void win_Closed(object sender, EventArgs e)
+        {
+            SystemInitializer.Stop();
+            Close();
+            System.Environment.Exit(0);
+        }
+
+        private void GetNum_Click(object sender, RoutedEventArgs e)
+        {
+            if (SystemInitializer.numMachineLinker != null)
+            {
+                try
+                {
+                    int id = Int32.Parse(NumMachineId.Text);
+                    string lic="";
+                    Task.Factory.StartNew(()=> {
+                        lic = SystemInitializer.numMachineLinker.GetLicensePlate(id);
+                        License.Dispatcher.BeginInvoke(new Action(() => { License.Text = lic; }));
+                        
+                        Console.WriteLine("号牌" + lic);
+                    });
+                }
+                catch { }
+            }
+        }
+
+    }
+}

+ 16 - 0
PLCLinker/WpfApp1/Monitor/IMonitor.cs

@@ -0,0 +1,16 @@
+namespace Monitor
+{
+	public interface IMonitor
+	{
+		void DisplayPLCInfo();
+
+		void DisplayTerminalState();
+
+		void DisplayLicensePlate();
+
+		void DisplayImage();
+
+	}
+
+}
+

+ 30 - 0
PLCLinker/WpfApp1/Monitor/Monitor.cs

@@ -0,0 +1,30 @@
+using Monitor;
+
+namespace Monitor
+{
+	public class Monitor : IMonitor
+	{
+		public void DisplayPLCInfo()
+		{
+
+		}
+
+		public void DisplayTerminalState()
+		{
+
+		}
+
+		public void DisplayLicensePlate()
+		{
+
+		}
+
+		public void DisplayImage()
+		{
+
+		}
+
+	}
+
+}
+

+ 17 - 0
PLCLinker/WpfApp1/NumMachine/INumMachineLinker.cs

@@ -0,0 +1,17 @@
+using System.Drawing;
+
+namespace NumMachine
+{
+	public interface INumMachineLinker
+	{
+		string GetLicensePlate(int id);
+
+		Image GetImage(int id);
+
+		void Start();
+
+		void Stop();
+	}
+
+}
+

+ 885 - 0
PLCLinker/WpfApp1/NumMachine/NumMachine.cs

@@ -0,0 +1,885 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Threading;
+using System.Collections;
+using VzClientSDKDemo;
+using System.Runtime.InteropServices;
+using System.IO;
+using System.Net;
+using parkMonitor.entity;
+using System.Diagnostics;
+using System.Threading.Tasks;
+using System.Configuration;
+using WpfApp1.Entry;
+
+namespace NumMachine
+{
+
+    /// <summary>
+    /// 号牌机通信类
+    /// </summary>
+    public partial class NumMachineLinker : INumMachineLinker
+    {
+        /// <summary>
+        /// 刷新时间间隔与个数
+        /// </summary>
+        public const int REFRESHINGTIME = 500, FILTERINGNUMBER = 8;
+        ///<summary>通过设备句柄访问pic;链接时add,系统关闭时remove</summary>
+        private static Dictionary<int, IntPtr> devPicMap = new Dictionary<int, IntPtr>();
+        ///<summary>通过名字获取pic对象;创建pic时add,系统关闭remove</summary>
+        private static Dictionary<string, IntPtr> namePicMap = new Dictionary<string, IntPtr>();
+        ///<summary>通过ip获取设备id;产生ip时创建</summary>
+        private static Dictionary<string, int> ipIdMap = new Dictionary<string, int>();
+        ///<summary>通过ip获取设备句柄;产生句柄时创建</summary>
+        private static Dictionary<string, int> ipHandleMap = new Dictionary<string, int>();
+        /// <summary>句柄到号牌回调映射</summary>
+        private static Dictionary<int, VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK> handleCallbackMap = new Dictionary<int, VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK>();
+        ///<summary>号牌队列</summary>
+        private static Queue<NumberMachineNode> LicBuffer = new Queue<NumberMachineNode>();
+        ///<summary>计数Map</summary>
+        private static Dictionary<string, Dictionary<NumberMachineNode, int>> filterMap = new Dictionary<string, Dictionary<NumberMachineNode, int>>();
+        /// <summary>号牌机编号与激活计数</summary>
+        private Dictionary<int, int> idCountMap = new Dictionary<int, int>();
+        /// <summary>筛选计数</summary>
+        private static int filterCount = 0;
+        private static double filterRatio = 0.7;
+        /// <summary>系统关闭</summary>
+        private static bool isClosing = false;
+        /// <summary>开启拍照的设备</summary>
+        private static int snapshotDevHandle = -1;
+        /// <summary>允许无号牌时拍照</summary>
+        private static bool enableEmptySnapshot = true;
+
+        private static NumberMachineMessage nmMsg = new NumberMachineMessage();
+        private static VzClientSDK.VZLPRC_FIND_DEVICE_CALLBACK_EX find_DeviceCB = null;
+        private const int MSG_PLATE_INFO = 0x901;
+        private const int MSG_DEVICE_INFO = 0x902;
+        /// <summary>
+        /// 用于消息传递机制
+        /// </summary>
+        //public static IntPtr hwndMain;
+
+        public static IntPtr flowLayoutPanel1;
+
+        public static ToolStripStatusLabel timeLabel;
+        /// <summary>
+        /// 号牌机类构造函数
+        /// </summary>
+        public NumMachineLinker(IntPtr flpHandle)
+        {
+            //Control.CheckForIllegalCrossThreadCalls = false;
+            //Thread thread = new Thread(new ThreadStart(DateTimeInfo));
+            //thread.IsBackground = true;
+            //thread.Start(); //显示当前时间            
+            flowLayoutPanel1 = flpHandle;
+
+
+
+            //timeLabel = new ToolStripStatusLabel();
+
+            try
+            {
+                VzClientSDK.VzLPRClient_Setup();
+                filterRatio = Double.Parse(ConfigurationManager.AppSettings.Get("filterRatio"));
+            }
+            catch (Exception e) { Console.WriteLine(e.Message + ",号牌机配置文件异常"); }
+            //m_sAppPath = System.IO.Directory.GetCurrentDirectory();
+        }
+
+        /// <summary>
+        /// 定义时钟委托
+        /// </summary>
+        public delegate void SetDateTime();
+
+        /// <summary>
+        /// 实时采集
+        /// </summary>
+        public delegate void Begin_Read();
+
+        private void FormSiemens_Load(object sender, EventArgs e)
+        {
+            //Thread thread = new Thread(new ThreadStart(DateTimeInfo));
+            //thread.IsBackground = true;
+            //thread.Start(); //显示当前时间            
+
+            //VzClientSDK.VzLPRClient_Setup();
+
+            //hwndMain = this.Handle;
+            //m_sAppPath = System.IO.Directory.GetCurrentDirectory();
+            //this.ShowInTaskbar = false;
+            //this.Opacity = 0;
+
+        }
+
+        private void FormSiemens_FormClosing(object sender, FormClosingEventArgs e)
+        {
+            Stop();
+        }
+
+        private void DateTimeInfo()
+        {
+            try
+            {
+                while (!isClosing)
+                {
+                    SetDateTime setDate = new SetDateTime(
+                    delegate
+                    {
+                        timeLabel.Text = DateTime.Now.ToString();
+                    });
+                    setDate();
+                    Thread.Sleep(1000);
+                }
+                // ReSharper disable once FunctionNeverReturns
+            }
+            catch (Exception e) { Debug.Print(e.StackTrace); }
+        }
+
+        //******************************************************************************************************************
+        private void UpdateStatus(NumberMachineNode nmn)
+        {
+            //提示次数计数
+            int count = 0;
+            while (!isClosing)
+            {
+                if (GetStatus(nmn.ip) == 1)
+                {
+                    nmn.status = EnumNumberMachineStatus.Normal;
+                    count = 0;
+                }
+                else
+                {
+                    count++;
+                    //号牌机断线写日志
+                    nmn.status = EnumNumberMachineStatus.Offline;
+                    if (count == 1)
+                    {
+                        Console.WriteLine("正在与ip为 " + nmn.ip + " 的号牌机 进行连接。");
+                    }
+                    else if (count == 30)
+                    {
+                        nmMsg.data.Remove(nmn);
+                    }
+                    Thread.Sleep(10000);
+                }
+            }
+        }
+
+        private void Run()
+        {
+            try
+            {
+                while (!isClosing)
+                {
+                    Thread.Sleep(REFRESHINGTIME);
+                    //定时更新号牌
+                    lock (devPicMap)
+                    {
+                        Dictionary<int, IntPtr>.Enumerator devEnumer = devPicMap.GetEnumerator();
+                        while (devEnumer.MoveNext())
+                        {
+                            ActivateSnap(devEnumer.Current.Key);
+                            //Debug.WriteLine(lv.data.Count.ToString()+":\n"+ lv.data[lv.data.Count-1].LicenseNum+ lv.data[lv.data.Count - 1].TimeRecord);
+                        }
+                    }
+                    //读取设备ip与id映射关系
+                    lock (ipHandleMap)
+                    {
+                        Dictionary<string, int>.Enumerator ipEnumer = ipHandleMap.GetEnumerator();
+                        while (ipEnumer.MoveNext())
+                        {
+                            //映射关系不存在则读取配置文件
+                            lock (ipIdMap)
+                            {
+                                if (ipEnumer.Current.Key != null && !ipIdMap.ContainsKey(ipEnumer.Current.Key))
+                                {
+                                    try
+                                    {
+                                        int id = Int32.Parse(ConfigurationManager.AppSettings.Get(ipEnumer.Current.Key));
+                                        ipIdMap.Add(ipEnumer.Current.Key, id);
+                                        idCountMap.Add(id, FILTERINGNUMBER);
+                                    }
+                                    catch (Exception) { Console.WriteLine("读取号牌机编号映射失败,配置文件填写有误"); }
+                                }
+                            }
+                        }
+                    }
+                    lock (LicBuffer)
+                    {
+                        //删除已停好车的号牌
+                        for (int i = 0; i < LicBuffer.Count; i++)
+                        {
+                            NumberMachineNode n = (NumberMachineNode)LicBuffer.Dequeue().Clone();
+                            if (n.ip != "")
+                            {
+                                LicBuffer.Enqueue((NumberMachineNode)n.Clone());
+                            }
+                        }
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                Debug.WriteLine(ex.ToString());
+            }
+        }
+
+        ///<summary>寻找设备回调函数</summary>
+        private void FIND_DEVICE_CALLBACK_EX(string pStrDevName, string pStrIPAddr, ushort usPort1, ushort usPort2, uint SL, uint SH, string netmask, string gateway, IntPtr pUserData)
+        {
+            string pStrDev = pStrIPAddr.ToString() + ":" + usPort1.ToString();
+            string serialNO = SL.ToString() + ":" + SH.ToString() + ":" + netmask + ":" + gateway;
+
+            VzClientSDK.VZ_LPR_DEVICE_INFO device_info = new VzClientSDK.VZ_LPR_DEVICE_INFO();
+            device_info.device_ip = pStrDev;
+            device_info.serial_no = serialNO;
+            DeviceLink(pStrDev, serialNO);
+        }
+
+        ///<summary>与设备连接,启动更新设备状态线程,输出视频</summary>
+        private void DeviceLink(string pStrDev, string serialNO)
+        {
+            IPEndPoint ipe;
+            GetIpEndPoint(pStrDev, out ipe);
+            string ip = ipe.Address.ToString();
+            if (ipHandleMap.ContainsKey(ip))
+            {
+                //MessageBox.Show("设备已分配句柄");
+                return;
+            }
+            int handle = 0;
+            //找到设备,加入list
+            NumberMachineNode node = new NumberMachineNode(ip, 0, "", "", 1);
+            nmMsg.data.Add(node);
+            handle = VzClientSDK.VzLPRClient_Open(ip, (ushort)80, "admin", "admin");
+            Task.Factory.StartNew(() =>
+            {
+                UpdateStatus(node);
+            });
+            if (handle == 0)
+            {
+                return;
+            }
+
+            VzClientSDK.VzLPRClient_SetVideoEncodeType(handle, 0);
+            //将句柄加入
+            lock (ipHandleMap)
+            {
+                ipHandleMap.Add(ip, handle);
+            }
+            //MessageBox.Show("摄像头打开成功");
+            lock (handleCallbackMap)
+            {
+                handleCallbackMap.Add(handle, null);
+            }
+            //链接句柄到新PictureBox
+            VideoOutput(handle);
+        }
+
+        ///<summary>视频输出</summary>
+        private void VideoOutput(int handle)
+        {
+            try
+            {
+                lock (devPicMap)
+                {
+                    lock (handleCallbackMap)
+                    {
+                        //存在设备则复位并在原pic上输出
+                        if (devPicMap.ContainsKey(handle))
+                        {
+                            VzClientSDK.VzLPRClient_SetPlateInfoCallBack(handle, null, IntPtr.Zero, 0);
+                            IntPtr pic;
+                            if (devPicMap.TryGetValue(handle, out pic) && handleCallbackMap.ContainsKey(handle))
+                            {
+                                int playHandle = VzClientSDK.VzLPRClient_StartRealPlay(handle, pic);
+                                // 设置车牌识别结果回调
+                                handleCallbackMap[handle] = new VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK(OnPlateResult);
+                                VzClientSDK.VzLPRClient_SetPlateInfoCallBack(handle, handleCallbackMap[handle], IntPtr.Zero, 1);
+                                //m_PlateResultCB = new VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK(OnPlateResult);
+                                //VzClientSDK.VzLPRClient_SetPlateInfoCallBack(handle, m_PlateResultCB, IntPtr.Zero, 1);
+                                //VzClientSDK.VzLPRClient_StopRealPlay(handle);
+                            }
+                        }
+                        else//否则找一个空位加pic
+                        {
+                            for (int i = 0; i < 20; i++)
+                            {
+                                string str = "PictureBox" + Convert.ToString(i);
+                                //该名称对应控件不存在,则创建并链接pic
+                                lock (namePicMap)
+                                {
+                                    if (!namePicMap.ContainsKey(str) && handleCallbackMap.ContainsKey(handle))
+                                    {
+                                        IntPtr pic;
+                                        if (CreatePic(i, out pic))
+                                        {
+                                            devPicMap.Add(handle, pic);
+                                            //ipIdMap.Add(Get_IP(handle), i);
+                                            VzClientSDK.VzLPRClient_SetPlateInfoCallBack(handle, null, IntPtr.Zero, 0);
+                                            //Console.WriteLine(handle+","+pic.ToString());
+                                            int playHandle = VzClientSDK.VzLPRClient_StartRealPlay(handle, pic);
+                                            // 设置车牌识别结果回调
+                                            handleCallbackMap[handle] = new VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK(OnPlateResult);
+                                            VzClientSDK.VzLPRClient_SetPlateInfoCallBack(handle, handleCallbackMap[handle], IntPtr.Zero, 1);
+                                            //m_PlateResultCB = new VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK(OnPlateResult);
+                                            //VzClientSDK.VzLPRClient_SetPlateInfoCallBack(handle, m_PlateResultCB, IntPtr.Zero, 1);
+                                            //VzClientSDK.VzLPRClient_StopRealPlay(handle);
+                                            break;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            catch (Exception e)
+            {
+                Debug.WriteLine(e.Message + ",jumped out");
+            }
+        }
+
+        ///<summary>号牌信息回调</summary>
+        private int OnPlateResult(int handle, IntPtr pUserData,
+                                                IntPtr pResult, uint uNumPlates,
+                                                VzClientSDK.VZ_LPRC_RESULT_TYPE eResultType,
+                                                IntPtr pImgFull,
+                                                IntPtr pImgPlateClip)
+        {
+            if (eResultType != VzClientSDK.VZ_LPRC_RESULT_TYPE.VZ_LPRC_RESULT_REALTIME)
+            {
+                VzClientSDK.TH_PlateResult result = (VzClientSDK.TH_PlateResult)Marshal.PtrToStructure(pResult, typeof(VzClientSDK.TH_PlateResult));
+                string strLicense = (new string(result.license)).Split('\0')[0];
+
+                VzClientSDK.VZ_LPR_MSG_PLATE_INFO plateInfo = new VzClientSDK.VZ_LPR_MSG_PLATE_INFO();
+                plateInfo.plate = strLicense;
+                SetDetail(plateInfo, Get_IP(handle));
+
+                //根据setMessage中通过id信息找到的handle保存图片
+                if (handle == snapshotDevHandle)
+                {
+                    if (enableEmptySnapshot || !strLicense.Contains("_无_"))
+                    {
+                        string strFilePath = ConfigurationManager.AppSettings["LogPath"] + DateTime.Now.ToString("yyyyMMdd") + "\\";
+                        if (!Directory.Exists(strFilePath))
+                        {
+                            Directory.CreateDirectory(strFilePath);
+                        }
+                        string ip = Get_IP(handle);
+                        string path = strFilePath + ip + "-" + DateTime.Now.ToString("hh_mm_ss") + ".jpg";
+                        int temp = VzClientSDK.VzLPRClient_ImageSaveToJpeg(pImgFull, path, 50);
+                        if (temp != -1)
+                        {
+                            Console.WriteLine("号牌机" + ip + "已拍照,图片保存于 " + strFilePath);
+                        }
+                        else
+                        {
+                            Console.WriteLine("图片保存失败");
+                        }
+                    }
+                    snapshotDevHandle = -1;
+                }
+            }
+
+            return 0;
+        }
+
+        ///<summary>记录车牌,时间,状态信息;刷新本地entity,并且入buffer</summary>
+        private void SetDetail(VzClientSDK.VZ_LPR_MSG_PLATE_INFO plateInformation, string strIP)
+        {
+            int stat = GetStatus(strIP);
+            bool found = false;
+            int id = 0;
+            lock (ipIdMap)
+            {
+                if (!ipIdMap.ContainsKey(strIP))
+                {
+                    try
+                    {
+                        id = Int32.Parse(ConfigurationManager.AppSettings.Get(strIP));
+                        ipIdMap.Add(strIP, id);
+                        idCountMap.Add(id, FILTERINGNUMBER);
+                    }
+                    catch (Exception) { Console.WriteLine("读取号牌机编号映射失败,配置文件填写有误"); }
+                }
+            }
+            //检查设备是否存在
+            foreach (NumberMachineNode nmn in nmMsg.data)
+            {
+                //相同设备
+                if (nmn.ip == strIP)
+                {
+                    found = true;
+                    //号牌不为空
+                    if (!(plateInformation.plate.Contains("_无_")))
+                    {
+                        nmn.SetLic(strIP, nmn.id, plateInformation.plate, DateTime.Now.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss"), GetStatus(strIP));
+                        FilterLic(strIP, (NumberMachineNode)nmn.Clone());
+                    }
+                    //号牌为空
+                    else
+                    {
+                        nmn.SetLic(strIP, nmn.id, "", "", GetStatus(strIP));
+                        FilterLic(strIP, null);
+                    }
+                }
+            }
+            //新设备
+            if (!found)
+            {
+                lock (ipIdMap)
+                {
+                    if (!(plateInformation.plate.Contains("_无_")) && ipIdMap.TryGetValue(strIP, out id))
+                    {
+                        NumberMachineNode nmn = new NumberMachineNode(strIP, id, plateInformation.plate, DateTime.Now.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss"), GetStatus(strIP));
+                        NumberMachineNode nmnc = (NumberMachineNode)nmn.Clone();
+                        nmMsg.data.Add(nmnc);
+                        FilterLic(strIP, nmnc);
+                    }
+                    else
+                    {
+                        nmMsg.data.Add(new NumberMachineNode(strIP, id, "", "", GetStatus(strIP)));
+                        FilterLic(strIP, null);
+                    }
+                }
+            }
+        }
+
+        ///<summary>筛选号牌</summary>
+        private void FilterLic(string ip, NumberMachineNode nmn)
+        {
+            int id = 0, activeCount = 0;
+            if (ipIdMap.TryGetValue(ip, out id) && idCountMap.TryGetValue(id, out activeCount) && activeCount < FILTERINGNUMBER)
+            {
+                Dictionary<NumberMachineNode, int> filter;
+                //该filter不存在则创建
+                if (!filterMap.ContainsKey(ip))
+                {
+                    filter = new Dictionary<NumberMachineNode, int>();
+                    filterMap.Add(ip, filter);
+                }
+                else if (!filterMap.TryGetValue(ip, out filter))//计数器异常
+                {
+                    return;
+                }
+                else if (activeCount == 0) //刚接到拍摄命令
+                {
+                    filter.Clear();
+                }
+
+                //激活次数统计
+                idCountMap[id] = activeCount + 1;
+
+                //filter计数
+                int count = 0;
+                if (nmn == null)
+                {
+                    if (activeCount >= FILTERINGNUMBER - 1)
+                    {
+                        //UILogServer.ins.error("本轮未扫描到号牌,请重新点击按钮停车");
+                        //string context = System.DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ":" + "号牌未扫描到,请重发指令";
+                        //string sql = "insert into messagequeue(userID,context,messageType) values (1,'" + context + "',1)";
+                        //List<string> strs = new List<string>();
+                        //strs.Add(sql);
+                        //DBOperation.InsertMessageQueue(EntityForCore.remoteBQ, strs);
+                    }
+                    return;
+                }
+                else if (filter.ContainsKey(nmn) && filter.TryGetValue(nmn, out count))//存在则数量+1
+                {
+                    filter[nmn] = count + 1;
+                }
+                else//不存在则计数1
+                {
+                    filter.Add(nmn, 1);
+                }
+
+                //计算总数
+                filterCount = 0;
+                Dictionary<NumberMachineNode, int>.Enumerator countEnumer = filter.GetEnumerator();
+                while (countEnumer.MoveNext())
+                {
+                    filterCount += countEnumer.Current.Value;
+                }
+
+                //达到计数限制,计算总数是否达标,达标则入队
+                if (filterCount >= FILTERINGNUMBER)
+                {
+                    lock (LicBuffer)
+                    {
+                        Dictionary<NumberMachineNode, int>.Enumerator enumer = filter.GetEnumerator();
+                        int maxCount = 0;
+                        NumberMachineNode node = null;
+                        while (enumer.MoveNext())
+                        {
+                            ////遍历,计数达标且队列中无此号牌
+                            //if (enumer.Current.Value >= (int)(filterCount * filterRatio) && enumer.Current.Key != null && !LicBuffer.Contains(enumer.Current.Key))
+                            //找到最大计数及相应号牌信息
+                            if (enumer.Current.Value >= maxCount && enumer.Current.Key != null && !LicBuffer.Contains(enumer.Current.Key))
+                            {
+                                //输出节点为空或与该号牌不同
+                                if (nmMsg.aNode == null || nmMsg.aNode.LicenseNum == null || nmMsg.aNode.LicenseNum != enumer.Current.Key.LicenseNum)
+                                {
+                                    maxCount = enumer.Current.Value;
+                                    node = (NumberMachineNode)enumer.Current.Key.Clone();
+                                    if (node != null && ipIdMap.TryGetValue(node.ip, out node.id))
+                                    {
+                                        LicBuffer.Enqueue((NumberMachineNode)node.Clone());
+                                        if (node.id == 1)
+                                        {
+                                            Task.Factory.StartNew(() =>
+                                            {
+                                                if (SystemInitializer.allInOneMachine != null)
+                                                {
+                                                    SystemInitializer.allInOneMachine.Play(1, BroadcastModule.BroadcastBoard.PlayMode.temporary, node.LicenseNum, 6);
+                                                    SystemInitializer.allInOneMachine.Play(1, BroadcastModule.BroadcastBoard.PlayMode.audio, node.LicenseNum + ",入场");
+                                                    Thread.Sleep(5000);
+                                                    SystemInitializer.allInOneMachine.Play(1, BroadcastModule.BroadcastBoard.PlayMode.readBuffer, "", 0, 0);
+                                                }
+                                            });
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    filterCount = 0;
+                    filter.Clear();
+                }
+            }
+        }
+
+        ///<summary>停止播放与设备句柄关联的视频</summary>
+        private void StopPlay(int handleInput)
+        {
+            if (handleInput != 0)
+            {
+                int ret = VzClientSDK.VzLPRClient_StopRealPlay(handleInput);
+            }
+        }
+
+        ///<summary>强制获取号牌</summary>
+        private void ActivateSnap(int handle)
+        {
+            if (handle > 0)
+            {
+                VzClientSDK.VzLPRClient_ForceTrigger(handle);
+            }
+
+        }
+
+        ///<summary>ip+port字符串转ipe</summary>
+        private void GetIpEndPoint(string ipp, out IPEndPoint ipe)
+        {
+            IPAddress myIP = IPAddress.Parse(ipp.Remove(ipp.LastIndexOf(':')) + "");
+            string myPort = ipp.Substring(ipp.IndexOf(':') + 1);
+            ipe = new IPEndPoint(myIP, int.Parse(myPort));
+        }
+
+        ///<summary>创建新pic并记录在picNameMap</summary>
+        private bool CreatePic(int index, out IntPtr pic)
+        {
+            pic = IntPtr.Zero;
+            PictureBox pb = new PictureBox
+            {
+                Width = 230,
+                Height = 180,
+                Bounds = new System.Drawing.Rectangle(0, 0, 230, 180),
+                Name = "PictureBox" + Convert.ToString(index)
+            };
+            lock (namePicMap)
+            {
+                if (!namePicMap.ContainsKey(pb.Name))
+                {
+                    PictureBox temp = pb;
+                    IntPtr picHandle = IntPtr.Zero;
+                    try
+                    {
+                        Control flp = Control.FromHandle(flowLayoutPanel1);
+
+                        //Control.FromHandle(flowLayoutPanel1).Controls.Add(temp);
+                        if (flp.InvokeRequired)
+                        {
+                            flp.Invoke(new Action(() => { flp.Controls.Add(temp); picHandle = temp.Handle; }));
+                        }
+                        else
+                        {
+                            flp.Controls.Add(pb);
+                        }
+                    }
+                    catch (Exception e) { Console.WriteLine(e.Message); }
+                    namePicMap.Add(pb.Name, picHandle);
+                    pic = picHandle;
+                    //Console.WriteLine(picHandle.ToString());
+                    return true;
+                }
+                else
+                    return false;
+            }
+        }
+
+        ///<summary>更新设备状态</summary>
+        private int GetStatus(string devIP)
+        {
+            int myHandle;
+            byte stat = 0;
+            if (ipHandleMap.TryGetValue(devIP, out myHandle))
+            {
+                VzClientSDK.VzLPRClient_IsConnected(myHandle, ref stat);
+                return stat;
+            }
+            return -1;
+        }
+
+        private string Get_IP(int lprHandle)
+        {
+            byte[] strDecIP = new byte[32];
+            int max_count = 32;
+            int ret = VzClientSDK.VzLPRClient_GetDeviceIP(lprHandle, ref strDecIP[0], max_count);
+            string strIP = System.Text.Encoding.Default.GetString(strDecIP);
+            strIP = strIP.TrimEnd('\0');
+            return strIP;
+        }
+
+        private bool NodeValidation(NumberMachineNode node)
+        {
+            return (node != null && node.ip != null && node.ip != "" && node.ip != "used" && node.LicenseNum != null && node.LicenseNum != "") ? true : false;
+        }
+
+        /// <summary>
+        /// 系统启动
+        /// </summary>
+        public void Start()
+        {
+
+            Task.Factory.StartNew(() =>
+            {
+                isClosing = false;
+
+                try
+                {
+                    VzClientSDK.VZLPRClient_StopFindDevice();
+
+                    find_DeviceCB = new VzClientSDK.VZLPRC_FIND_DEVICE_CALLBACK_EX(FIND_DEVICE_CALLBACK_EX);
+                    int ret = VzClientSDK.VZLPRClient_StartFindDeviceEx(find_DeviceCB, IntPtr.Zero);
+                }
+                catch (Exception ex)
+                {
+                    Debug.WriteLine(ex.ToString());
+                }
+            });
+
+            Task.Factory.StartNew(() =>
+            {
+                Run();
+            });
+            //Task imgTest = Task.Factory.StartNew(() =>
+            //{
+            //    while (!isClosing)
+            //    {
+            //        Command cmd = new Command
+            //        {
+            //            id = 1
+            //        };
+            //        SetMessage(cmd);
+            //        Thread.Sleep(30000);
+            //        Command cmd2 = new Command
+            //        {
+            //            id = 2
+            //        };
+            //        SetMessage(cmd2);
+            //        Thread.Sleep(30000);
+            //    }
+            //});
+
+        }
+
+        /// <summary>
+        /// 系统关闭
+        /// </summary>
+        public void Stop()
+        {
+            VzClientSDK.VZLPRClient_StopFindDevice();
+            lock (devPicMap)
+            {
+                Dictionary<int, IntPtr>.Enumerator enumer = devPicMap.GetEnumerator();
+                while (enumer.MoveNext())
+                {
+                    if (enumer.Current.Key != 0)
+                    {
+                        StopPlay(enumer.Current.Key);
+                        VzClientSDK.VzLPRClient_Close(enumer.Current.Key);
+                        //flowLayoutPanel1.Controls.Remove(enumer.Current.Value);
+                    }
+                }
+                isClosing = true;
+                devPicMap.Clear();
+            }
+            lock (namePicMap) { namePicMap.Clear(); }
+            lock (ipIdMap) { ipIdMap.Clear(); }
+            lock (ipHandleMap) { ipHandleMap.Clear(); }
+            //this.Close();
+        }
+
+        /// <summary>
+        /// 监控线程获取号牌机信息,核心线程获取号牌信息
+        /// </summary>
+        public AbstractMessage GetMessage()
+        {
+            lock (LicBuffer)
+            {
+                //准备输出的数据中存在非法Node,且LicBuffer可出队产生一个合法Node,则替换该非法Node
+                if (!NodeValidation(nmMsg.aNode))
+                {
+                    for (int i = 0; i < LicBuffer.Count; i++)
+                    {
+                        NumberMachineNode n = LicBuffer.Dequeue();
+                        if (NodeValidation(n))
+                        {
+                            if (nmMsg.aNode != null && nmMsg.aNode.ip != null)
+                            {
+                                LicBuffer.Enqueue((NumberMachineNode)nmMsg.aNode.Clone());
+                            }
+                            nmMsg.aNode = n;
+                            break;
+                        }
+                        else
+                        {
+                            LicBuffer.Enqueue(n);
+                        }
+                    }
+                    //遍历licBuffer后仍不合法,则丢入队列,将node置为null
+                    if (!NodeValidation(nmMsg.aNode))
+                    {
+                        if (nmMsg.aNode != null && nmMsg.aNode.ip != null)
+                        {
+                            LicBuffer.Enqueue((NumberMachineNode)nmMsg.aNode.Clone());
+                        }
+                        nmMsg.aNode = null;
+                    }
+                }
+            }
+            return nmMsg;
+        }
+
+        /// <summary>
+        /// 一次停车流程完成时调用该方法,发送已完成车辆号牌信息
+        /// </summary>
+        /// <param name="message">已完成车辆的号牌相关信息存于message的aNode中,用于标记需清空的号牌</param>
+        public void SetMessage(AbstractMessage message)
+        {
+            if (message.GetType().Equals(typeof(NumberMachineMessage)))
+            {
+                NumberMachineNode n = ((NumberMachineMessage)message).aNode;
+                lock (LicBuffer)
+                {
+                    //输入号牌格式无误
+                    if (n != null && n.ip != null && n.ip == "")
+                    {
+                        //与类成员变量中aNode号牌相同,将其ip复位表示已使用,重新入队等待清除
+                        if (nmMsg != null && nmMsg.aNode != null && nmMsg.aNode.LicenseNum == n.LicenseNum)
+                        {
+                            nmMsg.aNode.ip = "";
+                            LicBuffer.Enqueue((NumberMachineNode)nmMsg.aNode.Clone());
+                            nmMsg.aNode = null;
+                        }
+                        //搜索号牌队列,将相应号牌置空,准备清除
+                        else
+                        {
+                            for (int i = 0; i < LicBuffer.Count; i++)
+                            {
+                                NumberMachineNode temp = LicBuffer.Dequeue();
+                                //已匹配上,ip置空
+                                if (temp.LicenseNum == n.LicenseNum)
+                                {
+                                    temp.ip = "";
+                                    LicBuffer.Enqueue(temp);
+                                    break;
+                                }
+                                LicBuffer.Enqueue(temp);
+                            }
+                        }
+                    }
+                }
+            }
+
+            if (message.GetType().Equals(typeof(Command)))
+            {
+                Command cmd = (Command)message;
+                if (cmd != null && cmd.id != 0)
+                {
+                    //拍照功能根据ip找到handle,改变snapshotDevHandle的值在回调函数中截图
+                    lock (ipIdMap)
+                    {
+                        Dictionary<string, int>.Enumerator enumerator = ipIdMap.GetEnumerator();
+                        while (enumerator.MoveNext())
+                        {
+                            // if (enumerator.Current.Value == cmd.id && ipHandleMap.TryGetValue(enumerator.Current.Key, out int handle))
+                            int handle = 0;
+                            if (enumerator.Current.Value == cmd.id && ipHandleMap.TryGetValue(enumerator.Current.Key, out handle))
+                            {
+                                snapshotDevHandle = handle;
+                                break;
+                            }
+                        }
+                    }
+                }
+                else
+                {
+                    Console.WriteLine("参数错误,图片未保存");
+                }
+            }
+        }
+
+        public string GetLicensePlate(int id)
+        {
+            string license = "";
+            //将相应计数器归零,启动号牌记录
+            lock (idCountMap)
+            {
+                if (idCountMap.ContainsKey(id))
+                {
+                    idCountMap[id] = 0;
+                }
+            }
+            Task.Factory.StartNew(() =>
+            {
+                NumberMachineNode node = null;
+                int timeLimit = 8;
+                while (node == null && timeLimit-- > 0)
+                {
+                    lock (LicBuffer)
+                    {
+                        for (int i = 0; i < LicBuffer.Count; i++)
+                        {
+                            node = LicBuffer.Dequeue();
+                            if (node != null)
+                            {
+                                if (node.id == id)
+                                {
+                                    license = node.LicenseNum;
+                                    break;
+                                }
+                                else
+                                {
+                                    LicBuffer.Enqueue(node);
+                                }
+                            }
+                        }
+                    }
+                    Thread.Sleep(1000);
+                }
+            }).Wait();
+            return license;
+        }
+
+        public Image GetImage(int id)
+        {
+            return null;
+        }
+    }
+
+}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2287 - 0
PLCLinker/WpfApp1/NumMachine/VzClientSDK.cs


+ 8 - 9
PLCLinker/parkMonitor/Properties/AssemblyInfo.cs

@@ -3,16 +3,15 @@ using System.Resources;
 using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 using System.Windows;
-using System.Windows.Markup;
 
 // 有关程序集的一般信息由以下
 // 控制。更改这些特性值可修改
 // 与程序集关联的信息。
-[assembly: AssemblyTitle("parkMonitor")]
+[assembly: AssemblyTitle("WpfApp1")]
 [assembly: AssemblyDescription("")]
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("Microsoft")]
-[assembly: AssemblyProduct("parkMonitor")]
+[assembly: AssemblyProduct("WpfApp1")]
 [assembly: AssemblyCopyright("Copyright © Microsoft 2018")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
@@ -33,12 +32,12 @@ using System.Windows.Markup;
 
 
 [assembly: ThemeInfo(
-	ResourceDictionaryLocation.None, //主题特定资源词典所处位置
-									 //(未在页面中找到资源时使用,
-									 //或应用程序资源字典中找到时使用)
-	ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置
-											  //(未在页面中找到资源时使用,
-											  //、应用程序或任何主题专用资源字典中找到时使用)
+    ResourceDictionaryLocation.None, //主题特定资源词典所处位置
+                                     //(未在页面中找到资源时使用,
+                                     //或应用程序资源字典中找到时使用)
+    ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置
+                                              //(未在页面中找到资源时使用,
+                                              //、应用程序或任何主题专用资源字典中找到时使用)
 )]
 
 

+ 63 - 0
PLCLinker/WpfApp1/Properties/Resources.Designer.cs

@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     此代码由工具生成。
+//     运行时版本:4.0.30319.42000
+//
+//     对此文件的更改可能会导致不正确的行为,并且如果
+//     重新生成代码,这些更改将会丢失。
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace WpfApp1.Properties {
+    using System;
+    
+    
+    /// <summary>
+    ///   一个强类型的资源类,用于查找本地化的字符串等。
+    /// </summary>
+    // 此类是由 StronglyTypedResourceBuilder
+    // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
+    // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
+    // (以 /str 作为命令选项),或重新生成 VS 项目。
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   返回此类使用的缓存的 ResourceManager 实例。
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WpfApp1.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   使用此强类型资源类,为所有资源查找
+        ///   重写当前线程的 CurrentUICulture 属性。
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+    }
+}

+ 4 - 7
PLCLinker/parkMonitor/view/FormModbus/RVideoCfg_Form.resx

@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <root>
   <!-- 
     Microsoft ResX Schema 
@@ -46,7 +46,7 @@
     
     mimetype: application/x-microsoft.net.object.binary.base64
     value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : System.Serialization.Formatters.Binary.BinaryFormatter
             : and then encoded with base64 encoding.
     
     mimetype: application/x-microsoft.net.object.soap.base64
@@ -60,7 +60,6 @@
             : and then encoded with base64 encoding.
     -->
   <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
     <xsd:element name="root" msdata:IsDataSet="true">
       <xsd:complexType>
         <xsd:choice maxOccurs="unbounded">
@@ -69,10 +68,9 @@
               <xsd:sequence>
                 <xsd:element name="value" type="xsd:string" minOccurs="0" />
               </xsd:sequence>
-              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
               <xsd:attribute name="type" type="xsd:string" />
               <xsd:attribute name="mimetype" type="xsd:string" />
-              <xsd:attribute ref="xml:space" />
             </xsd:complexType>
           </xsd:element>
           <xsd:element name="assembly">
@@ -87,10 +85,9 @@
                 <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                 <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
               </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
               <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
               <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-              <xsd:attribute ref="xml:space" />
             </xsd:complexType>
           </xsd:element>
           <xsd:element name="resheader">

+ 2 - 2
PLCLinker/parkMonitor/Properties/Settings.Designer.cs

@@ -8,11 +8,11 @@
 // </auto-generated>
 //------------------------------------------------------------------------------
 
-namespace parkMonitor.Properties {
+namespace WpfApp1.Properties {
     
     
     [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.6.0.0")]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.5.0.0")]
     internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
         
         private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));

+ 7 - 0
PLCLinker/WpfApp1/Properties/Settings.settings

@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>

+ 20 - 0
PLCLinker/WpfApp1/SuperAdmin/ISuperAdmin.cs

@@ -0,0 +1,20 @@
+
+
+using System.Collections.Generic;
+
+namespace SuperAdmin
+{
+	public interface ISuperAdmin
+	{
+		void Login();
+
+		List<object> DisplayReport();
+
+		void PrintReport();
+
+		void ExportReport(int page);
+
+	}
+
+}
+

+ 31 - 0
PLCLinker/WpfApp1/SuperAdmin/SuperAdmin.cs

@@ -0,0 +1,31 @@
+using SuperAdmin;
+using System.Collections.Generic;
+
+namespace SuperAdmin
+{
+	public class SuperAdmin : ISuperAdmin
+	{
+		public void Login()
+		{
+
+		}
+
+		public List<object> DisplayReport()
+		{
+			return null;
+		}
+
+		public void PrintReport()
+		{
+
+		}
+
+		public void ExportReport(int page)
+		{
+
+		}
+
+	}
+
+}
+

+ 18 - 0
PLCLinker/WpfApp1/Terminal/ITerminalDisplay.cs

@@ -0,0 +1,18 @@
+
+
+using System.Collections.Generic;
+
+namespace Terminal
+{
+	public interface ITerminalDisplay
+	{
+		void GetTerminalState();
+
+		List<object> GetParkingRecords();
+
+		List<object> GetOrderRecords();
+
+	}
+
+}
+

+ 46 - 0
PLCLinker/WpfApp1/Terminal/Terminal.cs

@@ -0,0 +1,46 @@
+using Terminal;
+using DatabaseDLL;
+using System.Collections.Generic;
+
+namespace Terminal
+{
+	public class Terminal : ITerminalDisplay
+	{
+		private int terminalID;
+
+		private Terminal terminal;
+
+		public void FeeCal()
+		{
+
+		}
+
+		public void GetTerminalState()
+		{
+
+		}
+
+		public List<object> GetParkingRecords()
+		{
+			return null;
+		}
+
+		public List<object> GetOrderRecords()
+		{
+			return null;
+		}
+
+		private object SearchPaymentScheme()
+		{
+			return null;
+		}
+
+		private void UpdateParkingRecords(int Object)
+		{
+
+		}
+
+	}
+
+}
+

+ 64 - 36
PLCLinker/parkMonitor/server/WebThread/CentralForWebSocketServer.cs

@@ -9,15 +9,13 @@ using System.Net.Sockets;
 using System.Net;
 using System.Threading;
 using parkMonitor.tools;
-using parkMonitor.server.uiLogServer;
-using parkMonitor.LOG;
 
-namespace parkMonitor.server.WebThread
+namespace WebServer
 {
     /// <summary>
     /// web线程类,接收用户指令
     /// </summary>
-    public class CentralForWeb : IEquipments
+    public class CentralForWeb : IWebServer
     {
         public MultiSocketThread multiSocketThread { set; get; }
         public static BlockingQueue blockingQueue = new BlockingQueue();
@@ -25,15 +23,10 @@ namespace parkMonitor.server.WebThread
         IPAddress localAddr;
         bool isClosing;
 
-        public AbstractMessage GetMessage()
-        {
-            return (AbstractMessage)blockingQueue.Dequeue();
-        }
-
-        public void SetMessage(AbstractMessage message)
-        {
-            //multiSocketThread.SendMessage(message);
-        }
+        //public AbstractMessage GetMessage()
+        //{
+        //    return (AbstractMessage)blockingQueue.Dequeue();
+        //}
 
         private void WebConnect(TcpListener listener)
         {
@@ -72,8 +65,8 @@ namespace parkMonitor.server.WebThread
                     listener.Start();
                     linked = true;
                 }
-                catch (Exception) { UILogServer.ins.error("未能与Web服务器连接,本地ip错误或网络异常"); Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "与Web服务器连接失败"); linked = false; }
-                while (!isClosing)
+                catch (Exception) { Console.WriteLine("未能与Web服务器连接,本地ip错误或网络异常"); linked = false; }
+                while (isClosing)
                 {
                     try
                     {
@@ -100,18 +93,16 @@ namespace parkMonitor.server.WebThread
                                 listener = LazySingleton.GetInstance(localAddr, port);
                                 listener.Start();
                                 linked = true;
-                                UILogServer.ins.log("web已成功重连");
-                                Log.WriteLog(LogType.NOT_DATABASE, LogFile.INFO, "web已成功重连");
+                                Console.WriteLine("web已成功重连");
                                 break;
                             }
                             catch (Exception)
                             {
                                 mt.EndTiming();
-                                int count=0;
+                                int count = 0;
                                 if (mt.IsLonger(30, 1, true, out count))
                                 {
-                                    UILogServer.ins.error("未能与Web服务器连接,本地ip错误或网络异常");
-                                    Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "与Web服务器连接失败");
+                                    Console.WriteLine("未能与Web服务器连接,本地ip错误或网络异常");
                                 }
                             }
                         }
@@ -124,32 +115,69 @@ namespace parkMonitor.server.WebThread
             });
         }
 
-        public void Start()
+        private void DownloadAds()
+        {
+
+        }
+        /// <summary>
+        /// 启动
+        /// </summary>
+        public bool Start(int port)
         {
-            string strTemp = ConfigurationManager.AppSettings["WebConfig"];
-            string[] strArray = strTemp.Split(':');
-            string ipstr = strArray[0];
-            string portstr = strArray[1];
 
+            //string strTemp = ConfigurationManager.AppSettings["WebConfig"];
+            //string[] strArray = strTemp.Split(':');
+            //string ipstr = strArray[0];
+            //string portstr = strArray[1];
+            //获取本机ip地址
             try
             {
-                port = Convert.ToInt32(portstr);
-                localAddr = IPAddress.Parse(ipstr);
+                TcpClient client = new TcpClient();
+                client.Connect("www.baidu.com", 80);
+                string ip = ((IPEndPoint)client.Client.LocalEndPoint).Address.ToString();
+                client.Close();
+                localAddr = IPAddress.Parse(ip);
+                this.port = port;//Convert.ToInt32(ConfigurationManager.AppSettings["webPort"]);
+                Console.WriteLine(ip.ToString());
             }
-            catch (Exception) { }
-
-            //Thread thread = new Thread(() =>
-            //{
-
-            //});
-            //thread.IsBackground = true;
-            //thread.Start();
+            catch (Exception e) { Console.WriteLine("wrong ipAddr");return false; }
             Run();
+            return true;
         }
-
+        /// <summary>
+        /// 停止
+        /// </summary>
         public void Stop()
         {
             isClosing = true;
         }
+        /// <summary>
+        /// 停车预约
+        /// </summary>
+        public void ParkBooking()
+        {
+
+        }
+        /// <summary>
+        /// 取车预约
+        /// </summary>
+        public void FetchBooking()
+        {
+
+        }
+        /// <summary>
+        /// 预约停车记录
+        /// </summary>
+        public void bookParkRecord()
+        {
+
+        }
+        /// <summary>
+        /// 预约取车记录
+        /// </summary>
+        public void bookFetchRecord()
+        {
+
+        }
     }
 }

+ 24 - 0
PLCLinker/WpfApp1/WebServer/IWebServer.cs

@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace WebServer
+{
+    public interface IWebServer
+    {
+        bool Start(int port);
+
+        void Stop();
+
+        void ParkBooking();
+
+        void FetchBooking();
+
+        void bookParkRecord();
+
+        void bookFetchRecord();
+
+    }
+}

+ 1 - 1
PLCLinker/parkMonitor/server/WebThread/LazySingleton.cs

@@ -6,7 +6,7 @@ using System.Net.Sockets;
 using System.Text;
 using System.Threading.Tasks;
 
-namespace parkMonitor.server.WebThread
+namespace WebServer
 {
     class LazySingleton
     {

+ 1 - 1
PLCLinker/parkMonitor/server/WebThread/MultiSocketThread.cs

@@ -8,7 +8,7 @@ using System.Threading.Tasks;
 using parkMonitor.Tools;
 using parkMonitor.entity;
 
-namespace parkMonitor.server.WebThread
+namespace WebServer
 {
     public class MultiSocketThread
     {

+ 167 - 0
PLCLinker/WpfApp1/WpfApp1.csproj

@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{4B52BB18-B89A-47C0-A20C-27FF628437FE}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <RootNamespace>WpfApp1</RootNamespace>
+    <AssemblyName>WpfApp1</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <WarningLevel>4</WarningLevel>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="broadcastDLL, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>sdk\broadcast\broadcastDLL.dll</HintPath>
+    </Reference>
+    <Reference Include="DatabaseDLL, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>sdk\mysql\DatabaseDLL.dll</HintPath>
+    </Reference>
+    <Reference Include="HslCommunication">
+      <HintPath>sdk\VZ_Sdk\HslCommunication.dll</HintPath>
+    </Reference>
+    <Reference Include="MySql.Data, Version=6.7.9.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>sdk\mysql\MySql.Data.dll</HintPath>
+    </Reference>
+    <Reference Include="Newtonsoft.Json">
+      <HintPath>sdk\VZ_Sdk\Newtonsoft.Json.dll</HintPath>
+    </Reference>
+    <Reference Include="PLCS7, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>sdk\PLC\PLCS7.dll</HintPath>
+    </Reference>
+    <Reference Include="S7.Net, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d5812d469e84c693, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>sdk\PLC\S7.Net.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Configuration" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xaml">
+      <RequiredTargetFramework>4.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="WindowsBase" />
+    <Reference Include="PresentationCore" />
+    <Reference Include="PresentationFramework" />
+    <Reference Include="WindowsFormsIntegration" />
+  </ItemGroup>
+  <ItemGroup>
+    <ApplicationDefinition Include="App.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </ApplicationDefinition>
+    <Compile Include="Entry\MainEntry.cs" />
+    <Compile Include="entity\AbstractMessage.cs" />
+    <Compile Include="entity\Jsonhelper.cs" />
+    <Compile Include="Entry\SystemInitializer.cs" />
+    <Compile Include="NumMachine\NumMachine.cs" />
+    <Compile Include="SuperAdmin\ISuperAdmin.cs" />
+    <Compile Include="SuperAdmin\SuperAdmin.cs" />
+    <Compile Include="Terminal\ITerminalDisplay.cs" />
+    <Compile Include="Terminal\Terminal.cs" />
+    <Compile Include="tools\BlockingQueue.cs" />
+    <Compile Include="tools\JsonByByteToObjectTools.cs" />
+    <Compile Include="tools\MyTimer.cs" />
+    <Compile Include="NumMachine\VzClientSDK.cs" />
+    <Compile Include="WebServer\CentralForWebSocketServer.cs" />
+    <Compile Include="WebServer\IWebServer.cs" />
+    <Compile Include="WebServer\LazySingleton.cs" />
+    <Compile Include="WebServer\MultiSocketThread.cs" />
+    <Page Include="MainWindow.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Compile Include="App.xaml.cs">
+      <DependentUpon>App.xaml</DependentUpon>
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="MainWindow.xaml.cs">
+      <DependentUpon>MainWindow.xaml</DependentUpon>
+      <SubType>Code</SubType>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Monitor\IMonitor.cs" />
+    <Compile Include="Monitor\Monitor.cs" />
+    <Compile Include="NumMachine\INumMachineLinker.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config">
+      <SubType>Designer</SubType>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="sdk\broadcast\broadcastDLL.dll" />
+    <Content Include="sdk\log4net\log4net.dll" />
+    <Resource Include="sdk\log4net\log4net.xml" />
+    <Content Include="sdk\mysql\MySql.Data.dll" />
+    <Content Include="sdk\PLC\PLCS7.dll" />
+    <Content Include="sdk\PLC\S7.Net.dll" />
+    <Content Include="sdk\VZ_Sdk\iDecoders.dll" />
+    <Content Include="sdk\VZ_Sdk\VzDrawsLib.dll" />
+    <Content Include="sdk\VZ_Sdk\VzLPRSDK.dll" />
+    <Content Include="sdk\VZ_Sdk\VZ_Sdk.dll" />
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="AllinoneMachineModule\" />
+    <Folder Include="Database\" />
+    <Folder Include="PLCModule\" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>

+ 358 - 0
PLCLinker/WpfApp1/entity/AbstractMessage.cs

@@ -0,0 +1,358 @@
+using System;
+using System.Collections.Generic;
+
+namespace parkMonitor.entity
+{
+    /// <summary>
+    /// 抽象消息类
+    /// </summary>
+    public abstract class AbstractMessage
+    {
+    }
+
+    /// <summary>
+    /// 用户指令类,s停,f取,p预约停
+    /// </summary>
+    public class MessageUTF8 : AbstractMessage, ICloneable
+    {
+        public char cmd { set; get; }
+        public string context { set; get; }
+        public string sender { set; get; }
+        public string receiver { set; get; }
+        public int parkingRecordsID { set; get; }
+        public int garageID { get; set; }
+        public string bookTime { get; set; }
+
+        public MessageUTF8()
+        {
+
+        }
+        public MessageUTF8(char cmd, string context, string sender, string receiver, int garageID, int parkingRecordsID, string bookTime)
+        {
+            this.cmd = cmd;
+            this.context = context;
+            this.sender = sender;
+            this.receiver = receiver;
+            this.garageID = garageID;
+            this.parkingRecordsID = parkingRecordsID;
+            this.bookTime = bookTime;
+        }
+
+        public object Clone()
+        {
+            if (this == null)
+                return null;
+            MessageUTF8 webMsg = new MessageUTF8(this.cmd, this.context, this.sender, this.receiver, this.garageID, this.parkingRecordsID, this.bookTime);
+            return webMsg;
+        }
+    }
+
+    //********************************************* plc ************************************************
+    /// <summary>
+    /// plc节点类
+    /// </summary>
+    public class PLCNode : AbstractMessage
+    {
+        public string Address { get; set; }
+        public string Value { get; set; }
+
+        public PLCNode()
+        {
+            Address = "";
+            Value = "";
+        }
+        public PLCNode(string addr, string v)
+        {
+            Address = addr;
+            Value = v;
+        }
+
+        public override bool Equals(System.Object obj)
+        {
+            if (this == obj)
+                return true;
+            if (obj == null || obj.GetType() != this.GetType())
+                return false;
+            PLCNode p = obj as PLCNode;
+            return (Address == p.Address) && (Value == p.Value);
+        }
+
+        public override int GetHashCode()
+        {
+            int hash = 7;
+            return 31 * hash + Address.GetHashCode() + Value.GetHashCode();
+        }
+
+    }
+
+    /// <summary>
+    /// plc消息类
+    /// </summary>
+    public class PLCMessage : AbstractMessage, ICloneable
+    {
+        public List<PLCNode> extendedPlcList { get; set; }
+        public List<PLCNode> originalPlcList { get; set; }
+        public List<LaserMessage> laserMsgList { get; set; }
+
+        public PLCMessage()
+        {
+            extendedPlcList = new List<PLCNode>();
+            originalPlcList = new List<PLCNode>();
+            laserMsgList = new List<LaserMessage>();
+        }
+
+        public object Clone()
+        {
+            PLCMessage plcClone = new PLCMessage();
+            foreach (PLCNode pn in extendedPlcList)
+            {
+                plcClone.extendedPlcList.Add(pn);
+            }
+            foreach (PLCNode pn in originalPlcList)
+            {
+                plcClone.originalPlcList.Add(pn);
+            }
+            foreach (LaserMessage lm in laserMsgList)
+            {
+                plcClone.laserMsgList.Add(lm);
+            }
+            return plcClone;
+        }
+    }
+
+    //******************************************* NumMachine *********************************************
+    /// <summary>
+    /// 号牌机状态枚举
+    /// </summary>
+    public enum EnumNumberMachineStatus
+    {
+        Offline, Normal
+    }
+
+    /// <summary>
+    /// 号牌机节点类
+    /// </summary>
+    public class NumberMachineNode : ICloneable
+    {
+        public string ip { get; set; }
+        public string LicenseNum { get; set; }
+        public string TimeRecord { get; set; }
+        public int id;
+        public EnumNumberMachineStatus status;
+        public NumberMachineNode() { }
+        public NumberMachineNode(string ipAddr, int id, string license, string time, int stat)
+        {
+            SetLic(ipAddr, id, license, time, stat);
+        }
+        public void SetLic(string ipAddr, int id, string license, string time, int stat)
+        {
+            ip = ipAddr;
+            this.id = id;
+            LicenseNum = license;
+            TimeRecord = time;
+            if (stat == 1)
+                status = EnumNumberMachineStatus.Normal;
+            else
+                status = EnumNumberMachineStatus.Offline;
+        }
+        public override bool Equals(object obj)
+        {
+            if (obj == null || obj.GetType() != this.GetType())
+                return false;
+            if (this == obj)
+                return true;
+            NumberMachineNode l = (NumberMachineNode)obj;
+            return (l.LicenseNum == LicenseNum);
+        }
+        public override int GetHashCode()
+        {
+            return ip.GetHashCode() + LicenseNum.GetHashCode();
+        }
+
+        public object Clone()
+        {
+            if (status == EnumNumberMachineStatus.Normal)
+                return new NumberMachineNode(ip, id, LicenseNum, TimeRecord, 1);
+            else
+                return new NumberMachineNode(ip, id, LicenseNum, TimeRecord, 0);
+        }
+    }
+
+    /// <summary>
+    /// 号牌机消息类
+    /// </summary>
+    public class NumberMachineMessage : AbstractMessage
+    {
+        public List<NumberMachineNode> data { get; set; }
+        public NumberMachineNode aNode;
+
+        public NumberMachineMessage()
+        {
+            data = new List<NumberMachineNode>();
+            aNode = new NumberMachineNode();
+        }
+
+        public override bool Equals(System.Object obj)
+        {
+            if (this == obj)
+                return true;
+            if (obj == null || obj.GetType() != this.GetType())
+                return false;
+            NumberMachineMessage n = obj as NumberMachineMessage;
+            return (data.Equals(n.data));
+        }
+        public override int GetHashCode()
+        {
+            int hash = 7;
+            return 31 * hash + data.GetHashCode();
+        }
+    }
+
+    //********************************************** laser ************************************************
+    /// <summary>
+    /// 激光消息类
+    /// </summary>
+    public class LaserMessage : AbstractMessage, ICloneable
+    {
+        public int id { get; set; }
+        public int status { get; set; }
+        public bool recorded { get; set; }
+        public bool abort_rescan { get; set; }
+        public bool occupied { get; set; }
+        public bool disconnected { get; set; }
+        public string licenseNum { get; set; }
+        public Data data;
+        public LaserMessage()
+        {
+            data = new Data();
+            licenseNum = "";
+        }
+        public LaserMessage(int id, int status)
+        {
+            this.id = id;
+            this.status = status;
+            abort_rescan = false;
+            disconnected = false;
+            data = new Data();
+        }
+
+        public object Clone()
+        {
+            LaserMessage lm = new LaserMessage();
+            lm.id = id;
+            lm.status = status;
+            lm.data = (Data)data.Clone();
+            lm.recorded = recorded;
+            lm.abort_rescan = abort_rescan;
+            lm.licenseNum = licenseNum;
+            lm.disconnected = disconnected;
+            return lm;
+        }
+    }
+
+    /// <summary>
+    /// 激光数据类
+    /// </summary>
+    public class Data : ICloneable
+    {
+        public int centerX { get; set; }
+        public int centerY { get; set; }
+        public int angleA { get; set; }
+        public int length { get; set; }
+        public int width { get; set; }
+        public int height { get; set; }
+
+        public Data() : this(0, 0, 0, 0, 0, 0) { }
+        public Data(int cx, int cy, int aa, int l, int w, int h)
+        {
+            centerX = cx;
+            centerY = cy;
+            angleA = aa;
+            length = l;
+            width = w;
+            height = h;
+        }
+
+        public object Clone()
+        {
+            Data d = new Data(centerX, centerY, angleA, length, width, height);
+            return d;
+        }
+    }
+
+    //********************************************** command **********************************************
+    /// <summary>
+    /// 命令类,由队列线程处理号牌与指令后产生
+    /// </summary>
+    public class Command : AbstractMessage, ICloneable
+    {
+        public char commandType { get; set; }
+        public string LicenseNum { get; set; }
+        public string userID { get; set; }
+        public int garageID { get; set; }
+        public int parkingRecordsID { get; set; }
+        public string TimeRecord { get; set; }
+        public string ip { get; set; }//新添加,用于定位号牌机
+        public int returnedCount { get; set; }//标记被返回的命令
+        public int id { get; set; }
+        public bool manual { get; set; }//判断是否手动停取
+
+        public Command()
+        {
+            LicenseNum = "";
+            TimeRecord = "";
+            userID = "";
+            garageID = 0;
+            parkingRecordsID = 0;
+            ip = "";
+            returnedCount = 0;
+            id = 0;
+            manual = false;
+        }
+
+        public object Clone()
+        {
+            Command cmdClone = new Command();
+            cmdClone.commandType = commandType;
+            cmdClone.LicenseNum = LicenseNum;
+            cmdClone.userID = userID;
+            cmdClone.garageID = garageID;
+            cmdClone.parkingRecordsID = parkingRecordsID;
+            cmdClone.TimeRecord = TimeRecord;
+            cmdClone.ip = ip;
+            cmdClone.id = id;
+            cmdClone.returnedCount = returnedCount;
+            cmdClone.manual = manual;
+            return cmdClone;
+        }
+    }
+
+    /// <summary>
+    /// 控制信息类,核心在不同阶段发至plc
+    /// 1: 停车startLaser--park_command_address
+    /// 2: 停车激光的6个数据,startRobot,车位信息4个
+    /// 3:停车完成,归零--park_completed_address
+    /// 4:取车startRobot,车位信息4个
+    /// 5: 取车完成,归零-fetch_completed_address
+    /// </summary>
+    public class ControlMessage : AbstractMessage
+    {
+        public int status { get; set; }
+        public string LicenseNum { get; set; }
+        public int posID { get; set; }//激光地址
+        public string parkingSpaceID { get; set; }
+        public string parkingSpaceX { get; set; }
+        public string parkingSpaceY { get; set; }
+        public string parkingSpaceZ { get; set; }
+        public string centerX { get; set; }
+        public string centerY { get; set; }
+        public string angleA { get; set; }
+        public string length { get; set; }
+        public string width { get; set; }
+        public string height { get; set; }
+        public int fetchPosition { get; set; }//取车放置位置(临时缓冲位)
+        public int RobotID { get; set; }//机械手编号
+        public int frontWheelbase { get; set; }
+        public int rearWheelbase { get; set; }
+    }
+}

PLCLinker/parkMonitor/entity/Jsonhelper.cs → PLCLinker/WpfApp1/entity/Jsonhelper.cs


BIN=BIN
PLCLinker/WpfApp1/sdk/PLC/PLCS7.dll


BIN=BIN
PLCLinker/WpfApp1/sdk/PLC/S7.Net.dll


PLCLinker/parkMonitor/bin/Release/HslCommunication.dll → PLCLinker/WpfApp1/sdk/VZ_Sdk/HslCommunication.dll


PLCLinker/parkMonitor/bin/Release/Newtonsoft.Json.dll → PLCLinker/WpfApp1/sdk/VZ_Sdk/Newtonsoft.Json.dll


PLCLinker/parkMonitor/bin/Release/VZ_Sdk.dll → PLCLinker/WpfApp1/sdk/VZ_Sdk/VZ_Sdk.dll


PLCLinker/parkMonitor/bin/Release/VzDrawsLib.dll → PLCLinker/WpfApp1/sdk/VZ_Sdk/VzDrawsLib.dll


PLCLinker/parkMonitor/bin/Release/VzLPRSDK.dll → PLCLinker/WpfApp1/sdk/VZ_Sdk/VzLPRSDK.dll


PLCLinker/parkMonitor/bin/Release/iDecoders.dll → PLCLinker/WpfApp1/sdk/VZ_Sdk/iDecoders.dll


BIN=BIN
PLCLinker/WpfApp1/sdk/broadcast/DUCP.dll


BIN=BIN
PLCLinker/WpfApp1/sdk/broadcast/broadcastDLL.dll


BIN=BIN
PLCLinker/WpfApp1/sdk/broadcast/msvcr120d.dll


PLCLinker/parkMonitor/bin/Debug/log4net.dll → PLCLinker/WpfApp1/sdk/log4net/log4net.dll


PLCLinker/parkMonitor/bin/Debug/log4net.xml → PLCLinker/WpfApp1/sdk/log4net/log4net.xml


+ 0 - 0
PLCLinker/WpfApp1/sdk/mysql/DatabaseDLL.dll


Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio