public void Run(ZACommons commons) { var batteries = GetBatteries(commons); if (CurrentState == null) { // First time run, get to known state and return CurrentState = STATE_NORMAL; SinceLastStateChange = TimeSpan.FromSeconds(0); ZACommons.SetBatteryRecharge(batteries, false); return; } SinceLastStateChange += commons.Program.ElapsedTime; var aggregateDetails = new AggregateBatteryDetails(batteries); string stateStr = "Unknown"; switch (CurrentState) { case STATE_NORMAL: if (SinceLastStateChange >= DischargeInterval) { // Don't check again until next interval, regardless of whether we // change state SinceLastStateChange = TimeSpan.FromSeconds(0); // Only recharge if there is available power, e.g. the batteries have no load, // and there is need to if (aggregateDetails.CurrentPowerOutput == 0.0f && aggregateDetails.CurrentStoredPower < aggregateDetails.MaxStoredPower && Active) { CurrentState = STATE_RECHARGE; ZACommons.SetBatteryRecharge(batteries, true); } else { // Force discharge, just in case ZACommons.SetBatteryRecharge(batteries, false); } } stateStr = Active ? "Normal" : "Paused"; break; case STATE_RECHARGE: // Too bad we don't have access to battery input (w/o parsing DetailInfo) // Then we could figure out non-battery load and cancel recharge pre-emptively // when needed if (SinceLastStateChange >= RechargeInterval) { CurrentState = STATE_NORMAL; SinceLastStateChange = TimeSpan.FromSeconds(0); ZACommons.SetBatteryRecharge(batteries, false); } stateStr = "Recharging"; break; case STATE_DISABLED: // Switch back to auto if full if (aggregateDetails.CurrentStoredPower >= aggregateDetails.MaxStoredPower) { CurrentState = STATE_NORMAL; SinceLastStateChange = TimeSpan.FromSeconds(0); ZACommons.SetBatteryRecharge(batteries, false); } stateStr = "Disabled"; break; } // See if we have a net power loss var newDraining = AddDrainData(aggregateDetails.CurrentPowerOutput > 0.0f); if (powerDrainHandler != null) { if (!Draining && newDraining) { powerDrainHandler.PowerDrainStarted(commons); } else if (Draining && !newDraining) { powerDrainHandler.PowerDrainEnded(commons); } } Draining = newDraining; commons.Echo(string.Format("Battery Manager: {0}", stateStr)); commons.Echo(string.Format("Total Stored Power: {0}h", ZACommons.FormatPower(aggregateDetails.CurrentStoredPower))); commons.Echo(string.Format("Max Stored Power: {0}h", ZACommons.FormatPower(aggregateDetails.MaxStoredPower))); if (Draining) commons.Echo("Net power loss!"); }
public void Run(ZACommons commons) { var batteries = GetBatteries(commons); if (CurrentState == null) { // First time run, get to known state and return CurrentState = STATE_NORMAL; SinceLastStateChange = TimeSpan.FromSeconds(0); ZACommons.SetBatteryRecharge(batteries, false); return; } SinceLastStateChange += commons.Program.ElapsedTime; var aggregateDetails = new AggregateBatteryDetails(batteries); string stateStr = "Unknown"; switch (CurrentState) { case STATE_NORMAL: if (SinceLastStateChange >= DischargeInterval) { // Don't check again until next interval, regardless of whether we // change state SinceLastStateChange = TimeSpan.FromSeconds(0); // Only recharge if there is available power, e.g. the batteries have no load, // and there is need to if (aggregateDetails.CurrentPowerOutput == 0.0f && aggregateDetails.CurrentStoredPower < aggregateDetails.MaxStoredPower && Active) { CurrentState = STATE_RECHARGE; ZACommons.SetBatteryRecharge(batteries, true); } else { // Force discharge, just in case ZACommons.SetBatteryRecharge(batteries, false); } } stateStr = Active ? "Normal" : "Paused"; break; case STATE_RECHARGE: // Too bad we don't have access to battery input (w/o parsing DetailInfo) // Then we could figure out non-battery load and cancel recharge pre-emptively // when needed if (SinceLastStateChange >= RechargeInterval) { CurrentState = STATE_NORMAL; SinceLastStateChange = TimeSpan.FromSeconds(0); ZACommons.SetBatteryRecharge(batteries, false); } stateStr = "Recharging"; break; case STATE_DISABLED: // Switch back to auto if full if (aggregateDetails.CurrentStoredPower >= aggregateDetails.MaxStoredPower) { CurrentState = STATE_NORMAL; SinceLastStateChange = TimeSpan.FromSeconds(0); ZACommons.SetBatteryRecharge(batteries, false); } stateStr = "Disabled"; break; } // See if we have a net power loss var newDraining = AddDrainData(aggregateDetails.CurrentPowerOutput > 0.0f); if (powerDrainHandler != null) { if (!Draining && newDraining) { powerDrainHandler.PowerDrainStarted(commons); } else if (Draining && !newDraining) { powerDrainHandler.PowerDrainEnded(commons); } } Draining = newDraining; commons.Echo(string.Format("Battery Manager: {0}", stateStr)); commons.Echo(string.Format("Total Stored Power: {0}h", ZACommons.FormatPower(aggregateDetails.CurrentStoredPower))); commons.Echo(string.Format("Max Stored Power: {0}h", ZACommons.FormatPower(aggregateDetails.MaxStoredPower))); if (Draining) { commons.Echo("Net power loss!"); } }