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
}
}