using System; using System.Threading; using GSG.NET.Concurrent; using GSG.NET.Logging; using OHV.Common.Shareds; using VehicleControlSystem.ControlLayer.IO; using Prism.Events; using OHV.SqliteDAL; using OHV.Common.Model; using OHV.Common.Events; using VehicleControlSystem.ControlLayer; namespace VehicleControlSystem.Managers { /// /// Vehicle 전체 상태를 관리. /// public class AutoManager : IDisposable { static Logger logger = Logger.GetLogger(); Thread threadWorker = null; bool isThreadAlive = false; IIO iO = null; bool IsErrorProcessing = false; IEventAggregator eventAggregator = null; SqliteManager sql = null; private eOperatationMode operationMode; public eOperatationMode OperationModeProperty { get { return operationMode; } set { if (operationMode == value) return; operationMode = value; logger.D($"[AutoManager] OperationMode - {value}"); } } private eAutoModeState autoModeState; public eAutoModeState AutoModeStateProperty { get { return autoModeState; } set { if (autoModeState == value) return; autoModeState = value; logger.D($"[AutoManager] AutoModeState - {value}"); } } private eLampState lampState; public eLampState LampStateProperty { get { return lampState; } set { if (lampState == value) return; lampState = value; this.LampStateChange(value); } } private eBuzzerKind buzzerState; public eBuzzerKind BuzzerStateProperty { get { return buzzerState; } set { buzzerState = value; } } public AutoManager(IIO io, IEventAggregator ea, SqliteManager sql) { this.iO = io; this.eventAggregator = ea; this.sql = sql; } #region Vehicle Events private void Vehicle_OnChargingFull() { LampStateChange(eLampState.AutoRunNChargingFull); } private void Vehicle_OnCharging() { LampStateChange(eLampState.Charging); } private void Vehicle_OnMoveFinish() { BuzzerOnOff(false); logger.D("Vehicle Move Finish"); } private void Vehicle_OnMoving() { BuzzerOnOff(true, eBuzzerKind.Moving); logger.D("Vehicle Moving"); } private void Vehicle_OnMoveReady() { BuzzerOnOff(true, eBuzzerKind.StartWarn); logger.D("Vehicle Move Ready"); } #endregion public void Init(Vehicle vehicle) { this.OperationModeProperty = eOperatationMode.ManualMode; this.AutoModeStateProperty = eAutoModeState.Stop; this.isThreadAlive = true; this.threadWorker = ThreadUtils.Invoke(this.ThreadWork); vehicle.OnMoveReady += Vehicle_OnMoveReady; vehicle.OnMoving += Vehicle_OnMoving; vehicle.OnMoveFinish += Vehicle_OnMoveFinish; vehicle.OnCharging += Vehicle_OnCharging; vehicle.OnChargingFull += Vehicle_OnChargingFull; } #region Lamp & Buzzer void LampStateChange(eLampState state) { this.iO.OutputOff("OUT_TOWER_LAMP_RED"); this.iO.OutputOff("OUT_TOWER_LAMP_GREEN"); this.iO.OutputOff("OUT_TOWER_LAMP_BLUE"); switch (state) { case eLampState.Alarm: this.iO.OutputOff("OUT_TOWER_LAMP_RED"); break; case eLampState.Charging: this.iO.OutputOff("OUT_TOWER_LAMP_GREEN"); break; case eLampState.AutoRunNChargingFull: this.iO.OutputOff("OUT_TOWER_LAMP_BLUE"); break; default: break; } } 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"); if (!isOn) return; switch (kind) { case eBuzzerKind.Alarm: this.iO.OutputOn("OUT_BUZZER_00"); break; case eBuzzerKind.StartWarn: this.iO.OutputOn("OUT_BUZZER_01"); break; case eBuzzerKind.Moving: this.iO.OutputOn("OUT_BUZZER_02"); break; default: break; } } #endregion void ThreadWork() { while (this.isThreadAlive) { try { Thread.Sleep(5); DoWork(); } catch (Exception ex) { logger.E($"{GetType().Name} - Thread Exception : {ex.StackTrace}"); } } } public void DoWork() { switch (this.OperationModeProperty) { case eOperatationMode.ManualMode: break; case eOperatationMode.AutoMode: switch (this.AutoModeStateProperty) { case eAutoModeState.ErrorStop: if ( !IsErrorProcessing ) this.AutoModeStateProperty = eAutoModeState.WaitStop; break; case eAutoModeState.WaitStop: this.AutoModeStateProperty = eAutoModeState.Stop; break; case eAutoModeState.Stop: this.OperationModeProperty = eOperatationMode.ManualMode; break; case eAutoModeState.StartRun: this.AutoModeStateProperty = eAutoModeState.Run; this.LampStateProperty = eLampState.AutoRunNChargingFull; break; case eAutoModeState.Run: break; default: break; } break; case eOperatationMode.InitialMode: break; default: break; } } public void ProcessAlarm(int alarmID) { this.AutoModeStateProperty = eAutoModeState.ErrorStop; this.LampStateProperty = eLampState.Alarm; HisAlarm hisAlarm = new HisAlarm(); var alarm = sql.AlarmDAL.GetK(alarmID); if (alarm == null) { hisAlarm.AlarmId = alarmID; hisAlarm.Text = "Not Define Alarm"; } else { hisAlarm.AlarmId = alarmID; hisAlarm.Text = alarm.Text; hisAlarm.Solution = alarm.Solution; //hisAlarm.Alarm = alarm; } sql.HisAlarmDAL.Add(hisAlarm); if (IsErrorProcessing) return; var msg = new GUIMessageEventArgs { Kind = GUIMessageEventArgs.eGUIMessageKind.ModelPropertyChange, MessageKey = MessageKey.Alarm, MessageText = hisAlarm.Text, Args = hisAlarm, }; this.eventAggregator.GetEvent().Publish(msg); } #region IDisposable Support private bool disposedValue = false; // 중복 호출을 검색하려면 protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { // TODO: 관리되는 상태(관리되는 개체)를 삭제합니다. this.isThreadAlive = false; if (!this.threadWorker.Join(3000)) ThreadUtils.Kill(this.threadWorker); } // TODO: 관리되지 않는 리소스(관리되지 않는 개체)를 해제하고 아래의 종료자를 재정의합니다. // TODO: 큰 필드를 null로 설정합니다. disposedValue = true; } } // TODO: 위의 Dispose(bool disposing)에 관리되지 않는 리소스를 해제하는 코드가 포함되어 있는 경우에만 종료자를 재정의합니다. // ~AutoManager() // { // // 이 코드를 변경하지 마세요. 위의 Dispose(bool disposing)에 정리 코드를 입력하세요. // Dispose(false); // } // 삭제 가능한 패턴을 올바르게 구현하기 위해 추가된 코드입니다. public void Dispose() { // 이 코드를 변경하지 마세요. 위의 Dispose(bool disposing)에 정리 코드를 입력하세요. Dispose(true); // TODO: 위의 종료자가 재정의된 경우 다음 코드 줄의 주석 처리를 제거합니다. // GC.SuppressFinalize(this); } #endregion } }