public void ExecuteGeneralDiag() { // arrange InstrumentDiagnosticAction action = Helper.GetDiagnosticAction(DeviceType.MX4); InitializeForTest(action); InstrumentDiagnosticOperation diagOperation = new InstrumentDiagnosticOperation(action); InstrumentDiagnosticEvent diag = (InstrumentDiagnosticEvent)diagOperation.Execute(); Assert.True(diag.Diagnostics.Count == 2); instrumentController.Verify(x => x.ClearInstrumentErrors(), Times.Once); }
public void GetNothingActionDueToInstrumentCriticalError() { // arrange InstrumentDiagnosticAction action = new InstrumentDiagnosticAction(); InstrumentDiagnosticOperation operation = new InstrumentDiagnosticOperation(action); InstrumentDiagnosticEvent dsEvent = new InstrumentDiagnosticEvent(operation); instrument = Helper.GetInstrumentForTest(DeviceType.VPRO, DeviceSubType.VentisPro4); dsEvent.InstrumentInCriticalError = true; Initialize(); CreateMasterForTest(); // act nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is NothingAction); }
public void ExecuteDiagnosticsForMX6InstrumentErrorsOnCustomerAccount() { // arrange InstrumentDiagnosticAction action = Helper.GetDiagnosticAction(DeviceType.MX6); InitializeForTest(action); InstrumentDiagnosticOperation diagOperation = new InstrumentDiagnosticOperation(action); diagOperation.criticalErrorsList = DiagErrorDataAccess.Object.FindAll(); InstrumentDiagnosticEvent diag = (InstrumentDiagnosticEvent)diagOperation.Execute(); Assert.True(diag.Diagnostics.Count == 2 && diag.InstrumentInCriticalError && diag.InstrumentCriticalErrorCode == diagOperation.criticalErrorsList[0].Code.ToString()); instrumentController.Verify(x => x.ClearInstrumentErrors(), Times.Never); }
/// <summary> /// Executes an instrument diagnostic operation. /// </summary> /// <returns>Docking station event</returns> public DockingStationEvent Execute() { Stopwatch stopwatch = Log.TimingBegin("INSTRUMENT DIAGNOSTICS"); InstrumentDiagnosticEvent instrumentDiagnosticEvent = new InstrumentDiagnosticEvent(this); instrumentDiagnosticEvent.DockedInstrument = (ISC.iNet.DS.DomainModel.Instrument)Master.Instance.SwitchService.Instrument.Clone(); instrumentDiagnosticEvent.DockingStation = Master.Instance.ControllerWrapper.GetDockingStation(); // Open the serial port connection needed to communicate with the instrument. using (InstrumentController instrumentController = Master.Instance.SwitchService.InstrumentController) { instrumentController.Initialize(InstrumentController.Mode.Batch); // Cache the diagnostic start time and instrument serial numbers, // these will be used during each diagnostic object's instantiation. DateTime diagnosticTime = DateTime.UtcNow; string instSn = instrumentDiagnosticEvent.DockedInstrument.SerialNumber; // Download the "General diagnostics" from the instrument. // The diagnostics that are returned by the instrument will be different and based on the instrument's type. GeneralDiagnostic generalDiagnostic = new GeneralDiagnostic(instSn, diagnosticTime); generalDiagnostic.Items = instrumentController.GetGeneralDiagnosticProperties(); foreach (GeneralDiagnosticProperty gdp in generalDiagnostic.Items) { Log.Debug("GeneralDiagnosticProperty " + gdp.Name + "=" + gdp.Value); } instrumentDiagnosticEvent.Diagnostics.Add(generalDiagnostic); // Download instrument error log. ErrorDiagnostic[] errors = instrumentController.GetInstrumentErrors(); List <CriticalError> criticalErrors = new List <CriticalError>(); // we don't need to bother querying the database if there were no errors on // the instrument that need checked against the database. if (errors.Length > 0) { // INS-4236, 9/10/2014 - only populate criticalErrors list for MX6 instruments. // MX6 instruments due not have a "current error" register that can be read when it's // docked to determine if it's currently in a error state. But other instruments do. // For those instruments that do have this register, we read the register during discovery // and the docking station will go to "instrument error" state if it's no zero. // Since we can't do that for MX6, the best we can do is read its error log containing // historical errors. For each error in the log, we compare to list of errors we // have in our database that are considered "critical". If we find a match, // then we set a flag which will cause the docking station to go the "instrument error" // state when this operation returns the event. //INS-7715- Need to check if the DS belongs to the Service account, if so fetch all configured errors and compare with the instrument errors. //If any matches with the errors, then set instrument marked as in critical error. if ((instrumentDiagnosticEvent.DockedInstrument.Type == DeviceType.MX6) || Configuration.IsRepairAccount()) { criticalErrors = criticalErrorsList; //criticalErrors = new CriticalErrorDataAccess().FindAll(); Log.Debug(string.Format("{0} {1} critical errors loaded from database.", criticalErrors.Count, instrumentDiagnosticEvent.DockedInstrument.Type)); } } bool foundCrticalErrorInInstrument = false; string criticalErroCodeIdentified = string.Empty; // INS-8446 RHP v7.6 foreach (ErrorDiagnostic error in errors) { // these values are needed so they can be uploaded to iNet error.SerialNumber = instSn; error.Time = diagnosticTime; instrumentDiagnosticEvent.Diagnostics.Add(error); Log.Debug("InstrumentError " + error.Code + " on " + Log.DateTimeToString(error.ErrorTime)); // Errors that are logged in the instrument will be compared to the list of critical errors // downloaded from iNet. If any error code matches then instrument marked as in critical error. // This list will default to empty for non-MX6 instruments, so it will never find anything, on purpose. // Exception to that it loads all critical errors for Service accounts for any instrument types - INS-7715. if (criticalErrors.Exists(ce => ce.Code == error.Code)) { foundCrticalErrorInInstrument = true; criticalErroCodeIdentified = error.Code.ToString(); Log.Warning(string.Format("CRITICAL ERROR {0} LOGGED BY INSTRUMENT ON {1}", error.Code, Log.DateTimeToString(error.ErrorTime))); } } if (foundCrticalErrorInInstrument) { //if critical errors found then errors will NOT be cleared from the instrument. Setting the "InstrumentInCriticalError" //property to TRUE will make the docking station to set to "Instrument Error" state. instrumentDiagnosticEvent.InstrumentInCriticalError = true; // Setting the "InstrumentCriticalErrorCode" property to hold the Error Code will make the docking station // display the Error Code on its LCD during "Instrument Error" state. INS-8446 RHP v7.6 instrumentDiagnosticEvent.InstrumentCriticalErrorCode = criticalErroCodeIdentified; } else { //if no crtical error found then we will clear the errors from the instrument. instrumentController.ClearInstrumentErrors(); } } // end-using instrumentController Log.TimingEnd("INSTRUMENT DIAGNOSTICS", stopwatch); return(instrumentDiagnosticEvent); }
/// <summary> /// Determines if some specific action needs to be performed based /// on the event passed to it. (Some events require a specific /// followup action to be executed.) /// </summary> /// <param name="dsEvent"></param> /// <returns></returns> internal DockingStationAction GetFollowupAction(DockingStationEvent dsEvent) { // A SettingsUpdate is ALWAYS followed by a SettingsRead. if (dsEvent is SettingsUpdateEvent) { // If the SettingsUpdate was Scheduled, we want to inject a CylinderPressureReset before the SettingsRead. if (dsEvent.Trigger == TriggerType.Scheduled) { Log.Trace("EventProcessor returning CylinderPressureReset as followup to SettingsUpdate"); CylinderPressureResetAction cylPressureResetAction = new CylinderPressureResetAction(); // These values will be propogated to a followup SettingsRead. cylPressureResetAction.PostUpdate = true; cylPressureResetAction.SettingsRefId = ((SettingsUpdateEvent)dsEvent).DockingStation.RefId; return(cylPressureResetAction); } Log.Trace("EventProcessor returning SettingsRead as followup to SettingsUpdate"); SettingsReadAction settingsReadAction = new SettingsReadAction(); // Set the refId to indicate that this Read is occurring due to an Update that was just performed. settingsReadAction.PostUpdate = true; settingsReadAction.SettingsRefId = ((SettingsUpdateEvent)dsEvent).DockingStation.RefId; // Explicitly set the ChangedSmartCards to all falses so that no smart cards are read. settingsReadAction.ChangedSmartCards = new bool[Configuration.DockingStation.NumGasPorts]; return(settingsReadAction); } if (dsEvent is CylinderPressureResetEvent) { Log.Trace("EventProcessor returning SettingsRead as followup to CylinderPressureReset"); SettingsReadAction settingsReadAction = new SettingsReadAction(); // Copy the PostUpdate and SettingsRefId so it can be determined if the SettingsRead is // being run due to a SettingsUpdate that would have occurred before the CylinderPressureReset. settingsReadAction.PostUpdate = ((CylinderPressureResetEvent)dsEvent).PostUpdate; settingsReadAction.SettingsRefId = ((CylinderPressureResetEvent)dsEvent).SettingsRefId; // Explicitly set the ChangedSmartCards to null so all positions are read similar to startup. settingsReadAction.ChangedSmartCards = null; return(settingsReadAction); } // After downloading datalog, we clear it. if (dsEvent is InstrumentDatalogDownloadEvent) { InstrumentDatalogDownloadEvent datalogEvent = (InstrumentDatalogDownloadEvent)dsEvent; // D2G: Only clear the log if there is something to clear, or corruption was detected. if (datalogEvent.InstrumentSessions.Count > 0 || datalogEvent.Errors.Count > 0) { Log.Trace("EventProcessor returning InstrumentHygieneClearAction as followup to InstrumentHygieneDownloadEvent"); return(new InstrumentDatalogClearAction()); } else { Log.Debug("NO DATALOG TO CLEAR"); return(null); } } // After downloading alarm events, we clear them. if (dsEvent is InstrumentAlarmEventsDownloadEvent) { InstrumentAlarmEventsDownloadEvent alarmsEvent = (InstrumentAlarmEventsDownloadEvent)dsEvent; // D2G: Only clear the log if there is something to clear, or corruption was detected. if (alarmsEvent.AlarmEvents.Length > 0 || alarmsEvent.Errors.Count > 0) { Log.Trace("EventProcessor returning InstrumentAlarmEventsClearAction as followup to InstrumentAlarmEventsDownloadEvent"); return(new InstrumentAlarmEventsClearAction()); } else { Log.Debug("NO ALARM EVENTS TO CLEAR"); return(null); } } // After downloading alarm events, we clear them. if (dsEvent is InstrumentManualOperationsDownloadEvent) { InstrumentManualOperationsDownloadEvent manualOpsEvent = (InstrumentManualOperationsDownloadEvent)dsEvent; // D2G: Only clear the log if there is something to clear, or corruption was detected. if (manualOpsEvent.GasResponses.Count > 0 || manualOpsEvent.Errors.Count > 0) { Log.Trace("EventProcessor returning InstrumentManualOperationsDownloadAction as followup to InstrumentManualOperationsDownloadEvent"); return(new InstrumentManualOperationsClearAction()); } else { Log.Debug("NO MANUAL GAS OPERATIONS TO CLEAR"); return(null); } } if (dsEvent is InstrumentFirmwareUpgradeEvent) { if (((InstrumentFirmwareUpgradeEvent)dsEvent).UpgradeFailure) { Log.Trace("EventProcessor returning NothingAction as followup to InstrumentFirmwareUpgradeEvent due to an upgrade failure"); // Setting this to true will cause the docking station to go // into its UpgradingInstrumentError state. Master.Instance.SwitchService.InstrumentUpgradeError = true; // Return an action just to prevent further processing (there's no use // next letting the scheduler figure out what needs to be done next since // we know we're about to into the UpgradingInstrumentError state.) return(new NothingAction()); } } //Suresh 06-FEB-2012 INS-2622 //Check whether instrument is in critical error. if (dsEvent is InstrumentDiagnosticEvent) { InstrumentDiagnosticEvent diagnosticEvent = (InstrumentDiagnosticEvent)dsEvent; if (diagnosticEvent.InstrumentInCriticalError == true) { Log.Trace("EventProcessor returning NothingAction as followup to InstrumentDiagnosticEvent due to instrument having a critical error"); Master.Instance.SwitchService.Instrument.InstrumentInCriticalError = true; // INS-8446 RHP v7.6 - Set the SwitchService's InstrumentCriticalErrorCode to display the critical error code on LCD Log.Trace("EventProcessor identfied InstrumentDiagnosticEvent having a critical error code of " + diagnosticEvent.InstrumentCriticalErrorCode); Master.Instance.SwitchService.Instrument.InstrumentCriticalErrorCode = diagnosticEvent.InstrumentCriticalErrorCode; return(new NothingAction()); } } return(null); }