public void GetScheduledInstrumentAlarmEventDownloadAction() { // arrange instrument = Helper.GetInstrumentForTest(DeviceType.VPRO, DeviceSubType.VentisPro4); dockingStation = Helper.GetDockingStationForTest(DeviceType.MX4); InstrumentAlarmEventsDownloadOperation operation = new InstrumentAlarmEventsDownloadOperation(); List <EventJournal> eventJournals = new List <EventJournal>(); eventJournals.Add(new EventJournal(EventCode.GetCachedCode(EventCode.InstrumentDiagnostics), instrument.SerialNumber, DateTime.Now.AddMonths(-1), DateTime.Now.AddMonths(-1), true, instrument.SoftwareVersion)); eventJournals.Add(new EventJournal(EventCode.GetCachedCode(EventCode.DownloadAlarmEvents), instrument.SerialNumber, DateTime.Now.AddMonths(-1), DateTime.Now.AddMonths(-1), true, instrument.SoftwareVersion)); _eventJournalDataAccess.Setup(x => x.FindBySerialNumbers(It.IsAny <string[]>(), It.IsAny <IDataAccessTransaction>())).Returns(eventJournals); _eventJournalDataAccess.Setup(x => x.FindLastEventByInstrumentSerialNumber(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <IDataAccessTransaction>())).Returns(eventJournals); _scheduleDailyAccess.Setup(x => x.FindGlobalSchedules(It.IsAny <IDataAccessTransaction>())).Returns(new List <Schedule>() { new ScheduledDaily(DomainModelConstant.NullId, DomainModelConstant.NullId, string.Empty, EventCode.GetCachedCode(EventCode.DownloadAlarmEvents), EquipmentTypeCode.Instrument, string.Empty, true, true, 1, DateTime.Now.AddYears(-1), new TimeSpan(9, 0, 0)) }); Initialize(); // act schema.Setup(x => x.Activated).Returns(true); dsEvent = new InstrumentAlarmEventsDownloadEvent(operation); CreateMasterForTest(); nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is InstrumentAlarmEventsDownloadAction); }
public void InstrumentRequiresOperatorAction() { // arrange SettingsReadOperation operation = new SettingsReadOperation(); dsEvent = new SettingsReadEvent(operation); dockingStation = Helper.GetDockingStationForTest(DeviceType.MX4); instrument = Helper.GetInstrumentForTest(DeviceType.VPRO, DeviceSubType.VentisPro4); Initialize(); Sensor sensor = new Sensor(); sensor.Enabled = true; sensor.CalibrationStatus = Status.Failed; sensor.Type.Code = SensorCode.O3; InstalledComponent installedComponent = new InstalledComponent(); installedComponent.Position = 1; installedComponent.Component = sensor; instrument.InstalledComponents.Add(installedComponent); Configuration.DockingStation = dockingStation; CreateMasterForTest(); // act nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is ManualCalibrationRequiredAction); }
public void ReturnManualBumpTestRequiredActionForInstrumentWithBumpFailedSensor() { // arrange InstrumentBumpTestAction action = Helper.GetBumpTestAction(DeviceType.VPRO, new List <string>() { GasCode.CO, GasCode.H2S, GasCode.O3 }, DeviceSubType.VentisPro4); foreach (InstalledComponent installedComponent in action.Instrument.InstalledComponents.Where(comp => comp.Component is Sensor)) { Sensor sensor = installedComponent.Component as Sensor; sensor.BumpTestStatus = false; } instrument = action.Instrument; Initialize(); CreateMasterForTest(); // act InstrumentBumpTestOperation operation = new InstrumentBumpTestOperation(action); dsEvent = new InstrumentBumpTestEvent(operation); nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is ManualBumpTestRequiredAction); }
public void GetNothingActionIfNoEventIsScheduled() { // arrange instrument = Helper.GetInstrumentForTest(DeviceType.VPRO, DeviceSubType.VentisPro4); dockingStation = Helper.GetDockingStationForTest(DeviceType.MX4); InstrumentAlarmEventsClearOperation operation = new InstrumentAlarmEventsClearOperation(); List <EventJournal> eventJournals = new List <EventJournal>(); eventJournals.Add(new EventJournal(EventCode.GetCachedCode(EventCode.InstrumentDiagnostics), instrument.SerialNumber, DateTime.Now.AddMonths(-1), DateTime.Now.AddMonths(-1), true, instrument.SoftwareVersion)); _eventJournalDataAccess.Setup(x => x.FindBySerialNumbers(It.IsAny <string[]>(), It.IsAny <IDataAccessTransaction>())).Returns(eventJournals); _eventJournalDataAccess.Setup(x => x.FindLastEventByInstrumentSerialNumber(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <IDataAccessTransaction>())).Returns(eventJournals); Initialize(); // act schema.Setup(x => x.Activated).Returns(true); dsEvent = new InstrumentAlarmEventsClearEvent(operation); CreateMasterForTest(); nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is NothingAction); }
public void ReforceCalibration() { // arrange dockingStation = Helper.GetDockingStationForTest(DeviceType.GBPRO); instrument = Helper.GetInstrumentForTest(DeviceType.GBPRO); List <InstalledComponent> installedComponents = Helper.GetSensorsForTest(new List <string>() { GasCode.CO }); instrument.InstalledComponents.AddRange(installedComponents); Initialize(); // act dsEvent = new NothingEvent(); CreateMasterForTest(); scheduler.ReForceEvent(new InstrumentCalibrationAction() { Trigger = TriggerType.Forced }); nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is InstrumentCalibrationAction); Xunit.Assert.True(nextAction.Trigger == TriggerType.Forced); }
public void GetCalibrationActionForSensorRemoved() { // arrange InstrumentCalibrationAction action = new InstrumentCalibrationAction(); instrument = Helper.GetInstrumentForTest(DeviceType.VPRO, DeviceSubType.VentisPro4); List <InstalledComponent> installedComponents = Helper.GetSensorsForTest(new List <string>() { GasCode.CO, GasCode.H2S, GasCode.O2, GasCode.CombustibleLEL }); dockingStation = Helper.GetDockingStationForTest(DeviceType.MX4); List <EventJournal> eventJournals = new List <EventJournal>(); eventJournals.Add(new EventJournal(EventCode.GetCachedCode(EventCode.InstrumentDiagnostics), instrument.SerialNumber, DateTime.Now.AddMonths(-1), DateTime.Now.AddMonths(-1), true, instrument.SoftwareVersion)); installedComponents.ForEach(comp => eventJournals.Add(new EventJournal(EventCode.Calibration, comp.Component.Uid, instrument.SerialNumber, DateTime.Now.AddMonths(-1), DateTime.Now.AddMonths(-1), true, comp.Position, instrument.SoftwareVersion))); installedComponents.Remove(installedComponents.Last()); instrument.InstalledComponents.AddRange(installedComponents); _eventJournalDataAccess.Setup(x => x.FindBySerialNumbers(It.IsAny <string[]>(), It.IsAny <IDataAccessTransaction>())).Returns(eventJournals); _eventJournalDataAccess.Setup(x => x.FindLastEventByInstrumentSerialNumber(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <IDataAccessTransaction>())).Returns(eventJournals); Initialize(); // act CreateMasterForTest(); schema.Setup(x => x.Activated).Returns(true); InstrumentCalibrationOperation operation = new InstrumentCalibrationOperation(action); dsEvent = new InstrumentCalibrationEvent(operation); nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is InstrumentCalibrationAction); }
private DockingStationAction ExamineErrors(DockingStationEvent dsEvent, InetUploader inet) { DockingStationErrorLevel highestError = DockingStationErrorLevel.None; DockingStationAction dsAction = null; foreach (DockingStationError error in dsEvent.Errors) { highestError = (DockingStationErrorLevel)Math.Max((int)error.ErrorLevel, (int)highestError); } if (dsAction != null) { return(dsAction); } if (highestError >= DockingStationErrorLevel.Error) { dsAction = new UnavailableAction(); Log.Debug(string.Format("{0}Returning {1}", Name, dsAction.Name)); return(dsAction); } return(null); }
public void GetCalibrationActionforForcedBumpTestOnCalFailedSensors() { // arrange instrument = Helper.GetInstrumentForTest(DeviceType.VPRO, DeviceSubType.VentisPro4); List <InstalledComponent> installedComponents = Helper.GetSensorsForTest(new List <string>() { GasCode.CO, GasCode.H2S, GasCode.O2, GasCode.CombustibleLEL }); foreach (InstalledComponent installComp in installedComponents) { Sensor sensor = installComp.Component as Sensor; sensor.CalibrationStatus = Status.Failed; } instrument.InstalledComponents.AddRange(installedComponents); ScheduledNow scheduledNow = new ScheduledNow(0, 0, string.Empty, new EventCode(EventCode.BumpTest, 1, EquipmentTypeCode.Instrument, typeof(InstrumentBumpTestAction)), EquipmentTypeCode.VDS, null, false); scheduledNow.SerialNumbers.Add(instrument.SerialNumber); Initialize(); CreateMasterForTest(); // act dsEvent = new InstrumentBumpTestEvent(); scheduler.StackForcedSchedule(scheduledNow); nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is CalibrationFailureAction); }
public DockingStationAction ReportFlowFailedError(GasEndPoint gasEndPoint) { Log.Debug(string.Format("Empty Cylinder was reported on position {0} during gas operation.", gasEndPoint.Position)); using (InetUploader inetUploader = new InetUploader()) { DockingStationAction dsAction = ProcessEmptyGasEndPoint(gasEndPoint, inetUploader); return(dsAction); } }
public void GetInstrumentDatalogClearActionAsFollowUpActionForInstrumentDatalogDownloadToClearErrors() { // arrange InstrumentDatalogDownloadEvent dsEvent = new InstrumentDatalogDownloadEvent(); dsEvent.Errors.Add(new DockingStationError("Test Error!")); Initialize(); CreateMasterForTest(); // act nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is InstrumentDatalogClearAction); }
public void GetSettingsReadActionAsFollowUpActionForCylinderPressureReset() { // arrange CylinderPressureResetOperation operation = new CylinderPressureResetOperation(); dsEvent = new CylinderPressureResetEvent(operation); Initialize(); CreateMasterForTest(); // act nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is SettingsReadAction); }
public void GetSettingsReadActionAsFollowUpActionForSettingsUpdate() { // arrange SettingsUpdateOperation operation = new SettingsUpdateOperation(); dsEvent = new SettingsUpdateEvent(operation); Initialize(); CreateMasterForTest(); // act nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is SettingsReadAction); }
public void GetInstrumentDatalogClearActionAsFollowUpActionForInstrumentDatalogDownloadToClearInstrumentSessions() { // arrange InstrumentDatalogDownloadEvent dsEvent = new InstrumentDatalogDownloadEvent(); dsEvent.InstrumentSessions.Add(new DatalogSession()); Initialize(); CreateMasterForTest(); // act nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is InstrumentDatalogClearAction); }
public void GetInstrumentAlarmEventClearActionAsFollowUpActionForInstrumentAlarmEventDownloadToClearInstrumentAlarmEvents() { // arrange InstrumentAlarmEventsDownloadOperation operation = new InstrumentAlarmEventsDownloadOperation(); InstrumentAlarmEventsDownloadEvent dsEvent = new InstrumentAlarmEventsDownloadEvent(operation); dsEvent.AlarmEvents = new AlarmEvent[] { new AlarmEvent() }; Initialize(); CreateMasterForTest(); // act nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is InstrumentAlarmEventsClearAction); }
public void GetForcedSettingsReadForDockingStation() { // arrange instrument = Helper.GetInstrumentForTest(DeviceType.VPRO, DeviceSubType.VentisPro4); ScheduledNow scheduledNow = new ScheduledNow(0, 0, string.Empty, new EventCode(EventCode.SettingsRead, 1, EquipmentTypeCode.VDS, typeof(SettingsReadAction)), EquipmentTypeCode.VDS, null, false); Initialize(); CreateMasterForTest(); // act dsEvent = new NothingEvent(); scheduler.StackForcedSchedule(scheduledNow); nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is SettingsReadAction); }
public void ForceCylinderResetEvent() { // arrange dockingStation = Helper.GetDockingStationForTest(DeviceType.SC); instrument = Helper.GetInstrumentForTest(DeviceType.SC); Initialize(); // act dsEvent = new NothingEvent(); CreateMasterForTest(); scheduler.ForceEvent(EventCode.CylinderPressureReset, true); nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is CylinderPressureResetAction); Xunit.Assert.True(nextAction.Trigger == TriggerType.Forced); }
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 DSXNotSynchronized() { // arrange SettingsReadOperation operation = new SettingsReadOperation(); dsEvent = new SettingsReadEvent(operation); Mock <Schema> schema = new Mock <Schema>(); schema.Setup(x => x.Synchronized).Returns(false); Configuration.Schema = schema.Object; // act nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is NothingAction); }
public void InitialReadingNeeded() { // arrange SettingsUpdateOperation operation = new SettingsUpdateOperation(); dsEvent = new SettingsUpdateEvent(operation); Initialize(); switchService.Setup(x => x.InitialReadSettingsNeeded).Returns(true); CreateMasterForTest(); // act nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is NothingAction); }
public void ExecuteFollowUpAction() { // arrange SettingsUpdateOperation operation = new SettingsUpdateOperation(); dsEvent = new SettingsUpdateEvent(operation); Initialize(); dsEvent.Trigger = TriggerType.Scheduled; CreateMasterForTest(); // act nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is CylinderPressureResetAction); }
public void GetScheduledInstrumentDiagnosticsAction() { // arrange instrument = Helper.GetInstrumentForTest(DeviceType.VPRO, DeviceSubType.VentisPro4); dockingStation = Helper.GetDockingStationForTest(DeviceType.MX4); InstrumentSettingsUpdateOperation operation = new InstrumentSettingsUpdateOperation(); Initialize(); // act schema.Setup(x => x.Activated).Returns(true); dsEvent = new InstrumentSettingsUpdateEvent(operation); CreateMasterForTest(); nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is InstrumentDiagnosticAction); }
public void GetDockingStationFirmwareUpgradeAction() { // arrange instrument = Helper.GetInstrumentForTest(DeviceType.MX6); List <InstalledComponent> installedComponents = Helper.GetSensorsForTest(new List <string>() { GasCode.CO, GasCode.H2S, GasCode.O2 }); instrument.InstalledComponents.AddRange(installedComponents); dockingStation = Helper.GetDockingStationForTest(DeviceType.MX6); dockingStation.SoftwareVersion = "7.6.0.1"; List <EventJournal> eventJournals = new List <EventJournal>(); eventJournals.Add(new EventJournal(EventCode.GetCachedCode(EventCode.InstrumentDiagnostics), instrument.SerialNumber, DateTime.Now.AddMonths(-1), DateTime.Now.AddMonths(-1), true, instrument.SoftwareVersion)); installedComponents.ForEach(installComp => eventJournals.Add(new EventJournal(EventCode.Calibration, installComp.Component.Uid, instrument.SerialNumber, DateTime.Now.AddMonths(-1), DateTime.Now.AddMonths(-1), true, installComp.Position, instrument.SoftwareVersion))); installedComponents.ForEach(installComp => eventJournals.Add(new EventJournal(EventCode.BumpTest, installComp.Component.Uid, instrument.SerialNumber, DateTime.Now.AddMonths(-1), DateTime.Now.AddMonths(-1), true, installComp.Position, instrument.SoftwareVersion))); List <Schedule> schedules = new List <Schedule>(); Schedule firmwareUpgrade = new ScheduledOnce(DomainModelConstant.NullId, DomainModelConstant.NullId, string.Empty, EventCode.GetCachedCode(EventCode.FirmwareUpgrade), dockingStation.Type.ToString(), null, true, DateTime.Now.AddYears(-1), new TimeSpan(9, 0, 0)); firmwareUpgrade.ScheduleProperties.Add(new ScheduleProperty(DomainModelConstant.NullId, ScheduleProperty.FirmwareUpgradeVersion, 0, "7.6.2.1")); schedules.Add(firmwareUpgrade); _scheduleUponDockingAccess.Setup(x => x.FindGlobalTypeSpecificSchedules(It.IsAny <string[]>(), It.IsAny <IDataAccessTransaction>())).Returns(schedules); _eventJournalDataAccess.Setup(x => x.FindBySerialNumbers(It.IsAny <string[]>(), It.IsAny <IDataAccessTransaction>())).Returns(eventJournals); _eventJournalDataAccess.Setup(x => x.FindLastEventByInstrumentSerialNumber(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <IDataAccessTransaction>())).Returns(eventJournals); _queueDataAccess.Setup(x => x.GetCount()).Returns(0); Initialize(); // act schema.Setup(x => x.Activated).Returns(true); schema.Setup(x => x.AccountNum).Returns("12345"); schema.Setup(x => x.ServiceCode).Returns("REPAIR"); controllerWrapper.Setup(x => x.FirmwareVersion).Returns("7.6.0.1"); CreateMasterForTest(); dsEvent = new NothingEvent(); nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is FirmwareUpgradeAction); }
public void GetInstrumentManualOperationsClearActionAsFollowUpActionForInstrumentManualOperationsDownloadToClearGasReponses() { // arrange InstrumentManualOperationsDownloadAction action = new InstrumentManualOperationsDownloadAction(); InstrumentManualOperationsDownloadOperation operation = new InstrumentManualOperationsDownloadOperation(action); InstrumentManualOperationsDownloadEvent dsEvent = new InstrumentManualOperationsDownloadEvent(operation); dsEvent.GasResponses.Add(new SensorGasResponse()); Initialize(); CreateMasterForTest(); // act nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is InstrumentManualOperationsClearAction); }
public void GetBadPumpTubingDetectedActionForCalibration() { // arrange InstrumentManualOperationsDownloadAction action = new InstrumentManualOperationsDownloadAction(); InstrumentManualOperationsDownloadOperation operation = new InstrumentManualOperationsDownloadOperation(action); dsEvent = new InstrumentManualOperationsDownloadEvent(operation); instrument = Helper.GetInstrumentForTest(DeviceType.VPRO, DeviceSubType.VentisPro4); Initialize(); switchService.Setup(x => x.BadPumpTubingDetectedDuringCal).Returns(true); CreateMasterForTest(); // act nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is BadPumpTubingDetectedAction); }
public void GetNextForcedAction() { // arrange SettingsReadOperation operation = new SettingsReadOperation(); dsEvent = new SettingsReadEvent(operation); instrument = Helper.GetInstrumentForTest(DeviceType.VPRO, DeviceSubType.VentisPro4); Initialize(); // ScheduledNow nowSched = new ScheduledNow(DomainModelConstant.NullId, DomainModelConstant.NullId, string.Empty, EventCode.GetCachedCode(EventCode.Calibration), null, null, true); CreateMasterForTest(); // act scheduler.ForceEvent(EventCode.Calibration, false); nextAction = scheduler.GetNextAction(dsEvent); // assert Xunit.Assert.True(nextAction is InstrumentCalibrationAction); }
/// <summary> /// Reports a docking station event to the server. /// </summary> /// <param name="dockingStationEvent"> /// The event to be reported /// </param> /// <returns> /// A docking station action indicating the next task /// the docking station should perform. /// </returns> public DockingStationAction ReportEvent(DockingStationEvent dsEvent) { if (dsEvent == null) { return(null); } if (dsEvent.DockingStation.SerialNumber == string.Empty) { return(null); } LogEventDetails(dsEvent); DockingStationAction dsAction = null; // We don't yet instantiate the Uploader instance. We wait until we know for sure // we're going to use it. Note that it's Disposed of in the finally block below. InetUploader inetUploader = null; try { try { // It's now finally safe to log the event. _eventProcessor.Save(dsEvent, Master.Instance.SwitchService.DockedTime); // These upload calls won't actually try and upload if we're not associated with any account. // or even if we DO have an account number, it won't upload if we're not activated on iNet. // Yet it WILL upload if we're in Service mode, regardless if activated or not. // Confusing, eh? inetUploader = new InetUploader(); inetUploader.UploadEvent(dsEvent, Configuration.DockingStation.TimeZoneInfo); if (dsEvent is InstrumentGasResponseEvent) { // Print automated bumps and cals new PrintManager().Print((InstrumentGasResponseEvent)dsEvent); } // Only save event to USB drive when in Cal Station mode and not Service mode if (!Configuration.Schema.Activated && !Configuration.ServiceMode) { if (dsEvent is InstrumentDatalogDownloadEvent) { // if the full datalog can not be saved to the USB drive an exception will // be thrown to make the docking station go unavailable; this is to prevent // the DS from erasing the datalog when it wasn't able to save it new CsvFileManager().Save((InstrumentDatalogDownloadEvent)dsEvent); } else if (dsEvent is InstrumentGasResponseEvent) { // only bumps and cals are saved new CsvFileManager().Save((InstrumentGasResponseEvent)dsEvent); } } ReportQueuedErrors(inetUploader); // See if docking station needs to take any special action for any of the event's errors. dsAction = ExamineErrors(dsEvent, inetUploader); if (dsAction != null) { Log.Debug(string.Format("{0}: ExamineErrors returned {1}", Name, dsAction.Name)); return(dsAction); } } catch (Exception e) { Log.Error(Name, e); dsAction = new UnavailableAction(e); // DO NOT report the error. If we have an error uploading, then it makes // no sense to try and upload and error notifying of a problem trying to upload. //ProcessNotificationAction( dsAction, inet ); return(dsAction); } try { // Determine if the event that just transpired requires a followed up RebootAction. dsAction = CheckRebootableEvent(dsEvent); if (dsAction == null) { // Before determining our next action, make sure we have the most up-to-date // schedules and eventjournals, etc., from iNet. ExchangeInetStatus(dsEvent); // Find out what we're supposed to do next. dsAction = Master.Scheduler.GetNextAction(dsEvent); if (dsAction is InstrumentAction) { InstrumentAction instAction = (InstrumentAction)dsAction; if (instAction is InstrumentGasAction) { // Get the resources from the resource manager. StringBuilder explanation = new StringBuilder(); List <string> consoleMessages = new List <string>(); // SGF 20-Feb-2013 INS-3821 List <string> errorCodes = new List <string>(); // SGF 20-Feb-2013 INS-3821 InstrumentGasAction gasAction = instAction as InstrumentGasAction; string eventCode = null; if (gasAction is InstrumentBumpTestAction) { eventCode = EventCode.BumpTest; } else if (gasAction is InstrumentCalibrationAction) { eventCode = EventCode.Calibration; } else { throw new ArgumentOutOfRangeException("Unrecognized GasAction: " + gasAction.GetType().ToString()); } // SGF 20-Feb-2013 INS-3821 // SGF 03-Nov-2010 Single Sensor Cal and Bump gasAction.GasEndPoints = Master.Instance.ResourceService.GetGasEndPoints(eventCode, gasAction, explanation, consoleMessages, errorCodes); if (gasAction.GasEndPoints.Count == 0) { Log.Warning(string.Format("No gases for {0}. {1}", eventCode, explanation.ToString())); // Maintain the empty cylinder error state resulting from forced actions by re-forcing the action Master.Instance.Scheduler.ReForceEvent(instAction); dsAction = new ResourceUnavailableAction(errorCodes, consoleMessages); // SGF 20-Feb-2013 INS-3821 } } // For instrument firmware upgrades, we don't want to allow the upgrade to take place // if there's no gas to both calibrate and bump the instrument. This is because at the // end of the upgrade, the VDS will automatically calibrate then bump test the instrument. if (instAction is InstrumentFirmwareUpgradeAction) { StringBuilder explanation = new StringBuilder(); List <string> consoleMessages = new List <string>(); // SGF 20-Feb-2013 INS-3821 List <string> errorCodes = new List <string>(); // SGF 20-Feb-2013 INS-3821 // SGF 20-Feb-2013 INS-3821 // SGF 03-Nov-2010 Single Sensor Cal and Bump if (Master.Instance.ResourceService.GetGasEndPoints(EventCode.Calibration, instAction, explanation, consoleMessages, errorCodes).Count == 0) { Log.Warning(string.Format("No gases for firmware upgrade {0}. {1}", EventCode.Calibration, explanation.ToString())); dsAction = new ResourceUnavailableAction(errorCodes, consoleMessages); // SGF 20-Feb-2013 INS-3821 } else { explanation = new StringBuilder(); consoleMessages.Clear(); // SGF 20-Feb-2013 INS-3821 errorCodes.Clear(); // SGF 20-Feb-2013 INS-3821 // SGF 20-Feb-2013 INS-3821 // SGF 03-Nov-2010 Single Sensor Cal and Bump if (Master.Instance.ResourceService.GetGasEndPoints(EventCode.BumpTest, instAction, explanation, consoleMessages, errorCodes).Count == 0) { Log.Warning(string.Format("No gases for firmware upgrade {0}. {1}", EventCode.BumpTest, explanation.ToString())); dsAction = new ResourceUnavailableAction(errorCodes, consoleMessages); // SGF 20-Feb-2013 INS-3821 } } } } } } // INS-8228 RHP v7.6 Log and report InstrumentSystemAlarmException thrown from Scheduler catch (InstrumentSystemAlarmException e) { Log.Error(Name, e); Master.ConsoleService.UpdateState(ConsoleState.InstrumentSystemAlarm); Master.ExecuterService.ReportExceptionError(e); } catch (Exception e) { Log.Error(Name, e); dsAction = new UnavailableAction(e); } // If the scheduler says there's currently nothing to do, then check // if we have an illegal cylinder or not. Report an unsupported cylinder if so. if (dsAction is NothingAction) { DockingStationAction cylinderAction = ExamineGasEndPoints(); if (cylinderAction != null) { dsAction = cylinderAction; } } // If the action we're about to return is telling the VDS to display an error message, // then we should tell iNet the error too. We pass in our Uploader instance to re-use the // socket which should give a couple seconds performance benefit. ProcessNotificationAction(dsAction, inetUploader); } finally { if (inetUploader != null) { inetUploader.Dispose(); } } return(dsAction); }
/// <summary> /// For certain 'actions' that the VDS decides to do, iNet needs to be /// notified of. e.g. failed Leak check, Unavailable Gas, etc. /// </summary> /// <param name="dsAction"></param> /// <param name="inetUploader">May be null. /// If null is passed, the method will instantiate an Inet object to use.</param> private void ProcessNotificationAction(DockingStationAction dsAction, InetUploader inetUploader) { // _lastNotificationError is the last CONSECUTIVE NotificationAction. // This the passed-in action is not a NotificationAction, then that // breaks the current series of consecutive NotificationActions. // So, we set it to null to denote that. if (!(dsAction is INotificationAction)) { _lastNotificationError = null; return; } const string funcMsg = "ProcessNotificationAction: "; StringBuilder errMsg = new StringBuilder(dsAction.Name); foreach (string m in dsAction.Messages) { errMsg.AppendFormat("\r\n{0}", m); } if (dsAction is UnsupportedCylinderAction) { errMsg.AppendFormat("\r\non Port {0}", ((UnsupportedCylinderAction)dsAction).GasEndPoint.Position); } // If it's an UnavailableAction, then the content of the error should // be the Exception's error (if there is an Exception). if ((dsAction is UnavailableAction) && (((UnavailableAction)dsAction).Exception != null)) { errMsg.AppendFormat("\r\n{0}", ((UnavailableAction)dsAction).Exception.ToString()); } DockingStationError dsError; //Suresh 02-Feb-2012 INS-2392 if (Master.SwitchService.Instrument == null) { dsError = new DockingStationError(errMsg.ToString()); } else { dsError = new DockingStationError(errMsg.ToString(), Master.SwitchService.Instrument.SerialNumber); } // If this NotificationError's detail is the exact same as the last NotificationError's // detail, then we assume it's a duplicate. We don't want to upload duplicates. if (_lastNotificationError != null && _lastNotificationError.Description == dsError.Description) { Log.Debug(string.Format("{0}Ignoring duplicate: {1}", funcMsg, dsAction.ToString())); return; } _lastNotificationError = dsError; // We upload the error immediately (don't just queue it to our "Errors" List). if (inetUploader != null) { Log.Debug(string.Format("{0}Uploading ", funcMsg, dsAction.Name)); inetUploader.UploadError(dsError, Configuration.DockingStation.TimeZoneInfo); } else { // if an uploader wasn't passed in to us to be re-used, then we need to create our own local one. using (InetUploader localUploader = new InetUploader()) { Log.Debug(string.Format("{0}Uploading {1}", funcMsg, dsAction.Name)); localUploader.UploadError(dsError, Configuration.DockingStation.TimeZoneInfo); } } }
internal List <GasEndPoint> GetGasEndPoints(string eventCode, DockingStationAction dsAction, StringBuilder explanation, List <string> explanationCodes, List <string> errorCodes) { Log.Debug(string.Format("{0}.GetGasEndPoints, {1}", Name, eventCode)); //explanationCodes.Clear(); //errorCodes.Clear(); // SGF 20-Feb-2013 INS-3821 ISC.iNet.DS.DomainModel.Instrument dockedInstrument = Master.Instance.SwitchService.Instrument; DockingStation dockingStation = Configuration.DockingStation; List <GasEndPoint> gasEndPoints = new List <GasEndPoint>(); foreach (InstalledComponent installedComponent in dockedInstrument.InstalledComponents) { if (!(installedComponent.Component is Sensor)) { continue; } Sensor sensor = (Sensor)installedComponent.Component; if (!sensor.Enabled) { Log.Info(string.Format("{0}: Ignoring disabled sensor {1}", Name, sensor.Uid)); continue; } // SGF 21-May-2012 INS-3078 -- Comment out the following if statement //if (!GasOperationsSupported(sensor)) //{ // Log.Debug( string.Format( "{0}.GasOperationsSupported returned False for sensor {1}. Ignoring sensor.", Name, sensor.SerialNumber ) ); // continue; //} if (sensor.CalibrationGas.Code.Length == 0) { throw new ApplicationException("Sensor " + sensor.Uid + " has null calibration gas code."); } // SGF 03-Nov-2010 Single Sensor Cal and Bump if (dsAction is InstrumentGasAction) { InstrumentGasAction gasAction = (InstrumentGasAction)dsAction; if (gasAction.ComponentCodes.Count != 0 && !gasAction.ComponentCodes.Contains(sensor.Type.Code)) { Log.Debug(string.Format("{0}: Component type {1} is not included in the defined list of components to test. Ignoring sensor.", Name, sensor.Type.Code)); continue; } } Log.Debug(string.Format("{0}: Looking for sensor {1}'s cal gas ({2})", Name, sensor.Uid, sensor.CalibrationGas.Code)); _empty = _expired = _gasFound = _freshFound = _zeroFound = false; _gasNeeded = true; // SGF 21-May-2012 INS-3078 // INS-8630 RHP v7.5 clear the messages for every installed component to avoid confusion explanationCodes.Clear(); errorCodes.Clear(); // SGF 20-Feb-2013 INS-3821 // Loop thru the cylinders for the docking station and if the cylinder contains the gas that // the sensor needs, add that cylinder as a gas end point in the docking station action. FindInstalledCylinderGases(eventCode, gasEndPoints, dockingStation, installedComponent, explanation, explanationCodes, errorCodes); if (!_freshFound && !_zeroFound) { // Present which type of air should be, but is not, available. If the port1 restrictions // only allow for zero air, present 'ZERO AIR'; otherwise, present 'FRESH AIR'. if (Configuration.DockingStation.Port1Restrictions == PortRestrictions.ZeroAir) { explanationCodes.Add("ZEROAIR"); errorCodes.Add(string.Format("{0} ({1})", "ZEROAIR", GasCode.O2)); // SGF 20-Feb-2013 INS-3821 } else if (Configuration.DockingStation.Port1Restrictions == PortRestrictions.FreshAir) { GasType gasType = GasType.Cache[GasCode.FreshAir]; if (gasType != null) { explanationCodes.Add(gasType.Symbol); errorCodes.Add(string.Format("{0} ({1})", gasType.Symbol, gasType.Code)); // SGF 20-Feb-2013 INS-3821 } } else // SGF 19-Jan-2012 INS-1913 & INS-1914 { // either fresh air or zero air is allowed; present which type is connected, if something is connected. GasEndPoint gasEndPoint = dockingStation.GasEndPoints[0]; Cylinder cyl = gasEndPoint.Cylinder; if (cyl.IsZeroAir) { explanationCodes.Add("ZEROAIR"); errorCodes.Add(string.Format("{0} ({1})", "ZEROAIR", GasCode.O2)); // SGF 20-Feb-2013 INS-3821 } else //suresh 14-Mar-2012 INS-4427 (DEV) { // If port 1 cylinder is not Zero Air then we report that 'Fresh air' is unavailable GasType gasType = GasType.Cache[GasCode.FreshAir]; if (gasType != null) { explanationCodes.Add(gasType.Symbol); errorCodes.Add(string.Format("{0} ({1})", gasType.Symbol, gasType.Code)); // SGF 20-Feb-2013 INS-3821 } } } if (_expired) { explanationCodes.Add("Expired"); errorCodes.Add("Expired"); // INS-8630 RHP v7.5 - Notify iNet on the expired state } else if (_empty) { explanationCodes.Add(PressureLevel.Empty.ToString()); errorCodes.Add(PressureLevel.Empty.ToString()); // INS-8630 RHP v7.5 - Notify iNet on the empty state } explanation.Append("Fresh air not found for sensor " + sensor.Uid + '\n'); Log.Debug(string.Format("{0}: Returning nothing: gasFound={1}, freshFound={2}, expired={3}, empty={4}", Name, _gasFound, _freshFound, _expired, _empty)); return(new List <GasEndPoint>()); } if (_gasNeeded && !_gasFound) // SGF 21-May-2012 INS-3078 -- add the '_gasNeeded' clause to the if-condition { // If gas not found, IDS needs the symbol for that gas for display on its LCD. // Look it up in our cache. For Fresh Air, we just return the gas code; // The IDS knows to look for that as a special case. if (sensor.CalibrationGas.Code == GasCode.FreshAir) { GasType gasType = GasType.Cache[GasCode.FreshAir]; if (gasType != null) { explanationCodes.Add(gasType.Symbol); errorCodes.Add(string.Format("{0} ({1})", gasType.Symbol, gasType.Code)); // SGF 20-Feb-2013 INS-3821 } } // DSW-1758 RHP v9.6.1 - Added (! (_expired || _empty) ) since gas symbol has already been added to explanationCodes for Empty/Expired states. else if (!(_expired || _empty)) { // If we're doing a bump test, and this is a combustible sensor either in LEL or PPM mode, // and docking station has a CombustibleBumpTestGas setting, then make sure we report that the // gas type not found is the CombustibleBumpTestGas and not the sensor cal gas. string sensorGasCode = sensor.CalibrationGas.Code; if ((eventCode == EventCode.BumpTest) && (sensor.Type.Code == SensorCode.CombustibleLEL || sensor.Type.Code == SensorCode.CombustiblePPM) && (Configuration.DockingStation.CombustibleBumpTestGas.Length > 0)) { sensorGasCode = Configuration.DockingStation.CombustibleBumpTestGas; } GasType gasType = GasType.Cache[sensorGasCode]; if (gasType != null) { explanationCodes.Add(gasType.Symbol); errorCodes.Add(string.Format("{0} ({1})", gasType.Symbol, gasType.Code)); // SGF 20-Feb-2013 INS-3821 } } if (_expired) { explanationCodes.Add("Expired"); errorCodes.Add("Expired"); // INS-8630 RHP v7.5 - Notify iNet on the expired state } else if (_empty) { explanationCodes.Add(PressureLevel.Empty.ToString()); errorCodes.Add(PressureLevel.Empty.ToString()); // INS-8630 RHP v7.5 - Notify iNet on the empty state } explanation.Append("Could not find cylinder needed for sensor " + sensor.Uid + ", CalGasCode=\"" + sensor.CalibrationGas.Code + "\" ("); for (int i = 0; i < explanationCodes.Count; i++) { if (i > 0) { explanation.Append(" "); } explanation.Append(explanationCodes[i]); } explanation.Append(")\n"); Log.Debug(string.Format("{0}: Returning nothing: gasFound={1}, freshFound={2}, expired={3}, empty={4}", Name, _gasFound, _freshFound, _expired, _empty)); return(new List <GasEndPoint>()); } // Zero air is required for CO2 sensors; Only zero air is used to zero CO2, never fresh air. if ((sensor.CalibrationGas.Code == GasCode.CO2) && !_zeroFound) { GasType gasType = GasType.Cache[GasCode.O2]; if (gasType != null) { explanationCodes.Add("ZEROAIR"); // SGF 5-Feb-2013 INS-3837 errorCodes.Add(string.Format("{0} ({1})", "ZEROAIR", GasCode.O2)); // SGF 20-Feb-2013 INS-3821 } if (_expired) { explanationCodes.Add("Expired"); } else if (_empty) { explanationCodes.Add(PressureLevel.Empty.ToString()); } explanation.Append("Zero air not found for CO2 sensor " + sensor.Uid + '\n'); Log.Debug(string.Format("{0}: Returning nothing: gasFound={1}, freshFound={2}, expired={3}, empty={4}", Name, _gasFound, _freshFound, _expired, _empty)); return(new List <GasEndPoint>());; } } Log.Debug(string.Format("{0}.GetGasEndPoints returned {1} gas end points", Name, gasEndPoints.Count)); return(gasEndPoints); }