Explorar o código

정기 업데이트

DESKTOP-Kang %!s(int64=6) %!d(string=hai) anos
pai
achega
fa95b516ee
Modificáronse 30 ficheiros con 943 adicións e 204 borrados
  1. 2 4
      Dev/Connection/OHVProtocolServer/OHVProtocolClient/MainWindow.xaml.cs
  2. BIN=BIN
      Dev/OHV/Assambly/CalcBinding.dll
  3. BIN=BIN
      Dev/OHV/Assambly/CalcBinding.pdb
  4. 156 0
      Dev/OHV/Assambly/GSG.NET.XML
  5. BIN=BIN
      Dev/OHV/Assambly/GSG.NET.dll
  6. BIN=BIN
      Dev/OHV/Assambly/GSG.NET.pdb
  7. 1 0
      Dev/OHV/OHV.Common/Shareds/ConstString.cs
  8. 11 1
      Dev/OHV/OHV.Module.Interactivity/PopUp/ConveyorControlViewModel.cs
  9. 4 4
      Dev/OHV/OHV.Module.Monitoring/Interactivity/InOutIOViewModel.cs
  10. 70 66
      Dev/OHV/OHV.Vehicle/Concept/D_MainWindowViewModel.cs
  11. BIN=BIN
      Dev/OHV/OHV.Vehicle/Config/IO.xlsx
  12. 27 9
      Dev/OHV/OHV.Vehicle/Config/log4net.xml
  13. 2 1
      Dev/OHV/VehicleControlSystem/ControlLayer/Axis/EzAxis.cs
  14. 1 1
      Dev/OHV/VehicleControlSystem/ControlLayer/Clamp.cs
  15. 2 0
      Dev/OHV/VehicleControlSystem/ControlLayer/IO/BitBlock.cs
  16. 7 5
      Dev/OHV/VehicleControlSystem/ControlLayer/IO/EzIO.cs
  17. 179 0
      Dev/OHV/VehicleControlSystem/ControlLayer/Serial/BatteryTabos/BMUManager.cs
  18. 2 0
      Dev/OHV/VehicleControlSystem/ControlLayer/Serial/BatteryTabos/Config.cs
  19. 12 0
      Dev/OHV/VehicleControlSystem/ControlLayer/Serial/BatteryTabos/IConectionNet.cs
  20. 138 0
      Dev/OHV/VehicleControlSystem/ControlLayer/Serial/BatteryTabos/Peak.cs
  21. 13 0
      Dev/OHV/VehicleControlSystem/ControlLayer/Serial/BatteryTabos/QueObject.cs
  22. 53 0
      Dev/OHV/VehicleControlSystem/ControlLayer/Serial/DataModel/ReceivedData.cs
  23. 1 1
      Dev/OHV/VehicleControlSystem/ControlLayer/Steering.cs
  24. 193 105
      Dev/OHV/VehicleControlSystem/ControlLayer/Vehicle.cs
  25. 5 0
      Dev/OHV/VehicleControlSystem/Managers/AutoManager.cs
  26. 31 2
      Dev/OHV/VehicleControlSystem/Managers/HostManager.cs
  27. 18 0
      Dev/OHV/VehicleControlSystem/Managers/PhysicalCheckupLogger.cs
  28. 4 4
      Dev/OHV/VehicleControlSystem/VCSystem.cs
  29. 10 1
      Dev/OHV/VehicleControlSystem/VehicleControlSystem.csproj
  30. 1 0
      Dev/OHV/VehicleControlSystem/packages.config

+ 2 - 4
Dev/Connection/OHVProtocolServer/OHVProtocolClient/MainWindow.xaml.cs

@@ -98,6 +98,8 @@ namespace OHVProtocolClient
                 case eKind.B:
                 case eKind.H:
                 case eKind.F:
+                case eKind.I:
+                case eKind.O:
                     ReplyMessage( msg );
                     break;
 
@@ -107,10 +109,6 @@ namespace OHVProtocolClient
                     break;
                 case eKind.P:
                     break;
-                case eKind.I:
-                    break;
-                case eKind.O:
-                    break;
                 case eKind.A:
                     break;
                 case eKind.L:

BIN=BIN
Dev/OHV/Assambly/CalcBinding.dll


BIN=BIN
Dev/OHV/Assambly/CalcBinding.pdb


+ 156 - 0
Dev/OHV/Assambly/GSG.NET.XML

@@ -867,6 +867,162 @@
             Watch start
             </summary>
         </member>
+        <member name="T:GSG.NET.FTP.FTPClient">
+            <summary>
+            <para>WebClient에 CWD를 하는 함수는 없다</para>
+            <para>-</para>
+            <para>(주의) FTP Remote 경로는 모두 FTP 접속시 접근되는 폴더 기준으로 해야한다.</para>
+            <para>-</para>
+            <para>2012.07</para>
+            <para>UploadFile함수 기능 보강.</para>
+            <para>-</para>
+            </summary>
+        </member>
+        <member name="F:GSG.NET.FTP.FTPClient.lock1">
+            <summary>
+            Webclient Support Only One IO
+            </summary>
+        </member>
+        <member name="F:GSG.NET.FTP.FTPClient.ANONYMOUS">
+            <summary>Anonymous User ID</summary>
+        </member>
+        <member name="P:GSG.NET.FTP.FTPClient.User">
+            <summary>FTP Client User</summary>
+        </member>
+        <member name="P:GSG.NET.FTP.FTPClient.IpAddress">
+            <summary>FTP IpAddress</summary>
+        </member>
+        <member name="P:GSG.NET.FTP.FTPClient.Port">
+            <summary>FTP Port, Default 21</summary>
+        </member>
+        <member name="P:GSG.NET.FTP.FTPClient.Password">
+            <summary>FTP Password</summary>
+        </member>
+        <member name="M:GSG.NET.FTP.FTPClient.#ctor">
+            <summary/>
+        </member>
+        <member name="P:GSG.NET.FTP.FTPClient.Proxy">
+            <summary>
+            <para>Proxy</para>
+            <para>-</para>
+            <para>Default null</para>
+            </summary>
+        </member>
+        <member name="M:GSG.NET.FTP.FTPClient.CheckCredential">
+            <summary>
+            <para>필수 체크 항목</para>
+            <para>-</para>
+            <para>1. 계정 세팅 connect 호출 여부 체크.</para>
+            </summary>
+        </member>
+        <member name="M:GSG.NET.FTP.FTPClient.Connect">
+            <summary>
+            <para>User, Password 접속 정보만 세팅하며</para>
+            <para>바로 접속은 하지 않고 필요시 연결은 자동으로 처리한다.</para>
+            <para>User를 세팅하지 않으면 기본 Anonymous User로 접속된다.</para>
+            </summary>
+        </member>
+        <member name="M:GSG.NET.FTP.FTPClient.ListDirectory(System.String)">
+            <summary>
+            <para>FTP server 원격 ListDirectory 목록 조회.</para>
+            <para>-</para>
+            <para>현재 경로 List가져오기</para>
+            <para>ListDirectory("/")</para>
+            </summary>
+        </member>
+        <member name="M:GSG.NET.FTP.FTPClient.GetInitDirectory">
+            <summary>
+            <para>초기 접속 경로</para>
+            <para>에러가 발생할 경우 ??를 return한다</para>
+            </summary>
+        </member>
+        <member name="M:GSG.NET.FTP.FTPClient.ChangeFileName(System.String,System.String)">
+            <summary>
+            <para>예제.</para>
+            <para>ChangeFileName("/aaa.bbb", "aaa.ccc")</para>
+            </summary>
+        </member>
+        <member name="M:GSG.NET.FTP.FTPClient.MakeDirectory(System.String)">
+            <summary>
+            <para>Directory 생성이 필요할 경우마다 호출함, Exception이 발생하지 않으며 Debug로그만 Write한다.</para>
+            <para>-</para>
+            <para>모든 경로는 접속시 기본 경로에서 시작한다.</para>
+            <para>-</para>
+            <para>접속시 기본 경로: /home/fms</para>
+            <para>//home/fms/FTP 만들기 예제</para>
+            <para>-</para>
+            <para>상대 경로로 만들 경우</para>
+            <para>/FTP 앞에 /를 붙여 줘야 한다.</para>
+            <para>-</para>
+            <para>절대 경로로 만들 경우</para>
+            <para>//home/fms/FTP</para>
+            <param name="dir"></param>
+            </summary>
+        </member>
+        <member name="M:GSG.NET.FTP.FTPClient.DeleteFile(System.String)">
+            <summary>
+            <para>Delete Remote File or Directory</para>
+            </summary>
+            <param name="remote">File or Directory</param>
+        </member>
+        <member name="M:GSG.NET.FTP.FTPClient.DownloadFile(System.String)">
+            <summary>
+            <para>Use DownloadFile(remotePath, localPath)</para>
+            </summary>
+        </member>
+        <member name="M:GSG.NET.FTP.FTPClient.DownloadFile(System.String,System.String)">
+            <summary>
+            <para>Sync 방식 File Download</para>
+            <para>-</para>
+            <para>모든 경로는 접속시 기본 경로에서 시작한다.</para>
+            <para>-</para>
+            <para>접속시 기본 경로: /home/fms</para>
+            <para>//home/fms/FTP/aaa.txt Download 예제</para>
+            <para>-</para>
+            <para>상대 경로 Download</para>
+            <para>DownloadFile(/FTP/aaa.txt, c:\aaa.txt)</para>
+            <para>-</para>
+            <para>절대 경로 Download</para>
+            <para>DownloadFile("//home/fms/FTP/aaa.txt", "c:\aaa.txt")</para>
+            <para>-</para>/// </summary>
+            <param name="remotePath"></param>
+            <param name="localPath"></param>
+        </member>
+        <member name="M:GSG.NET.FTP.FTPClient.UploadFile(System.String,System.String)">
+            <summary>
+            <para>Sync방식 Upload FTP</para>
+            <para>-</para>
+            <para>모든 경로는 접속시 기본 경로에서 시작한다.</para>
+            <para>-</para>
+            <para>remoteFileName에는 파일 이름을 써줘야 한다.</para>
+            <para>-</para>
+            <para>접속시 기본 경로: /home/fms</para>
+            <para>//home/fms/FTP/aaa.txt파일 올리기 예제</para>
+            <para>-</para>
+            <para>상대 경로 Upload</para>
+            <para>UploadFile(/FTP/aaa.txt, c:\aaa.txt)</para>
+            <para>-</para>
+            <para>절대 경로 Upload</para>
+            <para>UploadFile(//home/fms/FTP/aaa.txt, c:\aaa.txt)</para>
+            <para>-</para>
+            <para>주의: Server에 해당 파일이 있을 경우는 Option에 따라 다르게 동작함</para>
+            <para>Delete 권한 있을 경우: Overwrite</para>
+            <para>Delete 권한 없을 경우: 에러 발생함</para>
+            <para>-</para>
+            </summary>
+        </member>
+        <member name="M:GSG.NET.FTP.FTPClient.UploadFileAsync(System.String,System.String)">
+            <summary>
+            <para>비동기 FTP File Upload Request</para>
+            <para>-</para>
+            <para>경로는 UploadFile을 참고한다.</para>
+            </summary>
+        </member>
+        <member name="M:GSG.NET.FTP.FTPClient.ToString">
+            <summary>
+            ("FTPClient '{0}/{1}' '{2}:{3}'", IpAddress, Port, User, Password);
+            </summary>
+        </member>
         <member name="T:GSG.NET.IO.ConsoleOutputter">
             <summary>
             console data를 richtext box로 redirect하는 class

BIN=BIN
Dev/OHV/Assambly/GSG.NET.dll


BIN=BIN
Dev/OHV/Assambly/GSG.NET.pdb


+ 1 - 0
Dev/OHV/OHV.Common/Shareds/ConstString.cs

@@ -17,6 +17,7 @@ namespace OHV.Common.Shareds
         public const string PIOInterLockTimeout = "PIO_INTERLOCK_TIMEOUT";
         public const string PIOTimeOut = "PIO_TIMEOUT";
         public const string DriveSpeed = "DRIVE_SPEED";
+        public const string FTPAddr = "FTP_ADDRESS";
 
         //Axis Name
         public const string AXIS_CARRIER_LOCK_LEFT = "Axis_CarrierLock_Left";

+ 11 - 1
Dev/OHV/OHV.Module.Interactivity/PopUp/ConveyorControlViewModel.cs

@@ -11,6 +11,7 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using System.Windows.Input;
+using VehicleControlSystem;
 using VehicleControlSystem.ControlLayer.IO;
 using static OHV.Common.Events.AxisControlEventArgs;
 
@@ -43,8 +44,12 @@ namespace OHV.Module.Interactivity.PopUp
 
         List<BitBlock> allIOList = new List<BitBlock>();
 
-        public ConveyorControlViewModel( IEventAggregator _ea , MessageController _msg)
+        EzIO iO = null; 
+
+        public ConveyorControlViewModel( IEventAggregator _ea , MessageController _msg, VCSystem vcSystem)
         {
+            this.iO = vcSystem.IO as EzIO;
+            this.iO.OnChangedIO += IO_OnChangedIO;
             this.eventAggregator = _ea;
 
             /*IO Publish Event*/
@@ -65,6 +70,11 @@ namespace OHV.Module.Interactivity.PopUp
             this.PosMoveCommand = new DelegateCommand<object>( ExecutePosMoveCommand );
         }
 
+        private void IO_OnChangedIO( BitBlock bit )
+        {
+            throw new NotImplementedException();
+        }
+
         private void UICallbackCommunication( GUIMessageEventArgs _args )
         {
             //TODO:[20/03/20 ys-hwang] Conveyor 에서 Vehicle 상태를 쓸 항목이 있으런지? 쓴다면 State만??

+ 4 - 4
Dev/OHV/OHV.Module.Monitoring/Interactivity/InOutIOViewModel.cs

@@ -46,7 +46,7 @@ namespace OHV.Module.Monitoring.Interactivity
             {
                 if(SetProperty( ref this.currentPage, value ) )
                 {
-                    var input = this.allIOList.Where(i => i.BoardNo == this.currentPage && i.IOType.Equals("IN")).ToArray();
+                    var input = this.allIOList.Where(i => i.PageNo == this.currentPage && i.IOType.Equals("IN")).ToArray();
                     this.InIOList = new SelectionList<BitBlock>( input );
                     this.InIOList.ForEach( i =>
                     {
@@ -56,7 +56,7 @@ namespace OHV.Module.Monitoring.Interactivity
                         i.IsSelected = i.Element.IsBitOn;
                     } );
 
-                    var output = this.allIOList.Where(i => i.BoardNo == this.currentPage && i.IOType.Equals("OUT")).ToArray();
+                    var output = this.allIOList.Where(i => i.PageNo == this.currentPage && i.IOType.Equals("OUT")).ToArray();
                     this.OutIOList = new SelectionList<BitBlock>( output );
                     this.OutIOList.PropertyChanged += OutIOList_PropertyChanged;
                     this.OutIOList.ForEach( o =>
@@ -107,7 +107,7 @@ namespace OHV.Module.Monitoring.Interactivity
                     this.allIOList = new List<BitBlock>(ezIO.InPutIOList);
                     this.allIOList.AddRange(ezIO.OutPutIOList);
 
-                    var input = this.allIOList.Where(i => i.BoardNo == this.currentPage && i.IOType.Equals("IN")).ToArray();
+                    var input = this.allIOList.Where(i => i.PageNo == this.currentPage && i.IOType.Equals("IN")).ToArray();
                     this.InIOList = new SelectionList<BitBlock>(input);
                     this.InIOList.ForEach(i =>
                     {
@@ -117,7 +117,7 @@ namespace OHV.Module.Monitoring.Interactivity
                         i.IsSelected = i.Element.IsBitOn;
                     });
 
-                    var output = this.allIOList.Where(i => i.BoardNo == this.currentPage && i.IOType.Equals("OUT")).ToArray();
+                    var output = this.allIOList.Where(i => i.PageNo == this.currentPage && i.IOType.Equals("OUT")).ToArray();
                     this.OutIOList = new SelectionList<BitBlock>(output);
                     this.OutIOList.PropertyChanged += OutIOList_PropertyChanged;
                     this.OutIOList.ForEach(o =>

+ 70 - 66
Dev/OHV/OHV.Vehicle/Concept/D_MainWindowViewModel.cs

@@ -254,7 +254,65 @@ namespace OHV.Vehicle.Concept
             var ll = GSG.NET.OSView.Mgnt.HddList();
             this.CDrive = ll.FirstOrDefault().AvailableFreeSpace / ConstUtils.ONE_GIGA_BYTES;
         }
+        void VehicleModeChang(bool isAutoMode)
+        {
+            if (isAutoMode)
+            {
+                this.StartEnable = false;
+                this.StopEnable = true;
+                this.IsManualMode = false;
+                regionManager.RequestNavigate(RegionNames.MainView, "AutoView");
+            }
+            else
+            {
+                this.StartEnable = true;
+                this.StopEnable = false;
+                this.IsManualMode = true;
+            }
+        }
+        private void Navigate(object obj)
+        {
+            var selectItem = obj.ToString();
+            if (!string.IsNullOrEmpty(selectItem))
+                regionManager.RequestNavigate("MainView", selectItem);
+        }
+        public static void SelectCulture(string culture)
+        {
+            if (String.IsNullOrEmpty(culture))
+                return;
+
+            //Copy all MergedDictionarys into a auxiliar list.
+            var dictionaryList = Application.Current.Resources.MergedDictionaries.ToList();
 
+            //Search for the specified culture.     
+            string requestedCulture = string.Format("StringResources.{0}.xaml", culture);
+            var resourceDictionary = dictionaryList.
+                FirstOrDefault(d => d.Source.OriginalString == "/OHV.ResourceDic;component/Resources/StringResource.en-US.xaml");
+
+            if (resourceDictionary == null)
+            {
+                //If not found, select our default language.             
+                requestedCulture = "StringResources.xaml";
+                resourceDictionary = dictionaryList.
+                    FirstOrDefault(d => d.Source.OriginalString == requestedCulture);
+            }
+
+            //If we have the requested resource, remove it from the list and place at the end.     
+            //Then this language will be our string table to use.      
+            if (resourceDictionary != null)
+            {
+                Application.Current.Resources.MergedDictionaries.Remove(resourceDictionary);
+                Application.Current.Resources.MergedDictionaries.Add(resourceDictionary);
+            }
+
+            //Inform the threads of the new culture.     
+            Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
+            Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
+
+        }
+
+
+        #region Execute Method
         private void Execte_ChangeLanguage()
         {
             //LanguageHalper.LanguagesSelcter.ChangLanguage(LanguageHalper.eLanguageType.Chinese);
@@ -269,7 +327,7 @@ namespace OHV.Vehicle.Concept
             vcsMessagePublisher.Publish(msg);
         }
 
-        private void ExecuteAlarmResetCommand( )
+        private void ExecuteAlarmResetCommand()
         {
             loggerRemote.I("123214wefsadfsdafsd");
             this.messageController.ShowConfirmationPopupView(" Alarm Reset ? ", r =>
@@ -342,31 +400,19 @@ namespace OHV.Vehicle.Concept
                       App.Current.Shutdown();
               });
         }
-
-        private void Navigate(object obj)
+        
+        private void ExecuteTextCommand()
         {
-            var selectItem = obj.ToString();
-            if (!string.IsNullOrEmpty(selectItem))
-                regionManager.RequestNavigate("MainView", selectItem);
-        }
+            //var m = new VCSMessageEventArgs();
+            //m.MessageKey = 1234;
+            //m.MessageText = "Test Message";
+            //m.Command = new Common.Model.Command() { CommandID = "TestCommand123", Type = Common.Shareds.eCommandType.Move };
 
-        void VehicleModeChang(bool isAutoMode)
-        {
-            if (isAutoMode)
-            {
-                this.StartEnable = false;
-                this.StopEnable = true;
-                this.IsManualMode = false;
-                regionManager.RequestNavigate(RegionNames.MainView, "AutoView");
-            }
-            else
-            {
-                this.StartEnable = true;
-                this.StopEnable = false;
-                this.IsManualMode = true;
-            }
+            //this.eventAggregator.GetEvent<VCSMessagePubSubEvent>().Publish(m);
         }
+        #endregion
 
+        #region Subscribe
         private void UICallbackCommunication(GUIMessageEventArgs obj)
         {
             switch (obj.Kind)
@@ -396,7 +442,7 @@ namespace OHV.Vehicle.Concept
 
         private void RspVehicleModeChange(GUIMessageEventArgs obj)
         {
-            if ( obj.Result.IsSuccess)
+            if (obj.Result.IsSuccess)
             {
                 if (obj.MessageKey.Equals(MessageKey.AutoMode)) { this.VehicleModeChang(true); }
                 if (obj.MessageKey.Equals(MessageKey.ManualMode)) { this.VehicleModeChang(false); }
@@ -429,15 +475,7 @@ namespace OHV.Vehicle.Concept
             }
         }
 
-        private void ExecuteTextCommand()
-        {
-            //var m = new VCSMessageEventArgs();
-            //m.MessageKey = 1234;
-            //m.MessageText = "Test Message";
-            //m.Command = new Common.Model.Command() { CommandID = "TestCommand123", Type = Common.Shareds.eCommandType.Move };
-
-            //this.eventAggregator.GetEvent<VCSMessagePubSubEvent>().Publish(m);
-        }
+        #endregion
 
         public void InitViewModel()
         {
@@ -457,39 +495,5 @@ namespace OHV.Vehicle.Concept
             //VCSystem.Instance.Dispose();
         }
 
-        public static void SelectCulture(string culture)
-        {
-            if (String.IsNullOrEmpty(culture))
-                return;
-
-            //Copy all MergedDictionarys into a auxiliar list.
-            var dictionaryList = Application.Current.Resources.MergedDictionaries.ToList();
-
-            //Search for the specified culture.     
-            string requestedCulture = string.Format("StringResources.{0}.xaml", culture);
-            var resourceDictionary = dictionaryList.
-                FirstOrDefault(d => d.Source.OriginalString == "/OHV.ResourceDic;component/Resources/StringResource.en-US.xaml");
-
-            if (resourceDictionary == null)
-            {
-                //If not found, select our default language.             
-                requestedCulture = "StringResources.xaml";
-                resourceDictionary = dictionaryList.
-                    FirstOrDefault(d => d.Source.OriginalString == requestedCulture);
-            }
-
-            //If we have the requested resource, remove it from the list and place at the end.     
-            //Then this language will be our string table to use.      
-            if (resourceDictionary != null)
-            {
-                Application.Current.Resources.MergedDictionaries.Remove(resourceDictionary);
-                Application.Current.Resources.MergedDictionaries.Add(resourceDictionary);
-            }
-
-            //Inform the threads of the new culture.     
-            Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
-            Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
-
-        }
     }
 }

BIN=BIN
Dev/OHV/OHV.Vehicle/Config/IO.xlsx


+ 27 - 9
Dev/OHV/OHV.Vehicle/Config/log4net.xml

@@ -1,6 +1,6 @@
 <log4net>
 
-	<root>
+	<root name="root">
 		<level value="ALL" />
 		<appender-ref ref="FileAppender" />
 		<appender-ref ref="WarnFileAppender" />
@@ -21,6 +21,10 @@
     <appender-ref ref="remotingAppender" />
   </logger>
 
+  <logger name="PhysicalCheckup" additivity="false">
+    <appender-ref ref="PhysicalCheckupFileAppender" />
+  </logger>
+
   <!--
 	ALL    DEBUG   INFO    WARN    ERROR   FATAL   OFF
 	•All
@@ -32,12 +36,27 @@
 	•OFF    •OFF    •OFF    •OFF    •OFF    •OFF    •OFF
 	-->
 
-	<appender name="FileAppender" type="GSG.NET.Logging.FileAppender, GSG.NET">
-		<filter type="log4net.Filter.LevelRangeFilter">
+  <appender name="PhysicalCheckupFileAppender" type="GSG.NET.Logging.FileAppender, GSG.NET">
+    <threshold value="WARN"/>
+    <file value="D:\LOG\OHV\Vehicle\PhysicalCheckup\PhysicalCheckup.log" />
+    <appendToFile value="true" />
+    <rollingStyle value="Date" />
+    <backupDays value="180" />
+    <datePattern value="-MMdd'.log'" />
+    <layout type="log4net.Layout.PatternLayout">
+      <conversionPattern value="%d{MM-dd HH:mm:ss.fff} %2t %p %m%n" />
+    </layout>
+  </appender>
+
+  <appender name="FileAppender" type="GSG.NET.Logging.FileAppender, GSG.NET">
+		<!--<filter type="log4net.Filter.LevelRangeFilter">
 			<param name="LevelMin" value="INFO"></param>
 			<param name="LevelMax" value="OFF"></param>
-		</filter>
-		<file value="D:\LOG\OHV\Vehicle\Vehicle.log" />
+		</filter>-->
+    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
+    <file type="log4net.Util.PatternString">
+      <conversionPattern value="D:\LOG\OHV\Vehicle\Vehicle.log"  />
+    </file>
 		<appendToFile value="true" />
 		<rollingStyle value="Date" />
 		<backupDays value="30" />
@@ -48,7 +67,7 @@
 	</appender>
 
 	<appender name="HostAppender" type="GSG.NET.Logging.FileAppender, GSG.NET">
-		<file value="D:\LOG\OHV\Vehicle\Hos\Host.log" />
+		<file value="D:\LOG\OHV\Vehicle\OCS\Host.log" />
 		<appendToFile value="true" />
 		<rollingStyle value="Date" />
 		<backupDays value="20" />
@@ -99,11 +118,11 @@
 
   <appender name="remotingAppender" type="log4net.Appender.RemotingAppender">
     <!-- The remoting URL to the remoting server object -->
-    <sink value="tcp://172.20.0.197:8085/Log4netRemotingServerService"/>
+    <sink value="tcp://localhost:8085/Log4netRemotingServerService"/>
     <!-- Send all events, do not discard events when the buffer is full -->
     <lossy value="false"/>
     <!-- The number of events to buffer before sending -->
-    <bufferSize value="10"/>
+    <bufferSize value="1"/>
     <!-- Do not store event data that is slow to generate -->
     <onlyFixPartialEventData value="true"/>
     <!-- Specify an evaluator to send the events immediately under certain conditions, e.g. when an error event ocurrs -->
@@ -112,7 +131,6 @@
     </evaluator>
   </appender>
 
-
   <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender"   >
 		<layout type="log4net.Layout.PatternLayout">
 			<param name="ConversionPattern" value="%d %m%n" />

+ 2 - 1
Dev/OHV/VehicleControlSystem/ControlLayer/Axis/EzAxis.cs

@@ -81,7 +81,8 @@ namespace VehicleControlSystem.ControlLayer.Axis
 
         public override int Initialize( AxisData data )
         {
-            EziMOTIONPlusELib.FAS_Connect( (byte)192, (byte)168, (byte)0, (byte)Config.AxisNo, Config.AxisNo );
+            //IO 에서 연결 시도.
+            //EziMOTIONPlusELib.FAS_Connect( (byte)192, (byte)168, (byte)0, (byte)Config.AxisNo, Config.AxisNo );
 
             this.ValocityData = data;
 

+ 1 - 1
Dev/OHV/VehicleControlSystem/ControlLayer/Clamp.cs

@@ -171,7 +171,7 @@ namespace VehicleControlSystem.ControlLayer
                         state.IsServoOn = a.IsServoOn();
                         state.IsOriginReturn = a.IsOriginReturn();
                         state.IsAmpFault = a.IsAmpFault();
-                        state.CurrentPosition = GSG.NET.Utils.NumUtils.Random(0, 3000);
+                        state.CurrentPosition = a.CurrentPosition;
 
                         if (a.Config.AxisName.Equals(ConstString.AXIS_CARRIER_LOCK_LEFT))
                             msg.Args.Add("Left", state);

+ 2 - 0
Dev/OHV/VehicleControlSystem/ControlLayer/IO/BitBlock.cs

@@ -28,6 +28,8 @@ namespace VehicleControlSystem.ControlLayer.IO
         [Column( "BoardType" )]
         public string BoardType { get; set; }
 
+        public int PageNo { get; set; }
+
         public bool IsBitOn { get; set; } = false;
         public bool IsChanged { get; set; } = false;
     }

+ 7 - 5
Dev/OHV/VehicleControlSystem/ControlLayer/IO/EzIO.cs

@@ -617,7 +617,9 @@ namespace VehicleControlSystem.ControlLayer.IO
                 if (IsConnetedBoard(b.BoardID))
                     continue;
 
-                if (EziMOTIONPlusELib.FAS_Connect((byte)192, (byte)168, (byte)0, (byte)b.BoardID, b.BoardID) != EziMOTIONPlusELib.FMM_OK)
+                var addr = b.IPAddress.Split( '.' );
+                byte boardNo = Convert.ToByte( addr[3] );
+                if (EziMOTIONPlusELib.FAS_Connect((byte)192, (byte)168, (byte)0, boardNo, b.BoardID ) != EziMOTIONPlusELib.FMM_OK)
                 {
                     logger.E($"EzIO - Connect Fail {b.BoardID}");
                     return false;
@@ -705,14 +707,14 @@ namespace VehicleControlSystem.ControlLayer.IO
                 if (disposing)
                 {
                     // TODO: 관리되는 상태(관리되는 개체)를 삭제합니다.
-                    if (this._readThread != null)
+                    if (this.pullThread != null)
                     {
                         this.IsThreadAlive = false;
-                        if (!this._readThread.Join(3000) && this._readThread.IsAlive)
+                        if (!this.pullThread.Join(2000) && this.pullThread.IsAlive)
                         {
-                            this._readThread.Abort();
+                            this.pullThread.Abort();
                         }
-                        this._readThread = null;
+                        this.pullThread = null;
                     }
 
                     ThreadUtils.Kill(this.pullThread);

+ 179 - 0
Dev/OHV/VehicleControlSystem/ControlLayer/Serial/BatteryTabos/BMUManager.cs

@@ -0,0 +1,179 @@
+using GSG.NET.Concurrent;
+using GSG.NET.Extensions;
+using GSG.NET.Logging;
+using GSG.NET.Quartz;
+using GSG.NET.Utils;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using VehicleControlSystem.ControlLayer.Serial.DataModel;
+
+namespace VehicleControlSystem.ControlLayer.Serial.BatteryTabos
+{
+    public class BMUManager
+    {
+        static Logger logger = Logger.GetLogger();
+
+        Peak com = null;
+        public Config BMUConfig { get; set; }
+        public bool IsConnected { get; set; }
+
+        internal Dictionary<string, ReceivedData> ReceivedDataDic = new Dictionary<string, DataModel.ReceivedData>();
+        protected TsQueue<QueObject> qq = new TsQueue<QueObject>( 512 );
+
+        public ThreadCancel cancel = new ThreadCancel();
+
+        CbTimer polling = new CbTimer();
+        long collectNo = 0;
+        long collectElasped = 0;
+
+        protected object LockObject = new object();
+
+        #region Event
+        public event Action<string> OnConnect;
+        public event Action<string> OnDisconnect;
+        public event Action<ReceivedData> OnChangedReceivedData;
+        public event Action<List<ReceivedData>> OnFirstColtd;
+        #endregion
+
+        public BMUManager()
+        {
+            this.BMUConfig = new Config();
+            this.Init();
+        }
+
+        private void Init()
+        {
+            EnumExtensions.GetValues<eDataKind>().ToList().ForEach( x => { this.ReceivedDataDic.Add( x.ToString(), new ReceivedData(x) ); } );
+        }
+
+        protected void EnqueueToNet( object o )
+        {
+            this.com.Enqueue( o );
+        }
+
+
+        protected void _ThPullQueue()
+        {
+            while ( !cancel.Canceled )
+            {
+                try
+                {
+                    var qo = this.qq.Dequeue();
+
+                    if ( qo is QoConnect )
+                        DelegateUtils.Invoke( OnConnect, qo.Arg0 );
+                    else if ( qo is QoDisconnected )
+                        DelegateUtils.Invoke( OnDisconnect, qo.Arg0 );
+                    else if ( qo is QoReceivedDataChanged )
+                        DelegateUtils.Invoke( OnChangedReceivedData, qo.Arg0 );
+                    //else if ( qo is QoSendMessageSuccess )
+                    //    DelegateUtils.Invoke( OnSendSetDataSuccess, qo.Arg0 );
+                    else
+                        Assert.Fail( "Unk Object {0}", qo );
+                }
+                catch ( ThreadAbortException )
+                {
+                    break;
+                }
+                catch ( Exception e )
+                {
+                    logger.E( e );
+                }
+            }
+        }
+
+
+        #region Net Invoke Method
+        internal void _OnConnected()
+        {
+            if ( 0 != collectNo )
+                this.qq.Enqueue( new QoConnect { Arg0 = this.BMUConfig.ID } );
+
+            _OnTimePoll();
+        }
+
+        internal void _OnDisconnected()
+        {
+            this.qq.Enqueue( new QoDisconnected { Arg0 = this.BMUConfig.ID } );
+        }
+
+        internal void _InvokeChgdWordsAndBits()
+        {
+            //Todo: 변경 된 내용 처리.
+            if ( 0 == collectNo )
+            {
+                //this.qq.Enqueue( new QoConnect { Arg0 = this.BMUConfig.ID } );
+                var ll = this.ReceivedDataDic.Values.ToList();
+                DelegateUtils.Invoke( OnFirstColtd, ll );
+            }
+
+            //var v = new MapScan
+            //{
+            //    CollectTime = (int)SwUtils.Elapsed( collectElasped )
+            //};
+            //DlgUtils.Invoke( OnCollected, v );
+            if ( long.MaxValue <= this.collectNo )
+                this.collectNo = 1;
+
+            this.collectNo++;
+
+            var rlist = this.ReceivedDataDic.ToList();
+            rlist.ForEach( r =>
+            {
+                if ( r.Value.IsChanged )
+                {
+                    r.Value.IsChanged = false;
+                    var clone = ObjectCopyUtils.DeepClone( r );
+                    this.qq.Enqueue( new QoReceivedDataChanged { Arg0 = clone } );
+                }
+            } );
+
+            //다음 timer 기동 시 까지 잠시 대기
+            polling.Once( _OnTimePoll, 100 );
+        }
+
+        void _OnTimePoll()
+        {
+            //Todo: Scan 으로 읽어 오는 영역의 명령을 Net 쪽으로 보내야함. 
+
+            lock ( this.LockObject )
+            {
+                collectElasped = SwUtils.T;
+
+                this.EnqueueToNet( new PollingObject() );
+                this.EnqueueToNet( new DoInvokeChangedReceivedData() );//Invoke Changed
+            }
+        }
+
+        //internal void _OnSendDataSuccess( ISetData data )
+        //{
+        //    this.qq.Enqueue( new QoSendMessageSuccess { Arg0 = data } );
+        //}
+        #endregion
+
+
+        #region Public Method
+        public void Connect()
+        {
+            //외부 전달 시작
+            this.cancel.AddGo( _ThPullQueue );
+
+            //읽기 시작.
+            this.com = new Peak(this);
+            this.cancel.AddGo( this.com._ThreadPoolingReceiveData );
+        }
+
+        public void Disconnect()
+        {
+            collectNo = 0;
+            //Thread Stop
+            this.cancel.Cancel();
+            this.cancel.StopWaitAll();
+        }
+        #endregion
+    }
+}

+ 2 - 0
Dev/OHV/VehicleControlSystem/ControlLayer/Serial/BatteryTabos/Config.cs

@@ -8,6 +8,8 @@ namespace VehicleControlSystem.ControlLayer.Serial.BatteryTabos
 {
     public class Config
     {
+        public string ID { get; set; } = "1";
+
         public double Voltage { get; set; }
         public double Current { get; set; }
         public double SOC { get; set; }

+ 12 - 0
Dev/OHV/VehicleControlSystem/ControlLayer/Serial/BatteryTabos/IConectionNet.cs

@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace VehicleControlSystem.ControlLayer.Serial.BatteryTabos
+{
+    interface IConectionNet
+    {
+    }
+}

+ 138 - 0
Dev/OHV/VehicleControlSystem/ControlLayer/Serial/BatteryTabos/Peak.cs

@@ -0,0 +1,138 @@
+using GSG.NET.Concurrent;
+using GSG.NET.Extensions;
+using GSG.NET.Logging;
+using GSG.NET.TCP;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using VehicleControlSystem.ControlLayer.Serial.DataModel;
+
+namespace VehicleControlSystem.ControlLayer.Serial.BatteryTabos
+{
+    public class Peak
+    {
+        static Logger logger = Logger.GetLogger();
+
+        protected TsQueue<object> qqW = new TsQueue<object>( 128 );//write
+
+        BMUManager manager = null;
+
+        object lockObject = new object();
+
+        public Peak( BMUManager mrg )
+        {
+            this.manager = mrg;
+        }
+
+        internal void Enqueue(object o )
+        {
+            this.qqW.Enqueue( o );
+        }
+
+        void TryToConnect()
+        {
+            this.qqW.Clear();
+
+            //h.Connect( new TcpComm
+            //{
+            //    Ip = this.manager.Config.IpAddress,
+            //    PortNo = this.manager.Config.Port,
+            //    RollCnt = 1,
+            //} );
+
+            manager._OnConnected();
+        }
+
+        //Todo:Dll 에서 상태 가져오기
+        bool IsConnected => true;
+
+
+        public void _ThreadPoolingReceiveData()
+        {
+            while ( !this.manager.cancel.Canceled )
+            {
+                try
+                {
+                    if ( !IsConnected )
+                    {
+                        this.TryToConnect();
+                        continue;
+                    }
+
+                    object o = this.qqW.Dequeue();
+
+                    if ( o is PollingObject ) //Scan 을 주기적 으로 진행.
+                    {
+                        this.PollingBattery();
+                    }
+                    //else if ( o is ISetData ) //하나의 명령을 수행.
+                    //{
+                    //    //ExecuteSetData( o as ISetData );
+                    //}
+                    else if ( o is DoInvokeChangedReceivedData ) //Scan 이후 결과를 처리. Manager 에서 처리
+                    {
+                        //this.manager._InvokeChgdReceivedData();
+                    }
+
+                }
+                catch ( ThreadAbortException exception )
+                {
+                    logger.E( $"eSlnet {this.manager.BMUConfig.ID} - {exception.Message}" );
+                    //h.CloseSocket();
+                }
+                catch ( ObjectDisposedException exception )
+                {
+                    //this.TcpError( exception );
+                }
+                catch ( IOException exception )
+                {
+                    //this.TcpError( exception );
+                }
+                catch ( Exception exception )
+                {
+                    logger.E( $"eSlnet {exception.Message}" );
+                }
+            }
+
+        }
+
+        private void PollingBattery()
+        {
+            var ll = this.manager.ReceivedDataDic.Values.ToList();
+            ll.ForEach( x => 
+            {
+                var kind = CastTo<eDataKind>.From<Enum>( x.DataKind );
+                switch ( kind )
+                {
+                    case eDataKind.Volte:
+                        break;
+                    case eDataKind.Current:
+                        break;
+                    case eDataKind.BatteryState:
+                        break;
+                    case eDataKind.ChargeCompleteTime:
+                        break;
+                    case eDataKind.DisChargeCompleteTime:
+                        break;
+                    case eDataKind.SOC:
+                        break;
+                    case eDataKind.SOH:
+                        break;
+                    case eDataKind.ResidualCapacity:
+                        break;
+                    case eDataKind.ResidualEnergy:
+                        break;
+                    case eDataKind.Temperature:
+                        break;
+                    default:
+                        break;
+                }
+            } );
+
+        }
+    }
+}

+ 13 - 0
Dev/OHV/VehicleControlSystem/ControlLayer/Serial/BatteryTabos/QueObject.cs

@@ -6,6 +6,14 @@ using System.Threading.Tasks;
 
 namespace VehicleControlSystem.ControlLayer.Serial.BatteryTabos
 {
+    public class DoInvokeChangedReceivedData
+    {
+    }
+
+    public class PollingObject
+    {
+    }
+
     public abstract class QueObject
     {
         public object Arg0 { get; set; }
@@ -13,6 +21,11 @@ namespace VehicleControlSystem.ControlLayer.Serial.BatteryTabos
     }
 
     public class QoConnect : QueObject { }
+    internal class QoDisconnected : QueObject { }
+    internal class QoSendMessageSuccess : QueObject { }
+    internal class QoReceivedDataChanged : QueObject { }
+
+
     public class QoVoltage : QueObject { }
     public class QoCurrent : QueObject { }
     public class QoSOC : QueObject { }

+ 53 - 0
Dev/OHV/VehicleControlSystem/ControlLayer/Serial/DataModel/ReceivedData.cs

@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace VehicleControlSystem.ControlLayer.Serial.DataModel
+{
+    public enum eDataKind
+    {
+        Volte = 0, //V
+        Current, //A
+        BatteryState, 
+        ChargeCompleteTime, //Min
+        DisChargeCompleteTime, //Min
+        SOC, //%
+        SOH, //%
+        ResidualCapacity,//Ah
+        ResidualEnergy,//Wh
+        Temperature,//C
+    }
+
+    public enum eBatteryState
+    {
+        OverVolte,
+        LowVolte,
+        OverChargeCurrent,
+        OverDisChargeCurrent,
+        HightTemperature,
+        LowTemperature,
+        BMUError,
+    }
+
+    public class ReceivedData
+    {
+        public Enum DataKind { get; set; } = eDataKind.BatteryState;
+        public eBatteryState BatteryState { get; set; }
+        public double Value { get; set; }
+        public double Scale { get; set; }
+        public string Unit { get; set; }//단위를 붙이기 위해
+        public bool IsChanged { get; set; }
+
+        public ReceivedData(eDataKind kind)
+        {
+            this.DataKind = kind;
+        }
+
+        public override string ToString()
+        {
+            return this.Value.ToString() + " " + this.Unit;
+        }
+    }
+}

+ 1 - 1
Dev/OHV/VehicleControlSystem/ControlLayer/Steering.cs

@@ -127,7 +127,7 @@ namespace VehicleControlSystem.ControlLayer
 
             return 0;
         }
-
+        
         void SetHightVolt()
         {
             this.iO.WriteOutputIO("OUT_F_STEERING_DA", true);

+ 193 - 105
Dev/OHV/VehicleControlSystem/ControlLayer/Vehicle.cs

@@ -19,6 +19,8 @@ using Prism.Events;
 using VehicleControlSystem.ControlLayer.Actuator.Cylinder;
 using VehicleControlSystem.ControlLayer.IO;
 using VehicleControlSystem.ControlLayer.Motion;
+using VehicleControlSystem.ControlLayer.Serial.BatteryTabos;
+using VehicleControlSystem.ControlLayer.Serial.DataModel;
 using VehicleControlSystem.Managers;
 
 namespace VehicleControlSystem.ControlLayer
@@ -49,13 +51,13 @@ namespace VehicleControlSystem.ControlLayer
         /// <summary>
         /// Tag 위치
         /// </summary>
-        private string currentTag;
+        private string currentTag = "0000";
         public string CurrentTag
         {
             get { return currentTag; }
-            set 
-            { 
-                if ( SetField(ref this.currentTag, value))
+            set
+            {
+                if (SetField(ref this.currentTag, value))
                     this.OnCurrentTagChanged?.Invoke(value);
             }
         }
@@ -107,8 +109,8 @@ namespace VehicleControlSystem.ControlLayer
         public eObstacleState ObstacleStateProperty
         {
             get { return obstacleState; }
-            set 
-            { 
+            set
+            {
                 if (SetField(ref this.obstacleState, value))
                 {
                     if (value == eObstacleState.Blocked)
@@ -124,6 +126,13 @@ namespace VehicleControlSystem.ControlLayer
             set { SetField(ref this.vehicleState, value); }
         }
 
+        private double batteryVolte;
+        public double BatteryVolt
+        {
+            get { return batteryVolte; }
+            set { SetField(ref this.batteryVolte, value); }
+        }
+
         //이동
         public bool Busy
         {
@@ -135,7 +144,6 @@ namespace VehicleControlSystem.ControlLayer
         }
 
         public bool IsMoving { get; set; }
-        public double BatteryVolt { get; set; }
         public bool IsError { get; set; }
 
         public SubCmd CurrentSubCommand { get; private set; }
@@ -180,9 +188,11 @@ namespace VehicleControlSystem.ControlLayer
         Clamp clamp = null;
         Steering steering = null;
         AutoManager autoManager = null;
+        BMUManager bMUManager = null;
 
         ThreadCancel cancel = new ThreadCancel();
         TaskCancel taskCancel = new TaskCancel();
+        TaskCancel moveTaskCancel = new TaskCancel(); // 이동 중에 필요한 사항들을 체크
 
         IEventAggregator eventAggregator;
 
@@ -205,23 +215,23 @@ namespace VehicleControlSystem.ControlLayer
             this.eventAggregator = ea;
 
             /*Drive*/
-            this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Unsubscribe( ReceiveDriveControlEvent );
-            this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Subscribe( ReceiveDriveControlEvent );
+            this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Unsubscribe(ReceiveDriveControlEvent);
+            this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Subscribe(ReceiveDriveControlEvent);
 
             /*IO*/
-            this.eventAggregator.GetEvent<IOControlPubSubEvent>().Unsubscribe( ReceiveIOControlEvent );
-            this.eventAggregator.GetEvent<IOControlPubSubEvent>().Subscribe( ReceiveIOControlEvent );
+            this.eventAggregator.GetEvent<IOControlPubSubEvent>().Unsubscribe(ReceiveIOControlEvent);
+            this.eventAggregator.GetEvent<IOControlPubSubEvent>().Subscribe(ReceiveIOControlEvent);
         }
 
-        private void ReceiveIOControlEvent( IOControlEventArgs _args )
+        private void ReceiveIOControlEvent(IOControlEventArgs _args)
         {
-            if ( this.autoManager.OperationModeProperty != eOperatationMode.ManualMode )
+            if (this.autoManager.OperationModeProperty != eOperatationMode.ManualMode)
                 return;
 
             var msg = _args;
-            if(msg.EventDir == IOControlEventArgs.eEventDir.ToBack)
+            if (msg.EventDir == IOControlEventArgs.eEventDir.ToBack)
             {
-                switch ( msg.ControlKind )
+                switch (msg.ControlKind)
                 {
                     case IOControlEventArgs.eControlKind.USE:
                         break;
@@ -306,6 +316,7 @@ namespace VehicleControlSystem.ControlLayer
             this.CreateClamp();
             this.CreateSteering();
             CreateDrive();
+            this.CreateBMUManager();
 
             ThreadStart();
 
@@ -330,6 +341,14 @@ namespace VehicleControlSystem.ControlLayer
         {
             this.cancel.Cancel();
             this.cancel.StopWaitAll();
+
+            this.taskCancel.Cancel();
+            this.taskCancel.WaitAll();
+
+            moveTaskCancel.Cancel();
+            moveTaskCancel.WaitAll();
+
+            this.bMUManager.Disconnect();
         }
 
         #region Request Method
@@ -349,7 +368,7 @@ namespace VehicleControlSystem.ControlLayer
             DriveControlEventPublish(msg);
         }
 
-        private void ReqMoveToPos( DriveControlEventArgs args )
+        private void ReqMoveToPos(DriveControlEventArgs args)
         {
             //var result = drive.Move( args.PositionTag );
             //this.MoveTo( "1111" );
@@ -357,7 +376,7 @@ namespace VehicleControlSystem.ControlLayer
 
             int targetTag = args.TargetRouteID;
             var route = sql.RouteDal.GetK(targetTag);
-            if ( route == null)
+            if (route == null)
             {
                 reply.Result = Results.Fail("Not Found Route");
                 this.DriveControlEventPublish(reply);
@@ -365,7 +384,7 @@ namespace VehicleControlSystem.ControlLayer
             }
 
             this.MoveTo(route.Name);
-            reply.Result = Results.Ok( "Position Move" );
+            reply.Result = Results.Ok("Position Move");
             this.DriveControlEventPublish(reply);
         }
 
@@ -406,15 +425,15 @@ namespace VehicleControlSystem.ControlLayer
                 {
                     LockUtils.Wait(500);
 
-                     var msg = new DriveControlEventArgs
-                     {
-                         EventDir = DriveControlEventArgs.eEventDir.ToFront ,
-                         ControlKind = DriveControlEventArgs.eControlKind.ReqCurrentPos ,
-                         CurrentPosition = new Random().Next(0, 1000),
-                     };
-                     
-                     this.DriveControlEventPublish( msg );
-                 }
+                    var msg = new DriveControlEventArgs
+                    {
+                        EventDir = DriveControlEventArgs.eEventDir.ToFront,
+                        ControlKind = DriveControlEventArgs.eControlKind.ReqCurrentPos,
+                        CurrentPosition = new Random().Next(0, 1000),
+                    };
+
+                    this.DriveControlEventPublish(msg);
+                }
             });
 
             this.taskCancel.Add(task);
@@ -454,6 +473,8 @@ namespace VehicleControlSystem.ControlLayer
         {
             this.cancel.AddGo(new Action(this._ThSubCmdWorker));
             this.cancel.AddGo(new Action(this._ThObstacleChecker));
+
+            this.bMUManager.Connect();
         }
 
         //장애물 감지 Thread
@@ -562,6 +583,8 @@ namespace VehicleControlSystem.ControlLayer
 
         void Move(SubCmd sub)
         {
+            //Todo: 이동 중 브레이크를 풀어야 함. 평소에는 풀고 있다가 Load Unload 시에만 잡아줘야 하는건가??
+            // 브레이크 플어 주기 B접 this.iO.OutputOn("OUT_DRIVE_BRAKE_OFF");
             if (this.MoveTo(sub.TargetID))
             {
                 sql.SubCmdDAL.Delete(sub);
@@ -650,7 +673,9 @@ namespace VehicleControlSystem.ControlLayer
                 return false;
             }
 
+            this.iO.OutputOn("OUT_PIO_SENSOR_ONOFF");
             result = this.PIOAndLoad(sub.TargetID);
+            this.iO.OutputOff("OUT_PIO_SENSOR_ONOFF");
             if (result != 0)
             {
                 this.OccurVehicleAlarm(result);
@@ -692,7 +717,9 @@ namespace VehicleControlSystem.ControlLayer
                 return false;
             }
 
+            this.iO.OutputOn("OUT_PIO_SENSOR_ONOFF");
             result = this.PIOAndUnload(sub.TargetID);
+            this.iO.OutputOff("OUT_PIO_SENSOR_ONOFF");
             if (result != 0)
             {
                 this.OccurVehicleAlarm(result);
@@ -940,100 +967,100 @@ namespace VehicleControlSystem.ControlLayer
             Thread.Sleep(1000);
             this.OnConveyorStop?.Invoke(true);
 #else
-            var pioTimeout = sql.ConfigDal.GetValueToInt( ConstString.PIOTimeOut );
+            var pioTimeout = sql.ConfigDal.GetValueToInt(ConstString.PIOTimeOut);
 
-            if ( this.IsInverterError() )
+            if (this.IsInverterError())
                 return 16;
 
-            if ( this.IsLifterPositinCheck() )
+            if (this.IsLifterPositinCheck())
                 return 14;
 
-            if ( !this.IsLifterDuplication() )
+            if (!this.IsLifterDuplication())
             {
-                this.OnFailReport?.Invoke( eFailCode.Load_PortHasNotCarrier );
+                this.OnFailReport?.Invoke(eFailCode.Load_PortHasNotCarrier);
                 return 0;
             }
 
-            if ( this.IsDetectedCenter() )
+            if (this.IsDetectedCenter())
             {
-                this.OnFailReport?.Invoke( eFailCode.Load_VehicleHasCarrier );
+                this.OnFailReport?.Invoke(eFailCode.Load_VehicleHasCarrier);
                 return 0;
             }
 
             PIOClear();
-            loggerPIO.I( $"Start Load PIO - [{targetName}]" );
-            this.OnPIOStart?.Invoke( true );
+            loggerPIO.I($"Start Load PIO - [{targetName}]");
+            this.OnPIOStart?.Invoke(true);
 
-            this.iO.WriteOutputIO( "OUT_PIO_RECEIVE_RUN", true );
-            loggerPIO.I( "[Vehicle] - 4 Receive Run On" );
+            this.iO.WriteOutputIO("OUT_PIO_RECEIVE_RUN", true);
+            loggerPIO.I("[Vehicle] - 4 Receive Run On");
 
-            if ( !this.iO.WaitChangeInputIO( true, pioTimeout, "IN_PIO_SENDABLE" ) )
+            if (!this.iO.WaitChangeInputIO(true, pioTimeout, "IN_PIO_SENDABLE"))
             {
                 PIOClear();
-                loggerPIO.E( "[Port] - 4 Ready Time Out" );
-                this.OnFailReport?.Invoke( eFailCode.LoadPIOInterlockTimeout );
+                loggerPIO.E("[Port] - 4 Ready Time Out");
+                this.OnFailReport?.Invoke(eFailCode.LoadPIOInterlockTimeout);
                 return 0;
             }
-            loggerPIO.E( "[Port] - 4 Ready On" );
+            loggerPIO.E("[Port] - 4 Ready On");
 
-            this.SetConveyorSpeed( true );
-            this.OnOffConveyor( true, true );
-            this.iO.WriteOutputIO( "OUT_PIO_RECEIVE_RUN", true );
-            loggerPIO.I( "[Vehicle] - Conveyor Run" );
-            this.OnConveyorStart?.Invoke( true );
+            this.SetConveyorSpeed(true);
+            this.OnOffConveyor(true, true);
+            this.iO.WriteOutputIO("OUT_PIO_RECEIVE_RUN", true);
+            loggerPIO.I("[Vehicle] - Conveyor Run");
+            this.OnConveyorStart?.Invoke(true);
 
-            if ( !this.iO.WaitChangeInputIO( true, pioTimeout, "IN_PIO_SEND_RUN" ) )
+            if (!this.iO.WaitChangeInputIO(true, pioTimeout, "IN_PIO_SEND_RUN"))
             {
-                this.OnOffConveyor( false, true );
+                this.OnOffConveyor(false, true);
                 PIOClear();
-                loggerPIO.E( "[Port] - 5 Sending Run Time Out" );
-                this.OnFailReport?.Invoke( eFailCode.LoadPIOInterlockTimeout );
+                loggerPIO.E("[Port] - 5 Sending Run Time Out");
+                this.OnFailReport?.Invoke(eFailCode.LoadPIOInterlockTimeout);
                 return 0;
             }
 
             bool isStartDetected = false;
             var sTime = SwUtils.CurrentTimeMillis;
-            while ( true )
+            while (true)
             {
-                if ( SwUtils.Gt( sTime, 20 * ConstUtils.ONE_SECOND ) )
+                if (SwUtils.Gt(sTime, 20 * ConstUtils.ONE_SECOND))
                 {
                     PIOClear();
-                    this.OnOffConveyor( false, true );
-                    loggerPIO.E( "[Vehicle] Conveyor Wait Time Out" );
-                    this.OnFailReport?.Invoke( eFailCode.LoadPIOInterlockTimeout );
+                    this.OnOffConveyor(false, true);
+                    loggerPIO.E("[Vehicle] Conveyor Wait Time Out");
+                    this.OnFailReport?.Invoke(eFailCode.LoadPIOInterlockTimeout);
 
-                    if ( this.IsDetectedLoadStart() ) // 감지가 시작 되었으면 이동중 Error 로 판단 설비를 정지 상태로
+                    if (this.IsDetectedLoadStart()) // 감지가 시작 되었으면 이동중 Error 로 판단 설비를 정지 상태로
                         return 10; //Conveyor Moving Timeout
                     else
                         return 0;
                 }
 
-                if ( this.IsDetectedLoadStart() && !isStartDetected )
+                if (this.IsDetectedLoadStart() && !isStartDetected)
                     isStartDetected = true;
 
-                if ( !this.IsDetectedLoadStart() && isStartDetected )
-                    this.SetConveyorSpeed( false );
+                if (!this.IsDetectedLoadStart() && isStartDetected)
+                    this.SetConveyorSpeed(false);
 
-                if ( this.IsDetectedLoadStop() ) break;
+                if (this.IsDetectedLoadStop()) break;
 
-                if ( this.IsPIOInterLockOn() )
+                if (this.IsPIOInterLockOn())
                 {
                     PIOClear();
-                    this.OnOffConveyor( false ); //Stop
-                    loggerPIO.E( "[Port] PIO InterLock On " );
+                    this.OnOffConveyor(false); //Stop
+                    loggerPIO.E("[Port] PIO InterLock On ");
                     return 19; //
                 }
             }
 
-            if ( this.IsDetectedCenter() )
-                this.OnCarrierDetected?.Invoke( true );
+            if (this.IsDetectedCenter())
+                this.OnCarrierDetected?.Invoke(true);
 
-            this.OnOffConveyor( false ); //Stop
+            this.OnOffConveyor(false); //Stop
             PIOClear();
-            this.OnConveyorStop?.Invoke( true );
+            this.OnConveyorStop?.Invoke(true);
 
-            this.iO.WriteOutputIO( "OUT_PIO_RECIVE_COMPLITE", true );
-            this.iO.WriteOutputIO( "OUT_PIO_RECIVE_COMPLITE", false, 1000 );
+            this.iO.WriteOutputIO("OUT_PIO_RECIVE_COMPLITE", true);
+            this.iO.WriteOutputIO("OUT_PIO_RECIVE_COMPLITE", false, 1000);
 
             this.OnLoadComplete?.Invoke();
 #endif
@@ -1063,84 +1090,84 @@ namespace VehicleControlSystem.ControlLayer
 
             this.OnUnloadComplete?.Invoke();
 #else
-            var pioTimeout = sql.ConfigDal.GetValueToInt( ConstString.PIOTimeOut );
+            var pioTimeout = sql.ConfigDal.GetValueToInt(ConstString.PIOTimeOut);
 
-            if ( this.IsInverterError() )
+            if (this.IsInverterError())
                 return 16;
 
-            if ( this.IsLifterDuplication() )
+            if (this.IsLifterDuplication())
             {
-                this.OnFailReport?.Invoke( eFailCode.Unload_PortHasCarrier );
+                this.OnFailReport?.Invoke(eFailCode.Unload_PortHasCarrier);
                 return 0;
             }
 
-            if ( !this.IsDetectedCenter() )
+            if (!this.IsDetectedCenter())
             {
-                this.OnFailReport?.Invoke( eFailCode.Unload_VehicleHasNotCarrier );
+                this.OnFailReport?.Invoke(eFailCode.Unload_VehicleHasNotCarrier);
                 return 0;
             }
 
-            if ( this.IsLifterPositinCheck() )
+            if (this.IsLifterPositinCheck())
                 return 13;
 
             PIOClear();
-            loggerPIO.I( $"Start Unload PIO - [{targetName}]" );
-            this.OnPIOStart?.Invoke( false );
+            loggerPIO.I($"Start Unload PIO - [{targetName}]");
+            this.OnPIOStart?.Invoke(false);
 
-            if ( !this.iO.IsOn( "IN_PIO_READY" ) )
+            if (!this.iO.IsOn("IN_PIO_READY"))
             {
-                loggerPIO.E( "[Port] - 1 Ready not On" );
-                this.OnFailReport?.Invoke( eFailCode.UnlaodPIOInterlockTimeout );
+                loggerPIO.E("[Port] - 1 Ready not On");
+                this.OnFailReport?.Invoke(eFailCode.UnlaodPIOInterlockTimeout);
                 return 0;
             }
 
-            this.iO.WriteOutputIO( "OUT_PIO_READY", true );
-            loggerPIO.I( "[Vehicle] - 1 Ready On" );
+            this.iO.WriteOutputIO("OUT_PIO_READY", true);
+            loggerPIO.I("[Vehicle] - 1 Ready On");
 
-            if ( !this.iO.WaitChangeInputIO( true, pioTimeout, "IN_PIO_RECEIVE_RUN" ) )
+            if (!this.iO.WaitChangeInputIO(true, pioTimeout, "IN_PIO_RECEIVE_RUN"))
             {
                 PIOClear();
-                loggerPIO.E( "[Port] - 2 Receive CV Run Timeout" );
-                this.OnFailReport?.Invoke( eFailCode.UnlaodPIOInterlockTimeout );
+                loggerPIO.E("[Port] - 2 Receive CV Run Timeout");
+                this.OnFailReport?.Invoke(eFailCode.UnlaodPIOInterlockTimeout);
                 return 0;
             }
 
-            this.iO.WriteOutputIO( "OUT_PIO_SENDING_RUN", true );
-            loggerPIO.I( "[Vehicle] - 2 Send Run On" );
+            this.iO.WriteOutputIO("OUT_PIO_SENDING_RUN", true);
+            loggerPIO.I("[Vehicle] - 2 Send Run On");
 
-            this.SetConveyorSpeed( true );
-            this.OnOffConveyor( true );
-            this.OnConveyorStart?.Invoke( false );
+            this.SetConveyorSpeed(true);
+            this.OnOffConveyor(true);
+            this.OnConveyorStart?.Invoke(false);
 
             var sTime = SwUtils.CurrentTimeMillis;
-            while ( true )
+            while (true)
             {
-                if ( SwUtils.Gt( sTime, 20 * ConstUtils.ONE_SECOND ) )
+                if (SwUtils.Gt(sTime, 20 * ConstUtils.ONE_SECOND))
                 {
                     PIOClear();
-                    this.OnOffConveyor( false, true );
-                    loggerPIO.E( "[Port] Conveyor Wait Time Out" );
-                    this.OnFailReport?.Invoke( eFailCode.UnlaodPIOInterlockTimeout );
+                    this.OnOffConveyor(false, true);
+                    loggerPIO.E("[Port] Conveyor Wait Time Out");
+                    this.OnFailReport?.Invoke(eFailCode.UnlaodPIOInterlockTimeout);
 
-                    if ( IsDetectedLoadStart() || IsDetectedCenter() ) //중간에 걸려 있다고 생각해서 알람 처리.
+                    if (IsDetectedLoadStart() || IsDetectedCenter()) //중간에 걸려 있다고 생각해서 알람 처리.
                         return 12; //Conveyor Moving Timeout
                     else
                         return 0;
                 }
 
-                if ( this.iO.IsOn( "IN_PIO_RECEIVE_COMPLITE" ) )
+                if (this.iO.IsOn("IN_PIO_RECEIVE_COMPLITE"))
                     break;
             }
 
-            if ( !IsDetectedCenter() )
-                this.OnCarrierDetected?.Invoke( false );
+            if (!IsDetectedCenter())
+                this.OnCarrierDetected?.Invoke(false);
 
-            this.OnOffConveyor( false ); //Stop
-            this.OnConveyorStop?.Invoke( false );
+            this.OnOffConveyor(false); //Stop
+            this.OnConveyorStop?.Invoke(false);
             PIOClear();
 
-            this.iO.WriteOutputIO( "OUT_PIO_SEND_COMPLITE", true );
-            this.iO.WriteOutputIO( "OUT_PIO_SEND_COMPLITE", false, 1000 );
+            this.iO.WriteOutputIO("OUT_PIO_SEND_COMPLITE", true);
+            this.iO.WriteOutputIO("OUT_PIO_SEND_COMPLITE", false, 1000);
 
             this.OnUnloadComplete?.Invoke();
 #endif
@@ -1175,6 +1202,15 @@ namespace VehicleControlSystem.ControlLayer
             this.motion = new GSIMotion(this.sql);
             this.motion.PropertyChanged += Motion_PropertyChanged;
         }
+        void CreateBMUManager()
+        {
+            this.bMUManager = new BMUManager();
+            this.bMUManager.BMUConfig = new Serial.BatteryTabos.Config() { ID = "1" };
+            this.bMUManager.OnConnect += BMUManager_OnConnect;
+            this.bMUManager.OnDisconnect += BMUManager_OnDisconnect;
+            this.bMUManager.OnFirstColtd += BMUManager_OnFirstColtd;
+            this.bMUManager.OnChangedReceivedData += BMUManager_OnChangedReceivedData;
+        }
 
         #endregion
 
@@ -1246,6 +1282,58 @@ namespace VehicleControlSystem.ControlLayer
         #endregion
 
         #region Event Subscribe 
+
+        #region Battery
+        private void BMUManager_OnChangedReceivedData( Serial.DataModel.ReceivedData obj )
+        {
+            var data = obj as ReceivedData;
+            if ( null == data )
+                logger.E( "[Battery Data] Null" );
+
+            var kind = CastTo<eDataKind>.From<Enum>( data.DataKind );
+            switch ( kind )
+            {
+                case eDataKind.Volte:
+                    this.BatteryVolt = data.Value;
+                    break;
+                case eDataKind.Current:
+                    break;
+                case eDataKind.BatteryState:
+                    break;
+                case eDataKind.ChargeCompleteTime:
+                    break;
+                case eDataKind.DisChargeCompleteTime:
+                    break;
+                case eDataKind.SOC:
+                    break;
+                case eDataKind.SOH:
+                    break;
+                case eDataKind.ResidualCapacity:
+                    break;
+                case eDataKind.ResidualEnergy:
+                    break;
+                case eDataKind.Temperature:
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        private void BMUManager_OnFirstColtd( List<Serial.DataModel.ReceivedData> obj )
+        {
+            logger.I( "[Battery Data] First Collected" );
+        }
+
+        private void BMUManager_OnDisconnect( string obj )
+        {
+        }
+
+        private void BMUManager_OnConnect( string obj )
+        {
+        }
+
+        #endregion
+
         private void Motion_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
         {
             var property = sender.GetType().GetProperty(e.PropertyName);

+ 5 - 0
Dev/OHV/VehicleControlSystem/Managers/AutoManager.cs

@@ -39,6 +39,11 @@ namespace VehicleControlSystem.Managers
                 logger.D($"[AutoManager] OperationMode - {value}");
 
                 this.OnOperationModeChanged?.Invoke(value);
+
+                if (value == eOperatationMode.AutoMode)
+                    this.iO.OutputOff("OUT_TEACH_MODE");
+                else
+                    this.iO.OutputOn("OUT_TEACH_MODE");
             }
         }
         public event Action<eOperatationMode> OnOperationModeChanged;

+ 31 - 2
Dev/OHV/VehicleControlSystem/Managers/HostManager.cs

@@ -28,11 +28,41 @@ namespace VehicleControlSystem.Managers
         Vehicle vehicle;
         SqliteManager sql = null;
 
-        public HostManager(IEventAggregator ea, Vehicle vehicle, SqliteManager sqlite)
+        public HostManager(IEventAggregator ea, Vehicle vehicle, SqliteManager sqlite, AutoManager autoManager)
         {
             this.eventAggregator = ea;
             this.vehicle = vehicle;
             this.sql = sqlite;
+
+            autoManager.OnOperationModeChanged += AutoManager_OnOperationModeChanged;
+
+        }
+
+        private void AutoManager_OnOperationModeChanged( eOperatationMode obj )
+        {
+            var mode = CastTo<eOperatationMode>.From<object>( obj );
+
+            var msg = new OCSMessage();
+            if ( mode == eOperatationMode.AutoMode )
+            {
+                msg.Kind = eKind.I;
+                msg.Tag = this.vehicle.CurrentTag;
+                msg.IsSubCode1 = this.vehicle.IsContain;
+                msg.IsSubCode2 = vehicle.IsMoving;
+                msg.IsSubCode3 = vehicle.IsError;
+            }
+            else if ( mode == eOperatationMode.ManualMode )
+            {
+                msg.Kind = eKind.O;
+                msg.Tag = this.vehicle.CurrentTag;
+                msg.IsSubCode1 = this.vehicle.IsContain;
+                msg.IsSubCode2 = vehicle.IsMoving;
+                msg.IsSubCode3 = vehicle.IsError;
+            }
+            else
+                return;
+
+            this.manager.Send( msg );
         }
 
         public void Init()
@@ -358,7 +388,6 @@ namespace VehicleControlSystem.Managers
             cmd.TargetID = route.Name;
 
             this.sql.CommandDAL.Add( cmd );
-
         }
 
         private void Manager_OnT3Timeout(OHVConnector.OCSMessage msg)

+ 18 - 0
Dev/OHV/VehicleControlSystem/Managers/PhysicalCheckupLogger.cs

@@ -0,0 +1,18 @@
+using GSG.NET.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace VehicleControlSystem.Managers
+{
+    /// <summary>
+    /// 아날로그 입력 정보를 종합하여 로그로 남기는 역할
+    /// FTP 를 이용하여 파일 전송
+    /// </summary>
+    class PhysicalCheckupLogger
+    {
+        Logger logger = Logger.GetLogger( "PhysicalCheckup" );
+    }
+}

+ 4 - 4
Dev/OHV/VehicleControlSystem/VCSystem.cs

@@ -25,7 +25,7 @@ namespace VehicleControlSystem
     {
         Scheduler scheduler = null;
         IEventAggregator eventAggregator = null;
-        IIO IO = null;
+        public IIO IO = null;
         public AutoManager autoManager = null;
         HostManager hostManager = null;
         Vehicle vehicle = null;
@@ -63,7 +63,7 @@ namespace VehicleControlSystem
             this.vehicle = new Vehicle(this.IO, this.sql, this.eventAggregator, this.autoManager);
             this.vehicle.PropertyChanged += Vehicle_PropertyChanged;
 
-            this.hostManager = new HostManager(this.eventAggregator, this.vehicle, this.sql);
+            this.hostManager = new HostManager(this.eventAggregator, this.vehicle, this.sql, this.autoManager);
 
             this.hostManager.Init();
             this.vehicle.Init();
@@ -163,8 +163,8 @@ namespace VehicleControlSystem
                     return;
                 }
 
-                this.autoManager.OperationModeProperty = OHV.Common.Shareds.eOperatationMode.AutoMode;
-                this.autoManager.AutoModeStateProperty = OHV.Common.Shareds.eAutoModeState.StartRun;
+                this.autoManager.AutoModeStateProperty = eAutoModeState.StartRun;
+                this.autoManager.OperationModeProperty = eOperatationMode.AutoMode;
                 reply = new GUIMessageEventArgs { Kind = GUIMessageEventArgs.eGUIMessageKind.RspVehicleModeChange, Result = FluentResults.Results.Ok(), MessageKey = MessageKey.AutoMode };
             }
             else

+ 10 - 1
Dev/OHV/VehicleControlSystem/VehicleControlSystem.csproj

@@ -18,7 +18,7 @@
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
     <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>TRACE;DEBUG</DefineConstants>
+    <DefineConstants>TRACE;DEBUG;SIMULATION</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
@@ -37,6 +37,9 @@
     <Reference Include="CommonServiceLocator, Version=2.0.4.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
       <HintPath>..\packages\CommonServiceLocator.2.0.4\lib\net45\CommonServiceLocator.dll</HintPath>
     </Reference>
+    <Reference Include="FluentFTP, Version=32.2.2.0, Culture=neutral, PublicKeyToken=f4af092b1d8df44f, processorArchitecture=MSIL">
+      <HintPath>..\packages\FluentFTP.32.2.2\lib\net45\FluentFTP.dll</HintPath>
+    </Reference>
     <Reference Include="FluentResults">
       <HintPath>..\Assambly\FluentResults.dll</HintPath>
     </Reference>
@@ -70,6 +73,7 @@
     <Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
       <HintPath>..\packages\System.ValueTuple.4.5.0\lib\netstandard1.0\System.ValueTuple.dll</HintPath>
     </Reference>
+    <Reference Include="System.Web" />
     <Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
       <HintPath>..\packages\Prism.Wpf.7.2.0.1422\lib\net45\System.Windows.Interactivity.dll</HintPath>
     </Reference>
@@ -104,16 +108,21 @@
     <Compile Include="ControlLayer\IO\Lib\MOTION_EziSERVO2_DEFINE.cs" />
     <Compile Include="ControlLayer\IO\QueueObjects.cs" />
     <Compile Include="ControlLayer\Motion\GSIMotion.cs" />
+    <Compile Include="ControlLayer\Serial\BatteryTabos\BMUManager.cs" />
     <Compile Include="ControlLayer\Serial\BatteryTabos\Config.cs" />
     <Compile Include="ControlLayer\Serial\BatteryTabos\Delegates.cs" />
     <Compile Include="ControlLayer\Serial\BatteryTabos\EnumBatteryStatus.cs" />
+    <Compile Include="ControlLayer\Serial\BatteryTabos\IConectionNet.cs" />
     <Compile Include="ControlLayer\Serial\BatteryTabos\Manager.cs" />
+    <Compile Include="ControlLayer\Serial\BatteryTabos\Peak.cs" />
     <Compile Include="ControlLayer\Serial\BatteryTabos\QueObject.cs" />
     <Compile Include="ControlLayer\Serial\BatteryTabos\Rs232c.cs" />
+    <Compile Include="ControlLayer\Serial\DataModel\ReceivedData.cs" />
     <Compile Include="ControlLayer\Steering.cs" />
     <Compile Include="ControlLayer\Vehicle.cs" />
     <Compile Include="Managers\AutoManager.cs" />
     <Compile Include="Managers\HostManager.cs" />
+    <Compile Include="Managers\PhysicalCheckupLogger.cs" />
     <Compile Include="Managers\Scheduler.cs" />
     <Compile Include="VCSystem.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />

+ 1 - 0
Dev/OHV/VehicleControlSystem/packages.config

@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="CommonServiceLocator" version="2.0.4" targetFramework="net45" />
+  <package id="FluentFTP" version="32.2.2" targetFramework="net45" />
   <package id="Prism.Core" version="7.2.0.1422" targetFramework="net45" />
   <package id="Prism.Wpf" version="7.2.0.1422" targetFramework="net45" />
   <package id="System.ValueTuple" version="4.5.0" targetFramework="net45" />