瀏覽代碼

Merge branch 'master' of http://unque781.synology.me:3000/GSI/OHV

# Conflicts:
#	Dev/OHV/VehicleControlSystem/ControlLayer/Serial/DataModel/ReceivedData.cs
ys-hwang 6 年之前
父節點
當前提交
547c2d430a
共有 24 個文件被更改,包括 2164 次插入286 次删除
  1. 3 0
      Dev/OHV/OHV.Common/Events/MessageEventArgs.cs
  2. 2 0
      Dev/OHV/OHV.Common/Model/Command.cs
  3. 7 1
      Dev/OHV/OHV.Common/Model/VehicleInfo.cs
  4. 16 1
      Dev/OHV/OHV.Common/Shareds/SharedEnumType.cs
  5. 1 0
      Dev/OHV/OHV.Module.ListViews/Views/CommandListViewModel.cs
  6. 39 0
      Dev/OHV/OHV.SqliteDAL/DAL/VehicleInfoDAL.cs
  7. 1 0
      Dev/OHV/OHV.SqliteDAL/ModelConfiguration.cs
  8. 1 0
      Dev/OHV/OHV.SqliteDAL/OHV.SqliteDAL.csproj
  9. 5 2
      Dev/OHV/OHV.SqliteDAL/OHVDbInitializer.cs
  10. 2 0
      Dev/OHV/OHV.SqliteDAL/SqliteManager.cs
  11. 20 1
      Dev/OHV/OHV.Vehicle/Concept/D_MainWindow.xaml
  12. 71 18
      Dev/OHV/OHV.Vehicle/Concept/D_MainWindowViewModel.cs
  13. 二進制
      Dev/OHV/OHV.Vehicle/Config/IO.xlsx
  14. 6 0
      Dev/OHV/VehicleControlSystem/ControlLayer/Motion/GSIMotion.cs
  15. 36 2
      Dev/OHV/VehicleControlSystem/ControlLayer/Serial/BatteryTabos/BMUManager.cs
  16. 1449 0
      Dev/OHV/VehicleControlSystem/ControlLayer/Serial/BatteryTabos/PCANBasic.cs
  17. 140 0
      Dev/OHV/VehicleControlSystem/ControlLayer/Serial/BatteryTabos/Peak.cs
  18. 11 2
      Dev/OHV/VehicleControlSystem/ControlLayer/Serial/DataModel/ReceivedData.cs
  19. 199 131
      Dev/OHV/VehicleControlSystem/ControlLayer/Vehicle.cs
  20. 5 3
      Dev/OHV/VehicleControlSystem/Managers/AutoManager.cs
  21. 113 88
      Dev/OHV/VehicleControlSystem/Managers/HostManager.cs
  22. 4 11
      Dev/OHV/VehicleControlSystem/Managers/Scheduler.cs
  23. 32 25
      Dev/OHV/VehicleControlSystem/VCSystem.cs
  24. 1 1
      Dev/OHV/VehicleControlSystem/VehicleControlSystem.csproj

+ 3 - 0
Dev/OHV/OHV.Common/Events/MessageEventArgs.cs

@@ -26,6 +26,7 @@ namespace OHV.Common.Events
             RspVehicleModeChange,
             RspEStop,
             RspVihicleState,
+            RspMachineModeChg,
         }
 
         //Property 이름임.
@@ -63,6 +64,7 @@ namespace OHV.Common.Events
             ReqVehicleModeChange,
             ReqEStop,
             ReqBuzzerStop,
+            ReqMachineModeChg,
         }
 
         public eVCSMessageKind Kind { get; set; }
@@ -70,6 +72,7 @@ namespace OHV.Common.Events
         public string MessageText { get; set; }
         public Command Command { get; set; }
         public Dictionary<string , object> Args { get; set; }
+        public object Arg { get; set; }
     }
 
     public class AxisControlEventArgs : EventArgs

+ 2 - 0
Dev/OHV/OHV.Common/Model/Command.cs

@@ -14,6 +14,8 @@ namespace OHV.Common.Model
         public DateTime CreateTime { get; set; }
         public eCommandType Type { get; set; }
         public eCommandState State { get; set; }
+        public eCommandByWho ByWho { get; set; }
+
         public eCommandResult Result { set; get; }
 
         /// <summary>

+ 7 - 1
Dev/OHV/OHV.Common/Model/VehicleInfo.cs

@@ -1,5 +1,7 @@
-using System;
+using OHV.Common.Shareds;
+using System;
 using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
@@ -8,10 +10,14 @@ namespace OHV.Common.Model
 {
     public class VehicleInfo
     {
+        [Key]
         public string VehicleID { get; set; }
+
         public string CurrentTag { get; set; }
         public double CurrentPosition { get; set; }
         public double CurrentSpeed { get; set; }
         public double CurrentTorque { get; set; }
+        public eVehicleState VehicleState { get; set; }
+        public eMachineMode MachineMode { get; set; }
     }
 }

+ 16 - 1
Dev/OHV/OHV.Common/Shareds/SharedEnumType.cs

@@ -72,7 +72,14 @@
 	}
     #endregion
 
-    #region Opertation
+    #region Operation
+	//Vehicle In/Out 보고 및 Vehicle 제어권 을 어디로 할지.
+	public enum eMachineMode
+	{
+		LocalMode,
+		HostMode,
+	}
+
     public enum eOperatationMode
 	{
 		ManualMode,
@@ -92,6 +99,14 @@
     #endregion
 
     #region Command
+	public enum eCommandByWho
+	{
+		Host,
+		HostOverWrite,
+		LocalSystem,
+		LocalOverWrite,
+	}
+
     public enum eCommandType
 	{
 		Move,

+ 1 - 0
Dev/OHV/OHV.Module.ListViews/Views/CommandListViewModel.cs

@@ -100,6 +100,7 @@ namespace OHV.Module.ListViews.Views
         private void ExecuteSaveCommand()
         {
             Command cmd = new Command() { TargetID = TargetID, Type = SelectedCommandType };
+            cmd.ByWho = eCommandByWho.LocalSystem;
 
             var route = sql.RouteDal.GetRoute( TargetID );
             if (route ==null )

+ 39 - 0
Dev/OHV/OHV.SqliteDAL/DAL/VehicleInfoDAL.cs

@@ -0,0 +1,39 @@
+using OHV.Common.Model;
+using OHV.Common.Shareds;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace OHV.SqliteDAL.DAL
+{
+    public class VehicleInfoDAL : GenericDAL<VehicleInfo>
+    {
+        public VehicleInfo GetInfo()
+        {
+            VehicleInfo info;
+            using ( var db = new OHVDbContext( "OHVDb" ) )
+            {
+                info = db.Set<VehicleInfo>().FirstOrDefault();
+            }
+            return info;
+        }
+
+        public void UpdateState( string id, eVehicleState state )
+        {
+            var info = GetK( id );
+            info.VehicleState = state;
+            Update( info );
+            base.OnChangedProperty();
+        }
+
+        public void UpdateTag( string id, string tag )
+        {
+            var info = GetK( id );
+            info.CurrentTag = tag;
+            Update( info );
+            base.OnChangedProperty();
+        }
+    }
+}

+ 1 - 0
Dev/OHV/OHV.SqliteDAL/ModelConfiguration.cs

@@ -21,6 +21,7 @@ namespace OHV.SqliteDAL
             modelBuilder.Entity<AxisConfig>();
             modelBuilder.Entity<Alarm>();
             modelBuilder.Entity<HisAlarm>();
+            modelBuilder.Entity<VehicleInfo>();
         }
     }
 }

+ 1 - 0
Dev/OHV/OHV.SqliteDAL/OHV.SqliteDAL.csproj

@@ -84,6 +84,7 @@
     <Compile Include="DAL\HisAlarmDAL.cs" />
     <Compile Include="DAL\RouteDAL.cs" />
     <Compile Include="DAL\SubCmdDAL.cs" />
+    <Compile Include="DAL\VehicleInfoDAL.cs" />
     <Compile Include="ModelConfiguration.cs" />
     <Compile Include="OHVDbContext.cs" />
     <Compile Include="OHVDbInitializer.cs" />

+ 5 - 2
Dev/OHV/OHV.SqliteDAL/OHVDbInitializer.cs

@@ -17,6 +17,8 @@ namespace OHV.SqliteDAL
         {
             //base.Seed( context );
             // Here you can seed your core data if you have any.
+            context.Set<VehicleInfo>().Add( new VehicleInfo { VehicleID = "V0001", CurrentTag="0000", VehicleState = eVehicleState.None } );
+
             context.Set<Config>().AddRange( new List<Config>()
             {
                 new Config
@@ -83,7 +85,7 @@ namespace OHV.SqliteDAL
                     Desc = "Drive Speed",
                     EditTime = DateTime.Now,
                 },
-            }) ;
+            } );
 
             context.Set<AxisPositionData>().AddRange( new List<AxisPositionData>()
             {
@@ -176,7 +178,8 @@ namespace OHV.SqliteDAL
                 new Alarm { AlarmId = 21, Kind = eAlarmKind.Axis, Name = "Conveyor",       Text="Unloading Position Wrong",                Solution="", Description="", Level = eAlarmLevel.Falut, },
                 new Alarm { AlarmId = 22, Kind = eAlarmKind.Axis, Name = "Init",           Text="Vehicle Drive Error",                     Solution="", Description="", Level = eAlarmLevel.Falut, },
                 new Alarm { AlarmId = 23, Kind = eAlarmKind.Axis, Name = "EStop",          Text="EStop",                                   Solution="", Description="", Level = eAlarmLevel.Falut, },
-            });
+                new Alarm { AlarmId = 24, Kind = eAlarmKind.Axis, Name = "Vehicle Move Error", Text="while Vehicle Move Obstacle Detected",Solution="", Description="", Level = eAlarmLevel.Falut, },
+            } );
 
             //context.Set<HisAlarm>().Add(new HisAlarm { AlarmId = 1, OccurTime = DateTime.Now.AddDays(-10) });
             context.Set<Route>().Add( new Route { Id = 1, Name = "P01", PrePoint = "P11", NextPoint = "P02", ScaleTolerance = 0.5, Form = eRoadForm.Straight, ScaleValue = 0.0, Type = ePointType.LoadPort, OCSMatchID = "1000", UsePIO = true } );

+ 2 - 0
Dev/OHV/OHV.SqliteDAL/SqliteManager.cs

@@ -22,6 +22,7 @@ namespace OHV.SqliteDAL
         public AxisVelocityDataDAL AxisVelocityDataDAL { get; set; }
         public AlarmDAL AlarmDAL { get; set; }
         public HisAlarmDAL HisAlarmDAL { get; set; }
+        public VehicleInfoDAL VehicleInfoDAL { get; set; }
 
         public SqliteManager()
         {
@@ -34,6 +35,7 @@ namespace OHV.SqliteDAL
             this.AxisVelocityDataDAL = new AxisVelocityDataDAL();
             this.AlarmDAL = new AlarmDAL();
             this.HisAlarmDAL = new HisAlarmDAL();
+            this.VehicleInfoDAL = new VehicleInfoDAL();
         }
 
         public void RegisterTypes(IContainerRegistry containerRegistry)

+ 20 - 1
Dev/OHV/OHV.Vehicle/Concept/D_MainWindow.xaml

@@ -14,6 +14,7 @@
         Background="{x:Null}" WindowStartupLocation="CenterScreen"
         xmlns:c ="clr-namespace:GSG.NET.WPF.CalcBinding;assembly=GSG.NET.WPF"
         xmlns:media ="clr-namespace:System.Windows.Media;assembly=PresentationCore"
+        xmlns:System="clr-namespace:System;assembly=mscorlib"
         >
 
     <Grid x:Name="GridMain" Background="{x:Null}">
@@ -180,7 +181,7 @@
                 <Grid Grid.Row="2">
                     <Border Margin="5" BorderBrush="#FF00FFD3" BorderThickness="2">
                     </Border>
-                    <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
+                    <!--<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
                         <StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
                             <Button Content="CPU" Margin="3" Background="{x:Null}"/>
                             <Button Content="Memory" Margin="3" Background="{x:Null}"/>
@@ -205,6 +206,24 @@
                             </Button>
 
                         </StackPanel>
+                    </StackPanel>-->
+                    <StackPanel Orientation="Vertical">
+
+                        <Button Margin="0,45,0,0" Width="200" Height="50"
+                                    Command="{Binding MachineModeChgCommand}"
+                                    CommandParameter="Host" Background="{c:Binding 'MachineMode == OHVCommonShareds:eMachineMode.LocalMode ? media:Brushes.Transparent : media:Brushes.DodgerBlue'}">
+                            <StackPanel Orientation="Horizontal">
+                                <materialDesign:PackIcon Kind="NetworkOff" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="35" Width="auto" Margin="0,0,20,0" 
+                                           Visibility="{c:Binding 'MachineMode == OHVCommonShareds:eMachineMode.LocalMode'}"/>
+                                <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="Local Mode" FontSize="15" 
+                                           Visibility="{c:Binding 'MachineMode == OHVCommonShareds:eMachineMode.LocalMode'}"/>
+                                <materialDesign:PackIcon Kind="Network" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="35" Width="auto" Margin="0,0,20,0"
+                                           Visibility="{c:Binding 'MachineMode == OHVCommonShareds:eMachineMode.HostMode'}"/>
+                                <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="Host Mode" FontSize="15"
+                                           Visibility="{c:Binding 'MachineMode == OHVCommonShareds:eMachineMode.HostMode'}" />
+                            </StackPanel>
+                        </Button>
+
                     </StackPanel>
                 </Grid>
 

+ 71 - 18
Dev/OHV/OHV.Vehicle/Concept/D_MainWindowViewModel.cs

@@ -29,8 +29,6 @@ namespace OHV.Vehicle.Concept
 {
     class D_MainWindowViewModel : BindableBase
     {
-        Logger loggerRemote = Logger.GetLogger("RemoteLogger");
-
         #region Properties
         private string _title = "Prism Unity Application";
         public string Title
@@ -131,7 +129,6 @@ namespace OHV.Vehicle.Concept
         }
 
         private bool isManualMode = true;
-
         public bool IsManualMode
         {
             get { return isManualMode; }
@@ -139,13 +136,19 @@ namespace OHV.Vehicle.Concept
         }
 
         private bool isVehicleAlarm = false;
-
         public bool IsVehicleAlarm
         {
             get { return isVehicleAlarm; }
             set { SetProperty(ref this.isVehicleAlarm, value); }
         }
 
+        private eMachineMode machineMode = eMachineMode.LocalMode;
+        public eMachineMode MachineMode
+        {
+            get { return machineMode; }
+            set { SetProperty(ref this.machineMode, value); }
+        }
+
         #endregion
 
         #region Brushes
@@ -190,6 +193,7 @@ namespace OHV.Vehicle.Concept
         public ICommand StopCommand { get; set; }
         public ICommand AlarmResetCommand { get; set; }
         public ICommand ChangeLanguage { get; set; }
+        public ICommand MachineModeChgCommand { get; set; }
         #endregion
 
         IEventAggregator eventAggregator = null;
@@ -232,6 +236,7 @@ namespace OHV.Vehicle.Concept
             this.AlarmResetCommand = new DelegateCommand( ExecuteAlarmResetCommand);
             this.EmergencyStopCommand = new DelegateCommand(ExecuteEStop);
             this.BuzzerStopCommand = new DelegateCommand( ExecuteBuzzerStop );
+            this.MachineModeChgCommand = new DelegateCommand<string>( ExecuteMachineModeChgCommand );
 
             DispatcherTimer dateTimer = new DispatcherTimer();
             dateTimer.Tick += (object sender, EventArgs e) =>
@@ -261,15 +266,6 @@ namespace OHV.Vehicle.Concept
             }
         }
 
-        private void ExecuteBuzzerStop( )
-        {
-            var msg = new VCSMessageEventArgs
-            {
-                Kind = VCSMessageEventArgs.eVCSMessageKind.ReqBuzzerStop ,
-            };
-            vcsMessagePublisher.Publish( msg );
-        }
-
         void QuzOnResourceUsage()
         {
             this.CPU = GSG.NET.OSView.Mgnt.CpuUseRate();
@@ -279,6 +275,35 @@ namespace OHV.Vehicle.Concept
             this.CDrive = ll.FirstOrDefault().AvailableFreeSpace / ConstUtils.ONE_GIGA_BYTES;
         }
 
+        private void ExecuteMachineModeChgCommand( string obj )
+        {
+            var msg = new VCSMessageEventArgs
+            {
+                Kind = VCSMessageEventArgs.eVCSMessageKind.ReqMachineModeChg,
+            };
+
+            if ( this.MachineMode == eMachineMode.LocalMode )
+                msg.Arg = eMachineMode.HostMode;
+            else
+                msg.Arg = eMachineMode.LocalMode;
+
+            this.messageController.ShowConfirmationPopupView( $"Change to {msg.Arg} ?", r => 
+            { 
+                if ( r.Result == ButtonResult.OK )
+                    vcsMessagePublisher.Publish( msg );
+            } );
+
+        }
+
+        private void ExecuteBuzzerStop( )
+        {
+            var msg = new VCSMessageEventArgs
+            {
+                Kind = VCSMessageEventArgs.eVCSMessageKind.ReqBuzzerStop ,
+            };
+            vcsMessagePublisher.Publish( msg );
+        }
+
         private void Execte_ChangeLanguage()
         {
             //LanguageHalper.LanguagesSelcter.ChangLanguage(LanguageHalper.eLanguageType.Chinese);
@@ -295,7 +320,6 @@ namespace OHV.Vehicle.Concept
 
         private void ExecuteAlarmResetCommand( )
         {
-            loggerRemote.I("123214wefsadfsdafsd");
             this.messageController.ShowConfirmationPopupView(" Alarm Reset ? ", r =>
             {
                 if (r.Result == ButtonResult.OK)
@@ -393,10 +417,10 @@ namespace OHV.Vehicle.Concept
 
         private void UICallbackCommunication(GUIMessageEventArgs obj)
         {
-            switch (obj.Kind)
+            switch ( obj.Kind )
             {
                 case GUIMessageEventArgs.eGUIMessageKind.ModelPropertyChange:
-                    this.UICallBackModelPropertyChange(obj);
+                    this.UICallBackModelPropertyChange( obj );
                     break;
                 case GUIMessageEventArgs.eGUIMessageKind.RspIOObject:
                     break;
@@ -411,13 +435,38 @@ namespace OHV.Vehicle.Concept
                 case GUIMessageEventArgs.eGUIMessageKind.RspAlarmReset:
                     break;
                 case GUIMessageEventArgs.eGUIMessageKind.RspVehicleModeChange:
-                    this.RspVehicleModeChange(obj);
+                    this.RspVehicleModeChange( obj );
+                    break;
+                case GUIMessageEventArgs.eGUIMessageKind.RspEStop:
+                    break;
+                case GUIMessageEventArgs.eGUIMessageKind.RspVihicleState:
+                    break;
+                case GUIMessageEventArgs.eGUIMessageKind.RspMachineModeChg:
+                    RspMachineModeChg(obj);
                     break;
                 default:
                     break;
             }
         }
 
+        private void RspMachineModeChg( GUIMessageEventArgs obj )
+        {
+            string reason = string.Empty;
+
+            FluentResults.Result result = obj.Result;
+            if ( obj.Result.IsFailed )
+            {
+                 reason = result.Errors.FirstOrDefault().Message;
+            }
+            else
+            {
+                var mode = CastTo<eMachineMode>.From<object>( obj.Args );
+                reason = $"Change To {mode} Successes";
+            }
+
+            this.messageController.ShowNotificationView( reason );
+        }
+
         private void RspVehicleModeChange(GUIMessageEventArgs obj)
         {
             if ( obj.Result.IsSuccess)
@@ -450,6 +499,11 @@ namespace OHV.Vehicle.Concept
                     else
                         this.IsVehicleAlarm = false;
                 }
+
+                if ( args.ModelPropertyName.Equals( "MachineMode" ) )
+                {
+                    this.MachineMode = CastTo<eMachineMode>.From<object>( args.Args );
+                }
             }
         }
 
@@ -513,7 +567,6 @@ namespace OHV.Vehicle.Concept
             //Inform the threads of the new culture.     
             Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
             Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
-
         }
     }
 }

二進制
Dev/OHV/OHV.Vehicle/Config/IO.xlsx


+ 6 - 0
Dev/OHV/VehicleControlSystem/ControlLayer/Motion/GSIMotion.cs

@@ -1,4 +1,5 @@
 using GSG.NET.Concurrent;
+using OHV.Common.Shareds;
 using OHV.SqliteDAL;
 using System;
 using System.Collections.Generic;
@@ -74,6 +75,11 @@ namespace VehicleControlSystem.ControlLayer.Motion
             return true;
         }
 
+        public void SetObstacleState( eObstacleState state )
+        {
+
+        }
+
         public bool VelocityChainge(double velocity)
         {
             return true;

+ 36 - 2
Dev/OHV/VehicleControlSystem/ControlLayer/Serial/BatteryTabos/BMUManager.cs

@@ -21,7 +21,7 @@ namespace VehicleControlSystem.ControlLayer.Serial.BatteryTabos
         public Config BMUConfig { get; set; }
         public bool IsConnected { get; set; }
 
-        internal Dictionary<string, ReceivedData> ReceivedDataDic = new Dictionary<string, DataModel.ReceivedData>();
+        internal Dictionary<eDataKind, ReceivedData> ReceivedDataDic = new Dictionary<string, DataModel.ReceivedData>();
         protected TsQueue<QueObject> qq = new TsQueue<QueObject>( 512 );
 
         public ThreadCancel cancel = new ThreadCancel();
@@ -47,7 +47,41 @@ namespace VehicleControlSystem.ControlLayer.Serial.BatteryTabos
 
         private void Init()
         {
-            EnumExtensions.GetValues<eDataKind>().ToList().ForEach( x => { this.ReceivedDataDic.Add( x.ToString(), new ReceivedData(x) ); } );
+            EnumExtensions.GetValues<eDataKind>().ToList().ForEach( x => 
+            {
+                var data = new ReceivedData( x );
+                switch ( x )
+                {
+                    case eDataKind.Volte:
+                        data.Scale = 0.01;
+                        break;
+                    case eDataKind.Current:
+                        data.Scale = 0.01;
+                        break;
+                    case eDataKind.BatteryState:
+                        break;
+                    case eDataKind.ChargeCompleteTime:
+                        break;
+                    case eDataKind.DisChargeCompleteTime:
+                        break;
+                    case eDataKind.SOC:
+                        break;
+                    case eDataKind.SOH:
+                        break;
+                    case eDataKind.ResidualCapacity:
+                        data.Scale = 0.01;
+                        break;
+                    case eDataKind.ResidualEnergy:
+                        data.Scale = 0.1;
+                        break;
+                    case eDataKind.Temperature:
+                        data.Scale = 0.1;
+                        break;
+                    default:
+                        break;
+                }
+                this.ReceivedDataDic.Add( x, data); 
+            } );
         }
 
         protected void EnqueueToNet( object o )

文件差異過大導致無法顯示
+ 1449 - 0
Dev/OHV/VehicleControlSystem/ControlLayer/Serial/BatteryTabos/PCANBasic.cs


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

@@ -2,6 +2,7 @@
 using GSG.NET.Extensions;
 using GSG.NET.Logging;
 using GSG.NET.TCP;
+using Peak.Can.Basic;
 using System;
 using System.Collections.Generic;
 using System.IO;
@@ -11,6 +12,9 @@ using System.Threading;
 using System.Threading.Tasks;
 using VehicleControlSystem.ControlLayer.Serial.DataModel;
 
+using TPCANTimestampFD = System.UInt64;
+using TPCANHandle = System.UInt16;
+
 namespace VehicleControlSystem.ControlLayer.Serial.BatteryTabos
 {
     public class Peak
@@ -23,6 +27,8 @@ namespace VehicleControlSystem.ControlLayer.Serial.BatteryTabos
 
         object lockObject = new object();
 
+        private TPCANHandle peakCanHandle;
+
         public Peak( BMUManager mrg )
         {
             this.manager = mrg;
@@ -50,6 +56,40 @@ namespace VehicleControlSystem.ControlLayer.Serial.BatteryTabos
         //Todo:Dll 에서 상태 가져오기
         bool IsConnected => true;
 
+        enum eMsgCaseFirst : int
+        {
+            Voltage_LOW = 2,
+            Voltage_HIGH = 3,
+
+            Current_LOW = 4,
+            Current_HIGH = 5,
+
+            BatteryBitStatus_LOW = 6,
+            BatteryBitStatus_HIGH = 7
+        }
+        enum eMsgCaseSecond : int
+        {
+            ChargeFull_LOW = 2,
+            ChargeFull_HIGH = 3,
+
+            DisChargeEmpty_LOW,
+            DisChargeEmpty_HIGH,
+
+            SOC,
+            SOH
+        }
+
+        enum eMsgCaseThird
+        {
+            Capacity_LOW = 2,
+            Capacity_High,
+
+            Energy_LOW,
+            Energy_HIGH,
+
+            Temperature_LOW,
+            Temperature_HIGH
+        }
 
         public void _ThreadPoolingReceiveData()
         {
@@ -68,6 +108,7 @@ namespace VehicleControlSystem.ControlLayer.Serial.BatteryTabos
                     if ( o is PollingObject ) //Scan 을 주기적 으로 진행.
                     {
                         this.PollingBattery();
+                        this.ReadMessage();
                     }
                     //else if ( o is ISetData ) //하나의 명령을 수행.
                     //{
@@ -109,6 +150,7 @@ namespace VehicleControlSystem.ControlLayer.Serial.BatteryTabos
                 switch ( kind )
                 {
                     case eDataKind.Volte:
+                        
                         break;
                     case eDataKind.Current:
                         break;
@@ -134,5 +176,103 @@ namespace VehicleControlSystem.ControlLayer.Serial.BatteryTabos
             } );
 
         }
+
+        /// <summary>
+        /// true = AutoSendMode, false = ManualSendMode
+        /// </summary>
+        /// <param name="auto"></param>
+        public int Write(bool auto = true)
+        {
+            var data = new TPCANMsg();
+            data.DATA = new byte[ 8 ];
+
+            data.ID = Convert.ToUInt32( "460" , 16 ); // ID 와 Battery NO 서로 같아야함.
+            data.LEN = Convert.ToByte( 8 );
+            data.MSGTYPE = TPCANMessageType.PCAN_MESSAGE_STANDARD;
+
+            data.DATA[0] = 0xAA;
+            if ( auto )
+                data.DATA[1] = 0xE0;
+            else
+                data.DATA[1] = 0x60;
+
+            var result = PeakCanWrite( this.peakCanHandle , data );
+
+            // Write Error
+            if ( result != TPCANStatus.PCAN_ERROR_OK )
+                return 9999;
+
+            return (int)result;
+        }
+
+        TPCANStatus PeakCanWrite(TPCANHandle handle, TPCANMsg msg)
+        {
+            return PCANBasic.Write( handle ,ref msg );
+        }
+
+
+        /// <summary>
+        /// Reading start 전 Connection 상태 체크
+        /// </summary>
+        /// <returns></returns>
+        TPCANStatus ReadMessage()
+        {
+            TPCANMsg canMsg;
+            TPCANTimestamp CANTimeStamp;
+            TPCANStatus stsResult;
+
+            // We execute the "Read" function of the PCANBasic                
+            //
+            stsResult = PCANBasic.Read( peakCanHandle , out canMsg , out CANTimeStamp );
+
+            if ( stsResult != TPCANStatus.PCAN_ERROR_QRCVEMPTY )
+                // We process the received message
+                this.PeackCANRecv( canMsg );
+
+            return stsResult;
+        }
+
+        void PeackCANRecv(TPCANMsg recv)
+        {
+            string packet = BitConverter.ToString( recv.DATA ).Replace( "-" , "" );
+            
+            List<string> sList = new List<string>();
+            for ( int i = 0; i < packet.Length; i++ )
+            {
+                if ( i % 2 == 0 )
+                    sList.Add( packet.Substring( i , 2 ) );
+            }
+
+            byte msgIndex = recv.DATA[ 1 ];
+
+            switch(msgIndex)
+            {
+                case 1:
+                    {
+                        this.manager.ReceivedDataDic[eDataKind.Volte].Value = double.Parse( sList[ ( int )eMsgCaseFirst.Voltage_HIGH ] + sList[ ( int )eMsgCaseFirst.Voltage_LOW ] , System.Globalization.NumberStyles.HexNumber );
+                        //this.manager.BMUConfig.Voltage = Int32.Parse( sList[(int)eMsgCaseFirst.Voltage_HIGH] + sList[(int)eMsgCaseFirst.Voltage_LOW] , System.Globalization.NumberStyles.HexNumber ) * 0.01;
+                        //this.manager.BMUConfig.Current = Int32.Parse( sList[(int)eMsgCaseFirst.Current_HIGH] + sList[(int)eMsgCaseFirst.Current_LOW] , System.Globalization.NumberStyles.HexNumber ) * 0.01;
+                        //this.manager.BMUConfig.BatteryStatus = Int32.Parse(sList[(int)eMsgCaseFirst.BatteryBitStatus_HIGH] + sList[(int)eMsgCaseFirst.BatteryBitStatus_LOW] , System.Globalization.NumberStyles.HexNumber );
+                    }
+                    break;
+                case 2:
+                    {
+                        //this.manager.BMUConfig.ChargeTime = Int32.Parse( sList[(int)eMsgCaseSecond.ChargeFull_HIGH] + sList[(int)eMsgCaseSecond.ChargeFull_LOW], System.Globalization.NumberStyles.HexNumber ) * 1;
+                        //this.manager.BMUConfig.DisChargeTime = Int32.Parse( sList[(int)eMsgCaseSecond.DisChargeEmpty_HIGH] + sList[(int)eMsgCaseSecond.DisChargeEmpty_LOW] , System.Globalization.NumberStyles.HexNumber ) * 1;
+                        //this.manager.BMUConfig.SOC = Int32.Parse( sList[(int)eMsgCaseSecond.SOC] , System.Globalization.NumberStyles.HexNumber );
+                        //this.manager.BMUConfig.SOH = Int32.Parse( sList[(int)eMsgCaseSecond.SOH] , System.Globalization.NumberStyles.HexNumber );
+                    }
+                    break;
+                case 3:
+                    {
+                        //this.manager.BMUConfig.Capacity = Int32.Parse( sList[(int)eMsgCaseThird.Capacity_High] + sList[(int)eMsgCaseThird.Capacity_LOW] , System.Globalization.NumberStyles.HexNumber ) * 0.01;
+                        //this.manager.BMUConfig.Energy = Int32.Parse( sList[(int)eMsgCaseThird.Energy_HIGH] + sList[(int)eMsgCaseThird.Energy_LOW] , System.Globalization.NumberStyles.HexNumber ) * 0.1;
+                        //this.manager.BMUConfig.Temperature = Int32.Parse( sList[(int)eMsgCaseThird.Temperature_HIGH] + sList[(int)eMsgCaseThird.Temperature_LOW] , System.Globalization.NumberStyles.HexNumber ) * 0.1;
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
     }
 }

+ 11 - 2
Dev/OHV/VehicleControlSystem/ControlLayer/Serial/DataModel/ReceivedData.cs

@@ -35,6 +35,9 @@ namespace VehicleControlSystem.ControlLayer.Serial.DataModel
     {
         public eDataKind DataKind { get; set; } = eDataKind.BatteryState;
         public eBatteryState BatteryState { get; set; }
+
+        public string OrgVule { get; set; }
+
         public double? Value { 
             get 
             { 
@@ -51,10 +54,16 @@ namespace VehicleControlSystem.ControlLayer.Serial.DataModel
                 }
             } 
         }
-        public string OrgVule { get; set; }
+        
+
+        //public double Value 
+        //{
+        //    get { return Value; }
+        //}
+        public string OrgValue { get; set; } = "0";
 
         public double Scale { get; set; }
-        public string Unit { get; set; }//단위를 붙이기 위해
+        public string Unit { get; set; } //단위를 붙이기 위해
         public bool IsChanged { get; set; }
 
         public ReceivedData(eDataKind kind)

+ 199 - 131
Dev/OHV/VehicleControlSystem/ControlLayer/Vehicle.cs

@@ -57,8 +57,14 @@ namespace VehicleControlSystem.ControlLayer
             get { return currentTag; }
             set
             {
-                if ( SetField( ref this.currentTag , value ) )
+                if ( SetField( ref this.currentTag, value ) )
+                {
+                    var info = sql.VehicleInfoDAL.GetInfo();
+                    info.CurrentTag = value;
+                    sql.VehicleInfoDAL.Update( info );
+
                     this.OnCurrentTagChanged?.Invoke( value );
+                }
             }
         }
 
@@ -71,7 +77,7 @@ namespace VehicleControlSystem.ControlLayer
             get { return currentPosition; }
             set
             {
-                if ( SetField( ref this.currentPosition , value ) )
+                if ( SetField( ref this.currentPosition, value ) )
                 {
                 }
             }
@@ -81,41 +87,41 @@ namespace VehicleControlSystem.ControlLayer
         public double CurrentSpeed
         {
             get { return currentSpeed; }
-            set { SetField( ref this.currentSpeed , value ); }
+            set { SetField( ref this.currentSpeed, value ); }
         }
 
         private double currentTorque;
         public double CurrentTorque
         {
             get { return currentTorque; }
-            set { SetField( ref this.currentTorque , value ); }
+            set { SetField( ref this.currentTorque, value ); }
         }
 
         private bool isContain;
         public bool IsContain
         {
             get { return isContain; }
-            set { SetField( ref this.isContain , value ); }
+            set { SetField( ref this.isContain, value ); }
         }
 
         eClampState _clampState;
         public eClampState ClampState
         {
             get { return this._clampState; }
-            set { this.SetField( ref this._clampState , value ); }
+            set { this.SetField( ref this._clampState, value ); }
         }
 
         private eSteeringState steeringState;
         public eSteeringState SteeringState
         {
             get { return steeringState; }
-            set { SetField( ref this.steeringState , value ); }
+            set { SetField( ref this.steeringState, value ); }
         }
 
         private int _obstacleDrive;
-        public int ObstacleDrive { get { return this._obstacleDrive; } set { SetField( ref this._obstacleDrive , value ); } }
+        public int ObstacleDrive { get { return this._obstacleDrive; } set { SetField( ref this._obstacleDrive, value ); } }
         private int _obstacleCurve;
-        public int ObstacleCurve { get { return this._obstacleCurve; } set { SetField( ref this._obstacleCurve , value ); } }
+        public int ObstacleCurve { get { return this._obstacleCurve; } set { SetField( ref this._obstacleCurve, value ); } }
 
         private eObstacleState obstacleState = eObstacleState.Normal;
         public eObstacleState ObstacleStateProperty
@@ -123,7 +129,7 @@ namespace VehicleControlSystem.ControlLayer
             get { return obstacleState; }
             set
             {
-                if ( SetField( ref this.obstacleState , value ) )
+                if ( SetField( ref this.obstacleState, value ) )
                 {
                     if ( value == eObstacleState.Blocked )
                         this.VehicleStateProperty = eVehicleState.Blocked;
@@ -131,11 +137,34 @@ namespace VehicleControlSystem.ControlLayer
             }
         }
 
-        private eVehicleState vehicleState;
+        private eVehicleState vehicleState = eVehicleState.None;
         public eVehicleState VehicleStateProperty
         {
             get { return vehicleState; }
-            set { SetField( ref this.vehicleState , value ); }
+            set
+            {
+                if ( SetField( ref this.vehicleState, value ) )
+                {
+                    var info = sql.VehicleInfoDAL.GetInfo();
+                    info.VehicleState = value;
+                    sql.VehicleInfoDAL.Update( info );
+                }
+            }
+        }
+
+        private eMachineMode machineMode = eMachineMode.LocalMode;
+        public eMachineMode MachineMode
+        {
+            get { return machineMode; }
+            set 
+            { 
+                if (SetField(ref this.machineMode, value ) )
+                {
+                    var info = sql.VehicleInfoDAL.GetInfo();
+                    info.MachineMode = value;
+                    sql.VehicleInfoDAL.Update( info );
+                }
+            }
         }
 
         //이동
@@ -201,7 +230,7 @@ namespace VehicleControlSystem.ControlLayer
 
         IEventAggregator eventAggregator;
 
-        public Vehicle( IIO io , SqliteManager sqliteManager , IEventAggregator ea , AutoManager auto )
+        public Vehicle( IIO io, SqliteManager sqliteManager, IEventAggregator ea, AutoManager auto )
         {
             this.iO = io as EzIO;
             this.iO.OnChangedIO += IO_OnChangedIO;
@@ -251,9 +280,9 @@ namespace VehicleControlSystem.ControlLayer
                         {
                             var msg = new ObstacleControlEventArgs
                             {
-                                ControlKind = ObstacleControlEventArgs.eControlKind.INFO ,
-                                Drive = this.ObstacleDrive ,
-                                Curve = this.ObstacleCurve ,
+                                ControlKind = ObstacleControlEventArgs.eControlKind.INFO,
+                                Drive = this.ObstacleDrive,
+                                Curve = this.ObstacleCurve,
                                 ObstacleState = this.ObstacleStateProperty.ToString()
                             };
                             this.ObstacleControlEventPublish( msg );
@@ -266,7 +295,7 @@ namespace VehicleControlSystem.ControlLayer
 
                             var reply = new ObstacleControlEventArgs
                             {
-                                    ControlKind = ObstacleControlEventArgs.eControlKind.SAVE
+                                ControlKind = ObstacleControlEventArgs.eControlKind.SAVE
                             };
                             reply.Result = Results.Ok( ObstacleControlEventArgs.eControlKind.SAVE );
                             this.ObstacleControlEventPublish( reply );
@@ -282,7 +311,6 @@ namespace VehicleControlSystem.ControlLayer
             this.eventAggregator.GetEvent<ObstacleControlPubSubEvent>().Publish( args );
         }
 
-
         private void ReceiveDriveControlEvent( DriveControlEventArgs _args )
         {
             if ( this.autoManager.OperationModeProperty != eOperatationMode.ManualMode )
@@ -351,11 +379,11 @@ namespace VehicleControlSystem.ControlLayer
         private void ReqConveyor( DriveControlEventArgs args )
         {
             if ( args.CvDir == DriveControlEventArgs.eCvDir.CW )
-                this.OnOffConveyor( true , true );
+                this.OnOffConveyor( true, true );
             else if ( args.CvDir == DriveControlEventArgs.eCvDir.CCW )
-                this.OnOffConveyor( true , false );
+                this.OnOffConveyor( true, false );
             else if ( args.CvDir == DriveControlEventArgs.eCvDir.STOP )
-                this.OnOffConveyor( false , false );
+                this.OnOffConveyor( false, false );
         }
 
         private void DriveControlEventPublish( DriveControlEventArgs args )
@@ -364,7 +392,7 @@ namespace VehicleControlSystem.ControlLayer
             this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Publish( args );
         }
 
-        public void Init( )
+        public void Init()
         {
             this.CreateClamp();
             this.CreateSteering();
@@ -374,9 +402,15 @@ namespace VehicleControlSystem.ControlLayer
             ThreadStart();
 
             //TimerUtils.Once(5000, () => { this.CurrentPosition = 1000; });
+            var v = sql.VehicleInfoDAL.GetInfo();
+            v.CurrentTag = "0000";
+            v.VehicleState = eVehicleState.None;
+            v.MachineMode = eMachineMode.LocalMode;
+
+            sql.VehicleInfoDAL.Update( v );
         }
 
-        public int InitializationVehicle( )
+        public int InitializationVehicle()
         {
             int result = 0;
             if ( this.IsDetectedCenter() ) //자제가 있으면 Lock
@@ -390,7 +424,7 @@ namespace VehicleControlSystem.ControlLayer
             return result;
         }
 
-        public void Dispose( )
+        public void Dispose()
         {
             this.cancel.Cancel();
             this.cancel.StopWaitAll();
@@ -457,9 +491,9 @@ namespace VehicleControlSystem.ControlLayer
                 drive = "NEGATIVE";
         }
 
-        void ReqCurrentPos( )
+        void ReqCurrentPos()
         {
-            var task = Task.Factory.StartNew( ( ) =>
+            var task = Task.Factory.StartNew( () =>
              {
                  while ( !this.taskCancel.Canceled )
                  {
@@ -467,9 +501,9 @@ namespace VehicleControlSystem.ControlLayer
 
                      var msg = new DriveControlEventArgs
                      {
-                         EventDir = DriveControlEventArgs.eEventDir.ToFront ,
-                         ControlKind = DriveControlEventArgs.eControlKind.ReqCurrentPos ,
-                         CurrentPosition = new Random().Next( 0 , 1000 ) ,
+                         EventDir = DriveControlEventArgs.eEventDir.ToFront,
+                         ControlKind = DriveControlEventArgs.eControlKind.ReqCurrentPos,
+                         CurrentPosition = new Random().Next( 0, 1000 ),
                      };
 
                      this.DriveControlEventPublish( msg );
@@ -509,7 +543,7 @@ namespace VehicleControlSystem.ControlLayer
         #endregion
 
         #region Thread
-        void ThreadStart( )
+        void ThreadStart()
         {
             this.cancel.AddGo( new Action( this._ThSubCmdWorker ) );
             this.cancel.AddGo( new Action( this._ThObstacleChecker ) );
@@ -517,7 +551,7 @@ namespace VehicleControlSystem.ControlLayer
 
         //장애물 감지 Thread
         //장애물 감지 패턴 변경도 여기 하자.
-        private void _ThObstacleChecker( )
+        private void _ThObstacleChecker()
         {
             while ( !this.cancel.Canceled )
             {
@@ -544,7 +578,7 @@ namespace VehicleControlSystem.ControlLayer
         /// <summary>
         /// Scheduler 가 주는 Sub Command 를 이용하여 동작하자.
         /// </summary>
-        public void _ThSubCmdWorker( )
+        public void _ThSubCmdWorker()
         {
             while ( !this.cancel.Canceled )
             {
@@ -610,7 +644,7 @@ namespace VehicleControlSystem.ControlLayer
         #endregion
 
         #region Control Action Method
-        public void EStop( )
+        public void EStop()
         {
             //Clamp EStop
             this.clamp.ClampEStop();
@@ -639,32 +673,39 @@ namespace VehicleControlSystem.ControlLayer
             ////TimerUtils.Once(3000, BuzzerOnOff, false, eBuzzerKind.StartWarn );
             //Thread.Sleep(3000);
             //this.BuzzerOnOff(false);
-            this.VehicleStateProperty = eVehicleState.Move;
 
-            this.OnMoveReady?.Invoke();
+            if ( this.VehicleStateProperty == eVehicleState.Idle )
+            {
+                this.OnMoveReady?.Invoke();
+
+                var moveReadyBuzzerTime = sql.ConfigDal.GetValueToInt( ConstString.BuzzerStartReadyTime );
+                Thread.Sleep( moveReadyBuzzerTime );
 
-            var moveReadyBuzzerTime = sql.ConfigDal.GetValueToInt( ConstString.BuzzerStartReadyTime );
-            Thread.Sleep( moveReadyBuzzerTime );
+                this.VehicleStateProperty = eVehicleState.Move;
+            }
 
             this.OnMoving?.Invoke();
             this.IsMoving = true;
 
             //this.BuzzerOnOff(true, eBuzzerKind.Moving);
-            this.motion.MoveToPoint( pointID , 100 );
+            this.motion.MoveToPoint( pointID, 100 );
 
             bool result = Wait4MoveDone();
-            this.IsMoving = false;
             //this.BuzzerOnOff(false);
-            this.OnMoveFinish?.Invoke();
+            if ( motion.IsStop )
+            {
+                this.IsMoving = false;
+                this.OnMoveFinish?.Invoke();
 
-            this.VehicleStateProperty = eVehicleState.Idle;
+                this.VehicleStateProperty = eVehicleState.Idle;
+            }
 
             return result;
         }
 
-        bool Wait4MoveDone( )
+        bool Wait4MoveDone()
         {
-            int waitTime = 6000; //설정 할 수있게.
+            int waitTime = 9000; //설정 할 수있게.
             long st = SwUtils.CurrentTimeMillis;
 
             //Todo: 이동시 확인 사항들.
@@ -672,19 +713,43 @@ namespace VehicleControlSystem.ControlLayer
             {
                 Thread.Sleep( 5 );
 
-                if ( SwUtils.Gt( st , waitTime ) )
+                if ( SwUtils.Gt( st, waitTime ) )
                 {
                     //Todo: 이동시간 초과 시 동작들.
                     break;
                 }
 
-                if ( this.ObstacleStateProperty == eObstacleState.Blocked )
-                    return false;
-
                 //Todo: 이동중 명령이 삭제 되면 처리 할일들.
-                //if (!sql.SubCmdDAL.HasK(this.CurrentSubCommand.ID))
-                //{
-                //}
+                //이동중 메인 명력이 없어진다면 정지 후 
+                if ( !sql.CommandDAL.HasK( this.CurrentSubCommand.CmdID ) )
+                {
+                    logger.D( "[Wait Move Done] - 메인 명령 사라짐" );
+                    var cmd = sql.CommandDAL.GetCmd();
+                    if ( cmd == null )
+                    {
+                        logger.D( "[Wait Move Done] - Main Command not Exist Motion Stop" );
+                        motion.Stop();
+                        return true;
+                    }
+                    else
+                    {
+                        logger.D( "[Wait Move Done] - Main Command not Exist Motion command 없음" );
+                        return true;
+                    }
+                }
+
+                if ( this.ObstacleStateProperty != eObstacleState.Normal )
+                {
+                    if ( this.ObstacleStateProperty == eObstacleState.Blocked )
+                        this.VehicleStateProperty = eVehicleState.Blocked;
+
+                    if ( this.ObstacleStateProperty == eObstacleState.Abnormal )
+                    {
+                        this.VehicleStateProperty = eVehicleState.Abnormal;
+                        this.OccurVehicleAlarm( 24 );
+                        return false;
+                    }
+                }
             }
 
             return true;
@@ -696,7 +761,7 @@ namespace VehicleControlSystem.ControlLayer
 
             var route = sql.RouteDal.GetRoute( sub.TargetID );
 
-            if ( !CorrectPosition( route , this.CurrentPosition ) )
+            if ( !CorrectPosition( route, this.CurrentPosition ) )
             {
                 this.OccurVehicleAlarm( 20 );
                 return false; //Alarm
@@ -724,7 +789,7 @@ namespace VehicleControlSystem.ControlLayer
             }
 
             //Load, Unload 가 끝나면 메인 Command 를 완료 했다고 판단.
-            sql.CommandDAL.UpdateState( sub.CmdID , eCommandState.Complete );
+            sql.CommandDAL.UpdateState( sub.CmdID, eCommandState.Complete );
             sql.SubCmdDAL.Delete( sub );
 
             this.VehicleStateProperty = eVehicleState.Idle;
@@ -738,7 +803,7 @@ namespace VehicleControlSystem.ControlLayer
 
             var route = sql.RouteDal.GetRoute( sub.TargetID );
 
-            if ( !CorrectPosition( route , this.CurrentPosition ) )
+            if ( !CorrectPosition( route, this.CurrentPosition ) )
             {
                 this.OccurVehicleAlarm( 21 );
                 return false; //Alarm
@@ -758,7 +823,7 @@ namespace VehicleControlSystem.ControlLayer
                 return false;
             }
 
-            sql.CommandDAL.UpdateState( sub.CmdID , eCommandState.Complete );
+            sql.CommandDAL.UpdateState( sub.CmdID, eCommandState.Complete );
             sql.SubCmdDAL.Delete( sub );
 
             this.VehicleStateProperty = eVehicleState.Idle;
@@ -776,7 +841,7 @@ namespace VehicleControlSystem.ControlLayer
         {
             var route = sql.RouteDal.GetRoute( sub.TargetID );
 
-            if ( !CorrectPosition( route , this.CurrentPosition ) )
+            if ( !CorrectPosition( route, this.CurrentPosition ) )
             {
                 this.OccurVehicleAlarm( 21 );
                 return false; //Alarm
@@ -795,10 +860,10 @@ namespace VehicleControlSystem.ControlLayer
                 //return 0;
             }
 
-            this.iO.WriteOutputIO( "OUT_PIO_READY" , true );
+            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" );
@@ -806,7 +871,7 @@ namespace VehicleControlSystem.ControlLayer
                 //return 0;
             }
 
-            this.iO.WriteOutputIO( "OUT_PIO_SENDING_RUN" , true );
+            this.iO.WriteOutputIO( "OUT_PIO_SENDING_RUN", true );
             loggerPIO.I( "[Vehicle] - 2 Send Run On" );
 
             this.SetConveyorSpeed( true );
@@ -816,10 +881,10 @@ namespace VehicleControlSystem.ControlLayer
             var sTime = SwUtils.CurrentTimeMillis;
             while ( true )
             {
-                if ( SwUtils.Gt( sTime , 20 * ConstUtils.ONE_SECOND ) )
+                if ( SwUtils.Gt( sTime, 20 * ConstUtils.ONE_SECOND ) )
                 {
                     PIOClear();
-                    this.OnOffConveyor( false , true );
+                    this.OnOffConveyor( false, true );
                     loggerPIO.E( "[Port] Conveyor Wait Time Out" );
                     this.OnFailReport?.Invoke( eFailCode.UnlaodPIOInterlockTimeout );
 
@@ -840,8 +905,8 @@ namespace VehicleControlSystem.ControlLayer
             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();
 
@@ -852,30 +917,31 @@ namespace VehicleControlSystem.ControlLayer
         #endregion
 
         #region Check Method
-        bool CheckObstacle( )
+        bool CheckObstacle()
         {
             if ( this.iO.IsOn( "IN_OBSTRUCTION_DETECT_SAFETY" ) || this.iO.IsOn( "IN_OBSTRUCTION_DETECT_ERROR" ) )
             {
-                this.motion.Stop();
                 this.ObstacleStateProperty = eObstacleState.Abnormal;
+                this.motion.SetObstacleState( this.ObstacleStateProperty );
                 return true;
             }
 
             if ( this.iO.IsOn( "IN_OBSTRUCTION_DETECT_STOP" ) )
             {
-                this.motion.Stop();
                 this.ObstacleStateProperty = eObstacleState.Blocked;
+                this.motion.SetObstacleState( this.ObstacleStateProperty );
                 return true;
             }
 
             if ( this.iO.IsOn( "IN_OBSTRUCTION_DETECT_SLOW" ) )
             {
-                this.motion.SlowStop();
                 this.ObstacleStateProperty = eObstacleState.Decelerate;
+                this.motion.SetObstacleState( this.ObstacleStateProperty );
                 return true;
             }
 
             this.ObstacleStateProperty = eObstacleState.Normal;
+            this.motion.SetObstacleState( this.ObstacleStateProperty );
 
             return false;
         }
@@ -891,7 +957,7 @@ namespace VehicleControlSystem.ControlLayer
         /// <param name="isOn"></param>
         /// <param name="isCW"></param>
         /// <returns></returns>
-        int OnOffConveyor( bool isOn , bool isCW = false )
+        int OnOffConveyor( bool isOn, bool isCW = false )
         {
             if ( IsInverterError() )
                 return 16;
@@ -912,45 +978,45 @@ namespace VehicleControlSystem.ControlLayer
         void SetConveyorSpeed( bool IsHight )
         {
             if ( IsHight )
-                this.iO.WriteOutputIO( "OUT_CV_DA" , true );
+                this.iO.WriteOutputIO( "OUT_CV_DA", true );
             else
-                this.iO.WriteOutputIO( "OUT_CV_DA" , false );
+                this.iO.WriteOutputIO( "OUT_CV_DA", false );
         }
 
-        bool IsCvRun( ) => this.iO.IsOn( "OUT_CV_RUN" );
-        bool IsCvCWCCW( ) => this.iO.IsOn( "OUT_CV_CWCCW" );
+        bool IsCvRun() => this.iO.IsOn( "OUT_CV_RUN" );
+        bool IsCvCWCCW() => this.iO.IsOn( "OUT_CV_CWCCW" );
 
         /// <summary>
         /// 입구 감지 로딩시 감속 사용
         /// </summary>
         /// <returns></returns>
-        bool IsDetectedLoadStart( ) => this.iO.IsOn( "IN_CV_DETECT_00" );
+        bool IsDetectedLoadStart() => this.iO.IsOn( "IN_CV_DETECT_00" );
 
         /// <summary>
         /// 실물 감지
         /// </summary>
         /// <returns></returns>
-        public bool IsDetectedCenter( ) => this.iO.IsOn( "IN_CV_DETECT_01" );
+        public bool IsDetectedCenter() => this.iO.IsOn( "IN_CV_DETECT_01" );
 
-        bool IsDetectedLoadStop( ) => this.iO.IsOn( "IN_CV_DETECT_02" );
-        bool IsInverterError( ) => this.iO.IsOn( "IN_CV_ERROR" );
-        bool IsLifterPositinCheck( ) => this.iO.IsOn( "IN_LIFTER_POSITION_DETECT" );
-        bool IsLifterDuplication( ) => this.iO.IsOn( "IN_LIFTER_DUPLICATION_DETECT" );
-        bool IsPIOInterLockOn( ) => this.iO.IsOn( "OUT_PIO_INTERLOCK" );
+        bool IsDetectedLoadStop() => this.iO.IsOn( "IN_CV_DETECT_02" );
+        bool IsInverterError() => this.iO.IsOn( "IN_CV_ERROR" );
+        bool IsLifterPositinCheck() => this.iO.IsOn( "IN_LIFTER_POSITION_DETECT" );
+        bool IsLifterDuplication() => this.iO.IsOn( "IN_LIFTER_DUPLICATION_DETECT" );
+        bool IsPIOInterLockOn() => this.iO.IsOn( "OUT_PIO_INTERLOCK" );
 
-        int Load_Carrier( )
+        int Load_Carrier()
         {
             if ( IsDetectedCenter() )
                 return 9;
 
-            OnOffConveyor( true , true );
+            OnOffConveyor( true, true );
 
             long sTime = SwUtils.CurrentTimeMillis;
             while ( true )
             {
-                if ( SwUtils.Gt( sTime , 20 * ConstUtils.ONE_SECOND ) ) //Wait 20Sec
+                if ( SwUtils.Gt( sTime, 20 * ConstUtils.ONE_SECOND ) ) //Wait 20Sec
                 {
-                    OnOffConveyor( false , true );
+                    OnOffConveyor( false, true );
                     return 10;
                 }
 
@@ -961,19 +1027,19 @@ namespace VehicleControlSystem.ControlLayer
             return 0;
         }
 
-        int UnloadCarrier( )
+        int UnloadCarrier()
         {
             if ( !IsDetectedLoadStart() )
                 return 11;
 
-            OnOffConveyor( true , true );
+            OnOffConveyor( true, true );
 
             long sTime = SwUtils.CurrentTimeMillis;
             while ( true )
             {
-                if ( SwUtils.Gt( sTime , 20 * ConstUtils.ONE_SECOND ) ) //Wait 20Sec
+                if ( SwUtils.Gt( sTime, 20 * ConstUtils.ONE_SECOND ) ) //Wait 20Sec
                 {
-                    OnOffConveyor( false , true );
+                    OnOffConveyor( false, true );
                     return 12;
                 }
 
@@ -988,25 +1054,25 @@ namespace VehicleControlSystem.ControlLayer
         {
 #if SIMULATION
             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" );
 
-            Thread.Sleep(1000);//상대 IO 기다린다 생각.
-            loggerPIO.E("[Port] - 4 Ready On");
+            Thread.Sleep( 1000 );//상대 IO 기다린다 생각.
+            loggerPIO.E( "[Port] - 4 Ready On" );
 
             //Conveyor Start
-            loggerPIO.I("[Vehicle] - Conveyor Run");
-            this.OnConveyorStart?.Invoke(true);
+            loggerPIO.I( "[Vehicle] - Conveyor Run" );
+            this.OnConveyorStart?.Invoke( true );
 
-            Thread.Sleep(10000);//Conveyor 구동
-            this.OnCarrierDetected?.Invoke(true);
+            Thread.Sleep( 10000 );//Conveyor 구동
+            this.OnCarrierDetected?.Invoke( true );
 
             PIOClear();
-            Thread.Sleep(1000);
-            this.OnConveyorStop?.Invoke(true);
+            Thread.Sleep( 1000 );
+            this.OnConveyorStop?.Invoke( true );
 #else
             var pioTimeout = sql.ConfigDal.GetValueToInt( ConstString.PIOTimeOut );
 
@@ -1113,20 +1179,20 @@ namespace VehicleControlSystem.ControlLayer
         {
 #if SIMULATION
             PIOClear();
-            loggerPIO.I($"Start Unload PIO - [{targetName}]");
-            this.OnPIOStart?.Invoke(false);
+            loggerPIO.I( $"Start Unload PIO - [{targetName}]" );
+            this.OnPIOStart?.Invoke( false );
 
-            Thread.Sleep(1000);
+            Thread.Sleep( 1000 );
 
-            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" );
 
-            Thread.Sleep(1000);
-            this.OnConveyorStart?.Invoke(false);
+            Thread.Sleep( 1000 );
+            this.OnConveyorStart?.Invoke( false );
 
-            Thread.Sleep(10000);
-            this.OnOffConveyor(false); //Stop
-            this.OnConveyorStop?.Invoke(false);
+            Thread.Sleep( 10000 );
+            this.OnOffConveyor( false ); //Stop
+            this.OnConveyorStop?.Invoke( false );
             PIOClear();
 
             this.OnUnloadComplete?.Invoke();
@@ -1216,9 +1282,9 @@ namespace VehicleControlSystem.ControlLayer
             return 0;
         }
 
-        void PIOClear( )
+        void PIOClear()
         {
-            string[] pio = { "OUT_PIO_READY" , "OUT_PIO_SENDING_RUN" , "OUT_PIO_SEND_COMPLITE" , "OUT_PIO_RECEIVABLE" , "OUT_PIO_RECEIVE_RUN" , "OUT_PIO_RECIVE_COMPLITE" , "OUT_PIO_INTERLOCK" };
+            string[] pio = { "OUT_PIO_READY", "OUT_PIO_SENDING_RUN", "OUT_PIO_SEND_COMPLITE", "OUT_PIO_RECEIVABLE", "OUT_PIO_RECEIVE_RUN", "OUT_PIO_RECIVE_COMPLITE", "OUT_PIO_INTERLOCK" };
             pio.FwEach( x => { this.iO.OutputOff( x ); } );
         }
 
@@ -1227,19 +1293,19 @@ namespace VehicleControlSystem.ControlLayer
         #endregion
 
         #region Hardware Create Method
-        void CreateSteering( )
+        void CreateSteering()
         {
-            this.steering = new Steering( this.iO , this.sql , this.eventAggregator );
+            this.steering = new Steering( this.iO, this.sql, this.eventAggregator );
             this.steering.OnSteeringError += Steering_OnSteeringError;
             this.steering.PropertyChanged += Steering_PropertyChanged;
         }
-        void CreateClamp( )
+        void CreateClamp()
         {
-            this.clamp = new Clamp( this.sql , this.eventAggregator );
+            this.clamp = new Clamp( this.sql, this.eventAggregator );
             this.clamp.Init();
             this.clamp.PropertyChanged += Clamp_PropertyChanged;
         }
-        void CreateDrive( )
+        void CreateDrive()
         {
             this.motion = new GSIMotion( this.sql );
             this.motion.PropertyChanged += Motion_PropertyChanged;
@@ -1274,6 +1340,7 @@ namespace VehicleControlSystem.ControlLayer
             switch ( kind )
             {
                 case eDataKind.Volte:
+                    this.BatteryVolt = obj.Value;
                     break;
                 case eDataKind.Current:
                     break;
@@ -1308,7 +1375,7 @@ namespace VehicleControlSystem.ControlLayer
         /// <param name="route"></param>
         /// <param name="currentPosition"></param>
         /// <returns></returns>
-        bool CorrectPosition( Route route , double currentPosition )
+        bool CorrectPosition( Route route, double currentPosition )
         {
             var rScale = route.ScaleValue;
             var rTolerance = route.ScaleTolerance;
@@ -1332,7 +1399,7 @@ namespace VehicleControlSystem.ControlLayer
             int bitIndex = 0;
             this.obstacleBitList.ForEach( b =>
              {
-                 if ( bitArray[ bitIndex ] )
+                 if ( bitArray[bitIndex] )
                      this.iO.OutputOff( b );
                  else
                      this.iO.OutputOn( b );
@@ -1342,7 +1409,7 @@ namespace VehicleControlSystem.ControlLayer
             return true;
         }
 
-        int GetObstacleDetectPattern( )
+        int GetObstacleDetectPattern()
         {
             int bitIndex = 0;
 
@@ -1351,9 +1418,9 @@ namespace VehicleControlSystem.ControlLayer
             this.obstacleBitList.ForEach( b =>
              {
                  if ( this.iO.IsOn( b ) )
-                     bitArray.Set( bitIndex , false );
+                     bitArray.Set( bitIndex, false );
                  else
-                     bitArray.Set( bitIndex , true );
+                     bitArray.Set( bitIndex, true );
                  bitIndex++;
              } );
 
@@ -1362,11 +1429,12 @@ namespace VehicleControlSystem.ControlLayer
 
         void OccurVehicleAlarm( int alarmID )
         {
+            this.MachineMode = eMachineMode.LocalMode;
             this.VehicleStateProperty = eVehicleState.Abnormal;
             this.autoManager.ProcessAlarm( alarmID );
         }
 
-        void SetObstaclePattern( ObstacleControlEventArgs.eControlKind state , int value )
+        void SetObstaclePattern( ObstacleControlEventArgs.eControlKind state, int value )
         {
             if ( state == ObstacleControlEventArgs.eControlKind.DRIVE )
             {
@@ -1384,10 +1452,10 @@ namespace VehicleControlSystem.ControlLayer
         #endregion
 
         #region Event Subscribe 
-        private void Motion_PropertyChanged( object sender , System.ComponentModel.PropertyChangedEventArgs e )
+        private void Motion_PropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs e )
         {
             var property = sender.GetType().GetProperty( e.PropertyName );
-            var newValue = property.GetValue( sender , null );
+            var newValue = property.GetValue( sender, null );
 
             if ( e.PropertyName.Equals( "CurrentPos" ) )
             {
@@ -1414,10 +1482,10 @@ namespace VehicleControlSystem.ControlLayer
             }
         }
 
-        private void Steering_PropertyChanged( object sender , System.ComponentModel.PropertyChangedEventArgs e )
+        private void Steering_PropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs e )
         {
             var property = sender.GetType().GetProperty( e.PropertyName );
-            var newValue = property.GetValue( sender , null );
+            var newValue = property.GetValue( sender, null );
 
             //Todo: 나중에 Test 하자
             //var ownPropperty = this.GetType().GetProperty(e.PropertyName);
@@ -1428,12 +1496,12 @@ namespace VehicleControlSystem.ControlLayer
             }
         }
 
-        private void Clamp_PropertyChanged( object sender , System.ComponentModel.PropertyChangedEventArgs e )
+        private void Clamp_PropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs e )
         {
             //TODO:[20/03/26 ys-hwang] Clamp State
 
             var property = sender.GetType().GetProperty( e.PropertyName );
-            var newValue = property.GetValue( sender , null );
+            var newValue = property.GetValue( sender, null );
 
             if ( e.PropertyName.Equals( "ClampState" ) )
             {
@@ -1450,7 +1518,7 @@ namespace VehicleControlSystem.ControlLayer
             }
         }
 
-        private void Steering_OnSteeringError( object sender , int e )
+        private void Steering_OnSteeringError( object sender, int e )
         {
             if ( e != 0 )
             {
@@ -1461,9 +1529,9 @@ namespace VehicleControlSystem.ControlLayer
             {
                 var msg = new DriveControlEventArgs()
                 {
-                    EventDir = DriveControlEventArgs.eEventDir.ToFront ,
-                    ControlKind = DriveControlEventArgs.eControlKind.Steering ,
-                    Result = FluentResults.Results.Ok<DriveControlEventArgs.eMoveDir>( DriveControlEventArgs.eMoveDir.LEFT ) ,
+                    EventDir = DriveControlEventArgs.eEventDir.ToFront,
+                    ControlKind = DriveControlEventArgs.eControlKind.Steering,
+                    Result = FluentResults.Results.Ok<DriveControlEventArgs.eMoveDir>( DriveControlEventArgs.eMoveDir.LEFT ),
                 };
 
                 this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Publish( msg );

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

@@ -138,7 +138,6 @@ namespace VehicleControlSystem.Managers
         {
             this.iO.OutputOff("OUT_TOWER_LAMP_RED");
             this.iO.OutputOff("OUT_TOWER_LAMP_GREEN");
-            this.iO.OutputOff("OUT_TOWER_LAMP_BLUE");
 
             switch (state)
             {
@@ -146,10 +145,13 @@ namespace VehicleControlSystem.Managers
                     this.iO.OutputOff("OUT_TOWER_LAMP_RED");
                     break;
                 case eLampState.Charging:
-                    this.iO.OutputOff("OUT_TOWER_LAMP_GREEN");
+                    this.iO.OutputOff( "OUT_TOWER_LAMP_RED" );
+                    this.iO.OutputOff( "OUT_TOWER_LAMP_GREEN" );
                     break;
                 case eLampState.AutoRunNChargingFull:
-                    this.iO.OutputOff("OUT_TOWER_LAMP_BLUE");
+                    this.iO.OutputOff( "OUT_TOWER_LAMP_GREEN" );
+                    //Blue 없음
+                    //this.iO.OutputOff("OUT_TOWER_LAMP_BLUE");
                     break;
                 default:
                     break;

+ 113 - 88
Dev/OHV/VehicleControlSystem/Managers/HostManager.cs

@@ -21,57 +21,61 @@ namespace VehicleControlSystem.Managers
     /// </summary>
     public class HostManager : IDisposable
     {
-        static Logger logger = Logger.GetLogger("Host");
+        static Logger logger = Logger.GetLogger( "Host" );
 
         OHVConnector.Manager manager = new OHVConnector.Manager();
         IEventAggregator eventAggregator = null;
         Vehicle vehicle;
         SqliteManager sql = null;
 
-        public HostManager(IEventAggregator ea, Vehicle vehicle, SqliteManager sqlite, AutoManager autoManager)
+        public HostManager( IEventAggregator ea, Vehicle vehicle, SqliteManager sqlite, AutoManager autoManager )
         {
             this.eventAggregator = ea;
             this.vehicle = vehicle;
+            this.vehicle.PropertyChanged += Vehicle_PropertyChanged;
             this.sql = sqlite;
-
-            autoManager.OnOperationModeChanged += AutoManager_OnOperationModeChanged;
         }
 
-        private void AutoManager_OnOperationModeChanged( eOperatationMode obj )
+        private void Vehicle_PropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs e )
         {
-            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 )
+            if ( e.PropertyName.Equals( "MachineMode" ) )
             {
-                msg.Kind = eKind.O;
-                msg.Tag = this.vehicle.CurrentTag;
-                msg.IsSubCode1 = this.vehicle.IsContain;
-                msg.IsSubCode2 = vehicle.IsMoving;
-                msg.IsSubCode3 = vehicle.IsError;
+                var property = sender.GetType().GetProperty( e.PropertyName );
+                var newValue = property.GetValue( sender, null );
+
+                var msg = new OCSMessage();
+
+                var mode = CastTo<eMachineMode>.From<object>( newValue );
+                if ( mode == eMachineMode.HostMode )
+                {
+                    msg.Kind = eKind.I;
+                    msg.Tag = this.vehicle.CurrentTag;
+                    msg.IsSubCode1 = this.vehicle.IsContain;
+                    msg.IsSubCode2 = vehicle.IsMoving;
+                    msg.IsSubCode3 = vehicle.IsError;
+                }
+                else
+                {
+                    msg.Kind = eKind.O;
+                    msg.Tag = this.vehicle.CurrentTag;
+                    msg.IsSubCode1 = this.vehicle.IsContain;
+                    msg.IsSubCode2 = vehicle.IsMoving;
+                    msg.IsSubCode3 = vehicle.IsError;
+                }
+
+                this.manager.Send( msg );
             }
-            else
-                return;
 
-            this.manager.Send( msg );
         }
 
         public void Init()
         {
             this.manager.Config = new OHVConnector.Config
             {
-                ID = sql.ConfigDal.GetK(ConstString.VehicleID).Value,
-                IpAddress = sql.ConfigDal.GetK(ConstString.Addr).Value,
-                Port = Convert.ToInt16(sql.ConfigDal.GetK(ConstString.PortNo).Value),
-                HostID = sql.ConfigDal.GetK(ConstString.OCSID).Value,
+                ID = sql.ConfigDal.GetK( ConstString.VehicleID ).Value,
+                IpAddress = sql.ConfigDal.GetK( ConstString.Addr ).Value,
+                Port = Convert.ToInt16( sql.ConfigDal.GetK( ConstString.PortNo ).Value ),
+                HostID = sql.ConfigDal.GetK( ConstString.OCSID ).Value,
             };
 
             this.manager.OnContd += Manager_OnContd;
@@ -82,7 +86,7 @@ namespace VehicleControlSystem.Managers
             this.manager.OnSent += Manager_OnSent;
 
             //Vehicle Server.
-            this.manager.Connect(false);
+            this.manager.Connect( false );
 
             //Vehicle Event
             vehicle.OnBatteryVelueChanged += Vehicle_OnBatteryVelueChanged;
@@ -126,7 +130,7 @@ namespace VehicleControlSystem.Managers
             msg.IsSubCode2 = false;
             msg.IsSubCode3 = false;
 
-            this.manager.Send(msg);
+            this.manager.Send( msg );
         }
 
         private void Vehicle_OnCharging()
@@ -138,7 +142,7 @@ namespace VehicleControlSystem.Managers
             msg.IsSubCode2 = true;
             msg.IsSubCode3 = false;
 
-            this.manager.Send(msg);
+            this.manager.Send( msg );
         }
 
         private void Vehicle_OnChargingStart()
@@ -150,14 +154,14 @@ namespace VehicleControlSystem.Managers
             msg.IsSubCode2 = false;
             msg.IsSubCode3 = false;
 
-            this.manager.Send(msg);
+            this.manager.Send( msg );
         }
 
-        private void Vehicle_OnCarrierDetected(bool isLoad)
+        private void Vehicle_OnCarrierDetected( bool isLoad )
         {
             var msg = new OCSMessage();
 
-            if (isLoad)
+            if ( isLoad )
                 msg.Kind = eKind.L;
             else
                 msg.Kind = eKind.U;
@@ -167,7 +171,7 @@ namespace VehicleControlSystem.Managers
             msg.IsSubCode2 = true;
             msg.IsSubCode3 = false;
 
-            this.manager.Send(msg);
+            this.manager.Send( msg );
         }
 
         private void Vehicle_OnUnloadComplete()
@@ -179,7 +183,7 @@ namespace VehicleControlSystem.Managers
             msg.IsSubCode2 = true;
             msg.IsSubCode3 = true;
 
-            this.manager.Send(msg);
+            this.manager.Send( msg );
         }
 
         private void Vehicle_OnLoadComplete()
@@ -191,14 +195,14 @@ namespace VehicleControlSystem.Managers
             msg.IsSubCode2 = true;
             msg.IsSubCode3 = true;
 
-            this.manager.Send(msg);
+            this.manager.Send( msg );
         }
 
-        private void Vehicle_OnConveyorStop(bool isLoad)
+        private void Vehicle_OnConveyorStop( bool isLoad )
         {
             var msg = new OCSMessage();
 
-            if (isLoad)
+            if ( isLoad )
                 msg.Kind = eKind.L;
             else
                 msg.Kind = eKind.U;
@@ -208,14 +212,14 @@ namespace VehicleControlSystem.Managers
             msg.IsSubCode2 = false;
             msg.IsSubCode3 = true;
 
-            this.manager.Send(msg);
+            this.manager.Send( msg );
         }
 
-        private void Vehicle_OnConveyorStart(bool isLoad)
+        private void Vehicle_OnConveyorStart( bool isLoad )
         {
             var msg = new OCSMessage();
 
-            if (isLoad)
+            if ( isLoad )
                 msg.Kind = eKind.L;
             else
                 msg.Kind = eKind.U;
@@ -225,14 +229,14 @@ namespace VehicleControlSystem.Managers
             msg.IsSubCode2 = false;
             msg.IsSubCode3 = false;
 
-            this.manager.Send(msg);
+            this.manager.Send( msg );
         }
 
-        private void Vehicle_OnPIOStart(bool isLoad)
+        private void Vehicle_OnPIOStart( bool isLoad )
         {
             var msg = new OCSMessage();
 
-            if (isLoad)
+            if ( isLoad )
                 msg.Kind = eKind.L;
             else
                 msg.Kind = eKind.U;
@@ -242,7 +246,7 @@ namespace VehicleControlSystem.Managers
             msg.IsSubCode2 = false;
             msg.IsSubCode3 = false;
 
-            this.manager.Send(msg);
+            this.manager.Send( msg );
         }
 
         private void Vehicle_OnManualCharging()
@@ -265,27 +269,27 @@ namespace VehicleControlSystem.Managers
             this.Send_ManualLoad();
         }
 
-        private void Vehicle_OnCurrentTagChanged(string point)
+        private void Vehicle_OnCurrentTagChanged( string point )
         {
-            this.Send_Tcmd(point);
+            this.Send_Tcmd( point );
         }
 
-        private void Vehicle_OnBatteryVelueChanged(double obj)
+        private void Vehicle_OnBatteryVelueChanged( double obj )
         {
-            this.Send_Bcmd(obj);
+            this.Send_Bcmd( obj );
         }
 
         #region Event Method
-        private void Manager_OnSent(OHVConnector.OCSMessage msg)
+        private void Manager_OnSent( OHVConnector.OCSMessage msg )
         {
-            logger.I("[Sent] : " + msg.LogFormat());
+            logger.I( "[Sent] : " + msg.LogFormat() );
         }
 
-        private void Manager_OnRecd(OHVConnector.OCSMessage msg)
+        private void Manager_OnRecd( OHVConnector.OCSMessage msg )
         {
-            logger.I("[Received] : " + msg.LogFormat());
+            logger.I( "[Received] : " + msg.LogFormat() );
 
-            switch (msg.Kind)
+            switch ( msg.Kind )
             {
                 case OHVConnector.eKind.Unknown:
                     break;
@@ -329,7 +333,7 @@ namespace VehicleControlSystem.Managers
 
         }
 
-        void Reply(OCSMessage recieve)
+        void Reply( OCSMessage recieve )
         {
             var reply = new OCSMessage();
             reply.Kind = recieve.Kind;
@@ -340,15 +344,15 @@ namespace VehicleControlSystem.Managers
 
         private void ReceiveRCommand( OCSMessage msg )
         {
-            this.Reply(msg);
+            this.Reply( msg );
 
-            if ( msg.SubCode.Equals("100") )
+            if ( msg.SubCode.Equals( "100" ) )
             {
                 Send_Scmd( (int)this.vehicle.CurrentPosition );
             }
             if ( msg.SubCode.Equals( "010" ) )
             {
-                Send_Bcmd(this.vehicle.BatteryVolt);
+                Send_Bcmd( this.vehicle.BatteryVolt );
             }
         }
 
@@ -356,6 +360,27 @@ namespace VehicleControlSystem.Managers
         {
             this.Reply( msg );
 
+            var info = sql.VehicleInfoDAL.GetInfo();
+            if ( info.MachineMode == eMachineMode.LocalMode )
+            {
+                logger.E( $"[OCS] Cmd - Current Mode Local Mode " );
+                return;
+            }
+
+            var hasCommand = this.sql.CommandDAL.GetCmd();
+            if ( hasCommand != null )
+            {
+                //Todo: 충전 중에는 어떻게 하지???
+                if ( !hasCommand.IsSecondCommanded )
+                    sql.CommandDAL.Delete( hasCommand );
+                else
+                {
+                    logger.E( $"[OCS] Cmd - {msg.Kind} Message Tag [{msg.Tag}] - Already Load/Unload " );
+                    return;
+                }
+
+            }
+
             var cmd = new Command();
 
             switch ( msg.SubCode )
@@ -377,10 +402,10 @@ namespace VehicleControlSystem.Managers
             }
 
             //Todo: 등록 되어 있는 경로 가 있는 지 확인 필요.
-            var route = this.sql.RouteDal.GetRouteFromOCSMatchID(msg.Tag);
-            if (route == null)
+            var route = this.sql.RouteDal.GetRouteFromOCSMatchID( msg.Tag );
+            if ( route == null )
             {
-                logger.E($"[OCS] Message Tag [{msg.Tag}] - not found route");
+                logger.E( $"[OCS] Message Tag [{msg.Tag}] - not found route" );
                 return;
             }
 
@@ -389,28 +414,28 @@ namespace VehicleControlSystem.Managers
             this.sql.CommandDAL.Add( cmd );
         }
 
-        private void Manager_OnT3Timeout(OHVConnector.OCSMessage msg)
+        private void Manager_OnT3Timeout( OHVConnector.OCSMessage msg )
         {
-            logger.E("[TimeOut] : " + msg.LogFormat());
+            logger.E( "[TimeOut] : " + msg.LogFormat() );
         }
 
-        private void Manager_OnLog(string id, string log)
+        private void Manager_OnLog( string id, string log )
         {
-            logger.I("[Log] : " + log);
+            logger.I( "[Log] : " + log );
         }
 
-        private void Manager_OnDiscontd(string id, Exception e)
+        private void Manager_OnDiscontd( string id, Exception e )
         {
-            var msg = new HostConnectedEventArgs(HostConnectedEventArgs.eConnectedState.Disconnected);
-            this.eventAggregator.GetEvent<HostConnectedPubSubEvent>().Publish(msg);
+            var msg = new HostConnectedEventArgs( HostConnectedEventArgs.eConnectedState.Disconnected );
+            this.eventAggregator.GetEvent<HostConnectedPubSubEvent>().Publish( msg );
 
             QuartzUtils.StopSchedule( "BatteryReport" );
         }
 
-        private void Manager_OnContd(string id)
+        private void Manager_OnContd( string id )
         {
-            var msg = new HostConnectedEventArgs(HostConnectedEventArgs.eConnectedState.Connected);
-            this.eventAggregator.GetEvent<HostConnectedPubSubEvent>().Publish(msg);
+            var msg = new HostConnectedEventArgs( HostConnectedEventArgs.eConnectedState.Connected );
+            this.eventAggregator.GetEvent<HostConnectedPubSubEvent>().Publish( msg );
 
             QuartzUtils.Invoke( "BatteryReport", QuartzUtils.GetExpnMinute( 1 ), BatteryState_Report );
         }
@@ -428,29 +453,29 @@ namespace VehicleControlSystem.Managers
         /// <summary>
         /// 현재 위치 보고 
         /// </summary>
-        public void Send_Scmd(int point)
+        public void Send_Scmd( int point )
         {
             var msg = new OCSMessage();
             msg.Kind = eKind.S;
-            msg.Tag = point.ToString("0000");
+            msg.Tag = point.ToString( "0000" );
             msg.IsSubCode1 = this.vehicle.IsContain;
             msg.IsSubCode2 = vehicle.IsMoving;
             msg.IsSubCode3 = vehicle.IsError;
 
-            this.manager.Send(msg);
+            this.manager.Send( msg );
         }
 
-        public void Send_Bcmd(double volt)
+        public void Send_Bcmd( double volt )
         {
             var msg = new OCSMessage();
             msg.Kind = eKind.B;
             var bData = volt;
-            msg.Tag = bData.ToString("00.00").Replace(".", "");
+            msg.Tag = bData.ToString( "00.00" ).Replace( ".", "" );
             msg.IsSubCode1 = this.vehicle.IsContain;
             msg.IsSubCode2 = vehicle.IsMoving;
             msg.IsSubCode3 = vehicle.IsError;
 
-            this.manager.Send(msg);
+            this.manager.Send( msg );
         }
 
         public void Send_Ecmd()
@@ -461,10 +486,10 @@ namespace VehicleControlSystem.Managers
             msg.IsSubCode2 = vehicle.IsMoving;
             msg.IsSubCode3 = vehicle.IsError;
 
-            this.manager.Send(msg);
+            this.manager.Send( msg );
         }
 
-        public void Send_Tcmd(string point)
+        public void Send_Tcmd( string point )
         {
             var msg = new OCSMessage();
             msg.Kind = eKind.T;
@@ -473,11 +498,11 @@ namespace VehicleControlSystem.Managers
             msg.IsSubCode2 = vehicle.IsMoving;
             msg.IsSubCode3 = vehicle.IsError;
 
-            this.manager.Send(msg);
+            this.manager.Send( msg );
         }
 
 
-        public void Send_Ccmd(string crossPointID)
+        public void Send_Ccmd( string crossPointID )
         {
             var msg = new OCSMessage();
             msg.Kind = eKind.C;
@@ -486,7 +511,7 @@ namespace VehicleControlSystem.Managers
             msg.IsSubCode2 = vehicle.IsMoving;
             msg.IsSubCode3 = vehicle.IsError;
 
-            this.manager.Send(msg);
+            this.manager.Send( msg );
         }
 
         public void Send_ManualMove()
@@ -499,7 +524,7 @@ namespace VehicleControlSystem.Managers
                 IsSubCode2 = false,
                 IsSubCode3 = true,
             };
-            this.manager.Send(msg);
+            this.manager.Send( msg );
         }
 
         public void Send_ManualLoad()
@@ -512,7 +537,7 @@ namespace VehicleControlSystem.Managers
                 IsSubCode2 = true,
                 IsSubCode3 = false,
             };
-            this.manager.Send(msg);
+            this.manager.Send( msg );
         }
 
         public void Send_ManualUnlaod()
@@ -525,7 +550,7 @@ namespace VehicleControlSystem.Managers
                 IsSubCode2 = false,
                 IsSubCode3 = false,
             };
-            this.manager.Send(msg);
+            this.manager.Send( msg );
 
         }
         public void Send_ManualCharging()
@@ -538,7 +563,7 @@ namespace VehicleControlSystem.Managers
                 IsSubCode2 = true,
                 IsSubCode3 = true,
             };
-            this.manager.Send(msg);
+            this.manager.Send( msg );
         }
         #endregion
         public void Dispose()

+ 4 - 11
Dev/OHV/VehicleControlSystem/Managers/Scheduler.cs

@@ -46,6 +46,10 @@ namespace VehicleControlSystem.Managers
 
         private void OnReceivedMessageEvent( VCSMessageEventArgs obj )
         {
+            var vInof = sql.VehicleInfoDAL.GetInfo();
+            if ( vInof.VehicleState == OHV.Common.Shareds.eVehicleState.Move )
+                this.sql.CommandDAL.Clean();
+
             this.AddCommand( obj.Command );
 
             //var m = new GUIMessageEventArgs() { MessageText = obj.MessageText, MessageKey = obj.MessageKey };
@@ -242,17 +246,6 @@ namespace VehicleControlSystem.Managers
             return true;
         }
 
-        public bool CreateTransferCommand()
-        {
-            Command cmd = new Command
-            {
-            };
-
-            sql.CommandDAL.Add( cmd );
-            logger.I( $"{cmd.CommandID} Command Create - Type={cmd.Type}, TargetID={cmd.TargetID}" );
-            return true;
-        }
-
         #region IDisposable Support
         private bool disposedValue = false; // 중복 호출을 검색하려면
 

+ 32 - 25
Dev/OHV/VehicleControlSystem/VCSystem.cs

@@ -5,6 +5,7 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using GSG.NET;
+using GSG.NET.Extensions;
 using GSG.NET.ObjectBase;
 using GSG.NET.Quartz;
 using OHV.Common.Events;
@@ -59,7 +60,7 @@ namespace VehicleControlSystem
             ezIO.OnChangedIO += EzIO_OnChangedIO;
 
             this.autoManager = new AutoManager(this.IO, this.eventAggregator, this.sql);
-            this.scheduler = new Scheduler(eventAggregator, this.autoManager, this.sql);
+            this.scheduler = new Scheduler(eventAggregator, this.autoManager, this.sql );
             this.vehicle = new Vehicle(this.IO, this.sql, this.eventAggregator, this.autoManager);
             this.vehicle.PropertyChanged += Vehicle_PropertyChanged;
 
@@ -137,11 +138,41 @@ namespace VehicleControlSystem
                 case VCSMessageEventArgs.eVCSMessageKind.ReqBuzzerStop:
                     ReqBuzzerStop();
                     break;
+                case VCSMessageEventArgs.eVCSMessageKind.ReqMachineModeChg:
+                    ReqMachineModeChg(msg);
+                    break;
                 default:
                     break;
             }
         }
 
+        private void ReqMachineModeChg( VCSMessageEventArgs msg )
+        {
+            var reply = new GUIMessageEventArgs();
+            reply.Kind = GUIMessageEventArgs.eGUIMessageKind.RspMachineModeChg;
+
+            var mode = CastTo<eMachineMode>.From<object>( msg.Arg );
+            if ( mode == eMachineMode.HostMode )
+            {
+                if (this.autoManager.OperationModeProperty != eOperatationMode.AutoMode )
+                    reply.Result = FluentResults.Results.Fail( "Vehicle Not Start" );
+                else
+                {
+                    this.vehicle.MachineMode = eMachineMode.HostMode;
+                    reply.Result = FluentResults.Results.Ok();
+                    reply.Args = eMachineMode.HostMode;
+                }
+            }
+            else
+            {
+                this.vehicle.MachineMode = eMachineMode.LocalMode;
+                reply.Result = FluentResults.Results.Ok<eMachineMode>( eMachineMode.LocalMode );
+                reply.Args = eMachineMode.LocalMode;
+            }
+
+            GUIMessageEventPublish( reply );
+        }
+
         private void ReqBuzzerStop( )
         {
             this.IO.OutputOff( "OUT_BUZZER_00" );
@@ -192,30 +223,6 @@ namespace VehicleControlSystem
             this.eventAggregator.GetEvent<GUIMessagePubSubEvent>().Publish(rspMsg);
         }
 
-        void ReqAutoModeChange(bool isAutoMode)
-        {
-            GUIMessageEventArgs msg;
-            if (isAutoMode)
-            {
-                int result = vehicle.InitializationVehicle();
-                if (result != 0)
-                {
-                    this.autoManager.ProcessAlarm(result); //Alarm 내용을 UI로 전달 해주니까 Reply 가 필요 없다.
-                    return;
-                }
-
-                this.autoManager.OperationModeProperty = OHV.Common.Shareds.eOperatationMode.AutoMode;
-                this.autoManager.AutoModeStateProperty = OHV.Common.Shareds.eAutoModeState.StartRun;
-                msg = new GUIMessageEventArgs { Kind = GUIMessageEventArgs.eGUIMessageKind.RspAutoModeChange, Result = FluentResults.Results.Ok() };
-            }
-            else
-            {
-                this.autoManager.AutoModeStateProperty = OHV.Common.Shareds.eAutoModeState.WaitStop;
-                msg = new GUIMessageEventArgs {Kind = GUIMessageEventArgs.eGUIMessageKind.RspManualModeChange, Result = FluentResults.Results.Ok() };
-            }
-
-            GUIMessageEventPublish(msg);
-        }
         #endregion
 
         /// <summary>

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

@@ -18,7 +18,7 @@
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
     <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>TRACE;DEBUG;SIMULATION</DefineConstants>
+    <DefineConstants>TRACE;DEBUG</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>