Esempio n. 1
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);
        }
Esempio n. 2
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);
        }