ys-hwang 6 年 前
コミット
04c353f7a8
29 ファイル変更1144 行追加34 行削除
  1. 2 4
      Dev/Connection/OHVProtocolServer/OHVProtocolClient/MainWindow.xaml.cs
  2. BIN
      Dev/OHV/Assambly/CalcBinding.dll
  3. BIN
      Dev/OHV/Assambly/CalcBinding.pdb
  4. 156 0
      Dev/OHV/Assambly/GSG.NET.XML
  5. BIN
      Dev/OHV/Assambly/GSG.NET.dll
  6. BIN
      Dev/OHV/Assambly/GSG.NET.pdb
  7. 1 0
      Dev/OHV/OHV.Common/Shareds/ConstString.cs
  8. 4 3
      Dev/OHV/OHV.Module.Interactivity/PopUp/ConveyorControlViewModel.cs
  9. 459 0
      Dev/OHV/OHV.Module.Interactivity/PopUp/ConveyorControlViewModel.cs.orig
  10. 4 4
      Dev/OHV/OHV.Module.Monitoring/Interactivity/InOutIOViewModel.cs
  11. 14 0
      Dev/OHV/OHV.Vehicle/Concept/D_MainWindowViewModel.cs
  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. 5 0
      Dev/OHV/VehicleControlSystem/Managers/AutoManager.cs
  25. 30 2
      Dev/OHV/VehicleControlSystem/Managers/HostManager.cs
  26. 18 0
      Dev/OHV/VehicleControlSystem/Managers/PhysicalCheckupLogger.cs
  27. 3 3
      Dev/OHV/VehicleControlSystem/VCSystem.cs
  28. 10 1
      Dev/OHV/VehicleControlSystem/VehicleControlSystem.csproj
  29. 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
Dev/OHV/Assambly/CalcBinding.dll


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
Dev/OHV/Assambly/GSG.NET.dll


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";

+ 4 - 3
Dev/OHV/OHV.Module.Interactivity/PopUp/ConveyorControlViewModel.cs

@@ -108,14 +108,16 @@ namespace OHV.Module.Interactivity.PopUp
 
         List<BitBlock> allIOList = new List<BitBlock>();
 
+        EzIO iO = null; 
+
         VCSystem VCSystem;
         EzIO IO = null;
 
-        public ConveyorControlViewModel( IEventAggregator _ea , MessageController _msg, VCSystem _vcSystem)
+        public ConveyorControlViewModel( IEventAggregator _ea , MessageController _msg, VCSystem vcSystem)
         {
             this.eventAggregator = _ea;
 
-            this.VCSystem = _vcSystem;
+            this.VCSystem = vcSystem;
             this.IO = VCSystem.IO as EzIO;
             this.IO.OnChangedIO += IO_OnChangedIO;
             this.GetSensorState(this.IO);
@@ -224,7 +226,6 @@ namespace OHV.Module.Interactivity.PopUp
 
         private void ChangeObstacleState( eObstacleState _reply )
         {
-            
         }
 
         private void ExecutePosMoveCommand( object obj )

+ 459 - 0
Dev/OHV/OHV.Module.Interactivity/PopUp/ConveyorControlViewModel.cs.orig

@@ -0,0 +1,459 @@
+using GSG.NET.Extensions;
+using OHV.Common.Events;
+using OHV.Common.Model;
+using OHV.Common.Shareds;
+using Prism.Commands;
+using Prism.Events;
+using Prism.Mvvm;
+using Prism.Services.Dialogs;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Input;
+<<<<<<< HEAD
+=======
+using System.Windows.Media;
+>>>>>>> eef332823de9e5e1c309ffa9e4d055ac4e281980
+using VehicleControlSystem;
+using VehicleControlSystem.ControlLayer.IO;
+using static OHV.Common.Events.AxisControlEventArgs;
+
+namespace OHV.Module.Interactivity.PopUp
+{
+    public class ConveyorControlViewModel : BindableBase, IDialogAware
+    {
+        private DelegateCommand<string> _closeDialogCommand;
+        public DelegateCommand<string> CloseDialogCommand =>
+            _closeDialogCommand ?? ( _closeDialogCommand = new DelegateCommand<string>( CloseDialog ) );
+
+        public event Action<IDialogResult> RequestClose;
+
+
+        private string _title = "ConveyorControlView";
+        public string Title
+        {
+            get { return this._title; }
+            set
+            {
+                this.SetProperty( ref this._title , value );
+            }
+        }
+
+        #region Brushes
+        private Brush _cvError = Brushes.Gray;
+        public Brush CvError { get { return _cvError; } set { SetProperty( ref _cvError , value ); } }
+
+        private Brush _cvStop = Brushes.Gray;
+        public Brush CvStop { get { return _cvStop; } set { SetProperty( ref _cvStop , value ); } }
+
+        private Brush _cvSlowStop = Brushes.Gray;
+        public Brush CvSlowStop { get { return _cvSlowStop; } set { SetProperty( ref _cvSlowStop , value ); } }
+
+        private Brush _cvEntryIn = Brushes.Gray;
+        public Brush CvEntryIn { get { return _cvEntryIn; } set { SetProperty( ref _cvEntryIn , value ); } }
+        private Brush _cvRun = Brushes.Gray;
+        public Brush CvRun { get { return _cvRun; } set { SetProperty( ref _cvRun , value ); } }
+
+        private Brush _cvCW = Brushes.Gray;
+        public Brush CvCW { get { return _cvCW; } set { SetProperty( ref _cvCW , value ); } }
+
+        private Brush _cvCCW = Brushes.Gray;
+        public Brush CvCCW { get { return _cvCCW; } set { SetProperty( ref _cvCCW , value ); } }
+
+        private Brush _axisLeftIsOrg = Brushes.Red;
+        private Brush _axisLeftAmpFault = Brushes.Gray;
+
+        private Brush _axisRightIsOrg = Brushes.Red;
+        private Brush _axisRightAmpFault = Brushes.Gray;
+
+        public Brush AxisLeftIsOrg
+        {
+            get { return _axisLeftIsOrg; }
+            set
+            {
+                SetProperty( ref _axisLeftIsOrg , value );
+            }
+        }
+        public Brush AxisLeftAmpFault
+        {
+            get { return _axisLeftAmpFault; }
+            set
+            {
+                SetProperty( ref _axisLeftAmpFault , value );
+            }
+        }
+        public Brush AxisRightIsOrg
+        {
+            get { return _axisRightIsOrg; }
+            set
+            {
+                SetProperty( ref _axisRightIsOrg , value );
+            }
+        }
+        public Brush AxisRightAmpFault
+        {
+            get { return _axisRightAmpFault; }
+            set
+            {
+                SetProperty( ref _axisRightAmpFault , value );
+            }
+        }
+
+        #endregion
+
+        public ICommand ConveyorRunCommand { get; set; }
+        public ICommand PosMoveCommand { get; set; }
+
+        IEventAggregator eventAggregator;
+        MessageController messageController;
+
+        List<BitBlock> allIOList = new List<BitBlock>();
+
+<<<<<<< HEAD
+        EzIO iO = null; 
+
+        public ConveyorControlViewModel( IEventAggregator _ea , MessageController _msg, VCSystem vcSystem)
+=======
+        VCSystem VCSystem;
+        EzIO IO = null;
+
+        public ConveyorControlViewModel( IEventAggregator _ea , MessageController _msg, VCSystem _vcSystem)
+>>>>>>> eef332823de9e5e1c309ffa9e4d055ac4e281980
+        {
+            this.iO = vcSystem.IO as EzIO;
+            this.iO.OnChangedIO += IO_OnChangedIO;
+            this.eventAggregator = _ea;
+
+            this.VCSystem = _vcSystem;
+            this.IO = VCSystem.IO as EzIO;
+            this.IO.OnChangedIO += IO_OnChangedIO;
+            this.GetSensorState(this.IO);
+
+            /*Lock&UnLock Publish Event*/
+            this.eventAggregator.GetEvent<AxisControlPubSubEvent>().Unsubscribe( AxisUICallbackCommunication );
+            this.eventAggregator.GetEvent<AxisControlPubSubEvent>().Subscribe( AxisUICallbackCommunication , ThreadOption.UIThread );
+
+            /*GUI Pubsub Event*/
+            this.eventAggregator.GetEvent<GUIMessagePubSubEvent>().Unsubscribe( UICallbackCommunication );
+            this.eventAggregator.GetEvent<GUIMessagePubSubEvent>().Subscribe( UICallbackCommunication, ThreadOption.UIThread );
+
+            this.messageController = _msg;
+
+            this.ConveyorRunCommand = new DelegateCommand<object>( ExecuteCvCommand );
+            this.PosMoveCommand = new DelegateCommand<object>( ExecutePosMoveCommand );
+        }
+
+<<<<<<< HEAD
+        private void IO_OnChangedIO( BitBlock bit )
+        {
+            throw new NotImplementedException();
+=======
+        private void GetSensorState( EzIO _iO )
+        {
+            //IO_OnChangedIO 중복됨 어쩌지
+            if ( _iO.IsOn( "IN_CV_ERROR" ) )
+                this.CvError = Brushes.LimeGreen;
+
+            if(_iO.IsOn( "IN_CV_DETECT_00" ) )
+                this.CvEntryIn = Brushes.LimeGreen;
+
+            if ( _iO.IsOn( "IN_CV_DETECT_01" ) )
+                this.CvSlowStop = Brushes.LimeGreen;
+
+            if ( _iO.IsOn( "IN_CV_DETECT_02" ) )
+                this.CvStop = Brushes.LimeGreen;
+
+            if ( _iO.IsOn( "OUT_CV_RUN" , false ) )
+                this.CvRun = Brushes.LimeGreen;
+
+            if(_iO.IsOn( "OUT_CV_CWCCW", false ) )
+            {
+                this.CvCW = Brushes.LimeGreen;
+                this.CvCCW = Brushes.Gray;
+            }
+            else
+            {
+                this.CvCW = Brushes.Gray;
+                this.CvCCW = Brushes.LimeGreen;
+            }
+        }
+
+        private void IO_OnChangedIO( BitBlock bit )
+        {
+            if ( bit.Tag.Equals( "IN_CV_ERROR" ) )
+                this.CvError = Brushes.LimeGreen;
+            else
+                this.CvError = Brushes.Gray;
+
+            if ( bit.Tag.Equals( "IN_CV_DETECT_00" ) )
+                this.CvEntryIn = Brushes.LimeGreen;
+            else
+                this.CvEntryIn = Brushes.Gray;
+
+            if ( bit.Tag.Equals( "IN_CV_DETECT_01" ) )
+                this.CvSlowStop = Brushes.LimeGreen;
+            else
+                this.CvSlowStop = Brushes.Gray;
+
+            if ( bit.Tag.Equals( "IN_CV_DETECT_02" ) )
+                this.CvStop = Brushes.LimeGreen;
+            else
+                this.CvStop = Brushes.Gray;
+
+            if ( bit.Tag.Equals( "OUT_CV_CWCCW" ) )
+            {
+                this.CvCW = Brushes.LimeGreen;
+                this.CvCCW = Brushes.Gray;
+            }
+            else
+            {
+                this.CvCW = Brushes.Gray;
+                this.CvCCW = Brushes.LimeGreen;
+            }
+        }
+
+        private void RspIOState( VCSMessageEventArgs args )
+        {
+            //var ioAll = args.Args as EzIO;
+>>>>>>> eef332823de9e5e1c309ffa9e4d055ac4e281980
+        }
+
+        private void UICallbackCommunication( GUIMessageEventArgs _args )
+        {
+            if( _args.Kind == GUIMessageEventArgs.eGUIMessageKind.ModelPropertyChange)
+            {
+                if( _args.MessageKey.Equals(MessageKey.Vehicle))
+                {
+                    switch(_args.ModelPropertyName)
+                    {
+                        case "ObstacleStateProperty":
+                            {
+                                var reply = CastTo<eObstacleState>.From<object>( _args.Args );
+                                this.ChangeObstacleState( reply );
+                            }
+                            break;
+                    }
+                }
+            }
+        }
+
+        private void ChangeObstacleState( eObstacleState _reply )
+        {
+            
+        }
+
+        private void ExecutePosMoveCommand( object obj )
+        {
+            this.messageController.ShowConfirmationPopupView( "Carrier Move To ?" , r =>
+            {
+                if ( r.Result == ButtonResult.OK )
+                {
+                    var selectedPos = obj.ToString();
+
+                    var msg = new AxisControlEventArgs
+                    {
+                        Dir = AxisControlEventArgs.eEventDir.ToBack ,
+                        Kind = AxisControlEventArgs.eAxisControlKind.SyncMove ,
+                    };
+
+                    switch ( selectedPos )
+                    {
+                        case "Lock":
+                            msg.PosDir = AxisControlEventArgs.ePosDir.Lock;
+                            break;
+                        case "UnLock":
+                            msg.PosDir = AxisControlEventArgs.ePosDir.UnLock;
+                            break;
+                    }
+
+                    this.AxisPublishEvent( msg );
+                }
+            } );
+        }
+
+        private void AxisPublishEvent( AxisControlEventArgs msg )
+        {
+            this.eventAggregator.GetEvent<AxisControlPubSubEvent>().Publish( msg );
+        }
+
+        private void AxisUICallbackCommunication( AxisControlEventArgs _args )
+        {
+            if ( _args.Dir == AxisControlEventArgs.eEventDir.ToFront )
+            {
+                switch ( _args.Kind )
+                {
+                    case AxisControlEventArgs.eAxisControlKind.NONE:
+                        break;
+                    case AxisControlEventArgs.eAxisControlKind.OriginReturn:
+                        break;
+                    case AxisControlEventArgs.eAxisControlKind.Stop:
+                        break;
+                    case AxisControlEventArgs.eAxisControlKind.EStop:
+                        break;
+                    case AxisControlEventArgs.eAxisControlKind.Move:
+                        ResponseMove( _args );
+                        break;
+                    case AxisControlEventArgs.eAxisControlKind.Jog:
+                        break;
+                    case AxisControlEventArgs.eAxisControlKind.ServoOn:
+                        break;
+                    case AxisControlEventArgs.eAxisControlKind.ServoOff:
+                        break;
+                    case AxisControlEventArgs.eAxisControlKind.ReqCurrentPosition:
+                        break;
+                    case AxisControlEventArgs.eAxisControlKind.ReqStopCurrentPosition:
+                        break;
+                    case AxisControlEventArgs.eAxisControlKind.FaultReset:
+                        break;
+                    case AxisControlEventArgs.eAxisControlKind.AxisState:
+                        AxisState( _args );
+                        break;
+                    case eAxisControlKind.SyncMove:
+                        if ( _args.Result.IsSuccess )
+                            this.messageController.ShowNotificationView( "Success" );
+                        else
+                            this.messageController.ShowNotificationView( "Fail" );
+                        break;
+                }
+            }
+        }
+
+        private void ResponseMove( AxisControlEventArgs _args )
+        {
+            var msg = string.Empty;
+
+            if ( _args.Result.IsSuccess )
+                msg = ( "Move Success" );
+            else
+            {
+                var error = _args.Result.Errors.FirstOrDefault();
+                var alarm = error.Metadata[ "Alarm" ] as Alarm;
+                msg = alarm.Name + " " + alarm.Text;
+            }
+
+            this.messageController.ShowNotificationView( msg );
+        }
+
+        private void AxisState( AxisControlEventArgs args )
+        {
+            var left = args.Args[ "Left" ] as AxisState;
+            var right = args.Args[ "Right" ] as AxisState;
+
+            if ( left.IsOriginReturn )
+                this.AxisLeftIsOrg = Brushes.LimeGreen;
+            else
+                this.AxisLeftIsOrg = Brushes.Red;
+
+            if ( left.IsAmpFault )
+                this.AxisLeftAmpFault = Brushes.Red;
+            else
+                this.AxisLeftAmpFault = Brushes.Gray;
+
+            if ( right.IsOriginReturn )
+                this.AxisRightIsOrg = Brushes.LimeGreen;
+            else
+                this.AxisRightIsOrg = Brushes.Red;
+
+            if ( right.IsAmpFault )
+                this.AxisRightAmpFault = Brushes.Red;
+            else
+                this.AxisRightAmpFault = Brushes.Gray;
+        }
+
+        private void ExecuteCvCommand( object _obj )
+        {
+            var type = _obj.ToString();
+            DriveControlEventArgs.eCvDir dir = DriveControlEventArgs.eCvDir.NONE;
+
+            switch ( type )
+            {
+                case "CW":
+                    dir = DriveControlEventArgs.eCvDir.CW;
+                    break;
+                case "CCW":
+                    dir = DriveControlEventArgs.eCvDir.CCW;
+                    break;
+                case "STOP":
+                    dir = DriveControlEventArgs.eCvDir.STOP;
+                    break;
+            }
+
+            var msg = new DriveControlEventArgs
+            {
+                EventDir = DriveControlEventArgs.eEventDir.ToBack ,
+                ControlKind = DriveControlEventArgs.eControlKind.Conveyor ,
+                CvDir = dir
+            };
+            this.PublishEvent( msg );
+        }
+
+        private void PublishEvent( DriveControlEventArgs _args )
+        {
+            this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Publish( _args );
+        }
+
+        private void IOPublish( VCSMessageEventArgs _args )
+        {
+            this.eventAggregator.GetEvent<VCSMessagePubSubEvent>().Publish( _args );
+        }
+
+        #region Dialog
+        public bool CanCloseDialog( )
+        {
+            return true;
+        }
+
+        public void OnDialogClosed( )
+        {
+            this.eventAggregator.GetEvent<AxisControlPubSubEvent>().Publish( new AxisControlEventArgs 
+            { 
+                Dir = AxisControlEventArgs.eEventDir.ToBack, 
+                Kind = AxisControlEventArgs.eAxisControlKind.NONE 
+            } );
+            this.eventAggregator.GetEvent<AxisControlPubSubEvent>().Unsubscribe( AxisUICallbackCommunication );
+
+            this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Publish( new DriveControlEventArgs { EventDir = DriveControlEventArgs.eEventDir.ToBack , ControlKind = DriveControlEventArgs.eControlKind.ReqStopCurrentPos } );
+            //this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Unsubscribe( DriveControlCallBack );
+
+            this.eventAggregator.GetEvent<GUIMessagePubSubEvent>().Unsubscribe( UICallbackCommunication );
+        }
+
+        public void OnDialogOpened( IDialogParameters parameters )
+        {
+            /*IO*/
+            var msg = new VCSMessageEventArgs() { Kind = VCSMessageEventArgs.eVCSMessageKind.ReqIOObject };
+            this.eventAggregator.GetEvent<VCSMessagePubSubEvent>().Publish( msg );
+
+            /*Lock Axis*/
+            //var axisMsg = new AxisControlEventArgs
+            //{
+            //    Dir = AxisControlEventArgs.eEventDir.ToBack ,
+            //    Kind = AxisControlEventArgs.eAxisControlKind.NONE
+            //};
+            //this.AxisPublishEvent(axisMsg);
+
+            this.eventAggregator.GetEvent<AxisControlPubSubEvent>().Publish( new AxisControlEventArgs { Dir = AxisControlEventArgs.eEventDir.ToBack , Kind = AxisControlEventArgs.eAxisControlKind.ReqCurrentPosition } );
+        }
+
+
+        private void CloseDialog( string parameter )
+        {
+            ButtonResult result = ButtonResult.None;
+
+            if ( parameter?.ToLower() == "true" )
+                result = ButtonResult.OK;
+            else if ( parameter?.ToLower() == "false" )
+                result = ButtonResult.Cancel;
+
+            RaiseRequestClose( new DialogResult( result ) );
+        }
+
+        public virtual void RaiseRequestClose( IDialogResult dialogResult )
+        {
+            RequestClose?.Invoke( dialogResult );
+        }
+        #endregion
+    }
+}

+ 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 =>

+ 14 - 0
Dev/OHV/OHV.Vehicle/Concept/D_MainWindowViewModel.cs

@@ -245,6 +245,20 @@ namespace OHV.Vehicle.Concept
             this.LastBuildedTime = new Helpler.AssemblyInfo().Get_BuildDateTime();
 
             GSG.NET.Quartz.QuartzUtils.Invoke("RESOURCE_CHECK", GSG.NET.Quartz.QuartzUtils.GetExpnSecond(1), QuzOnResourceUsage);
+
+
+            string d = "016030AA0000";
+
+            string[] word = new string[ d.Length];
+
+            List<string> tList = new List<string>();
+            for(int i = 0; i<d.Length; i++ )
+            {
+                if( i % 2 == 0 )
+                {
+                    tList.Add( d.Substring( i , 2 ) );
+                }
+            }
         }
 
         private void ExecuteBuzzerStop( )

+ 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

@@ -274,7 +274,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);

+ 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;

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

@@ -28,11 +28,40 @@ 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 +387,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" );
+    }
+}

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

@@ -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();
@@ -173,8 +173,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" />