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);
        }
        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 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 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 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);
        }
Esempio n. 8
0
        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 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);
        }
Esempio n. 11
0
        /// <summary>
        /// Returns a RebootAction if the passed in event is IRebootableEvent
        /// and its RebootRequired is true.
        /// </summary>
        /// <param name="dsEvent"></param>
        /// <returns></returns>
        private DockingStationAction CheckRebootableEvent(DockingStationEvent dsEvent)
        {
            if (!(dsEvent is IRebootableEvent))
            {
                return(null);
            }

            if (((IRebootableEvent)dsEvent).RebootRequired)
            {
                Log.Info(string.Format("\"{0}\" requires a reboot!", dsEvent));
                return(new RebootAction());
            }

            Log.Info(string.Format("\"{0}\" does not require a reboot.", dsEvent));
            return(null);
        }
        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 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 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 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 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 InstrumentInSystemAlarm()
        {
            // arrange
            SettingsReadOperation operation = new SettingsReadOperation();

            dsEvent        = new SettingsReadEvent(operation);
            instrument     = Helper.GetInstrumentForTest(DeviceType.VPRO, DeviceSubType.VentisPro4);
            dockingStation = Helper.GetDockingStationForTest(DeviceType.MX4);
            Initialize();

            Configuration.DockingStation = dockingStation;

            switchService.Setup(x => x.IsInstrumentInSystemAlarm).Returns(true);

            CreateMasterForTest();

            // act and assert
            Xunit.Assert.Throws <InstrumentSystemAlarmException>(() => scheduler.GetNextAction(dsEvent));
        }
        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);
        }
Esempio n. 21
0
        /// <summary>
        /// Logs the event's formatted Details string.
        /// </summary>
        /// <param name="dsEvent"></param>
        private void LogEventDetails(DockingStationEvent dsEvent)
        {
            // Keep the cached instrument info up to date.
            //if ( dsEvent is InstrumentSettingsReadEvent )
            //    SwitchService.DockedInstrument = (Instrument)( (InstrumentSettingsReadEvent)dsEvent ).DockedInstrument.Clone();

            // Parse out details so we can send to debug port below
            string[] details = dsEvent.Details.Split(new char[] { '\n' });

            Log.Debug(string.Format("{0}.Report uploading Event \"{1}\")", Name, dsEvent));
            foreach (DockingStationError err in dsEvent.Errors)
            {
                Log.Debug(string.Format("{0}.Report attaching queued Error to event: \"{1}\"", Name, err.Description));
            }

            foreach (string detail in details)
            {
                Log.Debug(detail);
            }
        }
        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);
        }
Esempio n. 23
0
        private void ExchangeInetStatus(DockingStationEvent dsEvent)
        {
            if (Configuration.DockingStation.SerialNumber == string.Empty)   // not serialized for some reason?
            {
                return;
            }

            // SGF  18-Feb-2013  INS-3824
            // In order to improve performance when processing a number of operations on instruments,
            // we will now limit the exchange status downloads so that they are performed as part of the
            // heart beats.  This will prevent the repeated downloads that occur when several operations
            // are performed in sequence after an instrument has been docked.
            if (!(dsEvent is InstrumentNothingEvent || dsEvent is NothingEvent))
            {
                Log.Debug(string.Format("\"{0}\" does not require an exchange status download.", dsEvent));
                return;
            }
            else
            {
                Log.Debug(string.Format("Exchange status download will be performed for \"{0}\".", dsEvent));
            }

            // Need to tell iNet what the current state of the docking station.
            string dsStatus = Master.Instance.ConsoleService.CurrentState.ToString();

            ExchangeStatusEvent exchangeStatusEvent = new ExchangeStatusOperation(dsStatus, true).Execute() as ExchangeStatusEvent;

            // If the exchangeStatus operation encountered any errors with the data returned by iNet,
            // then make sure we inform iNet of those errors.
            foreach (DockingStationError error in exchangeStatusEvent.Errors)
            {
                ReportError(error);
            }

            return;
        }
Esempio n. 24
0
        /// <summary>
        /// Get instrument settings off of the docked instrument.
        /// </summary>
        private ISC.iNet.DS.DomainModel.Instrument ReadDockedInstrument()
        {
            DockingStationEvent dsEvent = null;

            try
            {
                dsEvent = new DiscoveryOperation().Execute();
            }
            catch ( HardwareConfigurationException )
            {
                // For docking station with cradle lids, we may get this exception when the docking station hardware is 
                // not configured properly.  Request the user to reconfigure the cradle, then we try to discover again.
                if ( IsDiffusionLidProperlyPositioned() )
                    dsEvent = new DiscoveryOperation().Execute();
            }
            catch ( Exception e )
            {
                Log.Error( e.ToString() );
                dsEvent = null;
            }

            // InstrumentNothingEvent won't be returned by DiscoveryOperation if nothing is docked
            return ( dsEvent is InstrumentNothingEvent ) ? ( (InstrumentNothingEvent)dsEvent ).DockedInstrument : null;
        }
Esempio n. 25
0
        private bool SaveEventJournals(DockingStationEvent dsEvent, DateTime lastDockedTime, DataAccessTransaction trx)
        {
            if (dsEvent.EventCode == null)
            {
                return(true);
            }

            EventJournalDataAccess ejDataAccess = new EventJournalDataAccess();

            EventJournal eventJournal = null;

            // If the event implements IPassed, then use the result of its
            // Passed property.  Otherwise, just default to true.
            bool passed = ((dsEvent is IPassed)) ? ((IPassed)dsEvent).Passed : true;

            if (dsEvent is InstrumentEvent)
            {
                // special case for // bump & cals... need to save a separate
                // event journal for every sensor involved in gas operation.
                // Note that in this situation, we also do NOT save an entry for the instrument itself.
                if (dsEvent is InstrumentGasResponseEvent && !(dsEvent is InstrumentManualOperationsDownloadEvent))
                {
                    InstrumentGasResponseEvent gasResponseTestEvent = (InstrumentGasResponseEvent)dsEvent;
                    if (gasResponseTestEvent.GasResponses.Count <= 0)
                    {
                        return(true);
                    }

                    bool allSaved = true;
                    foreach (SensorGasResponse sgr in gasResponseTestEvent.GasResponses)
                    {
                        eventJournal = new EventJournal(gasResponseTestEvent.EventCode.Code, sgr.Uid,
                                                        gasResponseTestEvent.DockedInstrument.SerialNumber,
                                                        sgr.Time, dsEvent.Time, sgr.Passed,
                                                        sgr.Position, gasResponseTestEvent.DockedInstrument.SoftwareVersion);
                        allSaved &= ejDataAccess.Save(eventJournal, trx);
                    }
                    // If gasResponseEvent is a InstrumentBumpTestEvent, it might have calibration gas responses due to O2 high bump test failure.
                    // If there are any gas responses in HighBumpFailCalGasResponses, store them to the event journals.
                    foreach (SensorGasResponse sgr in gasResponseTestEvent.HighBumpFailCalGasResponses)
                    {
                        eventJournal = new EventJournal(EventCode.Calibration, sgr.Uid,
                                                        gasResponseTestEvent.DockedInstrument.SerialNumber,
                                                        sgr.Time, dsEvent.Time, sgr.Passed,
                                                        sgr.Position, gasResponseTestEvent.DockedInstrument.SoftwareVersion);
                        allSaved &= ejDataAccess.Save(eventJournal, trx);
                    }
                    return(allSaved);
                }
                else
                {
                    eventJournal = new EventJournal(dsEvent.EventCode, ((InstrumentEvent)dsEvent).DockedInstrument.SerialNumber, dsEvent.Time, dsEvent.Time, passed, ((InstrumentEvent)dsEvent).DockedInstrument.SoftwareVersion);
                }
            }
            else // DockingStationEvent
            {
                eventJournal = new EventJournal(dsEvent.EventCode, dsEvent.DockingStation.SerialNumber, dsEvent.Time, dsEvent.Time, passed, dsEvent.DockingStation.SoftwareVersion);
            }

            return(ejDataAccess.Save(eventJournal, trx));  // Update/insert EventJournal record for the event.
        }
Esempio n. 26
0
        /// <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);
        }
Esempio n. 27
0
        /// <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);
        }
Esempio n. 28
0
        /// <summary>
        /// This method implements the thread start for this service.
        /// </summary>
        protected override void Run()
        {
            try
            {
                bool activated    = Configuration.Schema.Activated;
                bool synchronized = Configuration.Schema.Synchronized;

                //Suresh 13-APR-2012 INS-4519 (DEV JIRA)
                //If the docking station is Initialized and Activated, but not Synchronized then set the console state to Synchronization.
                //Note: We cannot do this after Discover() method, because ExecuterService.Discover() method and
                //ExecuterService.Run( ExchangeStatusOperation ) method runs on mutual-exclusion lock and that causes "Synchronization" state not to be changed
                //until ExchangeStatusOperation completely finishes but by that time Synchronization will be completed.
                if ((_initialized == true) && (activated == true || Configuration.ServiceMode) && (synchronized == false))
                {
                    bool online = Inet.IsOnline;

                    Log.Trace("Schema is not synced with iNet. Connected=" + online);

                    // We don't bother getting the current state (which does a 'lock') until we know AllSynced is false.
                    ConsoleState state = Master.ConsoleService.CurrentState;

                    if (state == ConsoleState.Ready ||
                        state == ConsoleState.Discovering ||
                        state == ConsoleState.Synchronization ||
                        state == ConsoleState.SynchronizationError)
                    {
                        Master.ConsoleService.UpdateState(online ? ConsoleState.Synchronization : ConsoleState.SynchronizationError);
                    }
                }

                // Anytime an account number or activation changes, we need to do a re-discover and force another settings.
                // This is due to database being reset due to the account change, and the new database will no longer
                // have info regarding currenly attached cylinders.
                string curAccountNum = Configuration.Schema.AccountNum;
                if ((_wasAccountNum != curAccountNum) || (_wasActivated != activated))
                {
                    if (_wasAccountNum != curAccountNum)
                    {
                        Log.Info(string.Format("{0} detected changed Account. Old=\"{1}\", New=\"{2}\"", Name, _wasAccountNum, curAccountNum));
                    }

                    if (_wasActivated != activated)
                    {
                        Log.Info(string.Format("{0} detected changed Activation. Old=\"{1}\", New=\"{2}\"", Name, _wasActivated, activated));
                    }

                    _wasAccountNum = curAccountNum;
                    _wasActivated  = activated;

                    Log.Debug(string.Format("{0} initiating Discovery (account/activation changed).", Name));

                    Master.ExecuterService.Discover();
                    _initialized = true;

                    InitialReadSettingsNeeded = ReadSettingsNeeded = ReadAllCards = true; // need to do a full readsettings

                    return;                                                               // Simply return. Yes, we need to perform a ReadSettings, but it'll happen the next time Run is called.
                }

                // Special handling for docking stations in manufacturing accounts...
                if (Configuration.Schema.IsManufacturing)
                {
                    // If activated (not a Cal Station), and not online, then
                    // display error message saying that it needs to be online.
                    if (Configuration.Schema.Activated && !Inet.IsOnline)
                    {
                        Master.ConsoleService.UpdateState(ConsoleState.MfgNotConnected);
                        return;
                    }

                    ConsoleState state = Master.ConsoleService.CurrentState;

                    if (state == ConsoleState.MfgNotConnected)
                    {
                        Master.ConsoleService.UpdateState(ConsoleState.MfgConnected);
                    }

                    else if (state == ConsoleState.MfgConnected)
                    {
                        Master.ConsoleService.UpdateState(ConsoleState.Ready);
                    }
                }

                // Until we find out that we've successfully connected to iNet
                // in order to obtain an account number, factory cylinder info, etc.,
                // don't do anything more than a one-time Discover.  The initial Discover
                // is also needed in order to jump start the ExecuterService's thread into
                // doing something. (It won't do anything on bootup as it's 'next action' is null.)
                if (!synchronized)
                {
                    if (!_initialized)
                    {
                        Log.Debug(string.Format("{0} initiating initial Discovery (unsynchronized).", Name));

                        DockingStationEvent dsEvent = Master.ExecuterService.Discover();
                        Controller.LogDockingStation(dsEvent.DockingStation);
                        _initialized = true;

                        InitialReadSettingsNeeded = ReadSettingsNeeded = ReadAllCards = true; // need to do a full readsettings
                    }
                    return;                                                                   // Simply return. Yes, we might need to perform a ReadSettings but, if needed, it'll happen the next time Run is called.
                }

                // Force a Discovery if we're just booting up.
                if (!_initialized)
                {
                    Log.Debug(string.Format("{0} initiating initial Discovery.", Name));
                    DockingStationEvent dsEvent = Master.ExecuterService.Discover();
                    Controller.LogDockingStation(dsEvent.DockingStation);
                    _initialized = true;
                    return;
                }

                // Check if instrument has been docked or undocked and force a Discovery if something has been docked or undocked.
                if (!Master.Instance.SwitchService.InitialReadSettingsNeeded && CheckDockedStatus())
                {
                    Log.Debug(string.Format("{0} initiating Discovery.", Name));
                    Master.ExecuterService.Discover();
                    _initialized = true;
                    return;
                }

                // Check card readers for card insertions / removals, and for pressure
                // switch changes.  If any card or pressure switch changes detected,
                // then we need to force a Settings Read.
                ReadSettingsNeeded = CheckIgasPorts() || ReadSettingsNeeded;

                // When we first start up, we always want to perform a settings read operation,
                // and send the information to the server.
                if (ReadSettingsNeeded)
                {
                    ReadSettings(ReadAllCards);
                    ReadSettingsNeeded = ReadAllCards = false;
                }

                _lastCaughtException = null;                      // no error encountered on this iteration of Run(), so clear the last caught error.
            }
            catch (InstrumentSystemAlarmException systemalarmmex) // SGF  Nov-23-2009  DSW-355  (DS2 v7.6)
            {
                Master.ConsoleService.UpdateState(ConsoleState.InstrumentSystemAlarm);
                //Suresh 06-FEB-2012 INS-2622
                Master.ExecuterService.ReportExceptionError(systemalarmmex);   //Suresh 15-SEPTEMBER-2011 INS-1593
            }
            catch (HardwareConfigurationException hce)
            {
                // Set docked flag to false.  Otherwise, if user just reconfigures the hardware on the
                // docking station without redocking the instrument, the IDS will think that it's already
                // docked and won't want to do a discover.
                _wasDocked = false;
                Master.ConsoleService.UpdateState(ConsoleService.MapHardwareConfigError(hce));
            }
            catch (Exception e)
            {
                Log.Error(Name, e);

                // If the menu is currently active, then we don't want to interrupt what the user is doing for an error
                // that will likely be hit again in a few seconds and can be displayed when the menu is not active.
                // Viewing the Cylinders menu screen could be helpful for troubleshooting smart card issues.
                // The first DeviceDriverException should be uploaded to iNet.
                if (e is DeviceDriverException && Master.Instance.ConsoleService.CurrentState != ConsoleState.Menu)
                {
                    // DeviceDriverExceptions that the SwitchService can encounter will be from checking smart card presence,
                    // pressure switch presence, or pressure switch state.
                    if (((DeviceDriverException)e).DeviceHardware == DeviceHardware.SmartCardPresence)
                    {
                        Master.Instance.ConsoleService.UpdateState(ConsoleState.IGasError, ConsoleServiceResources.IGASERROR_SMARTCARDS);
                    }
                    else
                    {
                        Master.Instance.ConsoleService.UpdateState(ConsoleState.IGasError, ConsoleServiceResources.IGASERROR_PRESSURESWITCHES);
                    }

                    // Give the ConsoleService time to display the error state.
                    Thread.Sleep(3000);
                }

                // don't upload CommunicationAbortedException or InstrumentNotDockedException to iNet
                if (e is CommunicationAbortedException || e is InstrumentNotDockedException)
                {
                    Master.Instance.ConsoleService.UpdateState(ConsoleState.UndockedInstrument);
                    Thread.Sleep(3000);
                    _wasDocked = false;
                    // A heartbeat is called to get the executer service to update the LCD screen (to go idle)
                    // in case the instrument remains undocked.
                    Master.ExecuterService.HeartBeat();
                }
                // Whenever we catch an exception, report it to iNet, but only if it's not
                // the same as the last error - to prevent a problem where we repeatedly get,
                // say, a device driver exception trying to check smart cards or pressure switches.
                // In that situation, we don't want to upload the error continuously to iNet.
                else if (_lastCaughtException == null || _lastCaughtException.GetType() != e.GetType())
                {
                    Master.ReporterService.ReportError(new DockingStationError(e, DockingStationErrorLevel.Warning));
                    Master.ExecuterService.HeartBeat(); //	Perform one heartbeat to force the error to upload asap.
                    _lastCaughtException = e;
                }
            }
        }
Esempio n. 29
0
        /// <summary>
        /// Saves/updates in the database whatever needs to be saved/updated based
        /// on the results of the passed-in event.
        /// Includes saving the event, updating installed cylinders, deleting ScheduledOnces.
        /// </summary>
        /// <param name="dsEvent"></param>
        /// <param name="lastDockedTime"></param>
        internal void Save(DockingStationEvent dsEvent, DateTime lastDockedTime)
        {
            // We don't want to start a transaction unless we know we're going to update
            // the database, since merely just beginning a writable transaction causes a write.
            // Not every event type will have a code.  For those that don't, we don't
            // need the last run time saved (such as Nothing events or interactive diagnostics)
            if (dsEvent.EventCode == null)
            {
                return;
            }

            // Save event journals and installed cylinder updates all in a single transaction.
            // If this event was invoked by a run-once schedule, then that schedule is also
            // deleted in the same transaction.
            using (DataAccessTransaction trx = new DataAccessTransaction())
            {
                // Save/update EventJournals for the event.
                bool saved = SaveEventJournals(dsEvent, lastDockedTime, trx);

                Log.Debug(string.Format("SaveEventJournals({0})={1}", dsEvent, saved));

                // If this event was invoked by a run-once schedule, then delete the schedule
                // since, by definition, "run once" schedules are run once, then deleted.
                if ((dsEvent.Schedule != null) && (dsEvent.Schedule is ScheduledOnce))
                {
                    bool deleted = new ScheduledOnceDataAccess().DeleteById(dsEvent.Schedule.Id, trx);
                    Log.Debug(string.Format("ScheduledOnceDataAccess.Delete({0})={1}", dsEvent.Schedule.Id, deleted));
                }

                // If event is a SettingsRead, then SaveGasEndPoints will update the GasEndPoints
                // in the database based on what what cylinders the SettingsRead found attached to
                // the docking station.
                if (dsEvent is SettingsReadEvent)
                {
                    SaveGasEndPoints((SettingsReadEvent)dsEvent, trx);

                    // If this is a SettingsReadEvent, reload the GasEndPoints from the database
                    // now that  they've been saved and cache them in our global dockingstation.
                    // This also has the side effect of setting ech of their 'Supported' properties
                    // to null which will force a revalidation of their part numbers against the
                    // known FactoryCylinder part numbers.
                    Configuration.DockingStation.GasEndPoints = new GasEndPointDataAccess().FindAll(trx);
                }
                else if (dsEvent is InstrumentSettingsReadEvent)
                {
                    // If this is a InstrumentSettingsReadEvent, then refresh the switch'service's
                    // docked instrument information with the information from the event.
                    // If we don't do this, then the switch service's information can become out of
                    // date after Instrument Settings Updates are performed, or instrument firmware
                    // is updated, etc.
                    //
                    // TODO: the following is probably not necessary anymore do to changes made for INS-3825.
                    // InstrumentSettingsRead operation is now just returning a clone of SwitchService.Instrument.
                    // So setting the SwitchService.Instrument to be a clone of what InstrumentSettingsRead
                    // returned is pretty much just setting it to a clone of an exact copy of itself.
                    // -- JMP, 2/13/2013.
                    Master.Instance.SwitchService.Instrument = (DomainModel.Instrument)((InstrumentSettingsReadEvent)dsEvent).DockedInstrument.Clone();

                    //Suresh 05-JAN-2012 INS-2564
                    //During instrument setting read if we find any sensor in error state then we want to report it to iNet
                    Master.Instance.ExecuterService.ReportDiscoveredInstrumentErrors((InstrumentEvent)dsEvent);
                }
                else if ((dsEvent is InstrumentCalibrationEvent) &&
                         (Master.Instance.SwitchService.Instrument.SerialNumber != string.Empty)) // can this happen here?
                {
                    // Keep the Sensors in the cached instrument object updated with the status
                    // of what happened during the calibration, for use by the scheduler.

                    bool            cylinderHoseProblem   = false;
                    UsedGasEndPoint gasEndPointUsedForCal = null;       // INS-8446 RHP v7.6

                    foreach (SensorGasResponse sgr in (dsEvent as InstrumentCalibrationEvent).GasResponses)
                    {
                        // If any sensor failed calibration with a zero span reserve, then set the SwitchService's CylinderHoseProblem to true.
                        // We don't do this for O2 sensors, though, as a O2 calibration failure with a zero span reserve would not indicate a
                        // a problem with the hoses. - INS-1279, 6/20/2011, JMP // INETQA-4131 RHP v7.6 - Added Status.Failed condition check below.
                        if (sgr.SensorCode != SensorCode.O2 && (sgr.Status == Status.SpanFailed || sgr.Status == Status.SpanFailedZeroFailed || sgr.Status == Status.Failed) &&
                            sgr.FullSpanReserve == 0.0)
                        {
                            cylinderHoseProblem = true;
                            // INS-8446 RHP v7.6 - Save the Cylinder details which is expected to have hose problems.
                            // Do a NULL to ensure that we identify the first gas response that failed a calibration with Zero Span reserve and fetch its gas end point being used.
                            if (gasEndPointUsedForCal == null)
                            {
                                gasEndPointUsedForCal = sgr.UsedGasEndPoints.Find(uge => uge.Usage == CylinderUsage.Calibration && !uge.Cylinder.IsFreshAir && !uge.Cylinder.IsZeroAir);
                            }
                        }

                        Sensor sensor = (Sensor)Master.Instance.SwitchService.Instrument.InstalledComponents.Find(ic => ic.Component.Uid == sgr.Uid).Component;
                        if (sensor != null)
                        {
                            sensor.CalibrationStatus = sgr.Status;
                        }
                    }

                    //Suresh 22-Feb-2012 INS-2705
                    //After calibration is completed , we need to update sensor bump test status because in scheduler we have logic
                    //to force calibration based on sensor BumpTestStatus
                    foreach (InstalledComponent installedComponent in (dsEvent as InstrumentCalibrationEvent).DockedInstrument.InstalledComponents)
                    {
                        if (!(installedComponent.Component is Sensor))  // Skip non-sensors.
                        {
                            continue;
                        }

                        if (!installedComponent.Component.Enabled) // Skip disabled sensors.
                        {
                            continue;
                        }

                        Sensor bumpTestedSensor = (Sensor)installedComponent.Component;

                        Sensor sensor = (Sensor)Master.Instance.SwitchService.Instrument.InstalledComponents.Find(ic => ic.Component.Uid == bumpTestedSensor.Uid).Component;
                        if (sensor != null)
                        {
                            sensor.BumpTestStatus = bumpTestedSensor.BumpTestStatus;
                        }
                    }

                    // If at least one sensor had a status of InstrumentAborted, then we know the instrument reset.
                    // The check cylinders message should not be shown on the LCD.
                    foreach (SensorGasResponse sgr in (dsEvent as InstrumentCalibrationEvent).GasResponses)
                    {
                        if (sgr.Status == Status.InstrumentAborted)
                        {
                            cylinderHoseProblem   = false;
                            gasEndPointUsedForCal = null;
                            break;
                        }
                    }

                    Master.Instance.SwitchService.BadGasHookup = cylinderHoseProblem;
                    // INS-8446 RHP v7.6 - Set the SwitchService's BadGasHookUpCylinderPartNumber which is expected to have hose problems to display the same on LCD
                    Master.Instance.SwitchService.BadGasHookUpCylinderPartNumber = gasEndPointUsedForCal == null ? string.Empty : gasEndPointUsedForCal.Cylinder.PartNumber;
                    Log.Debug(string.Format("EventProcessor : BadGasHookUpCylinderPartNumber identified cylinder with Part Number {0}", Master.Instance.SwitchService.BadGasHookUpCylinderPartNumber));
                }
                //Suresh 22-Feb-2012 INS-2705
                else if ((dsEvent is InstrumentBumpTestEvent) &&
                         (Master.Instance.SwitchService.Instrument.SerialNumber != string.Empty)) // can this happen here?
                {
                    // Keep the Sensors in the cached instrument object updated with the status
                    // of what happened during the bumptest, for use by the scheduler.

                    foreach (InstalledComponent installedComponent in (dsEvent as InstrumentBumpTestEvent).DockedInstrument.InstalledComponents)
                    {
                        if (!(installedComponent.Component is Sensor))  // Skip non-sensors.
                        {
                            continue;
                        }

                        if (!installedComponent.Component.Enabled) // Skip disabled sensors.
                        {
                            continue;
                        }

                        Sensor bumpTestedSensor = (Sensor)installedComponent.Component;

                        Sensor sensor = (Sensor)Master.Instance.SwitchService.Instrument.InstalledComponents.Find(ic => ic.Component.Uid == bumpTestedSensor.Uid).Component;
                        if (sensor != null)
                        {
                            sensor.BumpTestStatus = bumpTestedSensor.BumpTestStatus;
                        }
                    }
                }

                trx.Commit();
            }
        }