Show battery level for selected devices in Power Monitoring Console (#33854)
* Use class instead of out variables * Show battery level in power monitoring console * Better color contrast for battery level + localized string * Add visualization to battery percentage * Reverts random ChatSystem.cs whitespace change * Address review * Show BatteryLevel stats in child view when selecting devices --------- Co-authored-by: Crotalus <crotalus@users.noreply.github.com>
This commit is contained in:
@@ -6,6 +6,7 @@ using Robust.Shared.Utility;
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using Vector4 = Robust.Shared.Maths.Vector4;
|
||||||
|
|
||||||
namespace Content.Client.Power;
|
namespace Content.Client.Power;
|
||||||
|
|
||||||
@@ -104,6 +105,26 @@ public sealed partial class PowerMonitoringWindow
|
|||||||
// Update power value
|
// Update power value
|
||||||
// Don't use SI prefixes, just give the number in W, so that it is readily apparent which consumer is using a lot of power.
|
// Don't use SI prefixes, just give the number in W, so that it is readily apparent which consumer is using a lot of power.
|
||||||
button.PowerValue.Text = Loc.GetString("power-monitoring-window-button-value", ("value", Math.Round(entry.PowerValue).ToString("N0")));
|
button.PowerValue.Text = Loc.GetString("power-monitoring-window-button-value", ("value", Math.Round(entry.PowerValue).ToString("N0")));
|
||||||
|
|
||||||
|
// Update battery level if applicable
|
||||||
|
if (entry.BatteryLevel != null)
|
||||||
|
{
|
||||||
|
button.BatteryLevel.Value = entry.BatteryLevel.Value;
|
||||||
|
button.BatteryLevel.Visible = true;
|
||||||
|
|
||||||
|
button.BatteryPercentage.Text = entry.BatteryLevel.Value.ToString("P0");
|
||||||
|
button.BatteryPercentage.Visible = true;
|
||||||
|
|
||||||
|
// Set progress bar color based on percentage
|
||||||
|
var color = Color.FromHsv(new Vector4(entry.BatteryLevel.Value * 0.33f, 1, 1, 1));
|
||||||
|
|
||||||
|
button.BatteryLevel.ForegroundStyleBoxOverride = new StyleBoxFlat { BackgroundColor = color };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
button.BatteryLevel.Visible = false;
|
||||||
|
button.BatteryPercentage.Visible = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateEntrySourcesOrLoads(BoxContainer masterContainer, BoxContainer currentContainer, PowerMonitoringConsoleEntry[]? entries, SpriteSpecifier.Texture icon)
|
private void UpdateEntrySourcesOrLoads(BoxContainer masterContainer, BoxContainer currentContainer, PowerMonitoringConsoleEntry[]? entries, SpriteSpecifier.Texture icon)
|
||||||
@@ -443,6 +464,11 @@ public sealed class PowerMonitoringButton : Button
|
|||||||
public BoxContainer MainContainer;
|
public BoxContainer MainContainer;
|
||||||
public TextureRect TextureRect;
|
public TextureRect TextureRect;
|
||||||
public Label NameLocalized;
|
public Label NameLocalized;
|
||||||
|
|
||||||
|
public ProgressBar BatteryLevel;
|
||||||
|
public PanelContainer BackgroundPanel;
|
||||||
|
public Label BatteryPercentage;
|
||||||
|
|
||||||
public Label PowerValue;
|
public Label PowerValue;
|
||||||
|
|
||||||
public PowerMonitoringButton()
|
public PowerMonitoringButton()
|
||||||
@@ -478,6 +504,49 @@ public sealed class PowerMonitoringButton : Button
|
|||||||
|
|
||||||
MainContainer.AddChild(NameLocalized);
|
MainContainer.AddChild(NameLocalized);
|
||||||
|
|
||||||
|
BatteryLevel = new ProgressBar()
|
||||||
|
{
|
||||||
|
SetWidth = 47f,
|
||||||
|
SetHeight = 20f,
|
||||||
|
Margin = new Thickness(15, 0, 0, 0),
|
||||||
|
MaxValue = 1,
|
||||||
|
Visible = false,
|
||||||
|
BackgroundStyleBoxOverride = new StyleBoxFlat { BackgroundColor = Color.Black },
|
||||||
|
};
|
||||||
|
|
||||||
|
MainContainer.AddChild(BatteryLevel);
|
||||||
|
|
||||||
|
BackgroundPanel = new PanelContainer
|
||||||
|
{
|
||||||
|
// Draw a half-transparent box over the battery level to make the text more readable.
|
||||||
|
PanelOverride = new StyleBoxFlat
|
||||||
|
{
|
||||||
|
BackgroundColor = new Color(0, 0, 0, 0.9f)
|
||||||
|
},
|
||||||
|
HorizontalAlignment = HAlignment.Center,
|
||||||
|
VerticalAlignment = VAlignment.Center,
|
||||||
|
HorizontalExpand = true,
|
||||||
|
VerticalExpand = true,
|
||||||
|
// Box is undersized perfectly compared to the progress bar, so a little bit of the unaffected progress bar is visible.
|
||||||
|
SetSize = new Vector2(43f, 16f)
|
||||||
|
};
|
||||||
|
|
||||||
|
BatteryLevel.AddChild(BackgroundPanel);
|
||||||
|
|
||||||
|
BatteryPercentage = new Label()
|
||||||
|
{
|
||||||
|
VerticalAlignment = VAlignment.Center,
|
||||||
|
HorizontalAlignment = HAlignment.Center,
|
||||||
|
Align = Label.AlignMode.Center,
|
||||||
|
SetWidth = 45f,
|
||||||
|
MinWidth = 20f,
|
||||||
|
Margin = new Thickness(10, -4, 10, 0),
|
||||||
|
ClipText = true,
|
||||||
|
Visible = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
BackgroundPanel.AddChild(BatteryPercentage);
|
||||||
|
|
||||||
PowerValue = new Label()
|
PowerValue = new Label()
|
||||||
{
|
{
|
||||||
HorizontalAlignment = HAlignment.Right,
|
HorizontalAlignment = HAlignment.Right,
|
||||||
|
|||||||
@@ -350,19 +350,20 @@ internal sealed partial class PowerMonitoringConsoleSystem : SharedPowerMonitori
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Get the device power stats
|
// Get the device power stats
|
||||||
var powerValue = GetPrimaryPowerValues(ent, device, out var powerSupplied, out var powerUsage, out var batteryUsage);
|
var powerStats = GetPowerStats(ent, device);
|
||||||
|
//, out var powerSupplied, out var powerUsage, out var batteryUsage);
|
||||||
|
|
||||||
// Update all running totals
|
// Update all running totals
|
||||||
totalSources += powerSupplied;
|
totalSources += powerStats.PowerSupplied;
|
||||||
totalLoads += powerUsage;
|
totalLoads += powerStats.PowerUsage;
|
||||||
totalBatteryUsage += batteryUsage;
|
totalBatteryUsage += powerStats.BatteryUsage;
|
||||||
|
|
||||||
// Continue on if the device is not in the current focus group
|
// Continue on if the device is not in the current focus group
|
||||||
if (device.Group != component.FocusGroup)
|
if (device.Group != component.FocusGroup)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Generate a new console entry with which to populate the UI
|
// Generate a new console entry with which to populate the UI
|
||||||
var entry = new PowerMonitoringConsoleEntry(EntityManager.GetNetEntity(ent), device.Group, powerValue);
|
var entry = new PowerMonitoringConsoleEntry(EntityManager.GetNetEntity(ent), device.Group, powerStats.PowerValue, powerStats.BatteryLevel);
|
||||||
allEntries.Add(entry);
|
allEntries.Add(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,28 +427,28 @@ internal sealed partial class PowerMonitoringConsoleSystem : SharedPowerMonitori
|
|||||||
loadsForFocus.ToArray()));
|
loadsForFocus.ToArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private double GetPrimaryPowerValues(EntityUid uid, PowerMonitoringDeviceComponent device, out double powerSupplied, out double powerUsage, out double batteryUsage)
|
private PowerStats GetPowerStats(EntityUid uid, PowerMonitoringDeviceComponent device)
|
||||||
{
|
{
|
||||||
var powerValue = 0d;
|
var stats = new PowerStats();
|
||||||
powerSupplied = 0d;
|
|
||||||
powerUsage = 0d;
|
|
||||||
batteryUsage = 0d;
|
|
||||||
|
|
||||||
if (device.Group == PowerMonitoringConsoleGroup.Generator)
|
if (device.Group == PowerMonitoringConsoleGroup.Generator)
|
||||||
{
|
{
|
||||||
// This covers most power sources
|
// This covers most power sources
|
||||||
if (TryComp<PowerSupplierComponent>(uid, out var supplier))
|
if (TryComp<PowerSupplierComponent>(uid, out var supplier))
|
||||||
{
|
{
|
||||||
powerValue = supplier.CurrentSupply;
|
stats.PowerValue = supplier.CurrentSupply;
|
||||||
powerSupplied += powerValue;
|
stats.PowerSupplied += stats.PowerValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Edge case: radiation collectors
|
// Edge case: radiation collectors
|
||||||
else if (TryComp<BatteryDischargerComponent>(uid, out var _) &&
|
else if (TryComp<BatteryDischargerComponent>(uid, out var _) &&
|
||||||
TryComp<PowerNetworkBatteryComponent>(uid, out var battery))
|
TryComp<PowerNetworkBatteryComponent>(uid, out var battery))
|
||||||
{
|
{
|
||||||
powerValue = battery.NetworkBattery.CurrentSupply;
|
stats.PowerValue = battery.NetworkBattery.CurrentSupply;
|
||||||
powerSupplied += powerValue;
|
stats.PowerSupplied += stats.PowerValue;
|
||||||
|
|
||||||
|
|
||||||
|
stats.BatteryLevel = GetBatteryLevel(uid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,18 +459,20 @@ internal sealed partial class PowerMonitoringConsoleSystem : SharedPowerMonitori
|
|||||||
|
|
||||||
if (TryComp<PowerNetworkBatteryComponent>(uid, out var battery))
|
if (TryComp<PowerNetworkBatteryComponent>(uid, out var battery))
|
||||||
{
|
{
|
||||||
powerValue = battery.CurrentSupply;
|
stats.BatteryLevel = GetBatteryLevel(uid);
|
||||||
|
|
||||||
|
stats.PowerValue = battery.CurrentSupply;
|
||||||
|
|
||||||
// Load due to network battery recharging
|
// Load due to network battery recharging
|
||||||
powerUsage += Math.Max(battery.CurrentReceiving - battery.CurrentSupply, 0d);
|
stats.PowerUsage += Math.Max(battery.CurrentReceiving - battery.CurrentSupply, 0d);
|
||||||
|
|
||||||
// Track battery usage
|
// Track battery usage
|
||||||
batteryUsage += Math.Max(battery.CurrentSupply - battery.CurrentReceiving, 0d);
|
stats.BatteryUsage += Math.Max(battery.CurrentSupply - battery.CurrentReceiving, 0d);
|
||||||
|
|
||||||
// Records loads attached to APCs
|
// Records loads attached to APCs
|
||||||
if (device.Group == PowerMonitoringConsoleGroup.APC && battery.Enabled)
|
if (device.Group == PowerMonitoringConsoleGroup.APC && battery.Enabled)
|
||||||
{
|
{
|
||||||
powerUsage += battery.NetworkBattery.LoadingNetworkDemand;
|
stats.PowerUsage += battery.NetworkBattery.LoadingNetworkDemand;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -486,16 +489,28 @@ internal sealed partial class PowerMonitoringConsoleSystem : SharedPowerMonitori
|
|||||||
if (childDevice.IsCollectionMaster && childDevice.ChildDevices.ContainsKey(uid))
|
if (childDevice.IsCollectionMaster && childDevice.ChildDevices.ContainsKey(uid))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var childPowerValue = GetPrimaryPowerValues(child, childDevice, out var childPowerSupplied, out var childPowerUsage, out var childBatteryUsage);
|
var childResult = GetPowerStats(child, childDevice);
|
||||||
|
|
||||||
powerValue += childPowerValue;
|
stats.PowerValue += childResult.PowerValue;
|
||||||
powerSupplied += childPowerSupplied;
|
stats.PowerSupplied += childResult.PowerSupplied;
|
||||||
powerUsage += childPowerUsage;
|
stats.PowerUsage += childResult.PowerUsage;
|
||||||
batteryUsage += childBatteryUsage;
|
stats.BatteryUsage += childResult.BatteryUsage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return powerValue;
|
return stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float? GetBatteryLevel(EntityUid uid)
|
||||||
|
{
|
||||||
|
if (!TryComp<BatteryComponent>(uid, out var battery))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var effectiveMax = battery.MaxCharge;
|
||||||
|
if (effectiveMax == 0)
|
||||||
|
effectiveMax = 1;
|
||||||
|
|
||||||
|
return battery.CurrentCharge / effectiveMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GetSourcesForNode(EntityUid uid, Node node, out List<PowerMonitoringConsoleEntry> sources)
|
private void GetSourcesForNode(EntityUid uid, Node node, out List<PowerMonitoringConsoleEntry> sources)
|
||||||
@@ -532,7 +547,7 @@ internal sealed partial class PowerMonitoringConsoleSystem : SharedPowerMonitori
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
indexedSources.Add(ent, new PowerMonitoringConsoleEntry(EntityManager.GetNetEntity(ent), entDevice.Group, powerSupplier.CurrentSupply));
|
indexedSources.Add(ent, new PowerMonitoringConsoleEntry(EntityManager.GetNetEntity(ent), entDevice.Group, powerSupplier.CurrentSupply, GetBatteryLevel(ent)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -562,7 +577,7 @@ internal sealed partial class PowerMonitoringConsoleSystem : SharedPowerMonitori
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
indexedSources.Add(ent, new PowerMonitoringConsoleEntry(EntityManager.GetNetEntity(ent), entDevice.Group, entBattery.CurrentSupply));
|
indexedSources.Add(ent, new PowerMonitoringConsoleEntry(EntityManager.GetNetEntity(ent), entDevice.Group, entBattery.CurrentSupply, GetBatteryLevel(ent)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -609,7 +624,7 @@ internal sealed partial class PowerMonitoringConsoleSystem : SharedPowerMonitori
|
|||||||
for (int i = 0; i < sources.Count; i++)
|
for (int i = 0; i < sources.Count; i++)
|
||||||
{
|
{
|
||||||
var entry = sources[i];
|
var entry = sources[i];
|
||||||
sources[i] = new PowerMonitoringConsoleEntry(entry.NetEntity, entry.Group, entry.PowerValue * powerFraction);
|
sources[i] = new PowerMonitoringConsoleEntry(entry.NetEntity, entry.Group, entry.PowerValue * powerFraction, entry.BatteryLevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -646,7 +661,7 @@ internal sealed partial class PowerMonitoringConsoleSystem : SharedPowerMonitori
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
indexedLoads.Add(ent, new PowerMonitoringConsoleEntry(EntityManager.GetNetEntity(ent), entDevice.Group, powerConsumer.ReceivedPower));
|
indexedLoads.Add(ent, new PowerMonitoringConsoleEntry(EntityManager.GetNetEntity(ent), entDevice.Group, powerConsumer.ReceivedPower, GetBatteryLevel(ent)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -676,7 +691,7 @@ internal sealed partial class PowerMonitoringConsoleSystem : SharedPowerMonitori
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
indexedLoads.Add(ent, new PowerMonitoringConsoleEntry(EntityManager.GetNetEntity(ent), entDevice.Group, battery.CurrentReceiving));
|
indexedLoads.Add(ent, new PowerMonitoringConsoleEntry(EntityManager.GetNetEntity(ent), entDevice.Group, battery.CurrentReceiving, GetBatteryLevel(ent)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -713,7 +728,7 @@ internal sealed partial class PowerMonitoringConsoleSystem : SharedPowerMonitori
|
|||||||
for (int i = 0; i < indexedLoads.Values.Count; i++)
|
for (int i = 0; i < indexedLoads.Values.Count; i++)
|
||||||
{
|
{
|
||||||
var entry = loads[i];
|
var entry = loads[i];
|
||||||
loads[i] = new PowerMonitoringConsoleEntry(entry.NetEntity, entry.Group, entry.PowerValue * powerFraction);
|
loads[i] = new PowerMonitoringConsoleEntry(entry.NetEntity, entry.Group, entry.PowerValue * powerFraction, entry.BatteryLevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -990,4 +1005,13 @@ internal sealed partial class PowerMonitoringConsoleSystem : SharedPowerMonitori
|
|||||||
|
|
||||||
Dirty(uid, component);
|
Dirty(uid, component);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private struct PowerStats
|
||||||
|
{
|
||||||
|
public double PowerValue { get; set; }
|
||||||
|
public double PowerSupplied { get; set; }
|
||||||
|
public double PowerUsage { get; set; }
|
||||||
|
public double BatteryUsage { get; set; }
|
||||||
|
public float? BatteryLevel { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,14 +102,16 @@ public struct PowerMonitoringConsoleEntry
|
|||||||
public NetEntity NetEntity;
|
public NetEntity NetEntity;
|
||||||
public PowerMonitoringConsoleGroup Group;
|
public PowerMonitoringConsoleGroup Group;
|
||||||
public double PowerValue;
|
public double PowerValue;
|
||||||
|
public float? BatteryLevel;
|
||||||
|
|
||||||
[NonSerialized] public PowerMonitoringDeviceMetaData? MetaData = null;
|
[NonSerialized] public PowerMonitoringDeviceMetaData? MetaData = null;
|
||||||
|
|
||||||
public PowerMonitoringConsoleEntry(NetEntity netEntity, PowerMonitoringConsoleGroup group, double powerValue = 0d)
|
public PowerMonitoringConsoleEntry(NetEntity netEntity, PowerMonitoringConsoleGroup group, double powerValue = 0d, float? batteryLevel = null)
|
||||||
{
|
{
|
||||||
NetEntity = netEntity;
|
NetEntity = netEntity;
|
||||||
Group = group;
|
Group = group;
|
||||||
PowerValue = powerValue;
|
PowerValue = powerValue;
|
||||||
|
BatteryLevel = batteryLevel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ power-monitoring-window-show-hv-cable = High voltage
|
|||||||
power-monitoring-window-show-mv-cable = Medium voltage
|
power-monitoring-window-show-mv-cable = Medium voltage
|
||||||
power-monitoring-window-show-lv-cable = Low voltage
|
power-monitoring-window-show-lv-cable = Low voltage
|
||||||
|
|
||||||
power-monitoring-window-flavor-left = [user@nanotrasen] $run power_net_query
|
power-monitoring-window-flavor-left = [user@nanotrasen] $run power_net_query
|
||||||
power-monitoring-window-flavor-right = v1.3
|
power-monitoring-window-flavor-right = v1.3
|
||||||
power-monitoring-window-rogue-power-consumer = [color=white][font size=14][bold]! WARNING - ROGUE POWER CONSUMING DEVICE DETECTED ![/bold][/font][/color]
|
power-monitoring-window-rogue-power-consumer = [color=white][font size=14][bold]! WARNING - ROGUE POWER CONSUMING DEVICE DETECTED ![/bold][/font][/color]
|
||||||
power-monitoring-window-power-net-abnormalities = [color=white][font size=14][bold]CAUTION - ABNORMAL ACTIVITY IN POWER NET[/bold][/font][/color]
|
power-monitoring-window-power-net-abnormalities = [color=white][font size=14][bold]CAUTION - ABNORMAL ACTIVITY IN POWER NET[/bold][/font][/color]
|
||||||
|
|||||||
Reference in New Issue
Block a user