using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using GSG.NET.Excel; using GSG.NET.Extensions; using GSG.NET.Logging; using GSG.NET.Quartz; using OHV.Common.Events; using OHV.Common.Model; using OHV.Common.Shareds; using OHV.SqliteDAL; using Prism.Events; using Prism.Ioc; using Prism.Modularity; using VehicleControlSystem.ControlLayer; using VehicleControlSystem.ControlLayer.Drive; using VehicleControlSystem.ControlLayer.IO; using VehicleControlSystem.ControlLayer.MQ; using VehicleControlSystem.ControlLayer.Serial.BatteryTabos; using VehicleControlSystem.Managers; namespace VehicleControlSystem { [Module( ModuleName = "VCSystem" )] public class VCSystem : IModule, IDisposable { Logger logger = Logger.GetLogger(); Scheduler scheduler = null; public AutoManager autoManager = null; HostManager hostManager = null; SqliteManager sql = null; IEventAggregator eventAggregator = null; public IIO IO = null; ZmqManager zmqManager = null; BMUManager bMUManager = null; Conveyor conveyor = null; Steering steering = null; GSIDrive drive = null; Clamp clamp = null; Vehicle vehicle = null; public RouteManager RouteManager { get; set; } public List Alarms { get; set; } public VCSystem( IEventAggregator ea, SqliteManager sql ) { this.sql = sql; this.eventAggregator = ea; this.eventAggregator.GetEvent().Subscribe( ( o ) => Dispose(), true ); this.eventAggregator.GetEvent().Unsubscribe( ReceivedMessageEvent ); this.eventAggregator.GetEvent().Subscribe( this.ReceivedMessageEvent, ThreadOption.BackgroundThread ); } public void Init() { QuartzUtils.Invoke( "HIS_ALARM", QuartzUtils.GetExpnHour( 5 ), this.CleanHisAlarm ); this.RouteManager = RouteManager.Instance; RouteManager.Instance.Init( this.sql ); Alarms = new ExcelMapper( Path.Combine( System.Environment.CurrentDirectory ) + @"\Config\AlarmDefind.xlsx" ).Fetch().ToList(); //Create IO this.IO = new EzIO(); var mapPath = Path.Combine( System.Environment.CurrentDirectory ) + @"\Config\IO.xlsx"; this.IO.LoadIOMap( mapPath ); this.IO.RunIOThread(); var ezIO = this.IO as EzIO; ezIO.OnContd += EzIO_OnContd; ezIO.OnDiscontd += EzIO_OnDiscontd; ezIO.OnChangedIO += EzIO_OnChangedIO; ezIO.OnFirstColtd += EzIO_OnFirstColtd; //Battery this.bMUManager = new BMUManager(); this.bMUManager.BMUConfig = new ControlLayer.Serial.BatteryTabos.Config() { ID = "0" }; var setV = Convert.ToInt32( sql.ConfigDal.GetById( ConstString.BatteryCanType ).Value ); var canType = CastTo.From( setV ); this.bMUManager.Connect( canType ); //Conveyor this.conveyor = new Conveyor( this.IO as EzIO ); //Clamp this.clamp = new Clamp( this.sql, this.eventAggregator ); this.clamp.Init(); //Steering this.steering = new Steering( this.IO, this.sql, this.eventAggregator ); //ZeroMQ this.zmqManager = new ZmqManager( this.bMUManager, this.steering ); this.zmqManager.Init(); //Drive this.drive = new GSIDrive( this.sql, this.steering, this.zmqManager ); this.drive.Init(); var refObject = new VehicleRefObjects(); refObject.IO = this.IO as EzIO; refObject.BMUManager = this.bMUManager; refObject.Drive = this.drive; refObject.Conveyor = this.conveyor; refObject.Clamp = this.clamp; refObject.Steering = this.steering; refObject.ZmqManager = this.zmqManager; //Process this.autoManager = new AutoManager( this.IO, this.eventAggregator, this.sql, this.Alarms ); this.scheduler = new Scheduler( eventAggregator, this.autoManager, this.sql ); this.vehicle = new Vehicle( refObject, this.IO, this.sql, this.eventAggregator, this.autoManager ); this.vehicle.PropertyChanged += Vehicle_PropertyChanged; this.hostManager = new HostManager( this.eventAggregator, this.vehicle, this.sql, this.autoManager, this.scheduler ); this.hostManager.Init(); this.vehicle.Init(); this.scheduler.Init(); this.autoManager.Init( this.vehicle ); } private void Vehicle_PropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs e ) { var arg = new GUIMessageEventArgs(); arg.Kind = GUIMessageEventArgs.eGUIMessageKind.ModelPropertyChange; arg.MessageKey = MessageKey.Vehicle; arg.ModelPropertyName = e.PropertyName; var property = sender.GetType().GetProperty( e.PropertyName ); var newValue = property.GetValue( sender, null ); arg.ModelPropertyName = e.PropertyName; arg.Args = newValue; GUIMessageEventPublish( arg ); } public void CleanHisAlarm() { var backup = DateTime.Now.AddDays( -15 ); sql.HisAlarmDAL.Delete( x=>x.OccurTime < backup ); } #region EzIO Event private void EzIO_OnChangedIO( BitBlock bit ) { this.eventAggregator.GetEvent().Publish( new IOChangedMessageEventArgs { Args = bit } ); } private void EzIO_OnDiscontd( string ID ) { //throw new NotImplementedException(); } private void EzIO_OnContd( string ID ) { //IO 연결 시 할일 들을 여기서 하자. this.IO.OutputOn( "OUT_TEACH_MODE" ); this.autoManager.LampStateProperty = eLampState.Alarm; //throw new NotImplementedException(); } private void EzIO_OnFirstColtd( string ID ) { if ( this.IO.IsOff( "IN_MC_ON" ) ) { this.vehicle.OccurVehicleAlarm( 29 ); } this.steering.ControlSteering( true );//초기에 직선 주행 상태로 핸들 조정. } #endregion #region ReqMessage Method void ReceivedMessageEvent( VCSMessageEventArgs msg ) { switch ( msg.Kind ) { case VCSMessageEventArgs.eVCSMessageKind.ReqIOObject: ReqIOObjectMessage(); break; case VCSMessageEventArgs.eVCSMessageKind.ReqIOMapList: break; case VCSMessageEventArgs.eVCSMessageKind.ReqCommandList: break; case VCSMessageEventArgs.eVCSMessageKind.ReqAutoModeChange: break; case VCSMessageEventArgs.eVCSMessageKind.ReqManualModeChange: break; case VCSMessageEventArgs.eVCSMessageKind.ModelPropertyChange: break; case VCSMessageEventArgs.eVCSMessageKind.ReqAlarmReset: ReqAlarmReset(); break; case VCSMessageEventArgs.eVCSMessageKind.ReqVehicleModeChange: this.ReqVehicleModeChange( msg ); break; case VCSMessageEventArgs.eVCSMessageKind.ReqEStop: ReqEStop(); break; case VCSMessageEventArgs.eVCSMessageKind.ReqBuzzerStop: ReqBuzzerStop(); break; case VCSMessageEventArgs.eVCSMessageKind.ReqMachineModeChg: ReqMachineModeChg( msg ); break; case VCSMessageEventArgs.eVCSMessageKind.ReqAddCommand: break; case VCSMessageEventArgs.eVCSMessageKind.ReqTest: ReqTest(); break; case VCSMessageEventArgs.eVCSMessageKind.ReqConveyorMove: ReqConveyorMove( msg ); break; case VCSMessageEventArgs.eVCSMessageKind.ReqConveyorLoad: ReqConveyorLoad( msg ); break; case VCSMessageEventArgs.eVCSMessageKind.ReqConveyorUnload: ReqConveyorUnload(); break; case VCSMessageEventArgs.eVCSMessageKind.ReqObstaclePatternChg: ReqObsticlePatternChange( msg ); break; case VCSMessageEventArgs.eVCSMessageKind.ReqObstaclePatternNo: ReqObsticlePatternNo(); break; case VCSMessageEventArgs.eVCSMessageKind.ReqPIOConveyor: this.ReqPIOConveyor( msg ); break; case VCSMessageEventArgs.eVCSMessageKind.ReqPIOBatteryCharge: this.ReqPIOBattery( msg ); break; case VCSMessageEventArgs.eVCSMessageKind.ReqBatteryState: this.ReqBatteryState(); break; case VCSMessageEventArgs.eVCSMessageKind.ReqPIOBatteryChargeStop: this.ReqBatteryChargeStop( msg ); break; default: break; } } void ReqBatteryState() { BatteryInfo battery = new BatteryInfo(); battery.Voltage = vehicle.BatteryVoltage; battery.Current = vehicle.BatteryCurrent; battery.ChargeTime = vehicle.BatteryChargeTime; battery.DisChargeTime = vehicle.BatteryDisChargeTime; battery.Capacity = vehicle.BatteryCapacity; battery.Energy = vehicle.BatteryEnergy; battery.SOC = vehicle.BatteryStateOfCharge; battery.SOH = vehicle.BatteryStateOfHealth; battery.State = vehicle.BatteryState; battery.IsConnect = vehicle.BatteryIsConnect; battery.Temperature = vehicle.BatteryTemperature; var reply = new GUIMessageEventArgs() { Args = battery, Kind = GUIMessageEventArgs.eGUIMessageKind.RspBatteryState }; GUIMessageEventPublish( reply ); } private void ReqConveyorMove( VCSMessageEventArgs msg ) { var result = 0; this.vehicle.ReqConveyorMove( msg.MessageText ); } private void ReqObsticlePatternNo() { var reply = new GUIMessageEventArgs(); reply.Kind = GUIMessageEventArgs.eGUIMessageKind.RspObstaclePatternNo; reply.MessageText = this.vehicle.GetObstacleDetectPattern().ToString(); GUIMessageEventPublish( reply ); } private void ReqObsticlePatternChange( VCSMessageEventArgs msg ) { var patternNo = Convert.ToInt32( msg.MessageText ); this.vehicle.ChgObstacleDetectPattern( patternNo ); var reply = new GUIMessageEventArgs(); reply.Kind = GUIMessageEventArgs.eGUIMessageKind.RspObstaclePatternChg; reply.Result = FluentResults.Results.Ok(); GUIMessageEventPublish( reply ); } private void ReqConveyorUnload() { int result = 0; result = this.vehicle.ConveyorUnload(); } private void ReqConveyorLoad( VCSMessageEventArgs msg ) { int result = 0; result = this.vehicle.ConveyorLoad(); } private void ReqPIOConveyor( VCSMessageEventArgs msg ) { int result = 0; var reply = new GUIMessageEventArgs() { Kind = GUIMessageEventArgs.eGUIMessageKind.RspPIOConveyor, MessageText = msg.MessageText, }; /*PIO Load// Unload*/ if ( msg.MessageText.Equals( "PL" ) ) result = this.vehicle.PIOAndLoad( "" ); else result = this.vehicle.PIOAndUnload( "" ); //실행 결과 확인 if ( result <= 0 ) reply.Result = FluentResults.Results.Ok(); else reply.Result = FluentResults.Results.Fail( "PIO Fail" ); GUIMessageEventPublish( reply ); } private void ReqPIOBattery( VCSMessageEventArgs msg ) { int result = 1; var reply = new GUIMessageEventArgs() { Kind = GUIMessageEventArgs.eGUIMessageKind.RspPIOBatteryCharge, MessageText = msg.MessageText, }; result = this.vehicle.StartBatteryCharge(); if ( result <= 0 ) reply.Result = FluentResults.Results.Ok(); else reply.Result = FluentResults.Results.Fail( "Battery Charge Start Fail" ); GUIMessageEventPublish( reply ); } private void ReqBatteryChargeStop( VCSMessageEventArgs msg ) { int result = 1; var reply = new GUIMessageEventArgs() { Kind = GUIMessageEventArgs.eGUIMessageKind.RsqPIOBatteryChargeStop, MessageText = msg.MessageText, }; result = this.vehicle.StopBatteryCharge(); if ( result <= 0 ) reply.Result = FluentResults.Results.Ok(); else reply.Result = FluentResults.Results.Fail( "Battery Charge Stop Fail" ); GUIMessageEventPublish( reply ); } 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" ); } private void ReqMachineModeChg( VCSMessageEventArgs msg ) { var reply = new GUIMessageEventArgs(); reply.Kind = GUIMessageEventArgs.eGUIMessageKind.RspMachineModeChg; var mode = CastTo.From( msg.Arg ); if ( mode == eMachineMode.HostMode ) { if ( this.autoManager.OperationModeProperty != eOperatationMode.AutoMode ) reply.Result = FluentResults.Results.Fail( "Vehicle Not Start" ); else { this.vehicle.MachineMode = eMachineMode.HostMode; reply.Result = FluentResults.Results.Ok(); reply.Args = eMachineMode.HostMode; } } else { this.vehicle.MachineMode = eMachineMode.LocalMode; reply.Result = FluentResults.Results.Ok( eMachineMode.LocalMode ); reply.Args = eMachineMode.LocalMode; } GUIMessageEventPublish( reply ); } private void ReqBuzzerStop() { this.IO.OutputOff( "OUT_BUZZER_00" ); this.IO.OutputOff( "OUT_BUZZER_01" ); this.IO.OutputOff( "OUT_BUZZER_02" ); } private void ReqAlarmReset() { //this.autoManager.IsErrorProcessing = false; //this.vehicle.VehicleStateProperty = eVehicleState.Idle; if ( !this.IO.IsOn( "IN_MC_ON" ) ) { this.IO.WriteOutputIO( "OUT_SAFETY_RESET", true ); Thread.Sleep( 2000 ); this.IO.WriteOutputIO( "OUT_SAFETY_RESET", false ); Thread.Sleep( 1000 ); } this.autoManager.IsErrorProcessing = false; this.vehicle.VehicleStateProperty = eVehicleState.Idle; } private void ReqEStop() { this.scheduler.IsCreateDryRunCommand = !this.scheduler.IsCreateDryRunCommand; //this.vehicle.EStop(); } private void ReqVehicleModeChange( VCSMessageEventArgs msg ) { GUIMessageEventArgs reply; if ( msg.MessageKey.Equals( MessageKey.AutoMode ) ) { int result = vehicle.InitializationVehicle(); if ( result != 0 ) { this.autoManager.ProcessAlarm( result ); return; } this.autoManager.AutoModeStateProperty = eAutoModeState.StartRun; this.autoManager.OperationModeProperty = eOperatationMode.AutoMode; reply = new GUIMessageEventArgs { Kind = GUIMessageEventArgs.eGUIMessageKind.RspVehicleModeChange, Result = FluentResults.Results.Ok(), MessageKey = MessageKey.AutoMode }; } else { this.autoManager.AutoModeStateProperty = OHV.Common.Shareds.eAutoModeState.WaitStop; reply = new GUIMessageEventArgs { Kind = GUIMessageEventArgs.eGUIMessageKind.RspVehicleModeChange, Result = FluentResults.Results.Ok(), MessageKey = MessageKey.ManualMode }; } GUIMessageEventPublish( reply ); } void ReqIOObjectMessage() { var rspMsg = new GUIMessageEventArgs { Kind = GUIMessageEventArgs.eGUIMessageKind.RspIOObject, Args = this.IO }; this.eventAggregator.GetEvent().Publish( rspMsg ); } #endregion /// /// GUI 로 보내는 Event /// /// public void GUIMessageEventPublish( GUIMessageEventArgs args ) { this.eventAggregator.GetEvent().Publish( args ); } public void Dispose() { this.scheduler.Dispose(); this.hostManager.Dispose(); this.vehicle.Dispose(); this.autoManager.Dispose(); this.bMUManager.Disconnect(); this.drive.Dispose(); this.zmqManager.Dispose(); ( this.IO as IDisposable ).Dispose(); //IO 는 마지막에 정리함. } public void RegisterTypes( IContainerRegistry containerRegistry ) { if ( !containerRegistry.IsRegistered() ) containerRegistry.RegisterSingleton(); } public void OnInitialized( IContainerProvider containerProvider ) { this.Init(); } } }