/// Zeroes all sensors contained on the instrument.
    /// 
    /// NOTE: THIS ROUTINE LOOKS LIKE IT CAN ZERO A SPECIFIC SENSOR 
    /// BUT IN ACTUALITY, IT ALWAYS ZEROS ALL SENSORS.
    /// </summary>
    /// <param name="installedComponents">Contains InstalledComponents for the instrument being zeroed.</param>
    private void ZeroSensors( IEnumerable<InstalledComponent> installedComponents )
    {
        Log.Debug( "ZEROING: Preparing to zero" );

        // Indicate that the zeroing process is now in progress
        Master.Instance.ConsoleService.UpdateState( ConsoleState.CalibratingInstrument, ConsoleServiceResources.ZEROING );

        // See if we have a CO2 sensor.  If so, then we can only zero using zero air.
        // fresh air is NOT allowed.  If no CO2 sensor is installed, then fresh
        // air may be used as an alternative to zero air, if zero air is not found.
        bool useZeroAirOnly = false;
        foreach ( InstalledComponent installedComponent in installedComponents )
        {
            if ( installedComponent.Component.Type.Code == SensorCode.CO2 )
            {
                Sensor sensor = (Sensor)installedComponent.Component;

                if ( !sensor.Enabled ) // if it's disabled, we won't be zeroing it.
                    continue;

                Log.Debug( "ZEROING: Found CO2 sensor.  Will not use fresh air to zero." );
                useZeroAirOnly = true;
                break;
            }
        }

		GasEndPoint zeroEndPoint = null;

        DateTime startTime = DateTime.UtcNow;

        try
        {
			_zeroingUsedGasEndPoint = null;  // Reset any previous setting (if any).

            zeroEndPoint = GetSensorZeroAir( null, useZeroAirOnly, false );  // Get the zeroing gas end point for this gas.

            _instrumentController.OpenGasEndPoint( zeroEndPoint, Pump.StandardFlowRate );

            // ZeroSensor will return false if IDS times out before instrument finishes zeroing.
            // Return value does NOT indicate if zeroing was successful or not!
            if ( !_instrumentController.ZeroSensors( zeroEndPoint ) )
                throw new UnableToZeroInstrumentSensorsException();

            // SGF  14-Jun-2011  INS-1732 -- get sensor readings after zeroing has taken place
            foreach ( InstalledComponent ic in _returnEvent.DockedInstrument.InstalledComponents )
            {
                if ( !( ic.Component is Sensor ) )  // Skip non-sensors.
                    continue;

                Sensor sensor = (Sensor)ic.Component;
                if ( !sensor.Enabled ) // Skip disabled sensors
                    continue;

                SensorGasResponse sgr = _returnEvent.GetSensorGasResponseByUid( sensor.Uid );
                if ( sgr != null )
                {
                    sgr.ReadingAfterZeroing = _instrumentController.GetSensorReading( ic.Position, sensor.Resolution );
                    sgr.TimeAfterZeroing = DateTime.UtcNow;
				}
            }
        }
        catch ( Exception e )
        {
            Log.Error( "Zeroing Sensor", e );
            throw;
        }
        finally
        {
            Log.Debug( "ZEROING: Finished" );

            _instrumentController.CloseGasEndPoint( zeroEndPoint );

            if ( zeroEndPoint != null )  // how could this ever be null?
                _zeroingUsedGasEndPoint = new UsedGasEndPoint( zeroEndPoint, CylinderUsage.Zero, DateTime.UtcNow - startTime, 0 );
        }
    }
Esempio n. 2
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();
            }
        }