private DockingStationAction ExamineErrors(DockingStationEvent dsEvent, InetUploader inet) { DockingStationErrorLevel highestError = DockingStationErrorLevel.None; DockingStationAction dsAction = null; foreach (DockingStationError error in dsEvent.Errors) { highestError = (DockingStationErrorLevel)Math.Max((int)error.ErrorLevel, (int)highestError); } if (dsAction != null) { return(dsAction); } if (highestError >= DockingStationErrorLevel.Error) { dsAction = new UnavailableAction(); Log.Debug(string.Format("{0}Returning {1}", Name, dsAction.Name)); return(dsAction); } return(null); }
/// <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); }