private IEnumerator <object> Run() { foreach (var yieldPoint in MaybeRescan()) { yield return(yieldPoint); } var batteriesState = new BatteriesState(); ScanBatteries(ref batteriesState); yield return(null); var reactorsState = new ReactorsState(); ScanReactors(ref reactorsState); yield return(null); if (UpdateState(batteriesState, reactorsState) && state.Display != null) { // Yield, then rescan before drawing display. yield return(null); ScanBatteries(ref batteriesState); yield return(null); ScanReactors(ref reactorsState); } if (state.Display != null) { yield return(null); new DisplayRenderer().Draw(state.Display, batteriesState, reactorsState); } }
private bool UpdateState(BatteriesState batteriesState, ReactorsState reactorsState) { /* * If battery power draw is near the limit, or remaining battery power is below the threshold, switch to reactors. * Otherwise if reactor power draw is low enough, switch to batteries. * Returns true if anything changed. */ var isBatteryTimeBelowThreshold = batteriesState.SecondsRemaining < Constants.ENABLE_REACTOR_THRESHOLD_BATTERY_POWER_SECONDS; var isBatteryPowerDrawNearLimit = batteriesState.PowerDrawPercent > Constants.POWER_DRAW_THRESHOLD_PERCENT; if (isBatteryTimeBelowThreshold || isBatteryPowerDrawNearLimit) { if (batteriesState.Charging > 0 || reactorsState.Enabled < state.Reactors.Count) { SwitchToReactors(); return(true); } } else if (reactorsState.PowerConsumedMW < Constants.DISABLE_REACTOR_THRESHOLD_POWER_DRAW_MW) { if (batteriesState.Charging < state.Batteries.Count || reactorsState.Enabled > 0) { SwitchToBatteries(); return(true); } } return(false); }
private void ScanBatteries(ref BatteriesState batteriesState) { foreach (var battery in state.Batteries) { batteriesState.MaxEnergyMWh += battery.MaxStoredPower; batteriesState.EnergyRemainingMWh += battery.CurrentStoredPower; batteriesState.PowerConsumedMW += battery.CurrentOutput - battery.CurrentInput; batteriesState.PowerDrawMW += battery.CurrentOutput; batteriesState.MaxPowerDrawMW += battery.MaxOutput; if (battery.Enabled && battery.ChargeMode != ChargeMode.Discharge) { batteriesState.Charging++; } } }
public void Draw(IMyTextPanel display, BatteriesState batteriesState, ReactorsState reactorsState) { local_DrawDisplay_builder.Clear(); local_DrawDisplay_builder.AppendFormat("Power Management {0}\n", Datestamp.Minutes); var totalEnergyRemainingMWh = batteriesState.EnergyRemainingMWh + reactorsState.EnergyRemainingMWh; var totalPowerConsumptionMW = batteriesState.PowerConsumedMW + reactorsState.PowerConsumedMW; var totalSecondsRemaining = totalPowerConsumptionMW > 0 ? (3600 * totalEnergyRemainingMWh / totalPowerConsumptionMW) : float.PositiveInfinity; local_DrawDisplay_builder.Append("Total Time: "); AppendTimeRemaining(local_DrawDisplay_builder, totalSecondsRemaining); local_DrawDisplay_builder.AppendLine(); if (totalSecondsRemaining < Constants.ALERT_POWER_SECONDS) { local_DrawDisplay_builder.AppendLine("*** L O W P O W E R ***"); } local_DrawDisplay_builder.AppendLine(); local_DrawDisplay_builder.Append("Batteries: "); local_DrawDisplay_builder.AppendLine(batteriesState.Charging > 0 ? "Auto" : "Discharging"); local_DrawDisplay_builder.Append("* Stored: "); local_DrawDisplay_builder.Append(Unit.Energy.FormatSI(batteriesState.EnergyRemainingMWh)); local_DrawDisplay_builder.Append(" / "); local_DrawDisplay_builder.Append(Unit.Energy.FormatSI(batteriesState.MaxEnergyMWh)); local_DrawDisplay_builder.AppendLine(); local_DrawDisplay_builder.Append("* Power: "); local_DrawDisplay_builder.Append(Unit.Power.FormatSI(Math.Max(batteriesState.PowerConsumedMW, 0))); local_DrawDisplay_builder.AppendFormat(" ({0}%)", batteriesState.PowerDrawPercent); local_DrawDisplay_builder.AppendLine(); local_DrawDisplay_builder.Append("* Time: "); AppendTimeRemaining(local_DrawDisplay_builder, batteriesState.SecondsRemaining); local_DrawDisplay_builder.AppendLine(); local_DrawDisplay_builder.AppendLine(); local_DrawDisplay_builder.Append("Reactors: "); local_DrawDisplay_builder.AppendLine(reactorsState.Enabled > 0 ? "Enabled" : "Disabled"); local_DrawDisplay_builder.Append("* Fuel: "); local_DrawDisplay_builder.Append(Unit.Mass.FormatSI(reactorsState.FuelAvailableKg)); local_DrawDisplay_builder.Append(" ("); local_DrawDisplay_builder.Append(Unit.Energy.FormatSI(reactorsState.EnergyRemainingMWh)); local_DrawDisplay_builder.AppendLine(")"); local_DrawDisplay_builder.Append("* Power: "); local_DrawDisplay_builder.Append(Unit.Power.FormatSI(Math.Max(reactorsState.PowerConsumedMW, 0))); local_DrawDisplay_builder.AppendFormat(" ({0:P})", reactorsState.PowerDrawPercent); local_DrawDisplay_builder.AppendLine(); local_DrawDisplay_builder.Append("* Time: "); AppendTimeRemaining(local_DrawDisplay_builder, reactorsState.SecondsRemaining); local_DrawDisplay_builder.AppendLine(); if (totalSecondsRemaining < Constants.ALERT_POWER_SECONDS) { local_DrawDisplay_builder.AppendLine(); local_DrawDisplay_builder.AppendLine("*** L O W P O W E R ***"); } display.WriteText(local_DrawDisplay_builder); }