Explorar el Código

비클 주행 시 주행 Buzzer Use Option 추가

SWGroupSetup01 hace 4 años
padre
commit
fd76cfa22a

+ 160 - 150
Dev/Connection/OHVProtocolServer/OHVConnector/Manager.cs

@@ -29,7 +29,7 @@ namespace OHVConnector
         TsQueue<QueueObject> qQ = new TsQueue<QueueObject>();
         TsQueue<OCSMessage> qqW = new TsQueue<OCSMessage>();
 
-        byte[] crcTable = ChksumUtils.Crc8GenTable( 0xD5 );
+        byte[] crcTable = ChksumUtils.Crc8GenTable(0xD5);
 
         TimerTemplate<byte, OCSMessage> quzT3 = new TimerTemplate<byte, OCSMessage>();
         TsMap<long, SyncObject> ddReq = new TsMap<long, SyncObject>(); //sync 통신을 위함.
@@ -75,61 +75,61 @@ namespace OHVConnector
         #endregion
 
         #region Connection Method
-        public void Connect( bool active = false )
+        public void Connect(bool active = false)
         {
             ModeActive = active;
-            if ( !inited.HasValue )//최초 한번 실행.
+            if (!inited.HasValue)//최초 한번 실행.
             {
-                _TQ = ThreadUtils.Invoke( _ThPullQueue );
+                _TQ = ThreadUtils.Invoke(_ThPullQueue);
                 inited = false;
             }
-            Assert.IsFalse( inited.Value, "Already connecting" );
+            Assert.IsFalse(inited.Value, "Already connecting");
 
             inited = true;
 
-            _TW = ThreadUtils.Invoke( _ThWriteTcp );
-            _TR = ThreadUtils.Invoke( _ThReadTcp );
-            _TLINK = ThreadUtils.Invoke( _ThLinkQuz );
+            _TW = ThreadUtils.Invoke(_ThWriteTcp);
+            _TR = ThreadUtils.Invoke(_ThReadTcp);
+            _TLINK = ThreadUtils.Invoke(_ThLinkQuz);
 
-            _OnLog( "OHV CONNECT REQ " + Config );
+            _OnLog("OHV CONNECT REQ " + Config);
         }
 
         public void Disconnect()
         {
             //if (inited.HasValue && inited.Value)
-            _OnLog( "OCS DISCONNECT REQ " + Config );
+            _OnLog("OCS DISCONNECT REQ " + Config);
 
             inited = false;
             quzT3.StopAll();
 
-            ThreadUtils.Kill( _TLINK );
-            ThreadUtils.Kill( _TW );
+            ThreadUtils.Kill(_TLINK);
+            ThreadUtils.Kill(_TW);
             h.StopListen();
-            ThreadUtils.Kill( _TR );
+            ThreadUtils.Kill(_TR);
 
             h.CloseSocket();//Kill 을 사용할 경우 뒤에 존재해야 한다.
         }
 
-        void _OnDicontd( Exception e )
+        void _OnDicontd(Exception e)
         {
-            _OnLog( "OHV DISCONNECTED" );
+            _OnLog("OHV DISCONNECTED");
             sysbyte = 0;
             ctrl_sysbyte = INIT_CTRL_SYSBYTE;
             //quzT3.StopAll(); //2020.08.261. Kang. 재연결 시 다시 Send 를 위해.
             ddReq.Clear();
 
-            qQ.Enqueue( new QoNotComm { Arg0 = e } );
+            qQ.Enqueue(new QoNotComm { Arg0 = e });
         }
 
         void _OnContd()
         {
-            _OnLog( "OHV CONNECTED" );
-            qQ.Enqueue( new QoComm() );
+            _OnLog("OHV CONNECTED");
+            qQ.Enqueue(new QoComm());
         }
 
         void TcpConnect()
         {
-            h.Connect( new TcpComm
+            h.Connect(new TcpComm
             {
                 Active = ModeActive,
                 RetryCnt = 1, //T5를 처리해야 함.
@@ -137,38 +137,38 @@ namespace OHVConnector
                 PortNo = Config.Port,
                 T5 = Config.T5,
                 T6 = Config.T6,//Config.TcpRecdTimeout,
-            } );
+            });
 
-            if ( !h.Connected )
+            if (!h.Connected)
             {
-                if ( ModeActive )
-                    _OnLog( "T5 TIMEOUT " + Config.ID );
+                if (ModeActive)
+                    _OnLog("T5 TIMEOUT " + Config.ID);
                 return;
             }
             _OnContd();
 
-            ChgTcpTimeout( true );
+            ChgTcpTimeout(true);
             //if (ModeActive)
             //SendCtrlMsg(1);//무조건 HSMS Active
         }
 
         #endregion
 
-        private void _OnLog( string obj )
+        private void _OnLog(string obj)
         {
-            qQ.Enqueue( new QoLog { Arg0 = obj } );
+            qQ.Enqueue(new QoLog { Arg0 = obj });
         }
 
-        private void _OnTimeout( byte crc, OCSMessage msg )
+        private void _OnTimeout(byte crc, OCSMessage msg)
         {
-            if ( null == msg )
+            if (null == msg)
             {
-                logger.W( "T3 [{0}] attachment is null", crc );
+                logger.W("T3 [{0}] attachment is null", crc);
                 return;
             }
 
-            qQ.Enqueue( new QoTimeout { Arg0 = msg } );
-            _OnLog( $"T3 TIMEOUT {msg.LogFormat()}" );
+            qQ.Enqueue(new QoTimeout { Arg0 = msg });
+            _OnLog($"T3 TIMEOUT {msg.LogFormat()}");
         }
 
         #region Thread Method
@@ -181,40 +181,40 @@ namespace OHVConnector
                 {
                     bool waked;
 
-                    if ( Config.LinkOn )
-                        waked = LockUtils.Wait( Config.TLink, lockLink );
+                    if (Config.LinkOn)
+                        waked = LockUtils.Wait(Config.TLink, lockLink);
                     else
-                        waked = LockUtils.Wait( lockLink );
+                        waked = LockUtils.Wait(lockLink);
 
-                    if ( waked )
+                    if (waked)
                         continue;//notify: 패킷을 수신할때마다 reset 함.
 
-                    if ( Connected )//연결여부와 상관없이 thread 가 기동되므로 연결시에만.
+                    if (Connected)//연결여부와 상관없이 thread 가 기동되므로 연결시에만.
                     {
                         //SendCtrlMsg(5);
                     }
                 }
-                catch ( ThreadAbortException )
+                catch (ThreadAbortException)
                 {
                     break;
                 }
-                catch ( Exception e )
+                catch (Exception e)
                 {
-                    logger.E( e );
+                    logger.E(e);
                 }
             }
         }
 
         void _ThWriteTcp()
         {
-            logger.I( "Write {0}", ThreadUtils.GetCurrThreadID() );
+            logger.I("Write {0}", ThreadUtils.GetCurrThreadID());
             for (; ; )
             {
                 try
                 {
                     var v = qqW.Dequeue();
 
-                    this.TcpWriteMsg( v );
+                    this.TcpWriteMsg(v);
                     //v.IsRecd = false;
 
                     //if (v.AfterMillis > 0)
@@ -225,13 +225,13 @@ namespace OHVConnector
                     //else
                     //    TcpWriteNormalMsg(v);
                 }
-                catch ( ThreadAbortException )
+                catch (ThreadAbortException)
                 {
                     break;
                 }
-                catch ( Exception e )
+                catch (Exception e)
                 {
-                    logger.E( e );
+                    logger.E(e);
                 }
             }
         }
@@ -242,31 +242,31 @@ namespace OHVConnector
             {
                 try
                 {
-                    if ( !h.Connected )
+                    if (!h.Connected)
                     {
                         TcpConnect();
                         continue;
                     }
                     ReadSocket();
                 }
-                catch ( ObjectDisposedException e )
+                catch (ObjectDisposedException e)
                 {
-                    TcpError( e );
+                    TcpError(e);
                 }
-                catch ( IOException e )
+                catch (IOException e)
                 {
-                    TcpError( e );
+                    TcpError(e);
                 }
-                catch ( ThreadAbortException )
+                catch (ThreadAbortException)
                 {
-                    _OnLog( "DISCONNECT REQUEST APPLIED " + Config );
-                    TcpError( new IOException( "DISCONNECT REQUEST" ) );
+                    _OnLog("DISCONNECT REQUEST APPLIED " + Config);
+                    TcpError(new IOException("DISCONNECT REQUEST"));
                     break;
                 }
-                catch ( Exception e )
+                catch (Exception e)
                 {
-                    TcpError( e );
-                    logger.E( e );
+                    TcpError(e);
+                    logger.E(e);
                 }
             }
         }
@@ -279,44 +279,44 @@ namespace OHVConnector
                 {
                     var qo = this.qQ.Dequeue();
 
-                    if ( qo is QoRecdUnk )
+                    if (qo is QoRecdUnk)
                     {
-                        DelegateUtils.Invoke( OnRecdUnk, qo.Arg0, qo.Arg1 );
+                        DelegateUtils.Invoke(OnRecdUnk, qo.Arg0, qo.Arg1);
                         //if (AutoS9Fy)
                         //{
                         //    var v = qo.Arg0 as SFMessage;
                         //    Send(v.S9Fy);
                         //}
                     }
-                    else if ( qo is QoComm )
-                        DelegateUtils.Invoke( OnContd, Config.ID );
-                    else if ( qo is QoNotComm )
-                        DelegateUtils.Invoke( OnDiscontd, Config.ID, qo.Arg0 );
-                    else if ( qo is QoLog )
-                        DelegateUtils.Invoke( OnLog, Config.ID, qo.Arg0 );
-                    else if ( qo is QoRecd )
-                        DelegateUtils.Invoke( OnRecd, qo.Arg0 );
-                    else if ( qo is QoTimeout )
+                    else if (qo is QoComm)
+                        DelegateUtils.Invoke(OnContd, Config.ID);
+                    else if (qo is QoNotComm)
+                        DelegateUtils.Invoke(OnDiscontd, Config.ID, qo.Arg0);
+                    else if (qo is QoLog)
+                        DelegateUtils.Invoke(OnLog, Config.ID, qo.Arg0);
+                    else if (qo is QoRecd)
+                        DelegateUtils.Invoke(OnRecd, qo.Arg0);
+                    else if (qo is QoTimeout)
                     {
-                        DelegateUtils.Invoke( OnT3Timeout, qo.Arg0 );
+                        DelegateUtils.Invoke(OnT3Timeout, qo.Arg0);
                         //if (AutoS9Fy)
                         //{
                         //    var v = qo.Arg0 as SFMessage;
                         //    Send(MessageSupport.MakeS9FX(9, v));
                         //}
                     }
-                    else if ( qo is QoSent )
-                        DelegateUtils.Invoke( OnSent, qo.Arg0 );
+                    else if (qo is QoSent)
+                        DelegateUtils.Invoke(OnSent, qo.Arg0);
                     else
-                        Assert.Fail( "Unk Object {0}", qo );
+                        Assert.Fail("Unk Object {0}", qo);
                 }
-                catch ( ThreadAbortException )
+                catch (ThreadAbortException)
                 {
                     break;
                 }
-                catch ( Exception e )
+                catch (Exception e)
                 {
-                    logger.E( e );
+                    logger.E(e);
                 }
             }
         }
@@ -332,54 +332,64 @@ namespace OHVConnector
                 stx = h.ReadByte(); //STX
                 //logger.D( $"[OCS] - {stx}" );
             }
-            while ( stx != STX );
+            while (stx != STX);
 
             string revID = string.Empty;
             string sendID = string.Empty;
 
-            if ( ModeActive )
+            if (ModeActive)
             {
-                revID = h.ReadAscii( 2 );
-                sendID = h.ReadAscii( 5 );
+                revID = h.ReadAscii(2);
+                sendID = h.ReadAscii(5);
             }
             else
             {
-                revID = h.ReadAscii( 5 );
-                sendID = h.ReadAscii( 2 );
+                revID = h.ReadAscii(5);
+                sendID = h.ReadAscii(2);
             }
 
-            if ( !this.Config.ID.Equals( revID ) )
-                OnLog( this.Config.ID, $"RevID Not Equals" );
+            if (!this.Config.ID.Equals(revID))
+                OnLog(this.Config.ID, $"RevID Not Equals");
 
             var ocsMeg = new OCSMessage();
             ocsMeg.RevID = revID;
             ocsMeg.SendID = sendID;
-            ocsMeg.Kind = h.ReadAscii( 1 ).ToEnum<eKind>( eKind.Unknown );
+            ocsMeg.Kind = h.ReadAscii(1).ToEnum<eKind>(eKind.Unknown);
 
-            if ( ocsMeg.Kind == eKind.M ) //M Command 가변으로 들어 온다.
+            if (ocsMeg.Kind == eKind.M) //M Command 가변으로 들어 온다.
             {
-                ocsMeg.Tag = h.ReadAscii( 4 );
-                ocsMeg.SubCode = h.ReadAscii( 3 );
-                var viaCount = Convert.ToInt16( h.ReadAscii( 4 ) ); //4byte
-                for ( int i = 0; i < viaCount; i++ )
+                ocsMeg.Tag = h.ReadAscii(4);
+                ocsMeg.SubCode = h.ReadAscii(3);
+                var viaCount = Convert.ToInt16(h.ReadAscii(4)); //4byte
+                for (int i = 0; i < viaCount; i++)
                 {
-                    ocsMeg.ViaRouteList.Add( h.ReadAscii( 4 ) );
+                    ocsMeg.ViaRouteList.Add(h.ReadAscii(4));
                 }
-                ocsMeg.CheckSum = h.ReadAscii( 1 );
-                h.ReadUntil( ETX );
+                ocsMeg.CheckSum = h.ReadAscii(1);
+                h.ReadUntil(ETX);
             }
             else
             {
+                if (ocsMeg.Kind == eKind.D) //시간동기화 메시지 
+                {
+                    ocsMeg.Tag = h.ReadAscii(4);
+                    ocsMeg.SubCode = h.ReadAscii(13);
+                    ocsMeg.CheckSum = h.ReadAscii(1);
+                    h.ReadUntil(ETX);
+                }
+                else
+                {
+                    ocsMeg.Tag = h.ReadAscii(4);
+                    ocsMeg.SubCode = h.ReadAscii(3);
 
-                ocsMeg.Tag = h.ReadAscii( 4 );
-                ocsMeg.SubCode = h.ReadAscii( 3 );
+                    if (ocsMeg.Kind == eKind.B)
+                        ocsMeg.BatterySOH = h.ReadAscii(3);
 
-                if ( ocsMeg.Kind == eKind.B )
-                    ocsMeg.BatterySOH = h.ReadAscii( 3 );
+                    //CheckSum 을 해야 하나??
+                    ocsMeg.CheckSum = h.ReadAscii(1);
+                    h.ReadUntil(ETX);
+                }
 
-                //CheckSum 을 해야 하나??
-                ocsMeg.CheckSum = h.ReadAscii( 1 );
-                h.ReadUntil( ETX );
             }
 
             //Todo: 응답으로 온건지 그냥 보낸건지 분류가 필요. = CheckSum 을 저장 했다가 이용하자.
@@ -390,20 +400,20 @@ namespace OHVConnector
             //var head = h.ReadBytes(10);
             //var body = h.ReadBytes(len - 10);
 
-            ChgTcpTimeout( true );//무언가 받으면
+            ChgTcpTimeout(true);//무언가 받으면
 
-            LockUtils.NotifyAll( lockLink );//Linktest thread 변환의 notify
+            LockUtils.NotifyAll(lockLink);//Linktest thread 변환의 notify
 
             //var v = new OCSMessage { Header = head, Body = body, IsRecd = true };
             //v.Decoding();
 
-            _OnRecd( ocsMeg );
+            _OnRecd(ocsMeg);
         }
 
-        void _OnRecd( OCSMessage recd )
-        {          
+        void _OnRecd(OCSMessage recd)
+        {
             //Alive Check Reply
-            if ( recd.Kind == eKind.A && !ModeActive ) //자동으로 응답을 보낸다. OCS 가 Active 상태
+            if (recd.Kind == eKind.A && !ModeActive) //자동으로 응답을 보낸다. OCS 가 Active 상태
             {
                 var reply = new OCSMessage()
                 {
@@ -414,50 +424,50 @@ namespace OHVConnector
                     Tag = recd.Tag,
                     SubCode = recd.SubCode,
                 };
-                Reply( reply );
+                Reply(reply);
                 return;
             }
 
-            if ( recd.Kind == eKind.M && !ModeActive ) //M Code 응답은 없음 
+            if (recd.Kind == eKind.M && !ModeActive) //M Code 응답은 없음 
             {
-                this.qQ.Enqueue( new QoRecd { Arg0 = recd } );
+                this.qQ.Enqueue(new QoRecd { Arg0 = recd });
                 return;
             }
 
-                  //Send 한 Message 의 Reply 로 판단.
-            var crc = MakeCRC8CheckSum( recd, false );
-            if ( this.quzT3.HasId( crc ) )
+            //Send 한 Message 의 Reply 로 판단.
+            var crc = MakeCRC8CheckSum(recd, false);
+            if (this.quzT3.HasId(crc))
             {
-                        //Send 목록에서 삭제한다.
-                this.quzT3.Stop( crc );
-                this._OnLog( $"[Reply] - {recd.LogFormat()}" );
+                //Send 목록에서 삭제한다.
+                this.quzT3.Stop(crc);
+                this._OnLog($"[Reply] - {recd.LogFormat()}");
                 return;
             }
 
-            this.qQ.Enqueue( new QoRecd { Arg0 = recd } );
+            this.qQ.Enqueue(new QoRecd { Arg0 = recd });
         }
 
-        void TcpError( Exception e )
+        void TcpError(Exception e)
         {
-            _OnLog( TcpUtils.GetTcpErrMsg( h.IPClient, e ) );
+            _OnLog(TcpUtils.GetTcpErrMsg(h.IPClient, e));
 
             h.CloseSocket();
-            _OnDicontd( e );
+            _OnDicontd(e);
 
-            var waitTime = ( this.Config.T3 + 2 ) * ConstUtils.ONE_SECOND;
-            LockUtils.Wait( waitTime );//잠시대기.
+            var waitTime = (this.Config.T3 + 2) * ConstUtils.ONE_SECOND;
+            LockUtils.Wait(waitTime);//잠시대기.
         }
 
         #endregion
 
         #region Write Method
-        void TcpWriteMsg( OCSMessage msg )
+        void TcpWriteMsg(OCSMessage msg)
         {
-            this.h.WriteFlush( msg.ToMemoryBuffer().ToBytes );
-            qQ.Enqueue( new QoSent { Arg0 = msg } );
+            this.h.WriteFlush(msg.ToMemoryBuffer().ToBytes);
+            qQ.Enqueue(new QoSent { Arg0 = msg });
         }
 
-        void TcpWriteNormalMsg( OCSMessage nm )
+        void TcpWriteNormalMsg(OCSMessage nm)
         {
             //nm.Encoding();
 
@@ -475,7 +485,7 @@ namespace OHVConnector
             //h.WriteFlush(mb.ToBytes);
         }
 
-        void TcpWriteCtrlMsg( OCSMessage ctrl )
+        void TcpWriteCtrlMsg(OCSMessage ctrl)
         {
             //var mb = new MemoryBuffer(16);
             //mb.AppendBeInt(10);
@@ -488,40 +498,40 @@ namespace OHVConnector
             //h.WriteFlush(mb.ToBytes);
         }
 
-        void SendCtrlMsg( int stype )
+        void SendCtrlMsg(int stype)
         {
             //Send(new OCSMessage { SType = stype });
         }
 
-        public void Send( OCSMessage msg, int after )
+        public void Send(OCSMessage msg, int after)
         {
-            if ( after > 0 )
-                TimerUtils.Once( after, Send, msg );
+            if (after > 0)
+                TimerUtils.Once(after, Send, msg);
             else
-                Send( msg );
+                Send(msg);
         }
 
-        public void Send( OCSMessage msg )
+        public void Send(OCSMessage msg)
         {
             //msg.Id = Config.ID;
 
             msg.RevID = Config.HostID;
             msg.SendID = Config.ID;
 
-            if ( !Connected )
+            if (!Connected)
             {
-                _OnLog( "Send fail not connected" + msg.LogFormat() );
+                _OnLog("Send fail not connected" + msg.LogFormat());
                 return;
             }
 
-            if ( msg.Kind == eKind.C ) // Control Message 는 페어로 응답이 오지 않는다.
+            if (msg.Kind == eKind.C) // Control Message 는 페어로 응답이 오지 않는다.
             {
-                qqW.Enqueue( msg );
+                qqW.Enqueue(msg);
                 return;
             }
 
             #region 2020.08.25. Kang. OCS에서 응답 안하는 것에 대해 Retry 를 위해 추가. 
-            if ( msg.Kind == eKind.L || msg.Kind == eKind.U )
+            if (msg.Kind == eKind.L || msg.Kind == eKind.U)
             {
                 var crc = MakeCRC8CheckSum(msg, true);
                 if (this.quzT3.HasId(crc))
@@ -550,50 +560,50 @@ namespace OHVConnector
             //        msg.Systembyte = Interlocked.Increment(ref sysbyte);
             //}
 
-            qqW.Enqueue( msg );
+            qqW.Enqueue(msg);
         }
 
         /// <summary>
         /// 응답을 보낼 때 사용.
         /// </summary>
         /// <param name="msg"></param>
-        public void Reply( OCSMessage msg )
+        public void Reply(OCSMessage msg)
         {
             msg.RevID = Config.HostID;
             msg.SendID = Config.ID;
 
-            if ( !Connected )
+            if (!Connected)
             {
-                _OnLog( "Reply fail not connected" + msg.LogFormat() );
+                _OnLog("Reply fail not connected" + msg.LogFormat());
                 return;
             }
 
-            qqW.Enqueue( msg );
+            qqW.Enqueue(msg);
         }
 
         #endregion
 
         #region HelpMothed
-        byte MakeCRC8CheckSum( OCSMessage msg, bool isSend )
+        byte MakeCRC8CheckSum(OCSMessage msg, bool isSend)
         {
-            if ( isSend )
-                return ChksumUtils.Crc8( this.crcTable, msg.ToCRC8Byte4Send() );
+            if (isSend)
+                return ChksumUtils.Crc8(this.crcTable, msg.ToCRC8Byte4Send());
             else
-                return ChksumUtils.Crc8( this.crcTable, msg.ToCRC8Byte4Received() );
+                return ChksumUtils.Crc8(this.crcTable, msg.ToCRC8Byte4Received());
         }
-        void ChgTcpTimeout( bool infinite )
+        void ChgTcpTimeout(bool infinite)
         {
-            if ( h.Connected )
+            if (h.Connected)
             {
-                if ( infinite )
+                if (infinite)
                 {
-                    if ( h.Socket.ReceiveTimeout != Timeout.Infinite )
-                        h.ChangeRecvTimeout( Timeout.Infinite );
+                    if (h.Socket.ReceiveTimeout != Timeout.Infinite)
+                        h.ChangeRecvTimeout(Timeout.Infinite);
                 }
                 else
                 {
-                    if ( Config.LinkOn )
-                        h.ChangeRecvTimeout( Config.T6 * ConstUtils.ONE_SECOND );
+                    if (Config.LinkOn)
+                        h.ChangeRecvTimeout(Config.T6 * ConstUtils.ONE_SECOND);
                 }
             }
         }

+ 1 - 0
Dev/Connection/OHVProtocolServer/OHVConnector/OCSMessage.cs

@@ -29,6 +29,7 @@ namespace OHVConnector
         G, //MTL 이동 명령
         W,
         K, //총 주행 거리.
+        D, //시간 동기화.
     }
 
     public class OCSMessage

BIN
Dev/OHV/Assambly/OHVConnector.dll


BIN
Dev/OHV/Assambly/OHVConnector.pdb


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

@@ -21,6 +21,7 @@ namespace OHV.Common.Shareds
         public const string BatteryCanType = "BATTERY_CAN_TYPE";
         public const string RouteFilePath = "ROUTE_FILE_PATH";
         public const string StandbyPattern = "STANDBY_PATTERN";
+        public const string UseMovingBuzzer = "USEMOVINGBUZZER";
 
         //Axis Name
         public const string AXIS_CARRIER_LOCK_LEFT = "Axis_CarrierLock_Left";

+ 8 - 0
Dev/OHV/OHV.SqliteDAL/OHVDbInitializer.cs

@@ -118,6 +118,14 @@ namespace OHV.SqliteDAL
                     Desc = "Auto Mode Standby State Pattern",
                     EditTime = DateTime.Now,
                 },
+                 new Config
+                {
+                    ID = ConstString.UseMovingBuzzer,
+                    Name= ConstString.UseMovingBuzzer,
+                    Value = "0",
+                    Desc = "0 Not Use, 1 Use",
+                    EditTime = DateTime.Now,
+                },
             });
 
             context.Set<AxisPositionData>().AddRange( new List<AxisPositionData>()

+ 1 - 1
Dev/OHV/OHV.SqliteDAL/SqliteManager.cs

@@ -28,10 +28,10 @@ namespace OHV.SqliteDAL
 
         public SqliteManager(IEventAggregator eventAggregator)
         {
-            this.ConfigDal = new GenericRepository<Config>();
             this.SubCmdDAL = new GenericRepository<SubCmd>();
             this.CommandDAL = new GenericRepository<Command>();
 
+            this.ConfigDal = new GenericRepository<Config>();
             this.AxisConfigDAL = new GenericRepository<AxisConfig>();
             this.AxisPositionDataDAL = new GenericRepository<AxisPositionData>();
             this.AxisVelocityDataDAL = new GenericRepository<AxisVelocityData>();

+ 0 - 1
Dev/OHV/OHV.Vehicle/App.xaml.cs

@@ -50,7 +50,6 @@ namespace OHV.Vehicle
                 QuartzUtils.Init(5);
                 logger.I(string.Format(string.Empty.PadRight(40, '+') + $" Ver. {AssemblyUtils.GetVersion()} " + string.Empty.PadRight(40, '+')));
 
-
                 //var mainView = new MainWindow();
                 //mainView.Show();
 

+ 3 - 2
Dev/OHV/OHV.Vehicle/Concept/D_MainWindow.xaml

@@ -40,7 +40,8 @@
                     <ColumnDefinition Width="400"/>
                 </Grid.ColumnDefinitions>
 
-                <TextBlock Text="{Binding SwVersion, FallbackValue=VCS.1.001}" Margin="10,0,0,0" Background="{x:Null}" FontSize="15" Foreground="Gray" VerticalAlignment="Top" HorizontalAlignment="Left"/>
+                <TextBlock Text="{Binding SwVersion, StringFormat=Ver.{0}, FallbackValue=VCS.1.001}" Margin="10,0,0,0" Background="{x:Null}" FontSize="15" Foreground="Gray" VerticalAlignment="Top" HorizontalAlignment="Left"/>
+                <TextBlock Text="{Binding LastBuildedTime, StringFormat=Build. {0:yyyy-MM-dd}, FallbackValue=Build. 2021.09.16}" Margin="10,20,0,0" Background="{x:Null}" FontSize="15" Foreground="Gray" VerticalAlignment="Top" HorizontalAlignment="Left"/>
                 <StackPanel Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center" Orientation="Horizontal">
                     <TextBlock Style="{StaticResource MaterialDesignHeadline3TextBlock}" HorizontalAlignment="Right" VerticalAlignment="Center" Foreground="White" FontSize="60" FontWeight="Bold" Text="Vehicle : "/>
                     <TextBlock Style="{StaticResource MaterialDesignHeadline3TextBlock}" HorizontalAlignment="Right" VerticalAlignment="Center" Foreground="White" FontSize="60" FontWeight="Bold" Text="{Binding VehicleID}"/>
@@ -108,7 +109,7 @@
                     </StackPanel>
                     <StackPanel Orientation="Horizontal">
                         <materialDesign:PackIcon HorizontalContentAlignment="Left" Kind="Timetable" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="30" Width="auto" Foreground="White" Margin="1,0,0,0"/>
-                        <TextBlock Text="{Binding DateTime, FallbackValue=2020-02-24 13:09:33, StringFormat=' \{0:yyyy-MM-dd HH:mm:ss\}'}" TextAlignment="Left" VerticalAlignment="Center" FontSize="20" Foreground="White" Margin="6,0,0,0"/>
+                        <TextBlock Text="{Binding DateTime, FallbackValue=2020-02-24 13:09:33, StringFormat='\{0:yyyy-MM-dd HH:mm:ss\}'}" TextAlignment="Left" VerticalAlignment="Center" FontSize="20" Foreground="White" Margin="6,0,0,0"/>
                     </StackPanel>
                 </StackPanel>
             </Grid>

+ 2 - 2
Dev/OHV/OHV.Vehicle/Concept/D_MainWindowViewModel.cs

@@ -340,8 +340,8 @@ namespace OHV.Vehicle.Concept
             dateTimer.Interval = TimeSpan.FromMilliseconds( 500 );
             dateTimer.Start();
 
-            this.SwVersion = AssemblyUtils.GetVersion();
-            this.LastBuildedTime = new Helpler.AssemblyInfo().Get_BuildDateTime();
+            this.SwVersion = AssemblyUtils.GetVersion(this);
+            this.LastBuildedTime = AssemblyUtils.BuildDate(this.GetType());
 
             GSG.NET.Quartz.QuartzUtils.Invoke( "RESOURCE_CHECK", GSG.NET.Quartz.QuartzUtils.GetExpnSecond( 1 ), QuzOnResourceUsage );
 

+ 10 - 0
Dev/OHV/OHV.Vehicle/OHV.Vehicle.csproj

@@ -125,6 +125,15 @@
     <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
     <Prefer32Bit>true</Prefer32Bit>
   </PropertyGroup>
+  <PropertyGroup>
+    <TargetZone>LocalIntranet</TargetZone>
+  </PropertyGroup>
+  <PropertyGroup>
+    <GenerateManifests>false</GenerateManifests>
+  </PropertyGroup>
+  <PropertyGroup>
+    <ApplicationManifest>Properties\app.manifest</ApplicationManifest>
+  </PropertyGroup>
   <ItemGroup>
     <Reference Include="Common.Logging">
       <HintPath>..\Assambly\Common.Logging.dll</HintPath>
@@ -308,6 +317,7 @@
     </None>
     <None Include="DB\OHVDb.sqlite" />
     <None Include="packages.config" />
+    <None Include="Properties\app.manifest" />
     <None Include="Properties\Settings.settings">
       <Generator>SettingsSingleFileGenerator</Generator>
       <LastGenOutput>Settings.Designer.cs</LastGenOutput>

+ 1 - 1
Dev/OHV/OHV.Vehicle/Properties/AssemblyInfo.cs

@@ -51,5 +51,5 @@ using System.Windows;
 // 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를
 // 기본값으로 할 수 있습니다.
 //[assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("2.0.0.0")]
+[assembly: AssemblyVersion("2.0.0.1")]
 [assembly: AssemblyFileVersion("2.0.0.0")]

+ 73 - 0
Dev/OHV/OHV.Vehicle/Properties/app.manifest

@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8"?>
+<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
+  <assemblyIdentity version="1.0.0.0" name="MyApplication.app" />
+  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
+    <security>
+      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
+        <!-- UAC 매니페스트 옵션
+             Windows 사용자 계정 컨트롤 수준을 변경하려면 
+             requestedExecutionLevel 노드를 다음 중 하나로 바꿉니다.
+
+        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
+        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
+        <requestedExecutionLevel  level="highestAvailable" uiAccess="false" />
+
+            requestedExecutionLevel 요소를 지정하면 파일 및 레지스트리 가상화를 사용하지 않습니다. 
+            이전 버전과의 호환성을 위해 애플리케이션에 가상화가 필요한 경우
+            이 요소를 제거합니다.
+        -->
+        <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
+      </requestedPrivileges>
+      <applicationRequestMinimum>
+        <defaultAssemblyRequest permissionSetReference="Custom" />
+        <PermissionSet class="System.Security.PermissionSet" version="1" ID="Custom" SameSite="site" Unrestricted="true" />
+      </applicationRequestMinimum>
+    </security>
+  </trustInfo>
+  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+    <application>
+      <!-- 이 애플리케이션이 테스트되고 함께 작동하도록 설계된 Windows 버전
+           목록입니다. 해당 요소의 주석 처리를 제거하면 Windows에서
+           호환 가능성이 가장 큰 환경을 자동으로 선택합니다. -->
+      <!-- Windows Vista -->
+      <!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
+      <!-- Windows 7 -->
+      <!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
+      <!-- Windows 8 -->
+      <!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
+      <!-- Windows 8.1 -->
+      <!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
+      <!-- Windows 10 -->
+      <!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->
+    </application>
+  </compatibility>
+  <!-- 애플리케이션이 DPI를 인식하며 높은 DPI에서 Windows가 자동으로 스케일링하지
+       않음을 나타냅니다. WPF(Windows Presentation Foundation) 애플리케이션은 자동으로 DPI를 인식하며 
+       옵트인할 필요가 없습니다. 이 설정에 옵트인한 .NET Framework 4.6을 대상으로 하는 
+       Windows Forms 애플리케이션은 app.config에서 'EnableWindowsFormsHighDpiAutoResizing' 설정도 'true'로 설정해야 합니다. 
+       
+       애플리케이션이 긴 경로를 인식하도록 설정합니다. https://docs.microsoft.com/windows/win32/fileio/maximum-file-path-limitation을 참조하세요. -->
+  <!--
+  <application xmlns="urn:schemas-microsoft-com:asm.v3">
+    <windowsSettings>
+      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
+      <longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
+    </windowsSettings>
+  </application>
+  -->
+  <!-- Windows 공용 컨트롤 및 대화 상자의 테마 사용(Windows XP 이상) -->
+  <!--
+  <dependency>
+    <dependentAssembly>
+      <assemblyIdentity
+          type="win32"
+          name="Microsoft.Windows.Common-Controls"
+          version="6.0.0.0"
+          processorArchitecture="*"
+          publicKeyToken="6595b64144ccf1df"
+          language="*"
+        />
+    </dependentAssembly>
+  </dependency>
+  -->
+</assembly>

+ 103 - 88
Dev/OHV/VehicleControlSystem/Managers/AutoManager.cs

@@ -12,6 +12,7 @@ using VehicleControlSystem.ControlLayer;
 using GSG.NET.Utils;
 using System.Collections.Generic;
 using System.Linq;
+using GSG.NET.LINQ;
 
 namespace VehicleControlSystem.Managers
 {
@@ -36,26 +37,27 @@ namespace VehicleControlSystem.Managers
                 //if (this.isErrorProcessing == value) return;
                 this.isErrorProcessing = value;
 
-                if ( value )
+                if (value)
                 {
                     //if ( this.activeAlarm == null ) return;
                     //this.OnOccurAlarm?.BeginInvoke( this.activeAlarm.AlarmId, null, null );
                 }
                 else
                 {
-                    this.ActiveAlarms.ForEach( x =>
-                    {
-                        this.OnClearAlarm?.Invoke( x.AlarmId );
-
-                        var al = ObjectCopyUtils.DeepClone<Alarm>( x );
-                        var args = new ActiveAlarmEventArgs( al, false );
-                        this.eventAggregator.GetEvent<ActiveAlarmPubSubEvent>().Publish( args );
-                    } );
+                    this.ActiveAlarms.ForEach(x =>
+                   {
+                       if (x.AlarmId != 45)
+                           this.OnClearAlarm?.Invoke(x.AlarmId);
+
+                       var al = ObjectCopyUtils.DeepClone<Alarm>(x);
+                       var args = new ActiveAlarmEventArgs(al, false);
+                       this.eventAggregator.GetEvent<ActiveAlarmPubSubEvent>().Publish(args);
+                   });
                     this.ActiveAlarms.Clear();
                     //if ( this.activeAlarm == null ) return;
                     //this.OnClearAlarm?.BeginInvoke( this.activeAlarm.AlarmId, null, null );
                     //this.activeAlarm = null;
-                    this.BuzzerOnOff( false );
+                    this.BuzzerOnOff(false);
                 }
             }
         }
@@ -101,17 +103,17 @@ namespace VehicleControlSystem.Managers
             get { return operationMode; }
             set
             {
-                if ( operationMode == value ) return;
+                if (operationMode == value) return;
 
                 operationMode = value;
-                logger.D( $"[AutoManager] OperationMode - {value}" );
+                logger.D($"[AutoManager] OperationMode - {value}");
 
-                this.OnOperationModeChanged?.Invoke( value );
+                this.OnOperationModeChanged?.Invoke(value);
 
-                if ( value == eOperatationMode.AutoMode )
-                    this.iO.OutputOff( "OUT_TEACH_MODE" );
+                if (value == eOperatationMode.AutoMode)
+                    this.iO.OutputOff("OUT_TEACH_MODE");
                 else
-                    this.iO.OutputOn( "OUT_TEACH_MODE" );
+                    this.iO.OutputOn("OUT_TEACH_MODE");
             }
         }
         public event Action<eOperatationMode> OnOperationModeChanged;
@@ -122,11 +124,11 @@ namespace VehicleControlSystem.Managers
             get { return autoModeState; }
             set
             {
-                if ( autoModeState == value ) return;
+                if (autoModeState == value) return;
 
                 autoModeState = value;
-                logger.D( $"[AutoManager] AutoModeState - {value}" );
-                switch ( value )
+                logger.D($"[AutoManager] AutoModeState - {value}");
+                switch (value)
                 {
                     case eAutoModeState.ErrorStop:
                         this.LampStateProperty = eLampState.Alarm;
@@ -155,10 +157,10 @@ namespace VehicleControlSystem.Managers
             get { return lampState; }
             set
             {
-                if ( lampState == value ) return;
+                if (lampState == value) return;
 
                 lampState = value;
-                this.LampStateChange( value );
+                this.LampStateChange(value);
             }
         }
 
@@ -170,7 +172,7 @@ namespace VehicleControlSystem.Managers
         }
 
         Vehicle vehicle = null;
-        public AutoManager( IIO io, IEventAggregator ea, SqliteManager sql, List<Alarm> al )
+        public AutoManager(IIO io, IEventAggregator ea, SqliteManager sql, List<Alarm> al)
         {
             this.iO = io;
             this.eventAggregator = ea;
@@ -183,43 +185,43 @@ namespace VehicleControlSystem.Managers
         #region Vehicle Events
         private void Vehicle_OnChargingFull()
         {
-            if ( this.OperationModeProperty == eOperatationMode.AutoMode )
-                LampStateChange( eLampState.AutoRunNChargingFull );
+            if (this.OperationModeProperty == eOperatationMode.AutoMode)
+                LampStateChange(eLampState.AutoRunNChargingFull);
             else
-                LampStateChange( eLampState.Manual );
+                LampStateChange(eLampState.Manual);
         }
 
         private void Vehicle_OnCharging()
         {
-            LampStateChange( eLampState.Charging );
+            LampStateChange(eLampState.Charging);
         }
 
         private void Vehicle_OnMoveFinish()
         {
-            BuzzerOnOff( false );
-            logger.D( "Vehicle Move Finish" );
+            BuzzerOnOff(false);
+            logger.D("Vehicle Move Finish");
         }
 
         private void Vehicle_OnMoving()
         {
-            BuzzerOnOff( true, eBuzzerKind.Moving );
-            logger.D( "Vehicle Moving" );
+            BuzzerOnOff(true, eBuzzerKind.Moving);
+            logger.D("Vehicle Moving");
         }
 
         private void Vehicle_OnMoveReady()
         {
-            BuzzerOnOff( true, eBuzzerKind.StartWarn );
-            logger.D( "Vehicle Move Ready" );
+            BuzzerOnOff(true, eBuzzerKind.StartWarn);
+            logger.D("Vehicle Move Ready");
         }
         #endregion
 
-        public void Init( Vehicle vehicle )
+        public void Init(Vehicle vehicle)
         {
             this.OperationModeProperty = eOperatationMode.ManualMode;
             this.AutoModeStateProperty = eAutoModeState.Stop;
 
             this.isThreadAlive = true;
-            this.threadWorker = ThreadUtils.Invoke( this.ThreadWork );
+            this.threadWorker = ThreadUtils.Invoke(this.ThreadWork);
 
             this.vehicle = vehicle;
             this.vehicle.OnMoveReady += Vehicle_OnMoveReady;
@@ -230,25 +232,25 @@ namespace VehicleControlSystem.Managers
         }
 
         #region Lamp & Buzzer
-        void LampStateChange( eLampState state )
+        void LampStateChange(eLampState state)
         {
-            this.iO.OutputOff( "OUT_TOWER_LAMP_RED" );
-            this.iO.OutputOff( "OUT_TOWER_LAMP_GREEN" );
+            this.iO.OutputOff("OUT_TOWER_LAMP_RED");
+            this.iO.OutputOff("OUT_TOWER_LAMP_GREEN");
 
-            switch ( state )
+            switch (state)
             {
                 case eLampState.Manual:
                 case eLampState.Alarm:
-                    this.iO.OutputOn( "OUT_TOWER_LAMP_RED" );
+                    this.iO.OutputOn("OUT_TOWER_LAMP_RED");
                     break;
                 case eLampState.Charging:
-                    this.iO.OutputOn( "OUT_TOWER_LAMP_RED" );
-                    this.iO.OutputOn( "OUT_TOWER_LAMP_GREEN" );
+                    this.iO.OutputOn("OUT_TOWER_LAMP_RED");
+                    this.iO.OutputOn("OUT_TOWER_LAMP_GREEN");
                     break;
                 case eLampState.AutoRunNChargingFull:
-                    this.iO.OutputOn( "OUT_TOWER_LAMP_GREEN" );
+                    this.iO.OutputOn("OUT_TOWER_LAMP_GREEN");
                     break;
-                case eLampState.Blocked :               //210812 Kkm 진행 막혀있는 상태 시 Buzzer 및 Lamp 상태 변경
+                case eLampState.Blocked:               //210812 Kkm 진행 막혀있는 상태 시 Buzzer 및 Lamp 상태 변경
                     this.iO.OutputOn("OUT_TOWER_LAMP_RED");
                     this.iO.OutputOn("OUT_TOWER_LAMP_GREEN");
                     break;
@@ -257,25 +259,36 @@ namespace VehicleControlSystem.Managers
             }
         }
 
-        void BuzzerOnOff( bool isOn, eBuzzerKind kind = eBuzzerKind.Alarm )
+        void BuzzerOnOff(bool isOn, eBuzzerKind kind = eBuzzerKind.Alarm)
         {
-            this.iO.OutputOff( "OUT_BUZZER_00" );
-            this.iO.OutputOff( "OUT_BUZZER_01" );
-            this.iO.OutputOff( "OUT_BUZZER_02" );
+            this.iO.OutputOff("OUT_BUZZER_00");
+            this.iO.OutputOff("OUT_BUZZER_01");
+            this.iO.OutputOff("OUT_BUZZER_02");
 
-            if ( !isOn )
+            if (!isOn)
                 return;
 
-            switch ( kind )
+            //21.09.16. Kang. 주행중 Buzzer 사용 선택.
+            if (kind == eBuzzerKind.Moving)
+            {
+                var useMovingBuzzer = sql.ConfigDal.Get(_ => _.ID.Equals(ConstString.UseMovingBuzzer)).FirstOrDefault();
+                if (useMovingBuzzer != null)
+                {
+                    if (useMovingBuzzer.Value.FwIntOf() <= 0)
+                        return;
+                }
+            }
+
+            switch (kind)
             {
                 case eBuzzerKind.Alarm:
-                    this.iO.OutputOn( "OUT_BUZZER_00" );
+                    this.iO.OutputOn("OUT_BUZZER_00");
                     break;
                 case eBuzzerKind.StartWarn:
-                    this.iO.OutputOn( "OUT_BUZZER_01" );
+                    this.iO.OutputOn("OUT_BUZZER_01");
                     break;
                 case eBuzzerKind.Moving:
-                    this.iO.OutputOn( "OUT_BUZZER_02" );
+                    this.iO.OutputOn("OUT_BUZZER_02");
                     break;
                 //case eBuzzerKind.Blocked:               //210812 Kkm 진행 막혀있는 상태 시 Buzzer 및 Lamp 상태 변경
                 //    break;
@@ -289,31 +302,31 @@ namespace VehicleControlSystem.Managers
         {
             Thread.CurrentThread.Name = $"{this.GetType().Name}-Work";
 
-            while ( this.isThreadAlive )
+            while (this.isThreadAlive)
             {
                 try
                 {
-                    Thread.Sleep( 100 );
+                    Thread.Sleep(100);
 
                     DoWork();
                 }
-                catch ( Exception ex )
+                catch (Exception ex)
                 {
-                    logger.E( $"{GetType().Name} - Thread Exception : {ex.StackTrace}" );
+                    logger.E($"{GetType().Name} - Thread Exception : {ex.StackTrace}");
                 }
             }
-            logger.D( "[AutoManager] - Work Thread Dispose" );
+            logger.D("[AutoManager] - Work Thread Dispose");
         }
 
         public void DoWork()
         {
-            switch ( this.OperationModeProperty )
+            switch (this.OperationModeProperty)
             {
                 case eOperatationMode.ManualMode:
                     break;
 
                 case eOperatationMode.AutoMode:
-                    switch ( this.AutoModeStateProperty )
+                    switch (this.AutoModeStateProperty)
                     {
                         case eAutoModeState.ErrorStop:
                             this.AutoModeStateProperty = eAutoModeState.WaitStop;
@@ -324,7 +337,7 @@ namespace VehicleControlSystem.Managers
                             break;
 
                         case eAutoModeState.Stop:
-                            if ( IsAllProcessStop() )
+                            if (IsAllProcessStop())
                             {
                                 //TODO: 여기서 메인명령을 정리하자.
                                 this.sql.SubCmdDAL.Clean();
@@ -336,7 +349,7 @@ namespace VehicleControlSystem.Managers
                             break;
 
                         case eAutoModeState.StartRun:
-                            if ( IsAllProcessStart() )
+                            if (IsAllProcessStart())
                                 this.AutoModeStateProperty = eAutoModeState.Run;
                             break;
 
@@ -356,11 +369,11 @@ namespace VehicleControlSystem.Managers
             }
         }
 
-        public void ProcessAlarm( int alarmID )
+        public void ProcessAlarm(int alarmID)
         {
             HisAlarm hisAlarm = new HisAlarm();
-            var alarm = this.Alarms.Where( x => x.AlarmId == alarmID ).FirstOrDefault();
-            if ( alarm == null )
+            var alarm = this.Alarms.Where(x => x.AlarmId == alarmID).FirstOrDefault();
+            if (alarm == null)
             {
                 hisAlarm.AlarmId = alarmID;
                 hisAlarm.Text = "Not Define Alarm";
@@ -370,7 +383,7 @@ namespace VehicleControlSystem.Managers
                 alarm.Level = eAlarmLevel.Fault;
                 alarm.Text = "Not Define Alarm";
 
-                logger.E( $"[{this.GetType().Name}] - Alarm Process / Not Define Alarm No {alarmID}" );
+                logger.E($"[{this.GetType().Name}] - Alarm Process / Not Define Alarm No {alarmID}");
             }
             else
             {
@@ -379,39 +392,40 @@ namespace VehicleControlSystem.Managers
                 hisAlarm.Solution = alarm.Solution;
             }
             //Add History
-            sql.HisAlarmDAL.Insert( hisAlarm );
-            logger.I( $"[Alarm Occur] - ID : {alarmID} / Text : {hisAlarm.Text}" );
+            sql.HisAlarmDAL.Insert(hisAlarm);
+            logger.I($"[Alarm Occur] - ID : {alarmID} / Text : {hisAlarm.Text}");
 
-            if ( this.ActiveAlarms == null )
+            if (this.ActiveAlarms == null)
                 return;
 
-            if ( !this.ActiveAlarms.Any( x => x.AlarmId == alarmID ) )
+            if (!this.ActiveAlarms.Any(x => x.AlarmId == alarmID))
             {
                 //OCS Report
-                this.OnOccurAlarm?.Invoke( alarm.AlarmId );
+                if (alarm.AlarmId != 45) //2021.09.13 Kang Servo Fault 알람은 제거 요청(나성권B)
+                    this.OnOccurAlarm?.Invoke(alarm.AlarmId);
 
-                var cloneAlarm = ObjectCopyUtils.DeepClone<Alarm>( alarm );
+                var cloneAlarm = ObjectCopyUtils.DeepClone<Alarm>(alarm);
                 this.activeAlarm = cloneAlarm;
-                this.ActiveAlarms.Add( cloneAlarm ); //Clear 보고를 위한 List Add
+                this.ActiveAlarms.Add(cloneAlarm); //Clear 보고를 위한 List Add
 
-                var args = new ActiveAlarmEventArgs( cloneAlarm );
-                this.eventAggregator.GetEvent<ActiveAlarmPubSubEvent>().Publish( args );
+                var args = new ActiveAlarmEventArgs(cloneAlarm);
+                this.eventAggregator.GetEvent<ActiveAlarmPubSubEvent>().Publish(args);
             }
 
-            if ( alarm.Level == eAlarmLevel.Warn )
+            if (alarm.Level == eAlarmLevel.Warn)
                 return;
 
             this.AutoModeStateProperty = eAutoModeState.ErrorStop;
             this.LampStateProperty = eLampState.Alarm;
             this.BuzzerStateProperty = eBuzzerKind.Alarm;
 
-            this.BuzzerOnOff( true, eBuzzerKind.Alarm );
+            this.BuzzerOnOff(true, eBuzzerKind.Alarm);
 
             this.sql.CommandDAL.Clean();
             this.sql.SubCmdDAL.Clean();
 
             //UI 로는 처음 발생한 Error 만 전송한다.
-            if ( IsErrorProcessing )
+            if (IsErrorProcessing)
                 return;
             IsErrorProcessing = true;
 
@@ -422,23 +436,24 @@ namespace VehicleControlSystem.Managers
                 MessageText = hisAlarm.Text,
                 Args = hisAlarm,
             };
-            this.eventAggregator.GetEvent<GUIMessagePubSubEvent>().Publish( msg );
+            this.eventAggregator.GetEvent<GUIMessagePubSubEvent>().Publish(msg);
         }
 
         /// <summary>
         /// Alarm Clear 를 여기서 모아서 하자.
         /// </summary>
         /// <param name="alarmID"></param>
-        public void ClearAlarm( int alarmID )
+        public void ClearAlarm(int alarmID)
         {
             var alarm = this.ActiveAlarms.FirstOrDefault(x => x.AlarmId == alarmID);
-            if ( alarm == null)
+            if (alarm == null)
                 return;
 
             this.ActiveAlarms.Remove(alarm);
             logger.I($"[{this.GetType().Name}] - Alarm Clear [{alarmID}]");
 
-            this.OnClearAlarm?.Invoke(alarm.AlarmId);
+            if (alarm.AlarmId != 45) //2021.09.13 Kang Servo Fault 알람은 제거 요청(나성권B)
+                this.OnClearAlarm?.Invoke(alarm.AlarmId);
 
             var al = ObjectCopyUtils.DeepClone<Alarm>(alarm);
             var args = new ActiveAlarmEventArgs(al, false);
@@ -447,7 +462,7 @@ namespace VehicleControlSystem.Managers
 
         bool IsAllProcessStop()
         {
-            if ( vehicle.IsAutoRun )
+            if (vehicle.IsAutoRun)
                 return false;
 
             return true;
@@ -461,16 +476,16 @@ namespace VehicleControlSystem.Managers
         #region IDisposable Support
         private bool disposedValue = false; // 중복 호출을 검색하려면
 
-        protected virtual void Dispose( bool disposing )
+        protected virtual void Dispose(bool disposing)
         {
-            if ( !disposedValue )
+            if (!disposedValue)
             {
-                if ( disposing )
+                if (disposing)
                 {
                     // TODO: 관리되는 상태(관리되는 개체)를 삭제합니다.
                     this.isThreadAlive = false;
-                    if ( !this.threadWorker.Join( 3000 ) )
-                        ThreadUtils.Kill( this.threadWorker );
+                    if (!this.threadWorker.Join(3000))
+                        ThreadUtils.Kill(this.threadWorker);
                 }
 
                 // TODO: 관리되지 않는 리소스(관리되지 않는 개체)를 해제하고 아래의 종료자를 재정의합니다.
@@ -491,7 +506,7 @@ namespace VehicleControlSystem.Managers
         public void Dispose()
         {
             // 이 코드를 변경하지 마세요. 위의 Dispose(bool disposing)에 정리 코드를 입력하세요.
-            Dispose( true );
+            Dispose(true);
             // TODO: 위의 종료자가 재정의된 경우 다음 코드 줄의 주석 처리를 제거합니다.
             // GC.SuppressFinalize(this);
         }

+ 9 - 0
Dev/OHV/VehicleControlSystem/Managers/HostManager.cs

@@ -14,6 +14,7 @@ using System.Collections.Generic;
 using VehicleControlSystem.ControlLayer.IO;
 using System.Collections.Concurrent;
 using GSG.NET.Concurrent;
+using System.Text;
 
 namespace VehicleControlSystem.Managers
 {
@@ -391,10 +392,18 @@ namespace VehicleControlSystem.Managers
                 case eKind.G:
                     ReceiveGCommand(msg);
                     break;
+                case eKind.D:
+                    ReceiveDateTimeSync(msg);
+                    break;
                 default:
                     break;
             }
+        }
 
+        private void ReceiveDateTimeSync(OCSMessage msg)
+        {
+            this.Reply(msg);
+            GSG.NET.Utils.DateUtils.ChangeSystemTime($"{msg.Tag}{msg.SubCode}");
         }
 
         private void ReceiveGCommand(OCSMessage msg)

BIN
Documents/Software/Interface/OCS for WATO_Message_ Scenario_Ver110.xlsx