/// <summary> /// Unpause the service, and immediately force it to update the charge status. /// </summary> public void Restart() { Log.Debug(Name + " Restarting..."); lock (this) { // Setting the interval equal to executeInterval will cause the charge status // to be updated on the service's next 'tick'. _currentInterval = new TimeSpan(_executeInterval.Ticks); // Whenever we restart the service, assume a docked instrument is charging (until we find out otherwise) if (IsBatteryRechargable()) { State = ChargingState.Charging; _phase = ChargePhase.FullCharge; } else { //State = ChargingState.NotCharging; _phase = ChargePhase.ChargeOff; } _phaseStart = DateTime.UtcNow; Paused = false; } }
/// <summary> /// Helper method for Run() which communicates with instrument to determine its charging status /// then updates charger service status properties /// </summary> private void RunUpdateChargerState() { const string funcName = "RunUpdateChargerState"; Log.Debug(string.Format("{0} invoking {1} on a \"{2}\" battery", Name, funcName, BatteryCode)); if (!Controller.IsDocked()) { Log.Debug(string.Format("{0}: instrument undocked.", funcName)); return; } try { InstrumentChargingOperation op = new InstrumentChargingOperation(); op.Execute(); // Keep track of consecutively occurring phases, and when they first occur. if (_phase != op.InstrumentChargePhase) { _phase = op.InstrumentChargePhase; _phaseStart = DateTime.UtcNow; } // If instrument is having any charging problems, report the error to server. // This will also allow the error to upload to iNet if they're an inet customer. if (_phase == ISC.iNet.DS.DomainModel.ChargePhase.ChargeFailure || _phase == ISC.iNet.DS.DomainModel.ChargePhase.ChargeFault // || _phase == ISC.iNet.DS.DomainModel.ChargePhase.ChargeOverTempFailure // || _phase == ISC.iNet.DS.DomainModel.ChargePhase.ChargeUnderTempFailure // || _phase == ISC.iNet.DS.DomainModel.ChargePhase.ChargeOff ( AND battery is lithium ) || _phase == ISC.iNet.DS.DomainModel.ChargePhase.PreChargeFault || _phase == ISC.iNet.DS.DomainModel.ChargePhase.ChargeTimeout) { // Do not change this message. iNet is parsing it! string msg = string.Format("Instrument \"{0}\" has reported a \"{1}\" charging error (Battery=\"{2}\", type=\"{3}\").", op.InstrumentSerialNumber, _phase.ToString(), op.BatterySerialNumber, op.BatteryCode); Master.ReporterService.ReportError(new DockingStationError(msg, DockingStationErrorLevel.Warning, op.InstrumentSerialNumber)); } // BatteryCode should be empty if user has docked a completely dead // battery. If the instrument has now charged up enough such that we // can now talk to it, then get the battery type. if (BatteryCode == string.Empty) { BatteryCode = op.BatteryCode; } if (op.ChargingState == ChargingState.Error) { // How much time has elasped between now and when we first saw the // instrument go into error? TimeSpan errorTimeElapsed = DateTime.UtcNow - _phaseStart; Log.Debug(string.Format("{0} - BATTERY IN {1} PHASE! ELAPSED TIME: {2}", Name, _phase.ToString(), errorTimeElapsed.ToString())); // Instrument hasn't been in error too long? Then // just treat it as if the intrument is normally charging; no need to // scare the user. But if it's been stuck in error too // long, then finally just report it as an error. TimeSpan maxTimeAllowed = (_phase == ChargePhase.ChargeOverTempFailure || _phase == ChargePhase.ChargeUnderTempFailure) ? _maxTempFailureTimeAllowed : _maxErrorPhaseAllowed; if (errorTimeElapsed <= maxTimeAllowed) { State = ChargingState.Charging; } else { State = ChargingState.Error; // Do not change this message. iNet is parsing it! string msg = string.Format("Instrument \"{0}\" has been in \"{1}\" for an overextended period of time ({2}). (Battery=\"{3}\", type=\"{4}\")", op.InstrumentSerialNumber, _phase.ToString(), errorTimeElapsed.ToString(), op.BatterySerialNumber, op.BatteryCode); Log.Error(string.Format("{0} - {1}", Name, msg.ToUpper())); Log.Error(string.Format("{0} - Reporting {1} to server", Name, op.InstrumentChargePhase.ToString())); Master.ReporterService.ReportError(new DockingStationError(msg, DockingStationErrorLevel.Warning, op.InstrumentSerialNumber)); } } // end ChargingState.Error else // op.State != ChargingState.Error { State = op.ChargingState; } Log.Debug(Name + " - ChargingState=" + State); // When instrument is done charging, then turn it off! if (State == ChargingState.NotCharging) { Log.Debug(Name + " - INSTRUMENT APPEARS FULLY CHARGED. TURNING OFF INSTRUMENT."); Log.Debug(Name + " - WILL NO LONGER POLL INSTRUMENT FOR CHARGING STATUS."); new InstrumentTurnOffOperation(InstrumentTurnOffOperation.Reason.ChargingComplete).Execute(); } } catch (InstrumentPingFailedException e) { Log.Error(Name, e); if (!Controller.IsDocked()) // May have got the exception because they undocked. Ignore it. { State = ChargingState.NotCharging; } else { State = ChargingState.Error; // Couldn't ping the instrument. dead battery? } } catch (Exception e) { Log.Error(Name, e); // Whatever the error was, if the instrument isn't present, then it's // not charging. if (!Controller.IsDocked()) { State = ChargingState.NotCharging; } // Not sure what the error is. Leave charging state as is. } }