/// <summary> /// Monitors the flow rate and adjustes voltage to pump as necessary in /// order to maintain desired flowrate. /// </summary> protected override void Run() { try { if (!Pump.IsRunning()) { return; } ConsoleState state = Master.ConsoleService.CurrentState; if (state == ConsoleState.Diagnosing || state == ConsoleState.InteractiveDiagnostics) { return; } int openedPosition = Pump.GetOpenValvePosition(); if (openedPosition > 0) { DateTime openTime = Pump.GetTimePumpStarted(); DateTime now = DateTime.UtcNow; Log.Debug(string.Format("Opened solenoid {0} at {1}", Pump.GetOpenValvePosition(), Log.DateTimeToString(openTime))); Pump.FlowStatus flowStatus = Pump.CheckFlow(); if (flowStatus != Pump.FlowStatus.TooLow) { _flowFailures = 0; if ((openTime != DateTime.MinValue) && ((now - openTime) > _periodAllowedOpen)) { Pump.CloseValve(openedPosition); // Close the valve. } } // Else, assumption is that FlowStatus is TooLow. (empty cylinder?) else if (((now - openTime) > _minOpenPeriod) && Pump.IsRunning()) { _flowFailures++; Log.Debug("Flow failed " + _flowFailures + " times."); if (_flowFailures >= _MIN_FLOW_FAILURES) { _flowFailures = 0; Pump.CloseValve(openedPosition); } else { Pump.OpenValve(Pump.GetOpenValvePosition(), false); } } } } catch (Exception e) { Log.Error(Name, e); } }
/// <summary> /// Test the specified solenoid /// </summary> /// <param name="details">The string to hold details.</param> private void TestFlow( DetailsBuilder details, int solenoid ) { // Validate the solenoid number if ( solenoid < 1 || solenoid > Configuration.DockingStation.NumGasPorts ) { Log.Debug( "TestFlow: Invalid solenoid value = " + solenoid.ToString() ); return; } Log.Debug( "TestFlow: port=" + solenoid.ToString() ); // Determine whether a cylinder is attached to this port. // If there is one attached, skip this test. DockingStation ds = Controller.GetDockingStation(); GasEndPoint gasEndPoint = ds.GasEndPoints.Find(m => m.Position == solenoid); if (gasEndPoint != null && gasEndPoint.Cylinder.IsFreshAir == false) { Log.Debug( "TestFlow: Cylinder attached to port " + solenoid.ToString() + "; SKIPPING THIS TEST." ); return; } Pump.DoCheckFlow = true; // Ensure that only the specified solenoid is open. Pump.CloseAllValves( true ); Thread.Sleep(500); // Give the valves a chance to finish closing Pump.OpenValve(solenoid, false); // Open the specified solenoid Thread.Sleep(500); // Pause at least 500ms. Pump.SetDesiredFlow( Pump.StandardFlowRate); Pump.Start( Pump.StandardStartVoltage ); // Turn on the pump. Thread.Sleep( 3000 ); // Wait for it to stabilize the flow before letting CheckFlow take its first reading. // CheckFlow could enter an infinite loop if it's unable to // establish the desired flow rate and we don't tell it to time out. // We therefore give it a time out of a minute which should be more than sufficient. ushort rawFlowCounts; ushort rawVacuumCounts; Pump.FlowStatus flowStatus = Pump.CheckFlow( new TimeSpan( 0, 1, 0 ), out rawFlowCounts, out rawVacuumCounts ); byte pumpVoltage = Pump.GetPumpVoltage(); // obtain and hold onto final voltage of the pump, to report it to inet. // Get the flow rate. ushort flowVolts = Pump.ConvertRawFlowToVolts( rawFlowCounts ); int flowRate = Pump.CalculateFlowRate( flowVolts, rawVacuumCounts ); // Convert that value to mL/min // Report the results. string flowString = BuildFlowString(flowRate, flowVolts); // We create a property for every value used to compute the flow rate, and also the flow rate itself. _gdpList.Add( new GeneralDiagnosticProperty( "DIAGNOSTIC_CHECK_FLOW_" + solenoid + "_VACUUM", rawVacuumCounts.ToString() ) ); _gdpList.Add( new GeneralDiagnosticProperty( "DIAGNOSTIC_CHECK_FLOW_" + solenoid + "_VACUUM_INCHES", Pump.ConvertRawVacuumToInches( rawVacuumCounts ).ToString() ) ); _gdpList.Add( new GeneralDiagnosticProperty( "DIAGNOSTIC_CHECK_FLOW_" + solenoid, rawFlowCounts.ToString() ) ); _gdpList.Add( new GeneralDiagnosticProperty( "DIAGNOSTIC_CHECK_FLOW_" + solenoid + "_VOLTS", flowVolts.ToString() ) ); _gdpList.Add( new GeneralDiagnosticProperty( "DIAGNOSTIC_CHECK_FLOW_" + solenoid + "_RATE", flowRate.ToString() ) ); _gdpList.Add( new GeneralDiagnosticProperty( "DIAGNOSTIC_CHECK_FLOW_" + solenoid + "_PUMP_VOLTS", pumpVoltage.ToString() ) ); // The flow is considered a failure if it's not equal to the StandardFlowRate plus/minus the standardtolerance bool flowFailed = flowRate < ( Pump.StandardFlowRate - Pump.FLOWRATE_TOLERANCE ) || flowRate > ( Pump.StandardFlowRate + Pump.FLOWRATE_TOLERANCE ); // TODO - we should rename the translation string so that it's prefixed with "CHECK_FLOW" instead of "SOLENOID_FLOW" ReportDiagnostic( details, details.GetText( "SOLENOID_FLOW_" + solenoid ), flowString, flowFailed ); // Check Pump Error Status -- FAIL IF STATE IS 1 int pumpErrorState = Pump.GetPumpErrorState(); // Report the results. _gdpList.Add( new GeneralDiagnosticProperty( "DIAGNOSTIC_CHECK_FLOW_" + solenoid + "_PUMP_ERROR", pumpErrorState.ToString() ) ); // TODO - we should rename the translation string so that it's prefixed with "CHECK_FLOW" instead of "SOLENOID_FLOW" ReportDiagnostic(details, details.GetText("SOLENOID_PUMP_ERROR_" + solenoid), pumpErrorState.ToString(), (pumpErrorState == 1)); // Stop the pump and close the solenoid Pump.CloseValve(solenoid); Pump.DoCheckFlow = false; }