private void updateOperatorMsgHandler(OperatorResponseMessage msg) { if (msg.PortNo != thisPortNo) { return; } AuthorizationLevel authLevel = msg.authLevel; BusyOp = false; OperatorStatus = authLevel == AuthorizationLevel.InvalidUser ? "../Images/CheckBoxRed.png" : "../Images/CheckBoxGreen.png"; if (authLevel == AuthorizationLevel.InvalidUser) { if (!string.IsNullOrEmpty(OperatorID)) { Application.Current.Dispatcher.Invoke((Action) delegate { var vm = new DialogViewModel($"Invalid Operator ID {OperatorID} entered! Please re-enter", "", "Ok"); dialogService.ShowDialog(vm); _operatorID = ""; Messenger.Default.Send(new ReFocusMessage("OperatorField", null)); Engineer = false; }); } } else if (authLevel == AuthorizationLevel.Engineer) { IsRecipeOverridable = true; Engineer = true; Messenger.Default.Send(new ReFocusMessage("ToolField", null)); RaisePropertyChanged(nameof(OperatorID)); RaisePropertyChanged(nameof(OperatorLevel)); } else { IsRecipeOverridable = false; Engineer = false; RaisePropertyChanged(nameof(OperatorID)); RaisePropertyChanged(nameof(OperatorLevel)); } if (authLevel != AuthorizationLevel.InvalidUser) { Messenger.Default.Send(new CurrentOperatorMessage(thisPortNo, OperatorID, authLevel)); } OperatorLevel = authLevel.ToString(); MyLog.Debug($"MES->ValidateEmployee->UpdateOperatorMsgHandler sets OperatorLevel=({OperatorLevel})"); //RaisePropertyChanged(nameof(OperatorID)); //RaisePropertyChanged(nameof(OperatorLevel)); //if (string.IsNullOrEmpty(_operatorID)) // Messenger.Default.Send(new ReFocusMessage("OperatorField", null)); //else // Messenger.Default.Send(new ReFocusMessage(string.Empty, null)); }
private void startTimerExpiredHandler() { StopTimer(); var vm = new DialogViewModel("The timer has expired to press Start. This lot will be placed onHold in Camstar now.", "", "Ok"); bool?result = dialogService.ShowDialog(vm); // HoldWafers("Start Timer ran out by: "+ OperatorID); //emailViewHandler("Start Timer expired"); Messenger.Default.Send(new ReInitializeSystemMessage(thisPortNo, 0)); }
private void startCmdHandler() { // Can use something like idx = CurrentTab (prob s/b CurrentTabIndex) //string port = CurrentToolConfig.Loadports[0]; string port = CurrentToolConfig.Loadports[thisPortNo - 1]; string startMessage = "Do you want to start the other port as well?"; StopTimer(); bool?result = true; //if (!string.IsNullOrEmpty(CurrentToolConfig.Dialogs.PostStartmessage)) if (!string.IsNullOrEmpty(startMessage)) { var vm = new DialogViewModel(startMessage, "Yes", "No"); result = dialogService.ShowDialog(vm); } if (result.HasValue && result.GetValueOrDefault() == true) { string[] lotIds; if (!string.IsNullOrEmpty(Lot2)) { lotIds = new string[] { Lot1, Lot2 } } ; else { lotIds = new string[] { Lot1 } }; // TODO: LoadingWafers = ToolBusy = true; TimerText = "Starting PreProcessing for Equipment..."; #if TIMERALL Task.Delay(5000).ContinueWith(_ => { ToolBusy = false; Started = true; IsProcessing = true; }); #endif StartToolAsync(port, lotIds); } else { } }
private void cancelPortCmdHandler() { if (string.IsNullOrEmpty(Port1Lot1) && string.IsNullOrEmpty(Port1Lot2)) { return; } var vm = new DialogViewModel("Are you sure you want to Cancel?", "Yes", "No"); bool?result = dialogService.ShowDialog(vm); if (result.HasValue && result == true) { Messenger.Default.Send(new ReInitializeSystemMessage(thisPortNo, 1)); } }
private void abortCmdHandler() { StopTimer(); var vm = new DialogViewModel("Are you sure you want to Abort?", "Yes", "No"); bool?result = dialogService.ShowDialog(vm); if (result.HasValue && result.GetValueOrDefault() == true) { MyLog.Information($"SECS->SendSECSAbort()"); //currentTool.SendSECSAbort(); //// TODO: Review with Zahir if this os ok //Aborted = true; //Started = false; //IsProcessing = false; //messenger underneath does the same thing as above Messenger.Default.Send(new ProcessAbortMessage(thisPortNo)); // HoldWafers("Aborted by: " + portLotInfo.OperatorID); Messenger.Default.Send(new SetAllWafersStatusMessage(thisPortNo, "", "Aborted")); } else { } }
private void confirmPort1CmdHandler() { bool? result = true; string newline = Environment.NewLine; // First check if we can confirm string cantConfirm = ""; if (string.IsNullOrEmpty(OperatorID) || OperatorLevel == null || OperatorLevel.Equals("InvalidUser")) { cantConfirm = "- Must have a valid Operator " + newline; } if (ToolStatus == null || ToolStatus == "../Images/CheckBoxRed.png") { cantConfirm += "- Must have a valid Tool " + newline; } // TODO: if (string.IsNullOrEmpty(Port1Lot1) && string.IsNullOrEmpty(Port1Lot2)) { cantConfirm += "- Must enter some valid lots " + newline; } if (!EquipmentReady) { cantConfirm += "- Control State must be 'REMOTE'"; } if (!ProcessStateReady) { cantConfirm += "- Process State must be 'READY'"; } if (!string.IsNullOrEmpty(cantConfirm)) { cantConfirm = "Confirmation cannot proceed until errors are fixed: " + newline + cantConfirm; var vm = new DialogViewModel(cantConfirm, "", "Ok"); result = dialogService.ShowDialog(vm); return; } if (CurrentToolConfig.Dialogs.ShowConfirmationBox) { var vm = new DialogViewModel("Are you sure you want to Confirm this lot?", "Yes", "No"); result = dialogService.ShowDialog(vm); } if (result.HasValue && result.GetValueOrDefault() == true) { // 2/22 Check if equipment is ready first // TODO: //if (currentTool.ReadyToStart()) { Messenger.Default.Send(new LoadingWafersMessage(thisPortNo, true, "Moving in wafers in Camstar...")); // TimerText = "Moving in wafers in Camstar..."; MyLog.Debug("ConfirmButtonPressed->"); MoveInAfterConfirmAsync(); } } }
private async void GetWafersLot2Async(string lot2Id) { string errString = ""; try { MyLog.Information($"GetWafersPort2Async->_mesService.GetContainerStatus({lot2Id})"); DataTable dtWafers = await Task.Run(() => _mesService.GetContainerStatus(lot2Id)); if (dtWafers == null) { MyLog.Information($"GetWafersPort2Async->_mesService.GetContainerStatus({lot2Id}) returned no wafers"); } else { MyLog.Information($"GetWafersPort2Async->_mesService.GetContainerStatus({lot2Id}) returned some wafers"); } if (dtWafers != null) { var wafers = DataHelpers.MakeDataTableIntoWaferList(dtWafers); // TODO: I think this check is wrong??!?! //if (wafers[0].Recipe != CurrentRecipe) // errString = "ERROR: Recipe mismatch! Cannot use different recipes between lots!"; //else { //_port1Lot2 = lotId; bool goodWafers = CheckWafers(ref wafers, ref errString); if (goodWafers) { // AddWafersToTopGrid(wafers); Messenger.Default.Send(new AddWafersToGridMessage(thisPortNo, wafers)); RaisePropertyChanged("Port1Wafers"); Lot2Enabled = false; _port1Lot2 = lot2Id; } else { if (!string.IsNullOrEmpty(errString)) { var vm = new DialogViewModel(errString, "", "Ok"); Application.Current.Dispatcher.Invoke((Action) delegate { dialogService.ShowDialog(vm); }); } Lot2Enabled = true; _port1Lot2 = ""; Messenger.Default.Send(new ReFocusMessage("Lot2", null)); } } } // else { if (dtWafers == null || !string.IsNullOrEmpty(errString)) { Messenger.Default.Send(new LoadingWafersMessage(thisPortNo, false, "")); if (dtWafers == null) { errString = $"MES->GetContainerStatus:Error getting lot #{lot2Id}."; } MyLog.Information(errString); var vm = new DialogViewModel(errString, "", "Ok"); Application.Current.Dispatcher.Invoke((Action) delegate { dialogService.ShowDialog(vm); }); _port1Lot2 = ""; Lot2Enabled = true; Port1Lot2Color = "White"; Messenger.Default.Send(new ReFocusMessage("Lot2", null)); } } } catch (Exception ex) { MyLog.Error(ex, "GetWafersLot2Async()"); _port1Lot2 = ""; RaisePropertyChanged(nameof(Port1Lot2)); Lot2Enabled = true; Port1Lot2Color = "White"; } finally { //await Task.Delay(0).ContinueWith(_ => //{ Messenger.Default.Send(new LoadingWafersMessage(thisPortNo, false, "")); //}); RaisePropertyChanged(nameof(IsRecipeOverridable)); RaisePropertyChanged(nameof(Port1Lot2)); // if (string.IsNullOrWhiteSpace(_port1Lot2) || _port1Lot2==_port1Lot1) if (!string.IsNullOrEmpty(errString)) { Messenger.Default.Send(new ReFocusMessage("Lot2", null)); } } }
private void ConvertAndAddToGrid(DataTable dtWafers, string lot1Id) { string errString = string.Empty; // string lot1Id = msg.lotID; MyLog.Debug($"GetWafersPort1Async->ConvertAndAddToGrid() start..."); MyLog.Debug($"GetWafersPort1Async->MakeDataTableIntoWaferList()..."); List <Wafer> wafers = DataHelpers.MakeDataTableIntoWaferList(dtWafers); MyLog.Debug($"GetWafersPort1Async->CheckWafers()..."); bool goodWafers = CheckWafers(ref wafers, ref errString); if (goodWafers) { MyLog.Debug($"GetWafersPort1Async->AddWafersToGrid()..."); // TODO: // AddWafersToGrid(wafers); Messenger.Default.Send(new AddWafersToGridMessage(thisPortNo, wafers)); try { CurrentOperation = wafers[0].Operation; Recipe = wafers[0].Recipe; Product = wafers[0].Product; Step = wafers[0].WorkFlowStepName; Spec = wafers[0].SpecName; Status = wafers[0].Status; Comments = wafers[0].SpecialProcessInstructions; _port1Lot1 = lot1Id; RaisePropertyChanged(nameof(Port1Lot1)); Messenger.Default.Send(new UpdateRecipeAndRunTypeMessage(thisPortNo, wafers)); } catch (Exception ex) { MyLog.Error(ex, "Error in ConvertAndAddToGrid probably by wafers[0] somehow"); } } if (dtWafers == null || !string.IsNullOrEmpty(errString)) { if (dtWafers == null) { errString = $"MES->GetContainerStatus:Error getting lot #{lot1Id}."; MyLog.Information($"GetWafersPort1Async->_mesService.GetContainerStatus({lot1Id}) returned no wafers: dtWafers==null."); } MyLog.Information(errString); var vm = new DialogViewModel(errString + " Please enter a new lot id", "", "Ok"); Application.Current.Dispatcher.Invoke((Action) delegate { dialogService.ShowDialog(vm); }); _port1Lot1 = ""; //Messenger.Default.Send(new ReFocusMessage("Lot1" ,null)); } RaisePropertyChanged(nameof(Port1Lot1)); MyLog.Debug($"GetWafersPort1Async->LoadLot1MsgHandler() end"); if (string.IsNullOrWhiteSpace(_port1Lot1)) { Messenger.Default.Send(new ReFocusMessage("Lot1", null)); } else { Messenger.Default.Send(new ReFocusMessage(string.Empty, null)); Lot1Enabled = false; } }
// GRID MANIPULATION private void AddWafersToTopGrid(List <Wafer> wafers) { ObservableCollection <Wafer> currentWafers = new ObservableCollection <Wafer>(WaferList); ObservableCollection <Wafer> goodList = new ObservableCollection <Wafer>(); ObservableCollection <Wafer> bottomList = new ObservableCollection <Wafer>(); int slotNo = 0; // Find first top index int topIdx = 0; for (int i = 0; i < MAXROWS; ++i) { if (!string.IsNullOrEmpty(currentWafers[i].WaferNo)) { topIdx = i; break; } } // Copy good rows to goodList if (topIdx > 0) { for (int i = topIdx; i < MAXROWS; ++i) { bottomList.Add(currentWafers[i]); } } int newListCount = wafers.Count; if (topIdx - newListCount < 0) { var vm = new DialogViewModel("There are too many new wafers to add to current list. Continue?", "Yes", "No"); bool?result = dialogService.ShowDialog(vm); if (result.HasValue && result.GetValueOrDefault() == true) { } WaferList = currentWafers; RenumberWafersHandler(null); Port1Lot2 = ""; return; } // Set currentWafers to goodList and WaferList = new ObservableCollection <Wafer>(wafers); // Add currentwafers to bottom then add in empty then renumber slots foreach (var tempwafer in bottomList) { WaferList.Add(tempwafer); } // Add in empty slots at top slotNo = WaferList.Count; for (int i = MAXROWS - slotNo; i > 0; --i) { WaferList.Insert(0, new Wafer()); } RenumberWafersHandler(null); }
private bool StartToolProcessing(string port, string[] lotIds) { bool success = false; bool? result = true; string errMessage = ""; bool yesRetry = false; int numTry = 1; MyLog.Information($"START TOOL PROCESSING for Port:{port}"); if (lotIds.Length == 1) { MyLog.Information($"START TOOL PROCESSING for Lot Id:{lotIds[0]}"); } else { MyLog.Information($"START TOOL PROCESSING for Lot Id:{lotIds[0]} AND Lot Id:{lotIds[1]}"); } do { MyLog.Information($"SECS->DoPreProcessing #{numTry}"); success = currentTool.DoPreprocessing(); MyLog.Information($"SECS->DoPreProcessing returned {success}"); } while (!success && ++numTry < 4); // System.Threading.Thread.Sleep(2000); numTry = 1; TimerText = "Sending RecipeSelection to Equipment..."; do { MyLog.Information($"SECS->DoRecipeSelection({port}, Lot1:{Lot1} and Lot2:{Lot2}, {CurrentRecipe}, {_operatorID})", true); success = currentTool.DoRecipeSelection(port, lotIds, CurrentRecipe, _operatorID, out errMessage); MyLog.Information($"SECS->DoRecipeSelection returned {success}:errMessage={errMessage}"); if (!success) { yesRetry = false; var vm = new DialogViewModel($"Error in DoRecipeSelection(). {errMessage}.", "Retry", "Cancel"); result = dialogService.ShowDialog(vm); if (result.HasValue) { yesRetry = result.GetValueOrDefault(); } } } while (!success && ++numTry < 4 && yesRetry == true); if (success) { numTry = 1; TimerText = "Sending StartProcessing to Equipment..."; do { MyLog.Information($"SECS->DoStartProcessing({port}, Lot1:{Lot1} and Lot2:{Lot2}, {CurrentRecipe}, {_operatorID})", true); success = currentTool.DoStartProcessing(port, lotIds, CurrentRecipe, _operatorID, out errMessage); MyLog.Information($"SECS->DoStartProcessing returned {success}:errMessage={errMessage}"); if (!success) { yesRetry = false; var vm = new DialogViewModel($"Error in DoStartProcessing(). {errMessage}.", "Retry", "Cancel"); result = dialogService.ShowDialog(vm); if (result.HasValue) { yesRetry = result.GetValueOrDefault(); } } } while (!success && ++numTry < 4 && yesRetry == true); } return(success); }