unque781 5 лет назад
Родитель
Сommit
031fc22e52
35 измененных файлов с 2446 добавлено и 98 удалено
  1. 9 9
      Dev/Connection/OHVProtocolServer/OHVConnector/Manager.cs
  2. BIN
      Dev/OHV/Assambly/ExcelMapper/GSG.NET.Excel.dll
  3. 3 0
      Dev/OHV/OHV.LanguageHalper/Languages/Chinese.xaml
  4. 5 1
      Dev/OHV/OHV.Vehicle/App.xaml.cs
  5. 15 0
      Dev/OHV/OHV.Vehicle/Concept/D_MainWindowViewModel.cs
  6. BIN
      Dev/OHV/OHV.Vehicle/Config/AlarmDefind.xlsx
  7. 18 1
      Dev/OHV/OHV.Vehicle/Config/log4net.xml
  8. 1 5
      Dev/OHV/VehicleControlSystem/ControlLayer/ControlObjectBase.cs
  9. 5 1
      Dev/OHV/VehicleControlSystem/ControlLayer/IO/EzIO.cs
  10. 8 35
      Dev/OHV/VehicleControlSystem/ControlLayer/MQ/ZmqManager.cs
  11. 211 12
      Dev/OHV/VehicleControlSystem/ControlLayer/Steering.cs
  12. 16 15
      Dev/OHV/VehicleControlSystem/ControlLayer/Vehicle.cs
  13. 4 4
      Dev/OHV/VehicleControlSystem/Managers/AutoManager.cs
  14. 2 0
      Dev/OHV/VehicleControlSystem/Managers/Scheduler.cs
  15. 35 11
      Dev/OHV/VehicleControlSystem/VCSystem.cs
  16. 1 1
      Dev/OHVDriveLogger/OHVDriveLogger/OHVDriveLogger/App.config
  17. 9 2
      Dev/OHVDriveLogger/OHVDriveLogger/OHVDriveLogger/FTPLogger.cs
  18. 1 1
      Dev/OHVDriveLogger/OHVDriveLogger/OHVDriveLogger/FormMain.cs
  19. 12 0
      Dev/PLCLogger/App.config
  20. BIN
      Dev/PLCLogger/Config/PLC_Config.xlsx
  21. 41 0
      Dev/PLCLogger/Config/log4net.xml
  22. 8 0
      Dev/PLCLogger/ConfuserPLC.crproj
  23. 61 0
      Dev/PLCLogger/Form1.Designer.cs
  24. 216 0
      Dev/PLCLogger/Form1.cs
  25. 1253 0
      Dev/PLCLogger/Form1.resx
  26. BIN
      Dev/PLCLogger/IO2.ico
  27. 122 0
      Dev/PLCLogger/PLCLogger.csproj
  28. 28 0
      Dev/PLCLogger/PLCLogger.sln
  29. 48 0
      Dev/PLCLogger/Program.cs
  30. 36 0
      Dev/PLCLogger/Properties/AssemblyInfo.cs
  31. 71 0
      Dev/PLCLogger/Properties/Resources.Designer.cs
  32. 117 0
      Dev/PLCLogger/Properties/Resources.resx
  33. 30 0
      Dev/PLCLogger/Properties/Settings.Designer.cs
  34. 7 0
      Dev/PLCLogger/Properties/Settings.settings
  35. 53 0
      Dev/PLCLogger/TargetPLC.cs

+ 9 - 9
Dev/Connection/OHVProtocolServer/OHVConnector/Manager.cs

@@ -521,17 +521,17 @@ namespace OHVConnector
             }
 
             #region 2020.08.25. Kang. OCS에서 응답 안하는 것에 대해 Retry 를 위해 추가. 
-            var crc = MakeCRC8CheckSum( msg, true );
-            //logger.D(checkSum);
-
-            if ( this.quzT3.HasId( crc ) )
+            if ( msg.Kind == eKind.L || msg.Kind == eKind.U )
             {
-                _OnLog( "quzT3 Has ID" + msg.LogFormat() );
-                return;
-            }
-
-            this.quzT3.StartOnce( Config.T3 * ConstUtils.ONE_SECOND, crc, msg );
+                var crc = MakeCRC8CheckSum(msg, true);
+                if (this.quzT3.HasId(crc))
+                {
+                    _OnLog("quzT3 Has ID" + msg.LogFormat());
+                    return;
+                }
 
+                this.quzT3.StartOnce(Config.T3 * ConstUtils.ONE_SECOND, crc, msg);
+            }
             #endregion
 
             //if (msg.CtrlMsg)

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


+ 3 - 0
Dev/OHV/OHV.LanguageHalper/Languages/Chinese.xaml

@@ -15,6 +15,9 @@
     <system:String x:Key="VehicleAutoMode">要转换成自动模式吗 ?</system:String>
     <system:String x:Key="VehicleManualMode">要转换成手动模式吗 ?</system:String>
 
+    <!-->Notification</-->
+    <system:String x:Key="AutoModeChangeWranOnRailState">车辆不是 Installed 状态 !</system:String>
+
     <!-->Main View</-->
     <system:String x:Key="MainView_Main">主板</system:String>
     <system:String x:Key="MainView_Teach">操纵</system:String>

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

@@ -2,6 +2,7 @@
 using System.Threading;
 using System.Windows;
 using CommonServiceLocator;
+using GSG.NET.Concurrent;
 using GSG.NET.Logging;
 using GSG.NET.Quartz;
 using GSG.NET.Utils;
@@ -31,6 +32,8 @@ namespace OHV.Vehicle
 
         private void Application_Startup(object sender, StartupEventArgs e)
         {
+            Thread.CurrentThread.Name = $"{this.GetType().Name}";
+
             LogUtils.Configure("CONFIG/log4net.xml");
             AppUtils.LogGlobalException();
 
@@ -43,7 +46,8 @@ namespace OHV.Vehicle
 
             try
             {
-                QuartzUtils.Init(20);
+                ThreadUtils.InitPoolSize(10);
+                QuartzUtils.Init(5);
                 logger.I(string.Format(string.Empty.PadRight(40, '+') + $" Ver. {AssemblyUtils.GetVersion()} " + string.Empty.PadRight(40, '+')));
 
 

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

@@ -22,6 +22,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using System.Windows;
 using System.Windows.Input;
+using System.Windows.Interop;
 using System.Windows.Media;
 using System.Windows.Threading;
 using VehicleControlSystem;
@@ -677,6 +678,20 @@ namespace OHV.Vehicle.Concept
             else
             {
                 var msg = obj.Result.Errors.FirstOrDefault().Message;
+                if (msg.Equals("NotOnRoute"))
+                {
+                    var hisAlarm = new HisAlarm()
+                    {
+                        AlarmId = 999,
+                        Text = "Vehicle is not On Route! (自动驾驶无法变更的位置)",
+                        Solution = "Use a Jog to Move the Vehicle Onto the OnRoute(Jog Menu = Contol -> Drive ) \n" +
+                                   "利用小号移动车辆移动到 OnRoute 变成绿色为止. 如果Servo Off,请先做Servo On \n" +
+                                   "移动时,请给我位置的直线",
+                    };
+                    this.messageController.ShowNotificationAlarmView(hisAlarm);
+                    return;
+                }
+
                 this.messageController.ShowNotificationView( msg, false );
             }
         }

BIN
Dev/OHV/OHV.Vehicle/Config/AlarmDefind.xlsx


+ 18 - 1
Dev/OHV/OHV.Vehicle/Config/log4net.xml

@@ -30,7 +30,11 @@
 		<appender-ref ref="PhysicalCheckupFileAppender_Rear" />
 	</logger>
 
-	<!--
+	<logger name="SteerLogger" additivity="false">
+		<appender-ref ref="SteerFileAppender" />
+	</logger>
+
+<!--
 	ALL    DEBUG   INFO    WARN    ERROR   FATAL   OFF
 	•All
 	•DEBUG  •DEBUG
@@ -40,6 +44,19 @@
 	•FATAL  •FATAL  •FATAL  •FATAL  •FATAL  •FATAL
 	•OFF    •OFF    •OFF    •OFF    •OFF    •OFF    •OFF
 	-->
+	<appender name="SteerFileAppender" type="GSG.NET.Logging.FileAppender, GSG.NET">
+		<threshold value="INFO"/>
+		<file value="C:\LOG\OHV\Vehicle\Steer.log" />
+		<staticLogFileName value="true"/>
+		<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
+		<appendToFile value="true" />
+		<rollingStyle value="Date" />
+		<backupDays value="5" />
+		<datePattern value="-MMdd'.log'" />
+		<layout type="log4net.Layout.PatternLayout">
+			<conversionPattern value="%d{MM-dd HH:mm:ss.fff}, %2t, %p, %m%n" />
+		</layout>
+	</appender>
 
 	<appender name="BatteryFileAppender" type="GSG.NET.Logging.FileAppender, GSG.NET">
 		<threshold value="INFO"/>

+ 1 - 5
Dev/OHV/VehicleControlSystem/ControlLayer/ControlObjectBase.cs

@@ -10,11 +10,7 @@ namespace VehicleControlSystem.ControlLayer
 
         protected void OnPropertyChanged(string name)
         {
-            PropertyChangedEventHandler handler = PropertyChanged;
-            if (handler != null)
-            {   
-                handler?.Invoke(this, new PropertyChangedEventArgs(name));
-            }
+            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
         }
 
         /// <summary>

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

@@ -396,7 +396,7 @@ namespace VehicleControlSystem.ControlLayer.IO
             {
                 ThreadStart();
             }
-            catch ( Exception )
+            catch ( Exception ex )
             {
             }
             finally
@@ -415,6 +415,8 @@ namespace VehicleControlSystem.ControlLayer.IO
         }
         void IOThread()
         {
+            Thread.CurrentThread.Name = $"{this.GetType().Name}-IO";
+
             var sTime = SwUtils.CurrentTimeMillis;
                 
             while ( !this.threadCancel.Canceled )
@@ -569,6 +571,8 @@ namespace VehicleControlSystem.ControlLayer.IO
 
         void PullQueueThread()
         {
+            Thread.CurrentThread.Name = $"{this.GetType().Name}-Pull";
+
             while ( !this.threadCancel.Canceled )
             {
                 try

+ 8 - 35
Dev/OHV/VehicleControlSystem/ControlLayer/MQ/ZmqManager.cs

@@ -445,7 +445,6 @@ namespace VehicleControlSystem.ControlLayer.MQ
                                         this.RequestSteering = eSteeringState.Right;
                                         break;
                                     default:
-                                        this.RequestSteering = eSteeringState.None;
                                         break;
                                 }
                             }
@@ -625,7 +624,7 @@ namespace VehicleControlSystem.ControlLayer.MQ
 
                     case "7120":
                         this.CurrentMCR = vl[0];
-                        logger.D($" <7021> Current MCR : {this.CurrentMCR}");
+                        //logger.D($" <7120> Current MCR : {this.CurrentMCR}");
                         break;
 
                     case "111": //0=StartUp, 1=DeviceOpened, 2=DiviceOpenFailed, 3=ManualOP, 4=AutomaticOp, 5=DeviceCloseed, 6=Finished
@@ -811,37 +810,6 @@ namespace VehicleControlSystem.ControlLayer.MQ
 
         public BitArray GetAlarmBits()
         {
-            //var rll = new List<Alarm>();
-
-            //string warningList = "4094/0xff/0x00/0x00/0x01";
-
-            //var v = warningList.Split('/');
-
-            //var mb = new MemoryBuffer();
-            //for (int i = 1; i < v.Length; i++)
-            //{
-            //    var _2b = v[i].Replace("0x", "");
-            //    mb.Append(HexaUtils.StringToByte(_2b));
-            //}
-
-            //var bs = mb.ToBytes;
-            //var bitA = new BitArray(bs);
-
-            //for (int i = 0; i < bitA.Length; i++)
-            //{
-            //    if (bitA[i])
-            //    {
-            //        //Alarm List 
-            //    }
-            //    else
-            //    {
-
-            //    }
-            //}
-
-            //return rll;
-
-
             var result = this.RequestDrive("getm", "502");
             if (result.Count == 0)
             {
@@ -1411,9 +1379,14 @@ namespace VehicleControlSystem.ControlLayer.MQ
                 this.OnDriveAlarmBitArrayChg?.Invoke(alarmBits);
         }
 
-        public void AlarmBitTest()
+        public void AlarmBitTest(bool on)
         {
-            string warningList = "4094/0xff/0x00/0x00/0x01";
+            string warningList = string.Empty;
+
+            if ( on )
+                warningList = "4094/0xff/0x00/0x00/0x01";
+            else
+                warningList = "4094/0x00/0x00/0x00/0x00";
 
             var v = warningList.Split('/');
 

+ 211 - 12
Dev/OHV/VehicleControlSystem/ControlLayer/Steering.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Security.Principal;
 using System.Threading.Tasks;
 using GSG.NET.Concurrent;
 using GSG.NET.Logging;
@@ -8,16 +9,22 @@ using OHV.Common.Shareds;
 using OHV.SqliteDAL;
 using Prism.Events;
 using VehicleControlSystem.ControlLayer.IO;
+using VehicleControlSystem.ControlLayer.MQ;
 
 namespace VehicleControlSystem.ControlLayer
 {
-    public class Steering : ControlObjectBase
+    public class Steering : ControlObjectBase, IDisposable
     {
         static Logger logger = Logger.GetLogger();
+        static Logger SteerLogger = Logger.GetLogger("SteerLogger");
+
+        ThreadCancel threadCancel = new ThreadCancel();
+        TsQueue<eSteeringState> qReqSteer = new TsQueue<eSteeringState>();
 
         EzIO iO = null;
         SqliteManager sql = null;
         IEventAggregator eventAggregator = null;
+        ZmqManager zmqManager = null;
 
         public event EventHandler<int> OnSteeringError;
 
@@ -26,17 +33,127 @@ namespace VehicleControlSystem.ControlLayer
         public eSteeringState SteeringState
         {
             get { return steeringState; }
-            set { SetField(ref this.steeringState, value); }
+            set { if (SetField(ref this.steeringState, value)) { /*this.zmqManager.SetCurrentSteeringState(value);*/ } }
+        }
+
+        public Steering() { }
+
+        public void Dispose()
+        {
+            this.threadCancel.Cancel();
         }
 
-        public Steering(IIO io, SqliteManager sql, IEventAggregator ea)
+        public void AssignRefObject(IIO io, SqliteManager sql, IEventAggregator ea, ZmqManager zm)
         {
             this.iO = io as EzIO;
+            this.iO.OnChangedIO += IO_OnChangedIO;
+
             this.sql = sql;
             this.eventAggregator = ea;
-            this.iO.OnChangedIO += IO_OnChangedIO;
+            this.zmqManager = zm;
+
+            this.threadCancel.AddGo(_DoControlSteer);
+        }
+
+        #region Thread Method
+        void _DoControlSteer()
+        {
+            while ( !this.threadCancel.Canceled )
+            {
+                var q = this.qReqSteer.Dequeue();
+                this.ControlSteerNWaitDone( q );
+            }
+        }
+
+        void ControlSteerNWaitDone( eSteeringState requestState )
+        {
+            logger.D( $"Steer - Start {requestState} -------------------------------------------------------" );
+
+            if ( requestState == eSteeringState.Left )
+            {
+                this.iO.WriteOutputIO( "OUT_F_STEERING_CWCCW", false );
+                this.iO.WriteOutputIO( "OUT_R_STEERING_CWCCW", true );
+            }
+            else
+            {
+                this.iO.WriteOutputIO( "OUT_F_STEERING_CWCCW", true );
+                this.iO.WriteOutputIO( "OUT_R_STEERING_CWCCW", false );
+            }
+
+            //Hight Voltage On
+            this.iO.WriteOutputIO( "OUT_F_STEERING_DA", true );
+            this.iO.WriteOutputIO( "OUT_R_STEERING_DA", true );
+
+            logger.D( $"Steer - OutPut On" );
+
+            var sT = SwUtils.CurrentTimeMillis;
+            bool isCheckedOutput = false;
+            var currentDirection = eSteeringState.None;
+            long eT = 0;
+            while ( true )
+            {
+                LockUtils.Wait( 10 );
+
+                currentDirection = GetSteerDirection();
+                if ( requestState == currentDirection )
+                    break;
+
+                eT = SwUtils.Elapsed( sT );
+
+                if ( eT > 700 && !isCheckedOutput )
+                {
+                    this.iO.WriteOutputIO( "OUT_F_STEERING_DA", false );
+                    this.iO.WriteOutputIO( "OUT_R_STEERING_DA", false );
+                    isCheckedOutput = true;
+                    logger.D( $"Steer - Output Off {eT}ms" );
+                }
+
+                if ( eT > ConstUtils.ONE_SECOND * 2 )
+                {
+                    logger.D( $"Steer - Wait Time Out {eT}ms" );
+                    this.SteeringState = eSteeringState.None;
+
+                    if ( !isCheckedOutput )
+                    {
+                        this.iO.WriteOutputIO( "OUT_F_STEERING_DA", false );
+                        this.iO.WriteOutputIO( "OUT_R_STEERING_DA", false );
+                        logger.D( $"Steer - Output Off {SwUtils.Elapsed( sT )}ms" );
+                    }
+                    return;
+                }
+            }
+
+            if ( !isCheckedOutput ) //위에서 Off 를 안했을 경우가 생길 수 있음. (700ms 이내에 조향 바뀌었을때)
+            {
+                this.iO.WriteOutputIO( "OUT_F_STEERING_DA", false );
+                this.iO.WriteOutputIO( "OUT_R_STEERING_DA", false );
+                logger.D( $"Steer - Output Off {SwUtils.Elapsed( sT )}ms" );
+            }
+
+            logger.D( $"Steer - Drive Request Start" );
+            this.SteeringState = currentDirection;
+            logger.D( $"Steer - Contorl End {SwUtils.Elapsed( sT )}ms -------------------------------------------------------" );
+
+            SteerLogger.I( SwUtils.Elapsed( sT ) );
+        }
+
+        eSteeringState GetSteerDirection()
+        {
+            if ( this.IsLeft() )
+                return eSteeringState.Left;
+            if ( this.IsRight() )
+                return eSteeringState.Right;
+
+            return eSteeringState.None;
+        }
+
+        public void RequestControl( eSteeringState state )
+        {
+            this.qReqSteer.Enqueue( state );
         }
 
+        #endregion
+
         private void IO_OnChangedIO(BitBlock bit)
         {
             //if ( bit.Tag.Equals( "IN_F_STEERING_DETECT_LEFT" ) || bit.Tag.Equals( "IN_F_STEERING_DETECT_RIGHT" ) )
@@ -66,7 +183,7 @@ namespace VehicleControlSystem.ControlLayer
                 rearState = eSteeringState.None;
             if (!this.IsRearLeft() && !this.IsRearRight())
                 rearState = eSteeringState.None;
-            
+
             if (this.IsRearRight())
                 rearState = eSteeringState.Right;
             else if (this.IsRearLeft())
@@ -74,14 +191,15 @@ namespace VehicleControlSystem.ControlLayer
             else
                 rearState = eSteeringState.None;
 
+            eSteeringState totalState = eSteeringState.None;
             if (frontState == eSteeringState.Left && rearState == eSteeringState.Left)
-                this.SteeringState = eSteeringState.Left;
+                totalState = eSteeringState.Left;
             else if (frontState == eSteeringState.Right && rearState == eSteeringState.Right)
-                this.SteeringState = eSteeringState.Right;
+                totalState = eSteeringState.Right;
             else
-                this.SteeringState = eSteeringState.None;
+                totalState = eSteeringState.None;
 
-            return this.SteeringState;
+            return totalState;
         }
 
         readonly object lockObject = new object();
@@ -151,7 +269,7 @@ namespace VehicleControlSystem.ControlLayer
                         logger.D($"[Steer Release Lock] - {SwUtils.Elapsed(sT)} ms");
 
                         LockUtils.Wait(200);
-                        GetSteeringState();
+                        this.SteeringState = GetSteeringState();
                         this.isExecuteSteering = false;
 
                     });
@@ -219,19 +337,100 @@ namespace VehicleControlSystem.ControlLayer
                return true;
            }).ContinueWith(t =>
               {
-                  logger.D($"[Steer Release Lock] - {SwUtils.Elapsed(sT)} ms");
+                  var eT = SwUtils.Elapsed(sT);
+                  logger.D($"[Steer Release Lock] - {eT} ms");
 
                   if (!t.Result)
                       this.SteeringState = eSteeringState.None;
                   else
                   {
                       LockUtils.Wait(200);
-                      GetSteeringState();
+                      this.SteeringState = GetSteeringState();
                   }
 
                   this.isExecuteSteering = false;
               });
         }
+        
+        /// <summary>
+        /// Test Control
+        /// </summary>
+        /// <param name="isLeft"></param>
+        public void TestSteerControl(bool isLeft = false)
+        {
+            if (this.isExecuteSteering) return;
+
+            this.isExecuteSteering = true;
+
+            logger.D($"[Steer Lock] ----------------------------------------------------------------");
+
+            var sT = SwUtils.CurrentTimeMillis;
+
+            Task.Run(() =>
+            {
+                if (isLeft) //Left IO 가 직진 이라고 생각하자.
+                {
+                    this.iO.WriteOutputIO("OUT_F_STEERING_CWCCW", false);
+                    this.iO.WriteOutputIO("OUT_R_STEERING_CWCCW", true);
+
+                    this.iO.WriteOutputIO("OUT_F_STEERING_DA", true);
+                    this.iO.WriteOutputIO("OUT_R_STEERING_DA", true);
+                    LockUtils.Wait(700);
+                    this.iO.WriteOutputIO("OUT_F_STEERING_DA", false);
+                    this.iO.WriteOutputIO("OUT_R_STEERING_DA", false);
+                }
+                else
+                {
+                    this.iO.WriteOutputIO("OUT_F_STEERING_CWCCW", true);
+                    this.iO.WriteOutputIO("OUT_R_STEERING_CWCCW", false);
+
+                    this.iO.WriteOutputIO("OUT_F_STEERING_DA", true);
+                    this.iO.WriteOutputIO("OUT_R_STEERING_DA", true);
+                    LockUtils.Wait(700);
+                    this.iO.WriteOutputIO("OUT_F_STEERING_DA", false);
+                    this.iO.WriteOutputIO("OUT_R_STEERING_DA", false);
+                }
+            });
+
+            Task.Run(() =>
+            {
+                long sTime = SwUtils.CurrentTimeMillis;
+                while (true)
+                {
+                    LockUtils.Wait(5);
+
+                    if (SwUtils.Gt(sTime, 2 * ConstUtils.ONE_SECOND))
+                    {
+                        this.SteeringState = eSteeringState.None;
+                        this.isExecuteSteering = false;
+                        logger.D($"Steer Control Fail {SwUtils.Elapsed(sT)}");
+                        return;
+                    }
+
+                    if (isLeft)
+                    {
+                        if (this.IsLeft())
+                            break;
+                    }
+                    else
+                    {
+                        if (this.IsRight())
+                            break;
+                    }
+                }
+                LockUtils.Wait(200); //안정화 시간.
+
+                logger.D($"Request Steer State Start");
+                this.SteeringState = GetSteeringState();
+                logger.D($"Request Steer State End");
+
+                var eT = SwUtils.Elapsed(sT);
+                logger.D($"[Steer Release Lock] - {eT} ms ----------------------------------------------------------");
+                SteerLogger.I(eT);
+            });
+
+            this.isExecuteSteering = false;
+        }
 
         void SetHightVolt()
         {

+ 16 - 15
Dev/OHV/VehicleControlSystem/ControlLayer/Vehicle.cs

@@ -603,7 +603,12 @@ namespace VehicleControlSystem.ControlLayer
             {
                 if (obj[i])
                     this.OccurVehicleAlarm(i + 1000);
+                else
+                    this.refObjects.AutoManager.ClearAlarm(i + 1000);
             }
+
+            if ( this.refObjects.AutoManager.ActiveAlarms.Count <= 0)
+                this.VehicleStateProperty = eVehicleState.Idle;
         }
 
         private void ObstacleReceiveEvent(ObstacleControlEventArgs obj)
@@ -677,10 +682,10 @@ namespace VehicleControlSystem.ControlLayer
                         break;
 
                     case DriveControlEventArgs.eControlKind.Steering:
-                        if (msg.MoveDir == DriveControlEventArgs.eMoveDir.LEFT)
-                            this.refObjects.Steering.ControlSteering(true);
+                        if ( msg.MoveDir == DriveControlEventArgs.eMoveDir.LEFT )
+                            this.refObjects.Steering.RequestControl( eSteeringState.Left );
                         else
-                            this.refObjects.Steering.ControlSteering();
+                            this.refObjects.Steering.RequestControl( eSteeringState.Right );
                         break;
 
                     case DriveControlEventArgs.eControlKind.SteeringState:
@@ -771,11 +776,6 @@ namespace VehicleControlSystem.ControlLayer
             //refObjects.Sqlite.VehicleInfoDAL.Update( v );
         }
 
-        void TestAction()
-        {
-
-        }
-
         public int InitializationVehicle()
         {
 #if SIMULATION
@@ -829,10 +829,6 @@ namespace VehicleControlSystem.ControlLayer
 
             this.cancel.Cancel();
             this.cancel.StopWaitAll();
-
-            //this.bMUManager.Disconnect();
-
-            //this.drive.Dispose();
         }
 
         #region Request Method
@@ -1006,6 +1002,9 @@ namespace VehicleControlSystem.ControlLayer
 
         void ThreadJob()
         {
+            Thread.CurrentThread.Name = $"{this.GetType().Name}Job";
+            logger.D($"Vehicle - Process Started {Thread.CurrentThread.Name}");
+
             while (!this.taskCancel.Canceled)
             {
                 try
@@ -2083,7 +2082,7 @@ namespace VehicleControlSystem.ControlLayer
             {
                 LockUtils.Wait(50);
 
-                if ( SwUtils.Gt( sTime, 20 * ConstUtils.ONE_SECOND ) )
+                if ( SwUtils.Gt( sTime, 30 * ConstUtils.ONE_SECOND ) )
                 {
                     this.refObjects.IO.WriteOutputIO( "OUT_PIO_INTERLOCK", true );
 
@@ -2527,6 +2526,8 @@ namespace VehicleControlSystem.ControlLayer
         /// <param name="alarmID"></param>
         public void OccurVehicleAlarm( int alarmID )
         {
+            logger.D($"[{this.GetType().Name}] - Occur Alarm Method- {alarmID}");
+
             var alarm = refObjects.Alarms.FirstOrDefault( x=>x.AlarmId == alarmID );
             if ( alarm != null )
             {
@@ -2658,10 +2659,10 @@ namespace VehicleControlSystem.ControlLayer
                             case eSteeringState.None:
                                 break;
                             case eSteeringState.Left:
-                                this.refObjects.Steering.ControlSteeringNotResult( true );
+                                this.refObjects.Steering.RequestControl( eSteeringState.Left );
                                 break;
                             case eSteeringState.Right:
-                                this.refObjects.Steering.ControlSteeringNotResult();
+                                this.refObjects.Steering.RequestControl( eSteeringState.Right );
                                 break;
                             default:
                                 break;

+ 4 - 4
Dev/OHV/VehicleControlSystem/Managers/AutoManager.cs

@@ -261,6 +261,8 @@ namespace VehicleControlSystem.Managers
 
         void ThreadWork()
         {
+            Thread.CurrentThread.Name = $"{this.GetType().Name}-Work";
+
             while ( this.isThreadAlive )
             {
                 try
@@ -353,7 +355,7 @@ namespace VehicleControlSystem.Managers
             if ( !this.ActiveAlarms.Any( x => x.AlarmId == alarmID ) )
             {
                 //OCS Report
-                this.OnOccurAlarm?.BeginInvoke( alarm.AlarmId, null, null );
+                this.OnOccurAlarm?.Invoke( alarm.AlarmId );
 
                 var cloneAlarm = ObjectCopyUtils.DeepClone<Alarm>( alarm );
                 this.activeAlarm = cloneAlarm;
@@ -398,12 +400,10 @@ namespace VehicleControlSystem.Managers
         {
             var alarm = this.ActiveAlarms.FirstOrDefault(x => x.AlarmId == alarmID);
             if ( alarm == null)
-            {
-                logger.E($"[{this.GetType().Name}] - Alarm Clear / Not Define Alarm No {alarmID}");
                 return;
-            }
 
             this.ActiveAlarms.Remove(alarm);
+            logger.I($"[{this.GetType().Name}] - Alarm Clear [{alarmID}]");
 
             this.OnClearAlarm?.Invoke(alarm.AlarmId);
 

+ 2 - 0
Dev/OHV/VehicleControlSystem/Managers/Scheduler.cs

@@ -130,6 +130,8 @@ namespace VehicleControlSystem.Managers
 
         void ExcuteCommand()
         {
+            Thread.CurrentThread.Name = $"{this.GetType().Name}";
+
             while (isThreadAlive)
             {
                 Thread.Sleep(300);

+ 35 - 11
Dev/OHV/VehicleControlSystem/VCSystem.cs

@@ -1,4 +1,5 @@
-using System;
+#define TEST
+using System;
 using System.Collections;
 using System.Collections.Generic;
 using System.IO;
@@ -103,13 +104,15 @@ namespace VehicleControlSystem
             this.clamp.Init();
 
             //Steering
-            this.steering = new Steering(this.IO, this.sql, this.eventAggregator);
+            this.steering = new Steering();
 
             //ZeroMQ
             this.ZmqManager = new ZmqManager();
             this.ZmqManager.AssignRefObject(this.bMUManager, this.steering, this.IO);
             this.ZmqManager.Init();
 
+            this.steering.AssignRefObject(this.IO, this.sql, this.eventAggregator, this.ZmqManager);
+
             //Drive
             this.drive = new GSIDrive(this.sql, this.steering, this.ZmqManager, this.Alarms);
             this.drive.Init();
@@ -213,7 +216,7 @@ namespace VehicleControlSystem
                 this.vehicle.OccurVehicleAlarm(29);
             }
 
-            this.steering.ControlSteering(true);//초기에 직선 주행 상태로 핸들 조정.
+            this.steering.RequestControl(eSteeringState.Left);//초기에 직선 주행 상태로 핸들 조정.
         }
 
         #endregion
@@ -254,7 +257,9 @@ namespace VehicleControlSystem
                 case VCSMessageEventArgs.eVCSMessageKind.ReqAddCommand:
                     break;
                 case VCSMessageEventArgs.eVCSMessageKind.ReqTest:
+#if TEST
                     ReqTest();
+#endif
                     break;
                 case VCSMessageEventArgs.eVCSMessageKind.ReqConveyorMove:
                     ReqConveyorMove(msg);
@@ -607,11 +612,27 @@ namespace VehicleControlSystem
 
         private void ReqTest()
         {
-            //logger.D( "Test Request" );
-            //if ( this.IO.WaitChangeInputIO( true, 30000, "IN_CV_DETECT_00" ) )
-            //    logger.D( "Test - Time in" );
-            //else
-            //    logger.D( "Test - Time out" );
+            var isS = QuartzUtils.StopSchedule("SteerTest");
+
+            LockUtils.Wait(1000);
+            QuartzUtils.Invoke("SteerTest", QuartzUtils.GetExpnSecond(30), StartSteerTest);
+        }
+
+        bool isSteerLeft = true;
+        void StartSteerTest()
+        {
+            var sT = SwUtils.CurrentTimeMillis;
+
+            if (isSteerLeft)
+            {
+                this.steering.RequestControl(eSteeringState.Right);
+                isSteerLeft = false;
+            }
+            else
+            {
+                this.steering.RequestControl(eSteeringState.Left);
+                isSteerLeft = true;
+            }
         }
 
         private void ReqMachineModeChg(VCSMessageEventArgs msg)
@@ -681,8 +702,7 @@ namespace VehicleControlSystem
         private void ReqEStop()
         {
             this.vehicle.EStop();
-
-            autoManager.ProcessAlarm(11);
+            autoManager.ProcessAlarm(23);
         }
 
         private void ReqVehicleModeChange(VCSMessageEventArgs msg)
@@ -690,6 +710,9 @@ namespace VehicleControlSystem
             GUIMessageEventArgs reply;
             if (msg.MessageKey.Equals(MessageKey.AutoMode))
             {
+                if (!QuartzUtils.StopSchedule("SteerTest"))
+                    return;
+
                 if (!this.ZmqManager.IsReqConnected)
                 {
                     reply = new GUIMessageEventArgs { Kind = GUIMessageEventArgs.eGUIMessageKind.RspVehicleModeChange, Result = FluentResults.Results.Fail(new Error("Drive P/G not Connected")), MessageKey = MessageKey.ManualMode };
@@ -699,7 +722,7 @@ namespace VehicleControlSystem
 
                 if (!this.ZmqManager.IsCanStanbyLocation)
                 {
-                    reply = new GUIMessageEventArgs { Kind = GUIMessageEventArgs.eGUIMessageKind.RspVehicleModeChange, Result = FluentResults.Results.Fail(new Error("Vehicle is not On Route!!")), MessageKey = MessageKey.ManualMode };
+                    reply = new GUIMessageEventArgs { Kind = GUIMessageEventArgs.eGUIMessageKind.RspVehicleModeChange, Result = FluentResults.Results.Fail(new Error("NotOnRoute")), MessageKey = MessageKey.ManualMode };
                     GUIMessageEventPublish(reply);
                     return;
                 }
@@ -799,6 +822,7 @@ namespace VehicleControlSystem
 
             this.bMUManager.Disconnect();
             this.drive.Dispose();
+            this.steering.Dispose();
             this.ZmqManager.Dispose();
 
             (this.IO as IDisposable).Dispose(); //IO 는 마지막에 정리함.

+ 1 - 1
Dev/OHVDriveLogger/OHVDriveLogger/OHVDriveLogger/App.config

@@ -5,7 +5,7 @@
     </startup>
 
 	<appSettings>
-		<add key="VehicleID" value="V01"/>
+		<add key="VehicleID" value="V02"/>
 		<add key="FTPUploadIP" value="109.19.54.164"/>
 		<add key="PLC_IP" value="192.168.0.20"/>
 		<add key="PLC_PORT" value="5000"/>

+ 9 - 2
Dev/OHVDriveLogger/OHVDriveLogger/OHVDriveLogger/FTPLogger.cs

@@ -4,6 +4,7 @@ using GSG.NET.Logging;
 using GSG.NET.ObjectBase;
 using GSG.NET.Utils;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -48,7 +49,7 @@ namespace OHVDriveLogger
                 ftp.Dispose();
             }
 
-            DeleteLocalFiles( @"C:\LOG\FTP" );
+            DeleteLocalFiles(@"C:\LOG\FTP");
         }
 
         public void FTPDriveLogUplaod()
@@ -85,7 +86,7 @@ namespace OHVDriveLogger
             logger.I($"{SwUtils.Elapsed(sTime)}");
         }
 
-        public void FTPDownload()
+        public void FTPDownload(string fileName)
         {
             var sTime = SwUtils.CurrentTimeMillis;
 
@@ -106,7 +107,13 @@ namespace OHVDriveLogger
 
                 ftp.Disconnect();
                 ftp.Dispose();
+
             }
+            var file = FileUtils.GetFileInfos(@"C:\FTP\", "*.csv", false).OrderByDescending(x => x.LastWriteTime).FirstOrDefault();
+            if (file == null)
+                return;
+
+            file.MoveTo(@"C:\FTP\PLCData_" + fileName + ".csv");
 
             logger.I($"[PLC File Downlaod Complete] - {SwUtils.Elapsed(sTime)} ms");
         }

+ 1 - 1
Dev/OHVDriveLogger/OHVDriveLogger/OHVDriveLogger/FormMain.cs

@@ -210,7 +210,7 @@ namespace OHVDriveLogger
             this.plc.WriteBit( "DRIVE_LOGGING_ONOFF", false );
 
             LockUtils.Wait(200);
-            FTPLogger.Instance.FTPDownload();
+            FTPLogger.Instance.FTPDownload($"{this.vehicleID}_"+now.ToString("MMdd_HHmmss"));
             LockUtils.Wait( 100 );
             //string uploadPath = $"\\LOG\\{this.vehicleID}";
             //FTPLogger.Instance.FTPUpload(uploadPath, fll);

+ 12 - 0
Dev/PLCLogger/App.config

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+    <startup> 
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
+    </startup>
+
+	<appSettings>
+		<add key="PLC_IP" value="192.168.0.100"/>
+		<add key="PLC_PORT" value="5000"/>
+	</appSettings>
+	
+</configuration>

BIN
Dev/PLCLogger/Config/PLC_Config.xlsx


+ 41 - 0
Dev/PLCLogger/Config/log4net.xml

@@ -0,0 +1,41 @@
+<log4net>
+
+	<root name="root">
+		<level value="ALL" />
+		<appender-ref ref="FileAppender" />
+	</root>
+
+	<!--
+	ALL    DEBUG   INFO    WARN    ERROR   FATAL   OFF
+	•All
+	•DEBUG  •DEBUG
+	•INFO   •INFO   •INFO
+	•WARN   •WARN   •WARN   •WARN
+	•ERROR  •ERROR  •ERROR  •ERROR  •ERROR
+	•FATAL  •FATAL  •FATAL  •FATAL  •FATAL  •FATAL
+	•OFF    •OFF    •OFF    •OFF    •OFF    •OFF    •OFF
+	-->
+
+	<appender name="FileAppender" type="GSG.NET.Logging.FileAppender, GSG.NET">
+		<threshold value="ALL"/>
+		<!--<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />-->
+		<file type="log4net.Util.PatternString">
+			<conversionPattern value="C:\LOG\PLCLogger\Logger.log"  />
+		</file>
+		<appendToFile value="true" />
+		<rollingStyle value="Date" />
+		<backupDays value="10" />
+		<datePattern value="-MMdd'.log'" />
+		<layout type="log4net.Layout.PatternLayout">
+			<conversionPattern value="%d{MM-dd HH:mm:ss.fff} %-2t %p %m%n" />
+		</layout>
+	</appender>
+
+	<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender"   >
+		<layout type="log4net.Layout.PatternLayout">
+			<param name="ConversionPattern" value="%d %m%n" />
+		</layout>
+		<threshold value="ALL"/>
+	</appender>
+
+</log4net>

+ 8 - 0
Dev/PLCLogger/ConfuserPLC.crproj

@@ -0,0 +1,8 @@
+<project outputDir="D:\Temp\PLCLogger\Confused" baseDir="D:\Temp\PLCLogger\bin\Debug" xmlns="http://confuser.codeplex.com">
+  <module path="PLCLogger.exe">
+    <rule pattern="true" preset="normal" inherit="false">
+      <protection id="constants" />
+      <protection id="rename" />
+    </rule>
+  </module>
+</project>

+ 61 - 0
Dev/PLCLogger/Form1.Designer.cs

@@ -0,0 +1,61 @@
+namespace PLCLogger
+{
+    partial class Form1
+    {
+        /// <summary>
+        /// 필수 디자이너 변수입니다.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// 사용 중인 모든 리소스를 정리합니다.
+        /// </summary>
+        /// <param name="disposing">관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form 디자이너에서 생성한 코드
+
+        /// <summary>
+        /// 디자이너 지원에 필요한 메서드입니다. 
+        /// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
+            this.lvwPLC = new System.Windows.Forms.ListView();
+            this.SuspendLayout();
+            // 
+            // lvwPLC
+            // 
+            this.lvwPLC.HideSelection = false;
+            this.lvwPLC.Location = new System.Drawing.Point(12, 12);
+            this.lvwPLC.Name = "lvwPLC";
+            this.lvwPLC.Size = new System.Drawing.Size(407, 108);
+            this.lvwPLC.TabIndex = 15;
+            this.lvwPLC.UseCompatibleStateImageBehavior = false;
+            // 
+            // Form1
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(431, 131);
+            this.Controls.Add(this.lvwPLC);
+            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+            this.Name = "Form1";
+            this.Text = "Form1";
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+        private System.Windows.Forms.ListView lvwPLC;
+    }
+}
+

+ 216 - 0
Dev/PLCLogger/Form1.cs

@@ -0,0 +1,216 @@
+using GSG.NET.Excel;
+using GSG.NET.LINQ;
+using GSG.NET.Logging;
+using GSG.NET.PLC;
+using GSG.NET.PLC.Model;
+using GSG.NET.PLC.SLMP;
+using NPOI.SS.Formula.Functions;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace PLCLogger
+{
+    public partial class Form1 : Form
+    {
+        static Logger logger = Logger.GetLogger();
+
+        public string PLCAddress { get; }
+        public int PLCPort { get; }
+
+        IList<TargetPLC> targetPLCs;
+        MultiFpc plc = new MultiFpc();
+
+        public Form1()
+        {
+            InitializeComponent();
+
+            this.Load += Form1_Load;
+            this.FormClosing += Form1_FormClosing;
+        }
+
+        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
+        {
+            this.plc.Disconnect();
+        }
+
+        private void Form1_Load(object sender, EventArgs e)
+        {
+            InitPLC();
+
+            this.lvwPLC.Columns.Add("Name", 50);
+            this.lvwPLC.Columns.Add("Address", 100);
+            this.lvwPLC.Columns.Add("PortNo", 50);
+            this.lvwPLC.Columns.Add("Dec", 100);
+            this.lvwPLC.Columns.Add("State", 100);
+
+            this.lvwPLC.Items.Clear();
+
+            this.lvwPLC.View = View.Details;
+            this.lvwPLC.HideSelection = false;
+
+            this.targetPLCs.ToList().ForEach(p =>
+           {
+               ListViewItem item = new ListViewItem();
+               item.Text = p.Name;
+               item.SubItems.Add(p.Addr);
+               item.SubItems.Add(p.PortNo.ToString());
+               item.SubItems.Add(p.Dec);
+               item.SubItems.Add("UNKOWN");
+               item.EnsureVisible();
+
+               this.lvwPLC.Items.Add(item);
+           });
+        }
+
+        void InitPLC()
+        {
+            this.targetPLCs = new ExcelMapper(Path.Combine(System.Environment.CurrentDirectory) + @"\Config\PLC_Config.xlsx").Fetch<TargetPLC>().ToList();
+
+            //Add Logger
+            this.targetPLCs.FwEach(x =>
+           {
+               LogUtils.AddAppender(x.Name, new FileAppender { File = $@"C:\LOG\PLCLogger\{x.Name}\PLC.log", });
+
+               var grpL = new SlmpGroup { Name = "L1", Device = SlmpDevice.L };
+               var grpD = new SlmpGroup { Name = "D1", Device = SlmpDevice.D };
+
+               MakeBitMap(x.Name, grpL, x.Name);
+               MakeWordMap(x.Name, grpD, x.Name);
+
+               var miz = new SlmpManager();
+               miz.Config.Id = x.Name;
+               miz.Config.IpAddress = x.Addr;
+               miz.Config.Port = x.PortNo;
+               miz.Config.RollingCount = 1;
+
+               miz.AddGroup(grpL);
+               miz.AddGroup(grpD);
+
+               this.plc.Add(miz);
+           });
+
+            this.plc.OnConnect += Plc_OnConnect;
+            this.plc.OnDisconnect += Plc_OnDisconnect;
+            this.plc.OnBitChanged += Plc_OnBitChanged;
+            this.plc.OnWordChanged += Plc_OnWordChanged;
+            this.plc.OnCollected += Plc_OnCollected;
+
+            this.plc.Connect();
+        }
+
+        private void Plc_OnCollected(GSG.NET.PLC.Support.MapScan scan)
+        {
+            //foreach (ListViewItem row in this.lvwPLC.Items)
+            //{
+            //    row.SubItems[3].Text = scan.CollectTime.ToString();
+            //}
+        }
+
+        bool MakeBitMap(string unitName, SlmpGroup grpB, string sheet)
+        {
+            var ll = new ExcelMapper(Path.Combine(System.Environment.CurrentDirectory) + @"\Config\PLC_Config.xlsx").Fetch<XlsB>($"{sheet}_L");
+            if (ll == null || !(ll.Count() > 0))
+                return false;
+
+            ll = ll.Where(x => !string.IsNullOrEmpty(x.TagName)).ToList();
+
+            foreach (var item in ll)
+            {
+                grpB.AddBitBlock(new SlmpBitBlock
+                {
+                    Name = unitName + item.TagName,
+                    Address = item.Addr,
+                    KindE = item.Kind,
+                    SubText = item.SubText,
+                    SubNo = item.SubNo,
+                    CallbackOrder = item.CallbackOrder,
+                    Comment = item.Comment,
+                });
+            }
+
+            return true;
+        }
+
+        bool MakeWordMap(string unitName, SlmpGroup grpW, string sheet)
+        {
+            var ll = new ExcelMapper(Path.Combine(System.Environment.CurrentDirectory) + @"\Config\PLC_Config.xlsx").Fetch<XlsW>($"{sheet}_D");
+            if (ll == null || !ll.Any())
+                return false;
+
+            ll = ll.Where(x => !string.IsNullOrEmpty(x.TagName)).ToList();
+
+            foreach (var item in ll)
+            {
+                grpW.AddWordBlock(new SlmpWordBlock
+                {
+                    Name = unitName + item.TagName,
+                    Address = item.Addr,
+                    SubText = item.SubText,
+                    SubNo = item.SubNo,
+                    Point = item.Point,
+                    Format = item.Format,
+                    Multiple = item.MultipleV,
+                    MultipleFormatter = item.MultipleFormat,
+                    IsWatch = item.Watch,
+                    KindE = item.Kind,
+                    CallbackOrder = item.CallbackOrder,
+                    Comment = item.Comment,
+                });
+            }
+
+            return true;
+        }
+
+        #region Event
+
+        private void Plc_OnDisconnect(string id)
+        {
+            Logger.GetLogger(id).I("Disconnected");
+
+            foreach (ListViewItem row in this.lvwPLC.Items)
+            {
+                if (row.Text.Equals(id))
+                {
+                    row.BackColor = Color.Red;
+                    row.SubItems[4].Text = "Discontected";
+                }
+            }
+        }
+
+        private void Plc_OnConnect(string id)
+        {
+            Logger.GetLogger(id).I("Connected");
+
+            foreach (ListViewItem row in this.lvwPLC.Items)
+            {
+                if (row.Text.Equals(id))
+                {
+                    row.BackColor = Color.Green;
+                    row.SubItems[4].Text = "Connected";
+                }
+            }
+        }
+
+        private void Plc_OnWordChanged(GSG.NET.PLC.Model.WordBlock block)
+        {
+            Logger.GetLogger(block.ConfigID).I("WordChd {0} {1}", block.ConfigID, block);
+        }
+
+        private void Plc_OnBitChanged(GSG.NET.PLC.Model.BitBlock block)
+        {
+            Logger.GetLogger(block.ConfigID).I("BitChd {0} {1}", block.ConfigID, block);
+        }
+
+        private void Plc_OnLog(string log)
+        {
+            logger.I(log);
+        }
+
+        #endregion   
+    }
+}

Разница между файлами не показана из-за своего большого размера
+ 1253 - 0
Dev/PLCLogger/Form1.resx


BIN
Dev/PLCLogger/IO2.ico


+ 122 - 0
Dev/PLCLogger/PLCLogger.csproj

@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{7B0C015D-5451-4AB6-9076-A2FFC526297D}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <RootNamespace>PLCLogger</RootNamespace>
+    <AssemblyName>PLCLogger</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <Deterministic>true</Deterministic>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <ApplicationIcon>IO2.ico</ApplicationIcon>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Common.Logging, Version=1.2.0.0, Culture=neutral, PublicKeyToken=af08829b84f0328e">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\Assambly\Common.Logging.dll</HintPath>
+    </Reference>
+    <Reference Include="GSG.NET, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\Assambly\GSG.NET.dll</HintPath>
+    </Reference>
+    <Reference Include="GSG.NET.Excel, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\Assambly\GSG.NET.Excel.dll</HintPath>
+    </Reference>
+    <Reference Include="GSG.NET.PLC, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\Assambly\GSG.NET.PLC.dll</HintPath>
+    </Reference>
+    <Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\Assambly\log4net.dll</HintPath>
+    </Reference>
+    <Reference Include="NPOI, Version=2.4.1.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\Assambly\NPOI.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Configuration" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Deployment" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Form1.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Form1.Designer.cs">
+      <DependentUpon>Form1.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="TargetPLC.cs" />
+    <EmbeddedResource Include="Form1.resx">
+      <DependentUpon>Form1.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <None Include="Config\PLC_Config.xlsx">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Config\log4net.xml">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="IO2.ico" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>

+ 28 - 0
Dev/PLCLogger/PLCLogger.sln

@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30413.136
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PLCLogger", "PLCLogger.csproj", "{7B0C015D-5451-4AB6-9076-A2FFC526297D}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+		Remote|Any CPU = Remote|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{7B0C015D-5451-4AB6-9076-A2FFC526297D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{7B0C015D-5451-4AB6-9076-A2FFC526297D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7B0C015D-5451-4AB6-9076-A2FFC526297D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{7B0C015D-5451-4AB6-9076-A2FFC526297D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{7B0C015D-5451-4AB6-9076-A2FFC526297D}.Remote|Any CPU.ActiveCfg = Release|Any CPU
+		{7B0C015D-5451-4AB6-9076-A2FFC526297D}.Remote|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {80678119-791D-42C2-99C3-447ADB0E1B12}
+	EndGlobalSection
+EndGlobal

+ 48 - 0
Dev/PLCLogger/Program.cs

@@ -0,0 +1,48 @@
+using GSG.NET.Logging;
+using GSG.NET.Utils;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace PLCLogger
+{
+    static class Program
+    {
+        static Logger logger = Logger.GetLogger();
+
+        /// <summary>
+        /// 해당 애플리케이션의 주 진입점입니다.
+        /// </summary>
+        [STAThread]
+        static void Main()
+        {
+            if (!ProcessUtils.IsOnlyOneInstance)
+            {
+                MessageBox.Show("{PLC Logger is running duplicate");
+                return;
+            }
+
+            LogUtils.Configure("Config/log4net.xml", true);
+
+            AppUtils.LogGlobalException();
+
+            logger.I("{0} PLC Logger Started {0}", string.Empty.PadRight(40, '+'));
+
+            try
+            {
+                Application.EnableVisualStyles();
+                Application.SetCompatibleTextRenderingDefault(false);
+                Application.Run(new Form1());
+
+            }
+            catch (Exception e)
+            {
+                logger.E(e);
+            }
+            logger.I("{0} PLC Logger Stopped {0}", string.Empty.PadRight(40, '-'));
+        }
+    }
+}
+

+ 36 - 0
Dev/PLCLogger/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해 
+// 제어됩니다. 어셈블리와 관련된 정보를 수정하려면
+// 이러한 특성 값을 변경하세요.
+[assembly: AssemblyTitle("PLCLogger")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("PLCLogger")]
+[assembly: AssemblyCopyright("Copyright ©  2020")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에 
+// 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면
+// 해당 형식에 대해 ComVisible 특성을 true로 설정하세요.
+[assembly: ComVisible(false)]
+
+// 이 프로젝트가 COM에 노출되는 경우 다음 GUID는 typelib의 ID를 나타냅니다.
+[assembly: Guid("7b0c015d-5451-4ab6-9076-a2ffc526297d")]
+
+// 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다.
+//
+//      주 버전
+//      부 버전 
+//      빌드 번호
+//      수정 버전
+//
+// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를
+// 기본값으로 할 수 있습니다.
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 71 - 0
Dev/PLCLogger/Properties/Resources.Designer.cs

@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     이 코드는 도구를 사용하여 생성되었습니다.
+//     런타임 버전:4.0.30319.42000
+//
+//     파일 내용을 변경하면 잘못된 동작이 발생할 수 있으며, 코드를 다시 생성하면
+//     이러한 변경 내용이 손실됩니다.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace PLCLogger.Properties
+{
+
+
+    /// <summary>
+    ///   지역화된 문자열 등을 찾기 위한 강력한 형식의 리소스 클래스입니다.
+    /// </summary>
+    // 이 클래스는 ResGen 또는 Visual Studio와 같은 도구를 통해 StronglyTypedResourceBuilder
+    // 클래스에서 자동으로 생성되었습니다.
+    // 멤버를 추가하거나 제거하려면 .ResX 파일을 편집한 다음 /str 옵션을 사용하여
+    // ResGen을 다시 실행하거나 VS 프로젝트를 다시 빌드하십시오.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources
+    {
+
+        private static global::System.Resources.ResourceManager resourceMan;
+
+        private static global::System.Globalization.CultureInfo resourceCulture;
+
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources()
+        {
+        }
+
+        /// <summary>
+        ///   이 클래스에서 사용하는 캐시된 ResourceManager 인스턴스를 반환합니다.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager
+        {
+            get
+            {
+                if ((resourceMan == null))
+                {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PLCLogger.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+
+        /// <summary>
+        ///   이 강력한 형식의 리소스 클래스를 사용하여 모든 리소스 조회에 대해 현재 스레드의 CurrentUICulture 속성을
+        ///   재정의합니다.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture
+        {
+            get
+            {
+                return resourceCulture;
+            }
+            set
+            {
+                resourceCulture = value;
+            }
+        }
+    }
+}

+ 117 - 0
Dev/PLCLogger/Properties/Resources.resx

@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 30 - 0
Dev/PLCLogger/Properties/Settings.Designer.cs

@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace PLCLogger.Properties
+{
+
+
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+    {
+
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+        public static Settings Default
+        {
+            get
+            {
+                return defaultInstance;
+            }
+        }
+    }
+}

+ 7 - 0
Dev/PLCLogger/Properties/Settings.settings

@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>

+ 53 - 0
Dev/PLCLogger/TargetPLC.cs

@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.AccessControl;
+using System.Text;
+using System.Threading.Tasks;
+using GSG.NET;
+
+namespace PLCLogger
+{
+    public class TargetPLC
+    {
+        public string Name { get; set; }
+        public string Addr { get; set; }
+        public int PortNo { get; set; }
+        public string Dec { get; set; }
+    }
+
+    public enum PlcKind
+    {
+        NONE,
+        PLC,
+        HOST
+    }
+
+    internal class XlsB : Poco
+    {
+        public int Addr { get; set; }
+        public string TagName { get; set; }
+        public string SubText { get; set; }
+        public int SubNo { get; set; }
+        public int CallbackOrder { get; set; }
+        public PlcKind Kind { get; set; }
+        public string Comment { get; set; }
+    }
+
+    internal class XlsW : Poco
+    {
+        public int Addr { get; set; }
+        public string TagName { get; set; }
+        public int Point { get; set; }
+        public string SubText { get; set; }
+        public string Format { get; set; }
+        public int MultipleV { get; set; }
+        public string MultipleFormat { get; set; }
+        public bool Watch { get; set; }
+        public int SubNo { get; set; }
+        public int CallbackOrder { get; set; }
+        public PlcKind Kind { get; set; }
+        public string Comment { get; set; }
+    }
+
+}