Esempio n. 1
0
        public void DockingStation_DockBike_ShouldAddABikeToTheBikeStore()
        {
            var bike           = new Bike();
            var dockingStation = new DockingStation(5);

            dockingStation.DockBike(bike, 0);

            Assert.Equal(dockingStation.BikeStore[0], bike);

            dockingStation.BikeStore[0].Should().Equals(bike);
        }
        public bool Save(DockingStation ds, DataAccessTransaction trx)
        {
            // First try and update.  If that fails, then it's likely because
            // the record doesn't already exist.  So then try and insert.
            if (Update(ds, trx))
            {
                return(true);
            }

            return(Insert(ds, trx));
        }
Esempio n. 3
0
        public void DockingStation_DockBike_ShouldThrowException_WhenThereIsNoSpaceInTheDockingStation()
        {
            var bike           = new Bike();
            var dockingStation = new DockingStation(0);

            Assert.Throws <Exception>(() => dockingStation.DockBike(bike, 0));

            Action action = () => dockingStation.DockBike(bike, 0);

            action.Should().Throw <Exception>().WithMessage("No space exists");
        }
Esempio n. 4
0
        internal static Mock <ControllerWrapper> GetControllerMock(DockingStation dockingStation, Instrument instrument)
        {
            Mock <ControllerWrapper> controllerWrapper = new Mock <ControllerWrapper>();

            controllerWrapper.Setup(x => x.GetDockingStation()).Returns(dockingStation);
            controllerWrapper.Setup(x => x.IsDocked()).Returns(instrument != null);
            controllerWrapper.Setup(x => x.IsUsbDriveAttached(It.IsAny <string>())).Returns(true);
            controllerWrapper.Setup(x => x.Round(It.IsAny <double>(), It.IsAny <int>())).Returns <double, int>((value, resolution) => Math.Round(value, resolution));
            controllerWrapper.Setup(x => x.GetKeyPress()).Returns(new KeyPress(Key.Left, new TimeSpan(0, 0, 5)));

            return(controllerWrapper);
        }
Esempio n. 5
0
        internal static Master GetMasterForTest(DockingStation dockingStation = null, Instrument instrument = null, bool isCal = true)
        {
            Master master = Master.CreateMaster();

            master.SwitchService     = MockHelper.GetSwitchServiceMock(instrument, isCal).Object;
            master.ConsoleService    = MockHelper.GetConsoleServiceMock().Object;
            master.ExecuterService   = MockHelper.GetExecuterServiceMock().Object;
            master.ControllerWrapper = MockHelper.GetControllerMock(dockingStation, instrument).Object;
            master.Scheduler         = MockHelper.GetSchedulerMock().Object;
            master.PumpWrapper       = MockHelper.GetPumpMock().Object;

            return(master);
        }
Esempio n. 6
0
        public void VanPickUp_PickupBrokenBikes_AddToVanDock()
        {
            var brokenBike = new Bike();

            brokenBike.IsBroken();
            var dockingStation = new DockingStation();

            dockingStation.DockBike(brokenBike);
            var van = new Van();

            van.PickupBikeForRepair(dockingStation);
            Assert.AreEqual(1, van.bikeDock.Count);
        }
Esempio n. 7
0
        public void VanReleaseBrokenBike_ReleaseBrokenBikes_RemoveFromVanDock()
        {
            var brokenBike = new Bike();

            brokenBike.IsBroken();
            var dockingStation = new DockingStation();

            dockingStation.DockBike(brokenBike);
            var van = new Van();

            van.PickupBikeForRepair(dockingStation);
            Assert.IsInstanceOf(typeof(Bike), van.ReleaseBikeForRepair());
        }
        /// <summary>
        /// Retrieve the docking station's information.
        /// </summary>
        /// <returns>A new instance of a populated docking station.
        /// The caller may do what they wish with it.</returns>
        static public DockingStation GetDockingStation(bool[] changedSmartCards)
        {
            DockingStation dockingStation = Controller.GetDockingStation();

            // Don't go any further if we're not serialized. If we're not serialized,
            // the device's clock may not even be synchronized with iNet yet, so
            // calling GetCylinders would be a bad thing to do since
            // it assigns InstallTime to whatever cylinders it detects.
            if (dockingStation.SerialNumber == string.Empty)
            {
                Log.Warning("GetDockingStation not calling GetCylinders due to unserialized device.");
                return(dockingStation);
            }

            // INS-3800 - need to tell iNet whether the DNS address were provided by user (i.e. via configurator)
            // or provided by the DHCP server. The only way to really tell is see if the user configuration ("boot vars")
            // matches the network adapter's current settings. If not, then assume DHCP server provided the DNS addresses.
            // *** Configuration.Dockingstation's network settings will have the values that are saved in the "bootbars" (i.e., configured by the user).
            // *** Controller.Dockingstation's network settings are the settings that are actually in effect on the NIC.
            // What is configured will often differ from what is actually in effect.  For example,
            // NOT the settings that the nic is currently using.
            bool userProvidedDns1 = dockingStation.NetworkSettings.DnsPrimary == Configuration.DockingStation.NetworkSettings.DnsPrimary;
            bool userProvidedDns2 = dockingStation.NetworkSettings.DnsSecondary == Configuration.DockingStation.NetworkSettings.DnsSecondary;

            // If either DNS does not match what user provided, then assume the DNS addresses were provided by the DHCP server.
            dockingStation.NetworkSettings.DnsDhcp = (!userProvidedDns1 || !userProvidedDns2);
            Log.Trace(string.Format("GetDockingStation: DnsPrimary={0}, BootDnsPrimary={1}, userProvidedDns1={2}", dockingStation.NetworkSettings.DnsPrimary, Configuration.DockingStation.NetworkSettings.DnsPrimary, userProvidedDns1));
            Log.Trace(string.Format("GetDockingStation: DnsSecondary={0}, BootDnsSecondary={1}, userProvidedDns2={2}", dockingStation.NetworkSettings.DnsSecondary, Configuration.DockingStation.NetworkSettings.DnsSecondary, userProvidedDns2));
            Log.Trace(string.Format("GetDockingStation: DnsDhcp=" + dockingStation.NetworkSettings.DnsDhcp));

            // Get size of databases.
            dockingStation.InetDatabaseTotalSize  = DataAccess.DataAccess.GetTotalSize(DataAccess.DataAccess.DataSource.iNetData);
            dockingStation.InetDatabaseUnusedSize = DataAccess.DataAccess.GetFreeSize(DataAccess.DataAccess.DataSource.iNetData);

            QueueDataAccess qda = new QueueDataAccess(ISC.iNet.DS.DataAccess.DataAccess.DataSource.iNetQueue);

            dockingStation.InetQueueDatabaseTotalSize  = DataAccess.DataAccess.GetTotalSize(DataAccess.DataAccess.DataSource.iNetQueue);
            dockingStation.InetQueueDatabaseUnusedSize = DataAccess.DataAccess.GetFreeSize(DataAccess.DataAccess.DataSource.iNetQueue);

            Controller.LogDockingStation(dockingStation);

            Log.Debug("        iNet DB Total Size: " + dockingStation.InetDatabaseTotalSize);
            Log.Debug("       iNet DB Unused Size: " + dockingStation.InetDatabaseUnusedSize);
            Log.Debug("       Queue DB Total Size: " + dockingStation.InetQueueDatabaseTotalSize);
            Log.Debug("      Queue DB Unused Size: " + dockingStation.InetQueueDatabaseUnusedSize);

            // Get the installed cylinders.
            GetCylinders(dockingStation, changedSmartCards);

            return(dockingStation);
        }
Esempio n. 9
0
        public void DockingStation_DockBike_ShouldThrowException_WhenThereAlreadyABikeParkedInTheLocation()
        {
            var bike1          = new Bike();
            var bike2          = new Bike();
            var dockingStation = new DockingStation(1);

            dockingStation.DockBike(bike1, 0);

            Assert.Throws <Exception>(() => dockingStation.DockBike(bike2, 0));

            Action action = () => dockingStation.DockBike(bike2, 0);

            action.Should().Throw <Exception>().WithMessage("Space is taken. MUPPET!");
        }
Esempio n. 10
0
        //Suresh 12-SEPTEMBER-2011 INS-2248
        /// <summary>
        /// Update local network settings.  It's assumed these can
        /// only be edited in Configurator and not in iNet.
        /// </summary>
        /// <param name="config"></param>
        /// <returns>true if any of the network settings are modified. Otherwise, false.</returns>
        private bool UpdateNetworkSettings(DockingStation config, DockingStation.NetworkInfo networksettings)
        {
            //Log.Assert(UseDockingStation, "UseDockingStation should be true!");

            bool modified = false;

            if (networksettings.IpAddress != config.NetworkSettings.IpAddress)
            {
                modified = LogUpdate("IpAddress", networksettings.IpAddress, config.NetworkSettings.IpAddress);
                config.NetworkSettings.IpAddress = networksettings.IpAddress;
            }

            if (networksettings.SubnetMask != config.NetworkSettings.SubnetMask)
            {
                modified = LogUpdate("SubnetMask", networksettings.SubnetMask, config.NetworkSettings.SubnetMask);
                config.NetworkSettings.SubnetMask = networksettings.SubnetMask;
            }

            if (networksettings.Gateway != config.NetworkSettings.Gateway)
            {
                modified = LogUpdate("Gateway", networksettings.Gateway, config.NetworkSettings.Gateway);
                config.NetworkSettings.Gateway = networksettings.Gateway;
            }

            if (networksettings.DhcpEnabled != config.NetworkSettings.DhcpEnabled)
            {
                modified = LogUpdate("DhcpEnabled", networksettings.DhcpEnabled, config.NetworkSettings.DhcpEnabled);
                config.NetworkSettings.DhcpEnabled = networksettings.DhcpEnabled;
            }

            if (networksettings.DnsPrimary != config.NetworkSettings.DnsPrimary)
            {
                modified = LogUpdate("DnsPrimary", networksettings.DnsPrimary, config.NetworkSettings.DnsPrimary);
                config.NetworkSettings.DnsPrimary = networksettings.DnsPrimary;
            }

            if (networksettings.DnsSecondary != config.NetworkSettings.DnsSecondary)
            {
                modified = LogUpdate("DnsSecondary", networksettings.DnsSecondary, config.NetworkSettings.DnsSecondary);
                config.NetworkSettings.DnsSecondary = networksettings.DnsSecondary;
            }

            if (modified)
            {
                _settingsUpdateEvent.RebootRequired = true;
            }

            return(modified);
        }
Esempio n. 11
0
        public void ThrowNotDockedExceptionIfInstrumentSerialNumberIsEmpty()
        {
            // arrange
            action         = new InstrumentSettingsUpdateAction();
            dockingStation = Helper.GetDockingStationForTest(DeviceType.MX4);
            instrument     = Helper.GetInstrumentForTest(DeviceType.MX4);

            instrument.SerialNumber = string.Empty;

            Initialize();

            InstrumentSettingsUpdateOperation operation = new InstrumentSettingsUpdateOperation(action);

            // act and assert
            Xunit.Assert.Throws <InstrumentNotDockedException>(() => operation.Execute());
        }
Esempio n. 12
0
        public void TakeBikeForRepair_AcceptsBrokenBike_FRomVan()
        {
            var brokenBike = new Bike();

            brokenBike.IsBroken();
            var dockingStation = new DockingStation();

            dockingStation.DockBike(brokenBike);
            var van = new Van();

            van.PickupBikeForRepair(dockingStation);
            var garage = new Garage();

            garage.TakeBikeForRepair(van);
            Assert.IsInstanceOf(typeof(Bike), garage.bikeDock[garage.bikeDock.Count - 1]);
        }
Esempio n. 13
0
        public void DockingStation_ReportBroken_ShouldChangeTheStateOfBikeWorkingToFalse()
        {
            var bike           = new Bike();
            var dockingStation = new DockingStation(1);

            dockingStation.DockBike(bike, 0);

            Assert.True(bike.Working);

            bike.Working.Should().Equals(true);

            dockingStation.ReportBroken(0);

            Assert.False(bike.Working);

            bike.Working.Should().Equals(false);
        }
Esempio n. 14
0
        public void DockingStation_ReleaseBike_ShouldRemoveABikeToTheBikeStore()
        {
            var bike           = new Bike();
            var dockingStation = new DockingStation(5);

            dockingStation.DockBike(bike, 0);

            Assert.Equal(dockingStation.BikeStore[0], bike);

            var acquiredBike = dockingStation.ReleaseBike(0);

            Assert.Null(dockingStation.BikeStore[0]);
            Assert.Equal(bike, acquiredBike);

            dockingStation.BikeStore[0].Should().Equals(null);
            bike.Should().Equals(acquiredBike);
        }
        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);
        }
Esempio n. 16
0
        public void RepairBikes_ShouldChangeBrokenStatusOnBikesToFalse_WhenRepaired()
        {
            var brokenBike = new Bike();

            brokenBike.IsBroken();
            var dockingStation = new DockingStation();

            dockingStation.DockBike(brokenBike);
            var van = new Van();

            van.PickupBikeForRepair(dockingStation);
            var garage = new Garage();

            garage.TakeBikeForRepair(van);
            garage.RepairBikes();
            Assert.IsTrue(garage.bikeDock[0].bikeStatus);
        }
        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);
        }
        private bool Insert(DockingStation ds, DataAccessTransaction trx)
        {
            try
            {
                using (IDbCommand cmd = GetCommand(_insertSql, trx))
                {
                    AddSaveParameters(cmd, ds, trx);

                    bool success = cmd.ExecuteNonQuery() > 0;

                    return(success);
                }
            }
            catch (Exception ex)
            {
                throw new DataAccessException(_insertSql, ex);
            }
        }
Esempio n. 19
0
        /// <summary>
        /// Gets a docking station object with default settings based on device type given
        /// </summary>
        internal static DockingStation GetDockingStationForTest(DeviceType deviceType)
        {
            DockingStation dockingStation = new DockingStation();

            if (deviceType != DeviceType.VPRO)
            {
                dockingStation.Type = deviceType;
            }
            else
            {
                dockingStation.Type = DeviceType.MX4;
            }
            dockingStation.SerialNumber   = "TESTDOC-001";
            dockingStation.Reservoir      = false;
            dockingStation.PurgeAfterBump = false;

            return(dockingStation);
        }
Esempio n. 20
0
 internal void AddDockingStation(DockingStation dockingStation)
 {
     Add("", DiagnosticResources.DETAILS_DOCKINGSTATION_HEADER, "");
     Add("    ", DiagnosticResources.DETAILS_DOCKINGSTATION_SERIALNUMBER, dockingStation.SerialNumber);
     Add("    ", DiagnosticResources.DETAILS_DOCKINGSTATION_TYPE, dockingStation.Type);
     Add("    ", DiagnosticResources.DETAILS_DOCKINGSTATION_PART_NUMBER, dockingStation.PartNumber);
     Add("    ", DiagnosticResources.DETAILS_DOCKINGSTATION_NUM_GAS_PORTS, dockingStation.NumGasPorts.ToString());
     Add("    ", DiagnosticResources.DETAILS_DOCKINGSTATION_RESERVOIR, dockingStation.Reservoir ? DiagnosticResources.TRUE : DiagnosticResources.FALSE);
     Add("    ", DiagnosticResources.DETAILS_DOCKINGSTATION_SETUP_DATE, dockingStation.SetupDate);
     Add("    ", DiagnosticResources.DETAILS_DOCKINGSTATION_SETUP_TECH, dockingStation.SetupTech);
     Add("    ", DiagnosticResources.DETAILS_DOCKINGSTATION_HARDWARE_VERSION, dockingStation.HardwareVersion);
     Add("    ", DiagnosticResources.DETAILS_DOCKINGSTATION_SOFTWARE_VERSION, dockingStation.SoftwareVersion);
     Add("    ", DiagnosticResources.DETAILS_DOCKINGSTATION_MAC_ADDRESS, dockingStation.NetworkSettings.MacAddress);
     Add("    ", DiagnosticResources.DETAILS_DOCKINGSTATION_IP_ADDRESS, dockingStation.NetworkSettings.IpAddress);
     Add("    ", DiagnosticResources.DETAILS_DOCKINGSTATION_LANGUAGE, dockingStation.Language);
     Add("    ", DiagnosticResources.DETAILS_DOCKINGSTATION_MENU_LOCKED, dockingStation.MenuLocked);
     Add("    ", DiagnosticResources.DETAILS_DOCKINGSTATION_USE_AUDIBLE_ALARM, dockingStation.UseAudibleAlarm);   // SGF  Feb-24-2009  DSW-136
 }
Esempio n. 21
0
        public void VanPicksUpRepairedBike_PicksUpRepairedBikes_RemoveRepairedBikeFromGarage()
        {
            var brokenBike = new Bike();

            brokenBike.IsBroken();
            var dockingStation = new DockingStation();

            dockingStation.DockBike(brokenBike);
            var van = new Van();

            van.PickupBikeForRepair(dockingStation);
            var garage = new Garage();

            garage.TakeBikeForRepair(van);
            garage.RepairBikes();
            van.PickupRepairedBike(garage);
            Assert.IsTrue(van.bikeDock[0].bikeStatus);
        }
        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));
        }
        static private void GetCylinders(DockingStation ds, bool[] changedSmartCards)
        {
            ds.GasEndPoints = ds.ChangedGasEndPoints = null;

            // On initial boot (changedSmartCards will be null), call old logic to read ALL cards
            // At all other times, the array should be non-null, meaning only read cards we know
            // have been inserted/removed. The intent is that we only read ALL cards one time on bootup.

            if (changedSmartCards == null)
            {
                Log.Debug("readAllCards=true.  Calling ReadInstalledCylinders");
                ReadInstalledCylinders(ds.GasEndPoints, ds.Port1Restrictions);
            }
            else
            {
                Log.Debug(ChangedSmartCardsToString(changedSmartCards) + ". Calling ReadChangedCylinders");
                ReadChangedCylinders(changedSmartCards, ds.ChangedGasEndPoints, ds.Port1Restrictions);
            }
        }
        private void AddSaveParameters(IDbCommand cmd, DockingStation ds, DataAccessTransaction trx)
        {
            cmd.Parameters.Add(GetDataParameter("@REFID", ds.RefId));
            cmd.Parameters.Add(GetDataParameter("@RECUPDATETIMEUTC", trx.TimestampUtc));
            cmd.Parameters.Add(GetDataParameter("@LANGUAGE", ds.Language.Code));
            cmd.Parameters.Add(GetDataParameter("@MENULOCKED", ds.MenuLocked ? 1 : 0));
            cmd.Parameters.Add(GetDataParameter("@SPEAKER", ds.UseAudibleAlarm ? 1 : 0));
            cmd.Parameters.Add(GetDataParameter("@LOGLEVEL", ds.LogLevel.ToString()));
            cmd.Parameters.Add(GetDataParameter("@LOGCAPACITY", ds.LogCapacity));
            cmd.Parameters.Add(GetDataParameter("@INETURL", ds.InetUrl));
            cmd.Parameters.Add(GetDataParameter("@INETPINGINTERVAL", ds.InetPingInterval));
            cmd.Parameters.Add(GetDataParameter("@INETTIMEOUTLOW", ds.InetTimeoutLow));
            cmd.Parameters.Add(GetDataParameter("@INETTIMEOUTMEDIUM", ds.InetTimeoutMedium));
            cmd.Parameters.Add(GetDataParameter("@INETTIMEOUTHIGH", ds.InetTimeoutHigh));
            cmd.Parameters.Add(GetDataParameter("@INETUSERNAME", ds.InetUserName));
            cmd.Parameters.Add(GetDataParameter("@INETPASSWORD", ds.InetPassword));
            cmd.Parameters.Add(GetDataParameter("@PRINTPERFORMEDBY", ds.PrintPerformedBy ? 1 : 0));
            cmd.Parameters.Add(GetDataParameter("@PRINTRECEIVEDBY", ds.PrintReceivedBy ? 1 : 0));
            cmd.Parameters.Add(GetDataParameter("@PORT1RESTRICTION", (int)ds.Port1Restrictions));
            cmd.Parameters.Add(GetDataParameter("@PURGEAFTERBUMP", ds.PurgeAfterBump ? 1 : 0));
            cmd.Parameters.Add(GetDataParameter("@TZBIAS", ds.TimeZoneInfo.Bias));
            cmd.Parameters.Add(GetDataParameter("@TZSTANDARDNAME", ds.TimeZoneInfo.StandardName));
            cmd.Parameters.Add(GetDataParameter("@TZSTANDARDDATEMONTH", ds.TimeZoneInfo.StandardDate.Month));
            cmd.Parameters.Add(GetDataParameter("@TZSTANDARDDATEDAYOFWEEK", ds.TimeZoneInfo.StandardDate.DayOfWeek));
            cmd.Parameters.Add(GetDataParameter("@TZSTANDARDDATEDAY", ds.TimeZoneInfo.StandardDate.Day));
            cmd.Parameters.Add(GetDataParameter("@TZSTANDARDDATEHOUR", ds.TimeZoneInfo.StandardDate.Hour));
            cmd.Parameters.Add(GetDataParameter("@TZSTANDARDBIAS", ds.TimeZoneInfo.StandardBias));
            cmd.Parameters.Add(GetDataParameter("@TZDAYLIGHTNAME", ds.TimeZoneInfo.DaylightName));
            cmd.Parameters.Add(GetDataParameter("@TZDAYLIGHTDATEMONTH", ds.TimeZoneInfo.DaylightDate.Month));
            cmd.Parameters.Add(GetDataParameter("@TZDAYLIGHTDATEDAYOFWEEK", ds.TimeZoneInfo.DaylightDate.DayOfWeek));
            cmd.Parameters.Add(GetDataParameter("@TZDAYLIGHTDATEDAY", ds.TimeZoneInfo.DaylightDate.Day));
            cmd.Parameters.Add(GetDataParameter("@TZDAYLIGHTDATEHOUR", ds.TimeZoneInfo.DaylightDate.Hour));
            cmd.Parameters.Add(GetDataParameter("@TZDAYLIGHTBIAS", ds.TimeZoneInfo.DaylightBias));
            cmd.Parameters.Add(GetDataParameter("@CLEARPEAKSUPONDOCKING", ds.ClearPeaksUponDocking ? 1 : 0));
            cmd.Parameters.Add(GetDataParameter("@SINGLESENSORMODE", ds.SingleSensorMode ? 1 : 0));
            cmd.Parameters.Add(GetDataParameter("@USEEXPIREDCYLINDERS", ds.UseExpiredCylinders ? 1 : 0));
            cmd.Parameters.Add(GetDataParameter("@COMBUSTIBLEBUMPTESTGAS", ds.CombustibleBumpTestGas));
            cmd.Parameters.Add(GetDataParameter("@SPANRESERVETHRESHOLD", ds.SpanReserveThreshold));
            cmd.Parameters.Add(GetDataParameter("@STOPONFAILEDBUMPTEST", ds.StopOnFailedBumpTest ? 1 : 0));
            cmd.Parameters.Add(GetDataParameter("@UPGRADEONERRORFAIL", ds.UpgradeOnErrorFail ? 1 : 0));

            Log.Assert(cmd.Parameters.Count == _fields.Length, "Number of SQL parameters does not equal number of strings in \"_fields\"");
        }
Esempio n. 26
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        internal static DockingStation Load()
        {
            DockingStation dockingStation = new DockingStation();

            try
            {
                LoadSerialization(dockingStation);
            }
            catch (System.IO.FileNotFoundException fnfe)
            {
                // It's expected that the file won't be found. So don't log the whole stack trace.
                Log.Error("Ds2Serialization.Load - " + fnfe.Message);
                dockingStation = null;
            }
            catch (Exception e)
            {
                Log.Error("Ds2Serialization.Load", e);
                dockingStation = null;
            }

            return(dockingStation);
        }
        public void GetCalibrationActionForSensorAdded()
        {
            // 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));
            for (int i = 0; i < 2; i++)
            {
                InstalledComponent comp = installedComponents[i];
                eventJournals.Add(new EventJournal(EventCode.Calibration, comp.Component.Uid, instrument.SerialNumber, DateTime.Now.AddMonths(-1), DateTime.Now.AddMonths(-1), true, comp.Position, instrument.SoftwareVersion));
            }
            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);
        }
Esempio n. 28
0
        public void ExecuteInstrumentSettingsReadOperation()
        {
            // arrange
            InstrumentSettingsReadAction action = new InstrumentSettingsReadAction();

            dockingStation = Helper.GetDockingStationForTest(DeviceType.MX4);
            instrument     = Helper.GetInstrumentForTest(DeviceType.VPRO, DeviceSubType.VentisPro5);
            Initialize();

            InstrumentSettingsReadOperation operation = new InstrumentSettingsReadOperation(action);

            // act
            InstrumentSettingsReadEvent dsEvent = (InstrumentSettingsReadEvent)operation.Execute();

            // assert
            Instrument testInstrument = dsEvent.DockedInstrument;

            Xunit.Assert.True(testInstrument.SerialNumber == instrument.SerialNumber &&
                              testInstrument.Type == instrument.Type &&
                              testInstrument.Subtype == instrument.Subtype &&
                              testInstrument.SoftwareVersion == instrument.SoftwareVersion &&
                              testInstrument.BumpTimeout == instrument.BumpTimeout);
        }
Esempio n. 29
0
        // INS-8630 RHP v7.5 - Updated method signature to include errorCodes and explanationCodes to display ISC Cylinder Part Number on LCD and to send the same as Alert
        private void FindInstalledCylinderGases(string eventCode, List <GasEndPoint> gasEndPoints,
                                                DockingStation dockingStation, InstalledComponent installedComponent,
                                                StringBuilder explanation,
                                                List <string> explanationCodes,
                                                List <string> errorCodes)
        {
            Sensor sensor = installedComponent.Component as Sensor;

            // INS-8630 RHP v7.5 - Initialize outside the loop since if no gas is found on entire loop, then we still need to pass expired/empty if either are true.
            _expired = _empty = false;

            // SGF  21-May-2012  INS-3078
            _gasNeeded = IsGasOperationSupported(eventCode, sensor);

            foreach (GasEndPoint gasEndPoint in dockingStation.GasEndPoints)
            {
                Cylinder cyl = gasEndPoint.Cylinder;

                // If we are examining the fresh air/zero air port to possibly add a gas to the gas end points list,
                // make sure that the type of fresh air/zero air is allowed based on port 1 descriptions.  For example,
                // if the installed cylinder is fresh air, make sure the port 1 restrictions allow for fresh
                // air to be specified on this port.
                //
                if (gasEndPoint.Position == Controller.FRESH_AIR_GAS_PORT)
                {
                    if (cyl.IsFreshAir && ((dockingStation.Port1Restrictions & PortRestrictions.FreshAir) != PortRestrictions.FreshAir))
                    {
                        Log.Debug(Name + ": FRESH AIR attached to Port 1; defined Port 1 Restrictions prohibit the use of FRESH AIR");
                        continue;
                    }

                    if (cyl.IsZeroAir && ((dockingStation.Port1Restrictions & PortRestrictions.ZeroAir) != PortRestrictions.ZeroAir))
                    {
                        Log.Debug(Name + ": ZERO AIR attached to Port 1; defined Port 1 Restrictions prohibit the use of ZERO AIR");
                        continue;
                    }
                }

                // Reset each time through loop. At end of loop, they'll be
                // set for the last cylinder matching desired gas that was looked at.
                //_expired = _empty = false; - INS-8630 RHP v7.5 Commented since if no gas is found on entire loop, then we still need to pass expired/empty if either are true.
                bool alreadyAdded = false;

                string msg = string.Format("{0} Examining port {1} ({2}), fid={3},pn={4},Fresh={5},ZeroAir={6},Exp={7},Pressure={8}",
                                           Name, gasEndPoint.Position, gasEndPoint.InstallationType.ToString(), cyl.FactoryId, cyl.PartNumber, cyl.IsFreshAir, cyl.IsZeroAir,
                                           cyl.ExpirationDate.ToShortDateString(), cyl.Pressure.ToString());
                Log.Debug(msg);

                msg = "......";
                foreach (GasConcentration gasCon in gasEndPoint.Cylinder.GasConcentrations)
                {
                    msg += "[" + gasCon.Type.Code + " ";
                    msg += (gasCon.Concentration == double.MinValue) ? "fresh" : gasCon.Concentration.ToString();
                    msg += "]";
                }
                Log.Debug(msg);

                string sensorGasCode = sensor.CalibrationGas.Code;

                // If we're doing a bump test, we use Chlorine for the calibration gas.
                if (sensor.Type.Code == SensorCode.ClO2 && eventCode == EventCode.BumpTest)
                {
                    sensorGasCode = GasCode.Cl2;
                    Log.Debug("...Sensor is CLO2. Looking for cylinders containing Chlorine instead of cal gas.");
                }

                bool containsGas = gasEndPoint.Cylinder.ContainsGas(sensorGasCode);

                if (Configuration.DockingStation.UseExpiredCylinders && (eventCode == EventCode.BumpTest))
                {
                    Log.Debug("...UseExpiredCylinders=true; Ignoring expiration date");
                }
                else if (Configuration.ToLocalTime(gasEndPoint.Cylinder.ExpirationDate) <= Configuration.GetLocalTime())
                {
                    //Log.Debug( "...Skipping expired cylinder" );
                    explanation.Append("Cylinder has expired." + '\n');
                    explanation.Append("Cylinder id =" + gasEndPoint.Cylinder.FactoryId + '\n');
                    explanation.Append("Port number: " + gasEndPoint.Position + '\n');

                    // INS-8630 RHP v7.5 - IDS is expected to display expired cylinder details on LCD
                    if (containsGas)
                    {
                        // INS-8630 RHP v7.5 - Multiple cylinder with the same gas code may be expired, in such scenarios IDS message
                        // should display the first cylinder it identifies.
                        if (!(_expired || _empty))
                        {
                            // For ISC cylinder IDS should display the cylinder part NUmber, so add the part number to explanation codes
                            if (!explanationCodes.Contains(gasEndPoint.Cylinder.PartNumber) && !string.IsNullOrEmpty(gasEndPoint.Cylinder.PartNumber))
                            {
                                explanationCodes.Add(gasEndPoint.Cylinder.PartNumber);
                                errorCodes.Add(string.Format("{0} ({1})", gasEndPoint.Cylinder.PartNumber, gasEndPoint.Position)); // see INS-3821
                            }
                            else
                            {
                                // For Non ISC Pass the gas code. But I believe that both ISC and Non-ISC cylinders have their own PArt numbers.
                                // So this condition may not be required ?
                                GasType gs = GasType.Cache[GasCode.FreshAir];
                                if (!explanationCodes.Contains(gasEndPoint.Cylinder.PartNumber) && gs != null)
                                {
                                    explanationCodes.Add(gs.Symbol);
                                    errorCodes.Add(string.Format("{0} ({1})", gs.Symbol, gs.Code));
                                }
                            }
                            _expired = true;
                        }
                        continue;
                    }
                }

                if (gasEndPoint.Cylinder.Pressure == PressureLevel.Empty)
                {
                    //Log.Debug( "...Skipping cylinder; Pressure is " + gasEndPoint.Cylinder.Pressure );
                    explanation.Append("Cylinder is empty." + '\n');
                    explanation.Append("Cylinder id =" + gasEndPoint.Cylinder.FactoryId + '\n');
                    explanation.Append("Port number: " + gasEndPoint.Position + '\n');

                    // INS-8630 RHP v7.5 - IDS is expected to display empty cylinder details on LCD
                    if (containsGas)
                    {
                        // INS-8630 RHP v7.5 - Multiple cylinder with the same gas code may be expired, in such scenarios IDS message
                        // should display the first cylinder it identifies.
                        if (!(_expired || _empty))
                        {
                            // For ISC cylinder IDS should display the cylinder part NUmber, so add the part number to explanation codes
                            if (!explanationCodes.Contains(gasEndPoint.Cylinder.PartNumber) && !string.IsNullOrEmpty(gasEndPoint.Cylinder.PartNumber))
                            {
                                explanationCodes.Add(gasEndPoint.Cylinder.PartNumber);
                                errorCodes.Add(string.Format("{0} ({1})", gasEndPoint.Cylinder.PartNumber, gasEndPoint.Position));  // see INS-3821
                            }
                            else
                            {
                                // For Non ISC Pass the gas code. But I believe that both ISC and Non-ISC cylinders have their own PArt numbers.
                                // So this condition may not be required ?
                                GasType gs = GasType.Cache[GasCode.FreshAir];
                                if (!explanationCodes.Contains(gasEndPoint.Cylinder.PartNumber) && gs != null)
                                {
                                    explanationCodes.Add(gs.Symbol);
                                    errorCodes.Add(string.Format("{0} ({1})", gs.Symbol, gs.Code));
                                }
                            }
                            _empty = true;
                        }
                        continue;
                    }
                }

                //string sensorGasCode = sensor.CalibrationGas.Code;

                if (eventCode == EventCode.BumpTest)
                {
                    // 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 ignore the sensor's cal
                    // gas code and instead only look for cylinders that match the CombustibleBumpTestGas setting.
                    if ((sensor.Type.Code == SensorCode.CombustibleLEL || sensor.Type.Code == SensorCode.CombustiblePPM) &&
                        (Configuration.DockingStation.CombustibleBumpTestGas.Length > 0))
                    {
                        sensorGasCode = Configuration.DockingStation.CombustibleBumpTestGas;
                        Log.Debug(string.Format("...Sensor is combustible and CombustibleBumpTestGas setting is {0}.", sensorGasCode));
                        Log.Debug(string.Format("...Overriding sensor cal gas. Looking for cylinders containing {0}.", sensorGasCode));
                    }
                    // If we're doing a bump test, we use Chlorine for the calibration gas.
                    else if (sensor.Type.Code == SensorCode.ClO2)
                    {
                        sensorGasCode = GasCode.Cl2;
                        Log.Debug("...Sensor is CLO2. Looking for cylinders containing Chlorine instead of cal gas.");
                    }
                }

                containsGas = gasEndPoint.Cylinder.ContainsGas(sensorGasCode);

                // Ensure bump tests for O2 sensors use concentrations of 19% O2 or less.
                // Zero air cylinders should not be selected for gasFound, but should be selected for zeroFound.
                if (containsGas && (eventCode == EventCode.BumpTest && sensor.CalibrationGas.Code == GasCode.O2))
                {
                    // The following Find should always succeed because containsGas is true.
                    GasConcentration gasConcentration = cyl.GasConcentrations.Find(gc => gc.Type.Code == sensorGasCode);
                    // Parts per million (ppm) of X divided by 10,000 = percentage concentration of X
                    if ((gasConcentration.Concentration / 10000.0) > 19.0)
                    {
                        Log.Debug("...Not allowed to use O2 concentration higher than 19%.");

                        containsGas = false;
                    }
                }

                // Ensure cylinder concentration is not higher than 60% for potentially explosive cal gases
                double lelMultiplier = GasType.Cache[sensorGasCode].LELMultiplier;
                if (containsGas && lelMultiplier > 0.0)
                {
                    double cylinderPPM = -1.0;
                    foreach (GasConcentration gasConcentration in cyl.GasConcentrations)
                    {
                        if (gasConcentration.Type.Code == sensorGasCode)
                        {
                            cylinderPPM = gasConcentration.Concentration;
                            break;
                        }
                    }

                    if (cylinderPPM < 0)   // this should never happen.  Which means we better check anyways.
                    {
                        Log.Debug("...Skipping cylinder. Does not contain " + sensorGasCode);
                        continue;
                    }

                    double cylinderLEL = cylinderPPM * lelMultiplier;
                    if (cylinderLEL > 60.0)                        // cylinder is higher than 60%?  Don't use it.
                    {
                        Log.Debug(string.Format("...Skipping cylinder. Contains {0} with too high LEL concentration ({1}%)",
                                                sensorGasCode, Math.Round(cylinderLEL, 1)));
                        Log.Debug("...Not allowed to use LEL concentration higher than 60%.");
                        continue;
                    }
                }

                // The gas is found if the cylinder contains a gas with a matching code, or
                // if the cylinder is fresh air and the sensor is an O2 sensor.
                // Fresh air is not acceptable as O2 if doing a bump test.
                // Zero air is not acceptable for an O2 bump test.
                if (containsGas || ((sensor.CalibrationGas.Code == GasCode.O2) && !(eventCode == EventCode.BumpTest) && gasEndPoint.Cylinder.IsFreshAir))
                {
                    Log.Debug("...Gas found.");
                    if (HasCylinder(gasEndPoint, gasEndPoints) == false)
                    {
                        gasEndPoints.Add(gasEndPoint);
                    }
                    _gasFound    = true;
                    alreadyAdded = true;
                }

                // Nitrogen is acceptable for doing O2 bump tests.
                if (sensor.CalibrationGas.Code == GasCode.O2 &&
                    (eventCode == EventCode.BumpTest) &&
                    gasEndPoint.Cylinder.ContainsOnlyGas(GasCode.N2) == true)
                {
                    Log.Debug("...Gas found.");
                    if (HasCylinder(gasEndPoint, gasEndPoints) == false)
                    {
                        gasEndPoints.Add(gasEndPoint);
                    }
                    _gasFound = true;
                }

                if (gasEndPoint.Cylinder.IsFreshAir)
                {
                    Log.Debug("...Fresh air found.");
                    if (!alreadyAdded)
                    {
                        if (HasCylinder(gasEndPoint, gasEndPoints) == false)
                        {
                            gasEndPoints.Add(gasEndPoint);
                        }
                    }
                    _freshFound  = true;
                    alreadyAdded = true;
                }

                if (gasEndPoint.Cylinder.IsZeroAir)
                {
                    Log.Debug("...Zero Air found.");
                    if (!alreadyAdded)
                    {
                        if (HasCylinder(gasEndPoint, gasEndPoints) == false)
                        {
                            gasEndPoints.Add(gasEndPoint);
                        }
                    }
                    _zeroFound   = true;
                    alreadyAdded = true;
                }
            }   // end-foreach  Gasendpoints

            // BEGIN INS-8630 RHP v7.5 - Loop through the entire list of installed cylinders.
            // if _gasFound is set to true, then the desired gas is found and hence we can reset _expired and _empty.
            // There may be cases where a docking station may have more than one gas code of the same kind assigned to it as a part of installed cylinders and
            // put of which one of the cylinders may be expired/empty and other may be full.
            if (_empty && _gasFound)
            {
                _empty = false;
            }
            else if (_expired && _gasFound)
            {
                _expired = false;
            }
            // END INS-8630 RHP v7.5
        }
Esempio n. 30
0
        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);
        }