// SGF 06-Jun-2011 INS-1735 -- Moving to this class to make available to inherited classes. // SGF 15-Jun-2010 DSW-470 -- New public SensorGasResponse GetSensorGasResponse(InstrumentGasResponseEvent igrEvent, Sensor sensor) { for (int i = 0; i < igrEvent.GasResponses.Count; i++) { SensorGasResponse sgr = (SensorGasResponse)igrEvent.GasResponses[i]; if (sensor.Uid == sgr.Uid) { return(sgr); } } return(null); }
/// <summary> /// Implementation of ICloneable::Clone - Creates a duplicate of a SensorGasResponse object. /// </summary> /// <returns>SensorGasResponse object</returns> public virtual object Clone() { SensorGasResponse sensorGasResponse = (SensorGasResponse)this.MemberwiseClone(); sensorGasResponse.GasConcentration = GasConcentration; sensorGasResponse.UsedGasEndPoints = new List <UsedGasEndPoint>(this.UsedGasEndPoints.Capacity); foreach (GasEndPoint used in UsedGasEndPoints) { sensorGasResponse.UsedGasEndPoints.Add((UsedGasEndPoint)used.Clone()); } return(sensorGasResponse); }
/// <summary> /// This method should be called to get a new SensorGasResponse object after WasCalibrationInstrumentAborted() returned true. This creates a new instance /// object to replace the passed in object while retaining a few properties of the original object. /// </summary> /// <param name="sgr">The SensorGasResponse object that will be replaced by a new SensorGasResponse object so that very few values /// will be uploaded to iNet since the calibration of this sensor was aborted by the instrument.</param> /// <returns>A new SensorGasResponse object that has an InstrumentAborted status and preserves a small subset of the passed in object's properties.</returns> public static SensorGasResponse CreateInstrumentAbortedSensorGasResponse(SensorGasResponse sgr) { // A default reading of double.MinValue is assumed for the new SensorGasResponse. SensorGasResponse response = new SensorGasResponse(sgr.Uid, DateTime.Now); // should this be UtcNow? - JMP,3/2016. response.Status = Status.InstrumentAborted; response.Type = sgr.Type; response.Position = sgr.Position; response.AccessoryPump = sgr.AccessoryPump; response.GasConcentration = (GasConcentration)sgr.GasConcentration.Clone(); // It would be proper to clone the CylindersUsed, but the original SensorGasResponse is going away // so it should not matter. response.UsedGasEndPoints = sgr.UsedGasEndPoints; // Clone? response.PreCal_LastCalibrationTime = sgr.PreCal_LastCalibrationTime; response.PostCal_LastCalibrationTime = sgr.PostCal_LastCalibrationTime; return(response); }
/// <summary> /// Returns a cal passed DualSense InstalledComponent sibling of the provided InstalledComponent if Single-Sensor mode is enabled /// and one exists. Otherwise, null is returned. GetDualSenseSibling is a helper method to be used in possible redundant /// bump passed scenarios. The calling method should determine if the sibling has a passed bump status. This method should only /// be called after determining that the instrument is NOT in cal failed state. /// </summary> public InstalledComponent GetDualSenseSibling(bool singleSensorMode, InstalledComponent bumpFailedComponent) { if (!singleSensorMode) { Log.Debug("Single-Sensor mode is currently disabled. A DualSense sibling will NOT be returned."); return(null); } // validate input parameter, only sensors are expected if (!(bumpFailedComponent.Component is Sensor)) { return(null); } Sensor bumpFailedSensor = (Sensor)bumpFailedComponent.Component; // an instrument must be docked and discovered if (this.Type == DeviceType.Unknown || this.SerialNumber.Length <= 0) { return(null); } if (this.Type == DeviceType.TX1) { // for TX1, a sensor that has a different S/N would be a DualSense sibling foreach (InstalledComponent ic in this.InstalledComponents) { if (!(ic.Component is Sensor)) { continue; } // We do not need to check if the sensor is enabled, because TX1 sensors cannot be disabled. Sensor sensor = (Sensor)ic.Component; if (sensor.Uid == bumpFailedSensor.Uid) { continue; } if (sensor.Type.Code == bumpFailedSensor.Type.Code && !SensorGasResponse.IsFailedCalibrationStatus(sensor.CalibrationStatus)) { return(ic); } } } else if (this.Type == DeviceType.VPRO || this.Type == DeviceType.SC) { // if the failed sensor is not capable of DualSense, then don't search for a sibling; // we check the flag here because TX1 does not use it if (!bumpFailedSensor.IsDualSenseCapable) { return(null); } // For Ventis Pro Series and SafeCore, a sibling will have a different S/N, but be DualSense capable, and have // the same sensor part number and sensor code. For SafeCore, we do not worry about sensor position because // if it were an issue the DS would go into the Sensor Error state. foreach (InstalledComponent ic in this.InstalledComponents) { if (!(ic.Component is Sensor)) { continue; } // Ventis Pro sensors cannot be disabled, but we check because SafeCore sensors can. if (!ic.Component.Enabled) { continue; } Sensor sensor = (Sensor)ic.Component; if (sensor.Uid == bumpFailedSensor.Uid) { continue; } if (sensor.IsDualSenseCapable && sensor.PartNumber == bumpFailedSensor.PartNumber && sensor.Type.Code == bumpFailedSensor.Type.Code && !SensorGasResponse.IsFailedCalibrationStatus(sensor.CalibrationStatus)) { return(ic); } } } // instrument does not support DualSense or no DualSense sibling found return(null); }
/// <summary> /// Returns the instrument-level calibration state based on the state of the installed sensors. /// <para>All passed sensors are returned in the passed-in "passedSensors" list.</para> /// <para>All failed sensors are returned in the passed-in "failedSensors" list.</para> /// </summary> /// <param name="passedSensors"> /// Sensors that passed calibration will be returned in this list. /// A null list can be specified to indicate that passed sensors do not need returned. /// </param> /// <param name="failedSensors"> /// Sensors that failed calibration will be returned in this list. /// A null list can be specified to indicate that failed sensors do not need returned. /// </param> /// <returns>RedundantSensorPassed will only be returned if SingleSensorMode is enabled and the instrument supports DualSense functionality.</returns> public CalibrationState GetInstrumentCalibrationState(bool singleSensorMode, List <InstalledComponent> passedSensors, List <InstalledComponent> failedSensors) { if (this.Type == DeviceType.Unknown || this.SerialNumber.Length <= 0) { return(CalibrationState.Unknown); } CalibrationState instrumentCalState = CalibrationState.Passed; if (this.Type == DeviceType.TX1) { CalibrationState sensor1CalState = CalibrationState.Unknown; CalibrationState sensor2CalState = CalibrationState.Unknown; foreach (InstalledComponent ic in this.InstalledComponents) { if (!(ic.Component is Sensor)) { continue; } // We do not need to check if the sensor is enabled, because TX1 sensors cannot be disabled. Sensor sensor = (Sensor)ic.Component; bool failedCal = SensorGasResponse.IsFailedCalibrationStatus(sensor.CalibrationStatus); if ((passedSensors != null) && !failedCal) { passedSensors.Add(ic); } if ((failedSensors != null) && failedCal) { failedSensors.Add(ic); } if (ic.Position == 1) { sensor1CalState = failedCal ? CalibrationState.Failed : CalibrationState.Passed; } if (ic.Position == 2) { sensor2CalState = failedCal ? CalibrationState.Failed : CalibrationState.Passed; } } if (sensor1CalState == sensor2CalState) { instrumentCalState = sensor1CalState; } else { if (singleSensorMode == true) { instrumentCalState = CalibrationState.RedundantSensorPassed; } else { instrumentCalState = CalibrationState.Failed; } } } else if (this.Type == DeviceType.VPRO || this.Type == DeviceType.SC) { // The caller may not care about which sensors are passed or failed so they may pass in null for // both lists which is okay. However, we need to use the lists to determine the overall calibration // state of the instrument. Instrument cal state is defaulted to Passed above. if (passedSensors == null) { passedSensors = new List <InstalledComponent>(); } if (failedSensors == null) { failedSensors = new List <InstalledComponent>(); } // Will use the dictionary like it's a HashSet. Dictionary <string, bool> passedDualSenseCapable = new Dictionary <string, bool>(); foreach (InstalledComponent ic in this.InstalledComponents) { if (!(ic.Component is Sensor)) { continue; } // Ventis Pro sensors cannot be disabled, but we check because SafeCore sensors can. if (!ic.Component.Enabled) { continue; } Sensor sensor = (Sensor)ic.Component; // If the sensor failed its last cal or bump add it to the failedSensors list. if (SensorGasResponse.IsFailedCalibrationStatus(sensor.CalibrationStatus)) { failedSensors.Add(ic); } else { passedSensors.Add(ic); if (sensor.IsDualSenseCapable) { // We do not use the Add() method because it will throw an exception if we have duplicate keys. passedDualSenseCapable[GetDualSenseCapableKey(sensor)] = sensor.IsDualSenseCapable; } } } if (failedSensors.Count > 0) { if (singleSensorMode == true) { // We will changed this to failed below if we do not find a matching DualSense capable sensor // in the passed list for every failed sensor. instrumentCalState = CalibrationState.RedundantSensorPassed; for (int i = 0; i < failedSensors.Count; i++) { // Only sensors should be in the list. Sensor failedSensor = (Sensor)failedSensors[i].Component; if (failedSensor.IsDualSenseCapable && passedDualSenseCapable.ContainsKey(GetDualSenseCapableKey(failedSensor))) { continue; } // At least one failed sensor does not have a paired sensor that passed. instrumentCalState = CalibrationState.Failed; break; } } else { instrumentCalState = CalibrationState.Failed; } } } else // All other instrument types. { // TODO - shouldn't we be adding sensors to passedSensors and failedSensors lists? - JMP, 6/7/2013 foreach (InstalledComponent ic in this.InstalledComponents) { if (!(ic.Component is Sensor)) { continue; } Sensor sensor = (Sensor)ic.Component; if (!sensor.Enabled) { continue; } if (SensorGasResponse.IsFailedCalibrationStatus(sensor.CalibrationStatus) == true) { instrumentCalState = CalibrationState.Failed; break; } } } return(instrumentCalState); }