Bladeren bron

SubCommand, Command DB 추가
Vehicle Thread 추가, Scheduler 변경

SK.Kang 6 jaren geleden
bovenliggende
commit
f59f5cedb8

+ 153 - 2
Dev/OHV/Assambly/GSG.NET.XML

@@ -451,17 +451,20 @@
         <member name="M:GSG.NET.Concurrent.TsQueue`1.GetEnumerator">
             <summary/>
         </member>
+        <member name="T:GSG.NET.Extensions.EnumExtensions">
+            <summary>
+            Enum Extensions 추가
+            </summary>
+        </member>
         <member name="M:GSG.NET.Extensions.EnumExtensions.GetValues``1">
             <summary>
             Enumerates all enum values
             </summary>
             <typeparam name="T">Enum type</typeparam>
             <returns>IEnumerable containing all enum values</returns>
-            <see cref="!:http://stackoverflow.com/questions/972307/can-you-loop-through-all-enum-values"/>
         </member>
         <member name="M:GSG.NET.Extensions.CastTo`1.From``1(``0)">
             <summary>
-            Casts <see cref="!:S"/> to <see cref="!:T"/>.
             This does not cause boxing for value types.
             Useful in generic methods.
             </summary>
@@ -1436,6 +1439,12 @@
             char array -> string
             </summary>
         </member>
+        <member name="M:GSG.NET.LinqEx.xFF(System.Byte[])">
+            <summary>
+            byte -&gt; 2byte(0xff) string
+            <para>1,2,3 -gt; 010203</para>
+            </summary>
+        </member>
         <member name="M:GSG.NET.Logging.AppenderUtils.RemoveAppender(log4net.Repository.Hierarchy.Logger,System.String)">
             <summary>
             <para>1. Logger에서 Appender 제거함.</para>
@@ -1941,6 +1950,148 @@
         <member name="M:GSG.NET.TCP.SocketTimeoutException.#ctor(System.String)">
             <summary/>
         </member>
+        <member name="T:GSG.NET.TCP.Tcp4">
+            <summary>
+            <para>2016.06.15 최초 개발</para>
+            <para>default: BigEndian</para>
+            <para>MaxBufSize 추가 (2018.03)</para>
+            </summary>
+        </member>
+        <member name="P:GSG.NET.TCP.Tcp4.Comm">
+            <summary>
+            Tcp 연결정보
+            <para>-</para>
+            <para>기본값</para>
+            <para>T2: 30sec</para>
+            <para>T5: 5sec</para>
+            <para>T6: 10sec</para>
+            <para>Retry: infinite</para>
+            <para>Active: true</para>
+            </summary>
+        </member>
+        <member name="P:GSG.NET.TCP.Tcp4.Connected">
+            <summary>
+            tcp connect or not
+            <para>Sck == null이면 false</para>
+            </summary>
+        </member>
+        <member name="P:GSG.NET.TCP.Tcp4.LittleEndian">
+            <summary>
+            default: false, 즉 BigEndian default
+            </summary>
+        </member>
+        <member name="P:GSG.NET.TCP.Tcp4.MaxBufSize">
+            <summary>
+            Read 함수 호출시 invalid size 체크
+            <para>OutOfMemoryException로 인한 application 다운 방어코드</para>
+            <para>-</para>
+            <para>단위 byte</para>
+            <para>Default: 10485760(10mb)</para>
+            <para>해당 값보다 클경우 IOException 발생</para>
+            </summary>
+        </member>
+        <member name="P:GSG.NET.TCP.Tcp4.Sck">
+            <summary />
+        </member>
+        <member name="M:GSG.NET.TCP.Tcp4.#ctor">
+            <summary>
+            <para>TcpIp 통신 class</para>
+            <para>-</para>
+            <para>기본세팅값</para>
+            <para>BigEndian</para>
+            <para>MaxBufSize (10mb)</para>
+            </summary>
+        </member>
+        <member name="M:GSG.NET.TCP.Tcp4.ChgTimeout(System.Boolean)">
+            <summary>
+            T6 기준 infinite timeout 변경 or 원복
+            <para>OS 시간 변경으로 연결 종료 방지</para>
+            </summary>
+        </member>
+        <member name="M:GSG.NET.TCP.Tcp4.Clean">
+            <summary>
+            In buffer clear
+            </summary>
+        </member>
+        <member name="M:GSG.NET.TCP.Tcp4.Close">
+            <summary>
+            <para>close socket</para>
+            <para>Exception이 없다, 내부적으로 모두 처리함.</para>
+            </summary>
+        </member>
+        <member name="M:GSG.NET.TCP.Tcp4.DefSckOpt(System.Net.Sockets.TcpClient)">
+            <summary>
+            tcp socket option 설정
+            <para>NoDelay, LingerState, ReceiveTimeout</para>
+            </summary>
+        </member>
+        <member name="M:GSG.NET.TCP.Tcp4.Ignore(System.Int32)">
+            <summary>
+            읽어서 버림.
+            </summary>
+        </member>
+        <member name="M:GSG.NET.TCP.Tcp4.Init">
+            <summary>
+            Client의 경우 Comm.Retry 회수 만큼 연결 시도후 함수 return 됨.
+            <para>BigEndian default</para>
+            </summary>
+        </member>
+        <member name="M:GSG.NET.TCP.Tcp4.KeepAlive(System.Single,System.Single)">
+            <summary>
+            KeepAlive 시도, 별도의 heart-beat 메시지 필요없음
+            <para>OS parameter 가 아닌 값 세팅 가능</para>
+            <para>idle 시간 동안 packet 수신이 없을 경우 자동 송신</para>
+            <para>-</para>
+            <para>초단위 데이터 대략 30정도 세팅 권장</para>
+            <para>interval 만큼 10회정도 시도</para>
+            </summary>
+        </member>
+        <member name="M:GSG.NET.TCP.Tcp4.Read(System.Int32)">
+            <summary>
+            size만큼 읽어 MemoryBuffer에 담고 Pos를 0으로 이동한다.
+            <para>-</para>
+            <para>TimeoutException catch 가능함</para>
+            <para>MaxBufSize 적용한 IOException 발생</para>
+            </summary>
+        </member>
+        <member name="M:GSG.NET.TCP.Tcp4.ReadInt(System.Int32,System.Boolean)">
+            <summary>
+            Int 변환
+            <para>LittleEndian property 를 이용하여 ByteOrder세팅이 가능함.</para>
+            <para>기본 양수만 반환</para>
+            <para>양,음수 지원을 위한 signed 설정</para>
+            </summary>
+        </member>
+        <member name="M:GSG.NET.TCP.Tcp4.ReadTo(System.Byte)">
+            <summary>
+            <para>ETX 까지 읽는 경우.</para>
+            <para>etx 는 포함되지 않음</para>
+            <para>in stream 에서 etx 까지 읽음</para>
+            <para>-</para>
+            <para>TimeoutException catch 가능함</para>
+            </summary>
+        </member>
+        <member name="M:GSG.NET.TCP.Tcp4.Send(System.IO.Stream)">
+            <summary>
+            source 데이터 Tcp 에 write
+            <para>Read 사용불가, Stream 의 끝을 잘 모름</para>
+            </summary>
+        </member>
+        <member name="M:GSG.NET.TCP.Tcp4.Send(GSG.NET.Utils.MemoryBuffer)">
+            <summary>
+            MemoryBuffer Position 관계 없이 모든 데이터 write
+            </summary>
+        </member>
+        <member name="M:GSG.NET.TCP.Tcp4.Send(System.Byte[])">
+            <summary />
+        </member>
+        <member name="M:GSG.NET.TCP.Tcp4.Send(System.Int32)">
+            <summary>
+            int 4 byte send
+            <para>LittleEndian property flag 에 따라 자동 변환</para>
+            <para>최대한 MemoryBuffer를 활용한 send 방식으로 구현하며 사용 최소화</para>
+            </summary>
+        </member>
         <member name="T:GSG.NET.TCP.TcpComm">
             <summary>
             <para>T2: 30</para>

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


+ 1 - 1
Dev/OHV/OHV.Common/Events/MessageEventArgs.cs

@@ -58,7 +58,7 @@ namespace OHV.Common.Events
         }
         public eConnectedState State { get; set; }
 
-        public HostConnectedEvent(eConnectedState state)
+        public HostConnectedEventArgs(eConnectedState state)
         {
             this.State = state;
         }

+ 10 - 1
Dev/OHV/OHV.Common/Model/Command.cs

@@ -10,15 +10,24 @@ namespace OHV.Common.Model
     public class Command
     {
         public string CommandID { get; set; }
+        public string TargetID { get; set; }
         public DateTime CreateTime { get; set; }
         public eCommandType Type { get; set; }
         public eCommandState State { get; set; }
         public eCommandResult Result { set; get; }
+
+        /// <summary>
+        /// 두번째 명령을 주었음을 확인 위해.
+        /// </summary>
+        public bool IsSecondCommanded { get; set; }
         public Command()
         {
+            CommandID = $"{Guid.NewGuid()}_{DateTime.Now.ToString("HHmmssfff")}";
+
             CreateTime = DateTime.Now;
-            State = eCommandState.init;
+            State = eCommandState.Queued;
             Result = eCommandResult.Completed;
+            this.IsSecondCommanded = false;
         }
     }
 }

+ 50 - 0
Dev/OHV/OHV.Common/Model/SubCmd.cs

@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace OHV.Common.Model
+{
+    /// <summary>
+    /// Vehicle 이 사용하는 Command
+    /// </summary>
+    public class SubCmd
+    {
+        public enum eType
+        {
+            Move,
+            Load,
+            Unload,
+            Chaging,
+        }
+
+        public enum eCmdType
+        {
+            Auto,
+            Manual,
+        }
+
+        public enum eSubCmdState
+        {
+            Processing,
+            Block,
+            Complete,
+        }
+
+        public SubCmd()
+        {
+            ID = $"{Guid.NewGuid()}_{DateTime.Now.ToString("HHmmssfff")}";
+        }
+
+        public string ID { get; set; }
+        public string CraneID { get; set; }
+        public string CmdID { get; set; }
+        public string TargetID { get; set; }
+
+        public eType Type { get; set; }
+
+        public eCmdType CmdType { get; set; }
+
+    }
+}

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

@@ -66,6 +66,7 @@
     <Compile Include="Model\Route.cs" />
     <Compile Include="Model\SelectionItem.cs" />
     <Compile Include="Model\SelectionList.cs" />
+    <Compile Include="Model\SubCmd.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Shareds\ConstString.cs" />
     <Compile Include="Shareds\SharedEnumType.cs" />

+ 6 - 11
Dev/OHV/OHV.Common/Shareds/SharedEnumType.cs

@@ -64,22 +64,17 @@
     public enum eCommandType
 	{
 		Move,
-		Transfer,
+		MoveNLoad,
+		MoveNUnload,
 		Charging,
 	}
 
 	public enum eCommandState
 	{
-		init,
-		MoveToSource,
-		Arrived,
-		AcquireStart,
-		AcquireComplete,
-		MoveToDest,
-		Departed,
-		DepositStart,
-		DepositComplete,
-		Finished,
+		Queued,
+		Assign,
+		Processing,
+		Complete,
 	}
 
 	public enum eCommandResult

+ 95 - 0
Dev/OHV/OHV.SqliteDAL/DAL/CommandDAL.cs

@@ -0,0 +1,95 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using OHV.Common.Model;
+using OHV.Common.Shareds;
+
+namespace OHV.SqliteDAL.DAL
+{
+    public class CommandDAL
+    {
+        public List<Command> All 
+        { 
+            get 
+            {
+                List<Command> ll = new List<Command>();
+                using (var db = new OHVDbContext("OHVDb"))
+                {
+                    ll = db.Set<Command>().ToList();
+                }
+                return ll;
+            }
+        }
+
+        public Command GetCmd()
+        {
+            Command cmd;
+            using (var db = new OHVDbContext("OHVDb"))
+            {
+                cmd = db.Set<Command>().FirstOrDefault();
+            }
+            return cmd;
+        }
+
+
+        public void Clean()
+        {
+            using (var db = new OHVDbContext("OHVDb"))
+            {
+                db.Set<Command>().RemoveRange(db.Set<Command>());
+                db.SaveChanges();
+            }
+        }
+
+        public void Delete(Command cmd)
+        {
+            using (var db = new OHVDbContext("OHVDb"))
+            {
+                db.Set<Command>().Remove(cmd);
+                db.SaveChanges();
+            }
+        }
+
+        public void Add(Command cmd)
+        {
+            using (var db = new OHVDbContext("OHVDb"))
+            {
+                db.Set<Command>().Add(cmd);
+                db.SaveChanges();
+            }
+        }
+
+        public void UpdateState(string id, eCommandState state)
+        {
+            using (var db = new OHVDbContext("OHVDb"))
+            {
+                var cmd = db.Set<Command>().Where(c => c.CommandID.Equals(id)).SingleOrDefault();
+                cmd.State = state;
+                db.SaveChanges();
+            }
+        }
+
+        public void UpdateResult(string id, eCommandResult result)
+        {
+            using (var db = new OHVDbContext("OHVDb"))
+            {
+                var cmd = db.Set<Command>().Where(c => c.CommandID.Equals(id)).SingleOrDefault();
+                cmd.Result = result;
+                db.SaveChanges();
+            }
+        }
+
+        public int GetCount()
+        {
+            int count = 0;
+            using (var db = new OHVDbContext("OHVDb"))
+            {
+                count = db.Set<Command>().Count();
+            }
+
+            return count;
+        }
+    }
+}

+ 69 - 0
Dev/OHV/OHV.SqliteDAL/DAL/SubCmdDAL.cs

@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using OHV.Common.Model;
+
+namespace OHV.SqliteDAL.DAL
+{
+    public class SubCmdDAL
+    {
+        public void Add(SubCmd subCmd)
+        {
+            using (var db = new OHVDbContext("OHVDb"))
+            {
+                db.Set<SubCmd>().Add(subCmd);
+                db.SaveChanges();
+            }
+        }
+
+        public int GetCount()
+        {
+            int count = 0;
+            using (var db = new OHVDbContext("OHVDb"))
+            {
+                count = db.Set<SubCmd>().Count();
+            }
+
+            return count;
+        }
+
+        public SubCmd GetSubCmd()
+        {
+            SubCmd sub;
+            using (var db = new OHVDbContext("OHVDb"))
+            {
+                sub = db.Set<SubCmd>().FirstOrDefault();
+            }
+            return sub;
+        }
+
+        public void Clean()
+        {
+            using (var db = new OHVDbContext("OHVDb"))
+            {
+                db.Set<SubCmd>().RemoveRange(db.Set<SubCmd>());
+                db.SaveChanges();
+            }
+        }
+
+        public void Delete(SubCmd sub)
+        {
+            using (var db = new OHVDbContext("OHVDb"))
+            {
+                db.Set<SubCmd>().Remove(sub);
+                db.SaveChanges();
+            }
+        }
+
+        public void Update(SubCmd sub)
+        {
+            using (var db = new OHVDbContext("OHVDb"))
+            {
+                db.Set<SubCmd>().Remove(sub);
+                db.SaveChanges();
+            }
+        }
+    }
+}

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

@@ -14,6 +14,8 @@ namespace OHV.SqliteDAL
         {
             modelBuilder.Entity<Config>();
             modelBuilder.Entity<Route>();
+            modelBuilder.Entity<Command>();
+            modelBuilder.Entity<SubCmd>();
         }
     }
 }

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

@@ -55,8 +55,10 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="CustomHistory.cs" />
+    <Compile Include="DAL\CommandDAL.cs" />
     <Compile Include="DAL\ConfigDAL.cs" />
     <Compile Include="DAL\RouteDAL.cs" />
+    <Compile Include="DAL\SubCmdDAL.cs" />
     <Compile Include="ModelConfiguration.cs" />
     <Compile Include="OHVDbContext.cs" />
     <Compile Include="OHVDbInitializer.cs" />

+ 75 - 3
Dev/OHV/VehicleControlSystem/ControlLayer/Vehicle.cs

@@ -2,10 +2,15 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
+using System.Threading;
 using System.Threading.Tasks;
+using GSG.NET.Concurrent;
+using GSG.NET.Logging;
 using GSG.NET.Utils;
+using OHV.Common.Model;
 using VehicleControlSystem.ControlLayer.Actuator.Cylinder;
 using VehicleControlSystem.ControlLayer.IO;
+using VehicleControlSystem.Managers;
 
 namespace VehicleControlSystem.ControlLayer
 {
@@ -14,6 +19,9 @@ namespace VehicleControlSystem.ControlLayer
     /// </summary>
     public class Vehicle
     {
+        static Logger logger = Logger.GetLogger();
+
+        #region Properties
         private double currentPosition;
 
         public double CurrentPosition
@@ -22,7 +30,21 @@ namespace VehicleControlSystem.ControlLayer
             set { currentPosition = value; }
         }
 
+        public bool Busy 
+        {
+            get
+            {
+                return this.CurrentSubCommand == null ? false : true;
+            }
+
+            private set { }
+        }
+
+        public SubCmd CurrentSubCommand{ get; private set; }
+        #endregion
+
         IIO iO = null;
+
         #region ActuatorLIst
         List<ICylinder> cylinders = new List<ICylinder>();
         #endregion
@@ -32,17 +54,67 @@ namespace VehicleControlSystem.ControlLayer
             this.iO = io;
         }
 
+        /// <summary>
+        /// Scheduler 가 주는 Sub Command 를 이용하여 동작하자.
+        /// </summary>
         public void Init()
         {
-
+            ThreadUtils.Invoke(() =>
+            {
+                for(; ; )
+                {
+                    try
+                    {
+                        var subCmd = SqlManager.Instance.SubCmdDAL.GetSubCmd();
+                        if (subCmd == null) continue;
+
+                        if (!SqlManager.Instance.CommandDAL.All.Any(x => x.CommandID.Equals(subCmd.CmdID)))
+                        {
+                            if ( subCmd.CmdType == SubCmd.eCmdType.Auto) //자동 명령중 Main Command 가 없으면 삭제.
+                            {
+                                SqlManager.Instance.SubCmdDAL.Delete(subCmd);
+                                logger.I($"SubCmd Deleted - ID={subCmd.ID}, CommandID={subCmd.CmdID}");
+                            }
+                        }
+
+                        switch (subCmd.Type)
+                        {
+                            case SubCmd.eType.Move:
+                                this.Move(subCmd);
+                                break;
+                            case SubCmd.eType.Load:
+                                break;
+                            case SubCmd.eType.Unload:
+                                break;
+                            case SubCmd.eType.Chaging:
+                                break;
+                            default:
+                                break;
+                        }
+
+                    }
+                    catch (Exception ex)
+                    {
+                        logger.E(ex);
+                    }
+                    finally
+                    {
+                        LockUtils.Wait(500);
+                    }
+                }
+            });
         }
 
         #region Control Action Method
-        public bool MoveTo(string pointID)
+        bool Move(SubCmd cmd)
         {
-            return Wait4MoveDone();
+            return true;
         }
 
+        bool MoveTo(string pointID)
+        {
+            return Wait4MoveDone();
+        }
         bool Wait4MoveDone()
         {
             int waitTime = 60000;

+ 5 - 4
Dev/OHV/VehicleControlSystem/Managers/HostManager.cs

@@ -63,13 +63,13 @@ namespace VehicleControlSystem.Managers
                     break;
                 case OHVConnector.eKind.S://마지막으로 읽은 TagNo
                     break;
-                case OHVConnector.eKind.B:
+                case OHVConnector.eKind.B://battery Report
                     break;
-                case OHVConnector.eKind.T:
+                case OHVConnector.eKind.T://위치 응답
                     break;
-                case OHVConnector.eKind.C:
+                case OHVConnector.eKind.C://제어 요청
                     break;
-                case OHVConnector.eKind.P:
+                case OHVConnector.eKind.P://수동명령보고
                     break;
                 case OHVConnector.eKind.I:
                     break;
@@ -94,6 +94,7 @@ namespace VehicleControlSystem.Managers
                 default:
                     break;
             }
+
         }
 
         private void Manager_OnT3Timeout(OHVConnector.OCSMessage msg)

+ 130 - 27
Dev/OHV/VehicleControlSystem/Managers/Scheduler.cs

@@ -93,16 +93,29 @@ namespace VehicleControlSystem.Managers
         {
             while (isThreadAlive)
             {
-                Thread.Sleep(100);
+                Thread.Sleep(500);
                 try
                 {
-                    Command cmd = null;
-                    cmd = CommandsList.FirstOrDefault();
-                    if ( cmd == null )
-                        continue;
-
-                    DoWork(cmd);
+                    var state = this.autoManager.AutoModeStateProperty;
+                    switch (state)
+                    {
+                        case OHV.Common.Shareds.eAutoModeState.ErrorStop:
+                            break;
+                        case OHV.Common.Shareds.eAutoModeState.StartRun:
+                            break;
+                        case OHV.Common.Shareds.eAutoModeState.Run:
+                            {
+                                Command cmd = SqlManager.Instance.CommandDAL.GetCmd();
+                                if (cmd == null) continue;
 
+                                DoWork(cmd);
+                            }
+                            break;
+                        case OHV.Common.Shareds.eAutoModeState.Stop:
+                            break;
+                        default:
+                            break;
+                    }
                 }
                 catch (Exception ex)
                 {
@@ -115,38 +128,128 @@ namespace VehicleControlSystem.Managers
         {
             switch (cmd.State)
             {
-                case OHV.Common.Shareds.eCommandState.init:
-                    break;
-                case OHV.Common.Shareds.eCommandState.MoveToSource:
+                case OHV.Common.Shareds.eCommandState.Queued:
+                    if ( SqlManager.Instance.SubCmdDAL.GetCount() <= 0)
+                    {
+                        switch (cmd.Type)
+                        {
+                            case OHV.Common.Shareds.eCommandType.Move:
+                            case OHV.Common.Shareds.eCommandType.MoveNLoad:
+                            case OHV.Common.Shareds.eCommandType.MoveNUnload:
+                                CreateSubCommand(cmd, SubCmd.eType.Move);
+                                break;
+                            case OHV.Common.Shareds.eCommandType.Charging:
+                                break;
+                            default:
+                                break;
+                        }
+                    }
+                    SqlManager.Instance.CommandDAL.UpdateState(cmd.CommandID, OHV.Common.Shareds.eCommandState.Assign);
                     break;
-                case OHV.Common.Shareds.eCommandState.Arrived:
-                    cmd.State = OHV.Common.Shareds.eCommandState.AcquireStart;
+
+                case OHV.Common.Shareds.eCommandState.Assign: //Assign 되면 Vehicle 의 상태가 Busy 면 Processing 으로 전환.
+                    { 
+                        var subCmd = SqlManager.Instance.SubCmdDAL.GetSubCmd();
+                        if (subCmd == null) break;
+
+                        if (!subCmd.CmdID.Equals(cmd.CommandID))
+                            break;
+                    }
+
+                    SqlManager.Instance.CommandDAL.UpdateState(cmd.CommandID, OHV.Common.Shareds.eCommandState.Processing);
                     break;
-                case OHV.Common.Shareds.eCommandState.AcquireStart:
-                    cmd.State = OHV.Common.Shareds.eCommandState.AcquireComplete;
+
+                case OHV.Common.Shareds.eCommandState.Processing:
+                    {
+                        var subCmd = SqlManager.Instance.SubCmdDAL.GetSubCmd();
+                        if (subCmd == null) // Move 명령을 수행 완료 했다고 판단.
+                        {
+                            if ( cmd.IsSecondCommanded)
+                            {
+                                SqlManager.Instance.CommandDAL.UpdateState(cmd.CommandID, OHV.Common.Shareds.eCommandState.Complete);
+                                break;
+                            }
+
+                            if (cmd.Type == OHV.Common.Shareds.eCommandType.MoveNLoad )
+                            {
+                                if (this.CreateSubCommand(cmd, SubCmd.eType.Load))
+                                    cmd.IsSecondCommanded = true;
+                                break;
+                            }
+                            else if(cmd.Type == OHV.Common.Shareds.eCommandType.MoveNUnload)
+                            {
+                                if (this.CreateSubCommand(cmd, SubCmd.eType.Unload))
+                                    cmd.IsSecondCommanded = true;
+                                break;
+                            }
+                            else if ( cmd.Type == OHV.Common.Shareds.eCommandType.Charging)
+                            {
+                                if ( this.CreateSubCommand(cmd, SubCmd.eType.Chaging))
+                                    cmd.IsSecondCommanded = true;
+                                break;
+                            }
+                            else //Move Command
+                            {
+                                SqlManager.Instance.CommandDAL.UpdateState(cmd.CommandID, OHV.Common.Shareds.eCommandState.Complete);
+                                break;
+                            }
+                        }
+
+                        if (subCmd.CmdID.Equals(cmd.CommandID)) //진행중 판단
+                            break;
+                        else //다른 아이디의 일을 하고 있을 경우 가 생길까??
+                        { }
+                    }
+                    SqlManager.Instance.CommandDAL.UpdateState(cmd.CommandID, OHV.Common.Shareds.eCommandState.Complete);
                     break;
-                case OHV.Common.Shareds.eCommandState.AcquireComplete:
-                    cmd.State = OHV.Common.Shareds.eCommandState.MoveToDest;
+
+                case OHV.Common.Shareds.eCommandState.Complete:
+                    SqlManager.Instance.CommandDAL.Delete(cmd);
                     break;
-                case OHV.Common.Shareds.eCommandState.MoveToDest:
-                    cmd.State = OHV.Common.Shareds.eCommandState.Departed;
+                default:
                     break;
-                case OHV.Common.Shareds.eCommandState.Departed:
-                    cmd.State = OHV.Common.Shareds.eCommandState.DepositStart;
+            }
+        }
+
+        private bool CreateSubCommand(Command cmd, SubCmd.eType type)
+        {
+            //명령을 만들기 전에 Vehicle 의 상태를 확인하여 만들자.
+            switch (type)
+            {
+                case SubCmd.eType.Move:
                     break;
-                case OHV.Common.Shareds.eCommandState.DepositStart:
-                    cmd.State = OHV.Common.Shareds.eCommandState.DepositComplete;
+                case SubCmd.eType.Load:
                     break;
-                case OHV.Common.Shareds.eCommandState.DepositComplete:
-                    cmd.State = OHV.Common.Shareds.eCommandState.Finished;
+                case SubCmd.eType.Unload:
                     break;
-                case OHV.Common.Shareds.eCommandState.Finished: //command Delete
-                    cmd.Result = OHV.Common.Shareds.eCommandResult.Completed;
-                    RemoveCommand(cmd);
+                case SubCmd.eType.Chaging:
                     break;
                 default:
                     break;
             }
+
+            var sub = new SubCmd
+            {
+                CmdType = SubCmd.eCmdType.Auto,
+                Type = type,
+                TargetID = cmd.TargetID,
+                CmdID = cmd.CommandID,
+            };
+            SqlManager.Instance.SubCmdDAL.Add(sub);
+            logger.I($"{sub.ID} Sub Command Create - Type={sub.Type}, TargetID={sub.TargetID}, CommandID={sub.CmdID}");
+
+            return true;
+        }
+
+        public bool CreateTransferCommand()
+        {
+            Command cmd = new Command
+            {
+            };
+
+            SqlManager.Instance.CommandDAL.Add(cmd);
+            logger.I($"{cmd.CommandID} Command Create - Type={cmd.Type}, TargetID={cmd.TargetID}");
+            return true;
         }
 
         #region IDisposable Support

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

@@ -12,10 +12,15 @@ namespace VehicleControlSystem.Managers
     {
         public ConfigDAL ConfigDal { get; set; }
         public RouteDAL RouteDal { get; set; }
+        public CommandDAL CommandDAL { get; set; }
+        public SubCmdDAL SubCmdDAL { get; set; }
+
         private SqlManager()
         {
             this.ConfigDal = new ConfigDAL();
             this.RouteDal = new RouteDAL();
+            this.SubCmdDAL = new SubCmdDAL();
+            this.CommandDAL = new CommandDAL();
         }
     }
 }

+ 0 - 2
Dev/OHV/VehicleControlSystem/VCSystem.cs

@@ -56,8 +56,6 @@ namespace VehicleControlSystem
 
             this.hostManager = new HostManager(this.eventAggregator);
             this.hostManager.Init();
-
-            //SqlManager.Instance.RouteDal.Add(new Route {Id=1, Name="P01", PrePoint="P10", NextPoint="P02", Form=Route.eRoadForm.Straight, Type=Route.ePointType.Charging, ScaleValue=0.005, UserPIO=false });
         }
 
         #region EzIO Event

BIN
RefranceProject/VeichleToHost_IF.pdf