AutoManager.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. using System;
  2. using System.Threading;
  3. using GSG.NET.Concurrent;
  4. using GSG.NET.Logging;
  5. using OHV.Common.Shareds;
  6. using VehicleControlSystem.ControlLayer.IO;
  7. using Prism.Events;
  8. using OHV.SqliteDAL;
  9. using OHV.Common.Model;
  10. using OHV.Common.Events;
  11. using VehicleControlSystem.ControlLayer;
  12. using GSG.NET.Utils;
  13. using System.Collections.Generic;
  14. using System.Linq;
  15. namespace VehicleControlSystem.Managers
  16. {
  17. /// <summary>
  18. /// Vehicle 전체 상태를 관리.
  19. /// </summary>
  20. public class AutoManager : IDisposable
  21. {
  22. static Logger logger = Logger.GetLogger();
  23. Thread threadWorker = null;
  24. bool isThreadAlive = false;
  25. IIO iO = null;
  26. private bool isErrorProcessing = false;
  27. public bool IsErrorProcessing
  28. {
  29. get { return this.isErrorProcessing; }
  30. set
  31. {
  32. if ( this.isErrorProcessing == value ) return;
  33. this.isErrorProcessing = value;
  34. if ( value )
  35. {
  36. if ( this.activeAlarm == null ) return;
  37. this.OnOccurAlarm?.BeginInvoke( this.activeAlarm.AlarmId, null, null );
  38. }
  39. else
  40. {
  41. if ( this.activeAlarm == null ) return;
  42. this.OnClearAlarm?.BeginInvoke( this.activeAlarm.AlarmId, null, null );
  43. this.activeAlarm = null;
  44. this.BuzzerOnOff( false );
  45. }
  46. }
  47. }
  48. public event Action<int> OnOccurAlarm;
  49. public event Action<int> OnClearAlarm;
  50. Alarm activeAlarm = null;
  51. List<Alarm> Alarms { get; set; }
  52. IEventAggregator eventAggregator = null;
  53. SqliteManager sql = null;
  54. private eOperatationMode operationMode;
  55. public eOperatationMode OperationModeProperty
  56. {
  57. get { return operationMode; }
  58. set
  59. {
  60. if ( operationMode == value ) return;
  61. operationMode = value;
  62. logger.D( $"[AutoManager] OperationMode - {value}" );
  63. this.OnOperationModeChanged?.Invoke( value );
  64. if ( value == eOperatationMode.AutoMode )
  65. this.iO.OutputOff( "OUT_TEACH_MODE" );
  66. else
  67. this.iO.OutputOn( "OUT_TEACH_MODE" );
  68. }
  69. }
  70. public event Action<eOperatationMode> OnOperationModeChanged;
  71. private eAutoModeState autoModeState;
  72. public eAutoModeState AutoModeStateProperty
  73. {
  74. get { return autoModeState; }
  75. set
  76. {
  77. if ( autoModeState == value ) return;
  78. autoModeState = value;
  79. logger.D( $"[AutoManager] AutoModeState - {value}" );
  80. switch ( value )
  81. {
  82. case eAutoModeState.ErrorStop:
  83. this.LampStateProperty = eLampState.Alarm;
  84. break;
  85. case eAutoModeState.StartRun:
  86. this.LampStateProperty = eLampState.AutoRunNChargingFull;
  87. break;
  88. case eAutoModeState.Run:
  89. this.LampStateProperty = eLampState.AutoRunNChargingFull;
  90. break;
  91. case eAutoModeState.Stop:
  92. this.LampStateProperty = eLampState.Alarm;
  93. break;
  94. case eAutoModeState.WaitStop:
  95. this.LampStateProperty = eLampState.Alarm;
  96. break;
  97. default:
  98. break;
  99. }
  100. }
  101. }
  102. private eLampState lampState = eLampState.None;
  103. public eLampState LampStateProperty
  104. {
  105. get { return lampState; }
  106. set
  107. {
  108. if ( lampState == value ) return;
  109. lampState = value;
  110. this.LampStateChange( value );
  111. }
  112. }
  113. private eBuzzerKind buzzerState;
  114. public eBuzzerKind BuzzerStateProperty
  115. {
  116. get { return buzzerState; }
  117. set { buzzerState = value; }
  118. }
  119. public AutoManager( IIO io, IEventAggregator ea, SqliteManager sql, List<Alarm> al )
  120. {
  121. this.iO = io;
  122. this.eventAggregator = ea;
  123. this.sql = sql;
  124. this.Alarms = al;
  125. }
  126. #region Vehicle Events
  127. private void Vehicle_OnChargingFull()
  128. {
  129. if ( this.OperationModeProperty == eOperatationMode.AutoMode )
  130. LampStateChange( eLampState.AutoRunNChargingFull );
  131. else
  132. LampStateChange( eLampState.Alarm );
  133. }
  134. private void Vehicle_OnCharging()
  135. {
  136. LampStateChange( eLampState.Charging );
  137. }
  138. private void Vehicle_OnMoveFinish()
  139. {
  140. BuzzerOnOff( false );
  141. logger.D( "Vehicle Move Finish" );
  142. }
  143. private void Vehicle_OnMoving()
  144. {
  145. BuzzerOnOff( true, eBuzzerKind.Moving );
  146. logger.D( "Vehicle Moving" );
  147. }
  148. private void Vehicle_OnMoveReady()
  149. {
  150. BuzzerOnOff( true, eBuzzerKind.StartWarn );
  151. logger.D( "Vehicle Move Ready" );
  152. }
  153. #endregion
  154. public void Init( Vehicle vehicle )
  155. {
  156. this.OperationModeProperty = eOperatationMode.ManualMode;
  157. this.AutoModeStateProperty = eAutoModeState.Stop;
  158. this.isThreadAlive = true;
  159. this.threadWorker = ThreadUtils.Invoke( this.ThreadWork );
  160. vehicle.OnMoveReady += Vehicle_OnMoveReady;
  161. vehicle.OnMoving += Vehicle_OnMoving;
  162. vehicle.OnMoveFinish += Vehicle_OnMoveFinish;
  163. vehicle.OnCharging += Vehicle_OnCharging;
  164. vehicle.OnChargingFull += Vehicle_OnChargingFull;
  165. }
  166. #region Lamp & Buzzer
  167. void LampStateChange( eLampState state )
  168. {
  169. this.iO.OutputOff( "OUT_TOWER_LAMP_RED" );
  170. this.iO.OutputOff( "OUT_TOWER_LAMP_GREEN" );
  171. switch ( state )
  172. {
  173. case eLampState.Alarm:
  174. this.iO.OutputOn( "OUT_TOWER_LAMP_RED" );
  175. break;
  176. case eLampState.Charging:
  177. this.iO.OutputOn( "OUT_TOWER_LAMP_RED" );
  178. this.iO.OutputOn( "OUT_TOWER_LAMP_GREEN" );
  179. break;
  180. case eLampState.AutoRunNChargingFull:
  181. this.iO.OutputOn( "OUT_TOWER_LAMP_GREEN" );
  182. //Blue 없음
  183. //this.iO.OutputOff("OUT_TOWER_LAMP_BLUE");
  184. break;
  185. default:
  186. break;
  187. }
  188. }
  189. void BuzzerOnOff( bool isOn, eBuzzerKind kind = eBuzzerKind.Alarm )
  190. {
  191. this.iO.OutputOff( "OUT_BUZZER_00" );
  192. this.iO.OutputOff( "OUT_BUZZER_01" );
  193. this.iO.OutputOff( "OUT_BUZZER_02" );
  194. if ( !isOn )
  195. return;
  196. switch ( kind )
  197. {
  198. case eBuzzerKind.Alarm:
  199. this.iO.OutputOn( "OUT_BUZZER_00" );
  200. break;
  201. case eBuzzerKind.StartWarn:
  202. this.iO.OutputOn( "OUT_BUZZER_01" );
  203. break;
  204. case eBuzzerKind.Moving:
  205. this.iO.OutputOn( "OUT_BUZZER_02" );
  206. break;
  207. default:
  208. break;
  209. }
  210. }
  211. #endregion
  212. void ThreadWork()
  213. {
  214. while ( this.isThreadAlive )
  215. {
  216. try
  217. {
  218. Thread.Sleep( 5 );
  219. DoWork();
  220. }
  221. catch ( Exception ex )
  222. {
  223. logger.E( $"{GetType().Name} - Thread Exception : {ex.StackTrace}" );
  224. }
  225. }
  226. logger.D( "[AutoManager] - Work Thread Dispose" );
  227. }
  228. public void DoWork()
  229. {
  230. switch ( this.OperationModeProperty )
  231. {
  232. case eOperatationMode.ManualMode:
  233. break;
  234. case eOperatationMode.AutoMode:
  235. switch ( this.AutoModeStateProperty )
  236. {
  237. case eAutoModeState.ErrorStop:
  238. this.AutoModeStateProperty = eAutoModeState.WaitStop;
  239. break;
  240. case eAutoModeState.WaitStop:
  241. this.AutoModeStateProperty = eAutoModeState.Stop;
  242. break;
  243. case eAutoModeState.Stop:
  244. this.OperationModeProperty = eOperatationMode.ManualMode;
  245. break;
  246. case eAutoModeState.StartRun:
  247. this.AutoModeStateProperty = eAutoModeState.Run;
  248. break;
  249. case eAutoModeState.Run:
  250. break;
  251. default:
  252. break;
  253. }
  254. break;
  255. case eOperatationMode.InitialMode:
  256. break;
  257. default:
  258. break;
  259. }
  260. }
  261. public void ProcessAlarm( int alarmID )
  262. {
  263. this.AutoModeStateProperty = eAutoModeState.ErrorStop;
  264. this.LampStateProperty = eLampState.Alarm;
  265. this.BuzzerStateProperty = eBuzzerKind.Alarm;
  266. HisAlarm hisAlarm = new HisAlarm();
  267. var alarm = this.Alarms.Where( x => x.AlarmId == alarmID ).FirstOrDefault();
  268. if ( alarm == null )
  269. {
  270. hisAlarm.AlarmId = alarmID;
  271. hisAlarm.Text = "Not Define Alarm";
  272. alarm = new Alarm();
  273. alarm.AlarmId = alarmID;
  274. alarm.Text = "Not Define Alarm";
  275. logger.E( $"[{this.GetType().Name}] - Not Defiine Alarm No {alarmID}" );
  276. }
  277. else
  278. {
  279. hisAlarm.AlarmId = alarmID;
  280. hisAlarm.Text = alarm.Name + " - " + alarm.Text;
  281. hisAlarm.Solution = alarm.Solution;
  282. //hisAlarm.Alarm = alarm;
  283. }
  284. sql.HisAlarmDAL.Insert( hisAlarm );
  285. logger.I( $"[Alarm Occur] - ID : {alarmID} / Text : {hisAlarm.Text}" );
  286. //UI 로는 처음 발생한 Error 만 전송한다.
  287. if ( IsErrorProcessing )
  288. return;
  289. this.BuzzerOnOff( true, eBuzzerKind.Alarm );
  290. this.sql.CommandDAL.Clean();
  291. this.sql.SubCmdDAL.Clean();
  292. this.activeAlarm = ObjectCopyUtils.DeepClone<Alarm>( alarm );
  293. IsErrorProcessing = true;
  294. var msg = new GUIMessageEventArgs
  295. {
  296. Kind = GUIMessageEventArgs.eGUIMessageKind.ModelPropertyChange,
  297. MessageKey = MessageKey.Alarm,
  298. MessageText = hisAlarm.Text,
  299. Args = hisAlarm,
  300. };
  301. this.eventAggregator.GetEvent<GUIMessagePubSubEvent>().Publish( msg );
  302. }
  303. #region IDisposable Support
  304. private bool disposedValue = false; // 중복 호출을 검색하려면
  305. protected virtual void Dispose( bool disposing )
  306. {
  307. if ( !disposedValue )
  308. {
  309. if ( disposing )
  310. {
  311. // TODO: 관리되는 상태(관리되는 개체)를 삭제합니다.
  312. this.isThreadAlive = false;
  313. if ( !this.threadWorker.Join( 3000 ) )
  314. ThreadUtils.Kill( this.threadWorker );
  315. }
  316. // TODO: 관리되지 않는 리소스(관리되지 않는 개체)를 해제하고 아래의 종료자를 재정의합니다.
  317. // TODO: 큰 필드를 null로 설정합니다.
  318. disposedValue = true;
  319. }
  320. }
  321. // TODO: 위의 Dispose(bool disposing)에 관리되지 않는 리소스를 해제하는 코드가 포함되어 있는 경우에만 종료자를 재정의합니다.
  322. // ~AutoManager()
  323. // {
  324. // // 이 코드를 변경하지 마세요. 위의 Dispose(bool disposing)에 정리 코드를 입력하세요.
  325. // Dispose(false);
  326. // }
  327. // 삭제 가능한 패턴을 올바르게 구현하기 위해 추가된 코드입니다.
  328. public void Dispose()
  329. {
  330. // 이 코드를 변경하지 마세요. 위의 Dispose(bool disposing)에 정리 코드를 입력하세요.
  331. Dispose( true );
  332. // TODO: 위의 종료자가 재정의된 경우 다음 코드 줄의 주석 처리를 제거합니다.
  333. // GC.SuppressFinalize(this);
  334. }
  335. #endregion
  336. }
  337. }