using Aurora; using Aurora.Api; using Aurora.Util.HislogPlus; using Aurora.View; using AuroraLaser; using DB; using Hermes.Functional; using WeldingCommon.Alarm; using WeldingCommon.Device; using WeldingCommon.Device.ACS; using WeldingCommon.Process; using WeldingCommon.Process.Services.History; using WeldingCommon.Tools; // 26.04.13 using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Configuration; using System.Dynamic; using System.IO; using System.Linq; using System.Reactive.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Documents; using WeldingCommon; using WeldingCommon.Devices; using WeldingCommon.Popup; using WeldingCommon.Sequences.Main; using WeldingCommon.Settings; using WeldingCommon.Utils; namespace WeldingCommon { public class ProcessManager { private static ProcessManager _Instance; public static ProcessManager Instance { get { if (_Instance is null) { _Instance = new ProcessManager(); } return _Instance; } } private static DualLogger _Log = new DualLogger(); private IAuroraEnvironment _env; private Laser _laser; public PalletInfo PalletInStageA { get; set; } public PalletInfo PalletInStageB { get; set; } public IHistoryReader HistoryReader { get; private set; } private IHistoryWriter _historyWriter; private static CsvLogger CsvLogStageA; private static CsvLogger CsvLogStageB; private object _lock = new object(); public bool StopRequest { get { lock(_lock) return _StopRequest; } private set { lock(_lock) _StopRequest = value; } } private bool _StopRequest; public ProcessManager() { _Log.AddLogger("ProcessManager", "StageA"); _Log.AddLogger("ProcessManager", "StageB"); } public void Init(IAuroraEnvironment env) { _env = env; //_plc = env.DeviceManager[CommonDeviceIds.PLCDevice] as PLCControllerPrismaticGun; //_laser = env.DeviceManager[CommonDeviceIds.Laser] as Laser; //env.EventObservable.AsObservable(CommonEventIds.EVENT_AUTO_RUN_START_REQUEST) // .ObserveOnDispatcher() // .Subscribe(x => { // AutoRunStart(); // _Log.W("PLC Request Auto Run"); // }); //// PLC Stop - 상태감시 필요 (Cycle Stop) //env.EventObservable.AsObservable(CommonEventIds.EVENT_AUTO_RUN_STOP_REQUEST) // .ObserveOnDispatcher() // .Subscribe(x => { // _Log.E("PLC Request Auto Run Cycle Stop!!!!"); // CycleStop(); // }); //// Cell History //var historyServ = new CellHistoryService(maxCount: 50, pumpMs: 100); //_historyWriter = historyServ as IHistoryWriter; //HistoryReader = historyServ as IHistoryReader; //var setting = _env.SettingEntry[CommonSettingIds.SystemParameter] as SystemParameter; //CsvLogStageA = new CsvLogger(Path.Combine(setting.CellHistoryFolderPath, "StageA"), "StageA_CellInfo"); //CsvLogStageB = new CsvLogger(Path.Combine(setting.CellHistoryFolderPath, "StageB"), "StageB_CellInfo"); // Pallet Register RegistrySerializer.Init(); LoadRegistryData(); } private void SaveRegistryData(eStage stage, PalletInfo cell) { RegistrySerializer.SaveToRegistry("PalletInfo", cell); Thread.Sleep(50); } private void LoadRegistryData() { PalletInStageA = RegistrySerializer.LoadFromRegistry("PalletInfo"); } public bool LoadingComplete(PalletInfo cell) { cell.SetState(ePalletState.LoadingComp); if (Status.EquipmentStatus == eEqpStatus.Auto) SaveRegistryData(cell.WeldingStage, cell); _Log.W($"{cell.ToString()} Load Complete", cell.WeldingStage); return true; } public void WeldingStart(PalletInfo cell) { // 저장은 하지 않는다. 웰딩중에 끊기면 배출함 cell.SetState(ePalletState.Welding); cell.weldingData.WeldingStartTime = DateTime.Now; if (Status.EquipmentStatus == eEqpStatus.Auto) SaveRegistryData(cell.WeldingStage, cell); _Log.W($"{cell.ToString()} Welding Start", cell.WeldingStage); } public bool WeldingComplete(PalletInfo cell) { // 메뉴얼은 카운팅이 안됨 if (cell.weldingData.TotalProduct < uint.MaxValue && cell.weldingData.IsLaserOn) cell.weldingData.TotalProduct++; if (cell.weldingData.TodayProduct < uint.MaxValue && cell.weldingData.IsLaserOn) cell.weldingData.TodayProduct++; cell.SetState(ePalletState.WeldingComp); cell.weldingData.WeldingEndTime = DateTime.Now; if (Status.EquipmentStatus == eEqpStatus.Auto) SaveRegistryData(cell.WeldingStage, cell); // 히스토리 파일 저장 if (cell.WeldingStage is eStage.A) CsvLogStageA.WriteLineCellData(cell); else CsvLogStageB.WriteLineCellData(cell); _Log.W($"{cell.ToString()} Welding Complete", cell.WeldingStage); return true; } public bool UnloadingComplete(PalletInfo cell) { cell.SetState(ePalletState.UnloadingComp); if (Status.EquipmentStatus == eEqpStatus.Auto) SaveRegistryData(cell.WeldingStage, cell); // 일단 메뉴얼도 히스토리로 남기도록 함 _historyWriter.Append(cell.WeldingStage, cell.weldingData.Clone() as WeldingDataForPrismaticGun); _Log.W($"{cell.ToString()} Unload Complete", cell.WeldingStage); return true; } public bool PalletClear(eStage stage) { if(stage is eStage.A) { PalletInStageA.Clear(); SaveRegistryData(stage, PalletInStageA); } else { PalletInStageB.Clear(); SaveRegistryData(stage, PalletInStageB); } return true; } #region Welding Enable >> Stage 두개 다 사용못하는 경우 알람 발생을 하기위한 플래그.. 이렇게 하면 복잡한데 일단 필요 private bool _enableLaserUse = true; public bool IsEnableLaserUse() { lock (_lock) { return _enableLaserUse; } } public void EnableLaserUse(bool enable) { lock (_lock) { _enableLaserUse = enable; } } #endregion #region Cycle Stop을 하기 위한 동작 private bool autoStartStageA = false; private bool autoStartStageB = false; internal void SetAutoPrepare(eStage stage, bool on) { lock (_lock) { if (stage is eStage.A) autoStartStageA = on; else autoStartStageB = on; _Log.I($"Stage {Enum.GetName(typeof(eStage), stage)} [Prepare > {on}]", stage); if (!autoStartStageA && !autoStartStageB) { //_plc.WriteBit(eBitOutput.PC_AUTO_STATUS, false); //_plc.WriteBit(eBitOutput.PC_AUTO_COMPLETE, false); //_plc.WriteBit(eBitOutput.PC_MANUAL_COMPLETE, true); Status.SetStatus(eEqpStatus.Manual); _laser.LaserOff(); _Log.W($"Run Stop >> Laser Off && Manual Change"); } } } internal bool IsAutoPrepare() { lock (_lock) { if (autoStartStageA && autoStartStageB) { //_plc.WriteBit(eBitOutput.PC_AUTO_STATUS, true); //_plc.WriteBit(eBitOutput.PC_AUTO_COMPLETE, true); //_plc.WriteBit(eBitOutput.PC_MANUAL_COMPLETE, false); Status.SetStatus(eEqpStatus.Auto); _Log.W($"Run Prepare OK"); return true; } } return false; } #endregion internal void AutoStart(bool on) { if (on) { //if (_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageA].RunState == SequenceRunState.Running) // _env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageA].Stop(); //if (_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageB].RunState == SequenceRunState.Running) // _env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageB].Stop(); StopRequest = false; //EnableLaserUse(true); //_laser.LaserOn(); _Log.W($"Laser On Start!!!"); // 수정필요 Jeongin //_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageA].Start(); //_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageB].Start(); _Log.W($"Auto Sequence Start"); } else { //if (_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageA].RunState == SequenceRunState.Running) // _env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageA].Stop(); //if (_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageB].RunState == SequenceRunState.Running) // _env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageB].Stop(); //_laser.LaserOff(); _Log.W($"Auto Sequence Stop"); } } public async void AutoRunStart() { bool shouldStop = await TimerMessageBox.ShowAsync(Application.Current.MainWindow, "자동 시작", "자동 운전을 시작하시겠습니까?", true, 5000); if (!shouldStop) return; AutoStart(true); } internal void CycleStop() { // 용접중이면, 정지 신호만 주고 정상 시퀀스 종료를 준다 if (PalletInStageA.palletState == ePalletState.Welding) { _Log.E($"{PalletInStageA.ToString()} CycleStop OK!! State is welding", eStage.A); StopRequest = true; } } } }