Ejemplo n.º 1
0
        /// <summary>
        /// </summary>
        /// <remarks>
        /// 1) Updates the cylinder's pressure in the database (change it from Full to Low, or Low to Empty).
        /// 2) Update cached cylinder (in Configuration.DockingStation.InstalledCylinders) with the pressure
        /// change.
        /// 3) Also forces an upload of a SettingsReadEvent in order to notify iNet of the pressure change.
        /// </remarks>
        /// <param name="emptyCylinderError"></param>
        /// <param name="inetUploader"></param>
        /// <returns></returns>
        private DockingStationAction ProcessEmptyGasEndPoint(GasEndPoint emptyEndPoint, InetUploader inetUploader)
        {
            Log.Debug(string.Format("Empty Cylinder was reported on position {0}", emptyEndPoint.Position));

            GasEndPoint gasEndPoint = null;

            using (DataAccessTransaction trx = new DataAccessTransaction())
            {
                GasEndPointDataAccess gepDataAccess = new GasEndPointDataAccess();

                gasEndPoint = gepDataAccess.FindByPosition(emptyEndPoint.Position, trx);

                if (gasEndPoint == null)
                {
                    return(null); // should we display an error?
                }
                if (gasEndPoint.Cylinder.Pressure == PressureLevel.Full)
                {
                    gasEndPoint.Cylinder.Pressure = PressureLevel.Low;
                    Log.Warning("Low pressure warning, position " + emptyEndPoint.Position);
                }
                else
                {
                    gasEndPoint.Cylinder.Pressure = PressureLevel.Empty;
                    Log.Warning("Empty pressure warning, position " + emptyEndPoint.Position);
                }

                Log.Debug(string.Format("Changing pressure to \"{0}\" for cylinder on position {1}", gasEndPoint.Cylinder.Pressure.ToString(), gasEndPoint.Position));
                Log.Debug(string.Format("...PartNumber={0}, FactoryId={1}", gasEndPoint.Cylinder.PartNumber, gasEndPoint.Cylinder.FactoryId));

                gepDataAccess.UpdatePressureLevel(gasEndPoint, trx);

                trx.Commit();
            }

            // After updating the database, we need to update the cached copy of the
            // installed cylinder, too, which is kept in the global DockingStation.
            GasEndPoint cachedGasEndPoint = Configuration.DockingStation.GasEndPoints.Find(g => g.Position == gasEndPoint.Position);

            if (cachedGasEndPoint != null)
            {
                cachedGasEndPoint.Cylinder.Pressure = gasEndPoint.Cylinder.Pressure;
            }

            // We need to inform iNet whenever a cylinder's pressure changes. We can only do this
            // by uploading a full docking station with the cylinder information.  Which means we
            // need to immediately do a SettingsRead to get the full docking station info, and then
            // upload that info along with the currently installed cylinder info.

            SettingsReadOperation settingsReadOperation = new SettingsReadOperation();

            // Explicitly set the ChangedSmartCards to all falses so that no smart cards are read.
            settingsReadOperation.ChangedSmartCards = new bool[Configuration.DockingStation.NumGasPorts];

            SettingsReadEvent settingsReadEvent = (SettingsReadEvent)settingsReadOperation.Execute();

            // Copy currently installed cylinder info to the docking station object we're going to upload.
            settingsReadEvent.DockingStation.GasEndPoints.Clear();
            settingsReadEvent.DockingStation.ChangedGasEndPoints.Clear();

            foreach (GasEndPoint gep in Configuration.DockingStation.GasEndPoints)
            {
                settingsReadEvent.DockingStation.GasEndPoints.Add((GasEndPoint)gep.Clone());
            }

            inetUploader.UploadEvent(settingsReadEvent, Configuration.DockingStation.TimeZoneInfo);

            // BEGIN INS-8630 RHP v7.5
            List <string> consoleMessages = new List <string>();

            consoleMessages.Add(gasEndPoint.Cylinder.Pressure.ToString());

            if (!string.IsNullOrEmpty(gasEndPoint.Cylinder.PartNumber)) // For ISC Pass the Cylinder Part Number
            {
                consoleMessages.Add(gasEndPoint.Cylinder.PartNumber);
            }
            // For Non ISC Pass the gas code. But I believe that both ISC and Non-ISC cylinders have their own PArt numbers.
            // So below condition may not be required ?
            else if (gasEndPoint.Cylinder.GasConcentrations.Count > 0)
            {
                consoleMessages.Add(gasEndPoint.Cylinder.GasConcentrations[0].Type.Symbol);
            }

            Log.Info("Sending IDS ReplaceCylinderAction");
            DockingStationAction dsAction = new ResourceUnavailableAction(new List <string>()
            {
                gasEndPoint.Cylinder.Pressure.ToString()
            }, consoleMessages);

            // END INS-8630

            return(dsAction);
        }
Ejemplo 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);
        }