Search code examples
c#windowsuwpbattery

C#: Does Windows.Devices.Power.Battery.ReportUpdate state if computer is plugged in, and limiting events


I would like to be informed when the computer has been unplugged and is running on battery. Once on battery I'd like to know when the battery percentage reaches 25%. I'd prefer an event, but can poll if necessary.

There are several ways to check if the computer is plugged in or on battery. You can poll and look at:

System.Windows.SystemParameters.PowerLineStatus == System.Windows.PowerLineStatus.Offline;

var batteryPercentage == SystemInformation.PowerStatus.BatteryLifePercent;

I don't see any down sides to this other than having to poll.

You can also use the event ReportUpdate from Windows.Devices.Power.Battery.AggregateBattery.ReportUpdated. This seems tantalizingly close to what I want. From this you can get BatteryStatus Enum.

The possibilities are Charging, Discharging, Idle, and NotPresent. My guess would be that Charging or Idle necessarily mean the laptop is plugged in, and Discharging would mean it is only on battery. But that's just my guess! It doesn't say that anywhere in the documentation. I could imagine that you could have a really bad battery that is discharging even though it is plugged in. How do I tell definitively it is plugged in?

Additionally, there are really too many events. I don't really want an event when it's plugged in and charging and the battery percentage goes up. I really only care about it being unplugged, and once it's unplugged, getting to 25%. I suppose if there are not too many events I can ignore the unnecessary information. Is there a way to cut down or choose the events or are there not too many and I should ignore this?


Solution

  • I really only care about it being unplugged, and once it's unplugged, getting to 25%

    Please check Get battery information, Once you have an aggregate battery object, call GetReport to get the corresponding BatteryReport.

    The Battery object triggers the ReportUpdated event when charge, capacity, or status of the battery changes. This typically happens immediately for status changes and periodically for all other changes.

    Battery.AggregateBattery.ReportUpdated += AggregateBattery_ReportUpdated;
    
    async private void AggregateBattery_ReportUpdated(Battery sender, object args)
    {
        if (reportRequested)
        {
    
            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                // Clear UI
                BatteryReportPanel.Children.Clear();
    
    
                if (AggregateButton.IsChecked == true)
                {
                    // Request aggregate battery report
                    RequestAggregateBatteryReport();
                }
                else
                {
                    // Request individual battery report
                    RequestIndividualBatteryReports();
                }
            });
        }
    }
    

    If you just want to detect it's unplugged and getting to 25%. you could package above code with a method.

    For example:

    public static class BatteryUnpluggedTo25
    {
        private static Action<bool> _action;
        public static void Report(Action<bool> action)
        {
            Battery.AggregateBattery.ReportUpdated += AggregateBattery_ReportUpdated;
            _action = action;
        }
    
        private static void AggregateBattery_ReportUpdated(Battery sender, object args)
        {
            var aggBattery = Battery.AggregateBattery;
            var report = aggBattery.GetReport();
            switch (report.Status)
            {
                case Windows.System.Power.BatteryStatus.NotPresent:
                    break;
                case Windows.System.Power.BatteryStatus.Discharging:
                    currentBatteryLevel(report, _action);
                    break;
                case Windows.System.Power.BatteryStatus.Idle:
                    break;
                case Windows.System.Power.BatteryStatus.Charging:
    
                    break;
                default:
                    break;
            }
        }
        private  static void currentBatteryLevel(BatteryReport report, Action<bool> action)
        {
    
            var Maximum = Convert.ToDouble(report.FullChargeCapacityInMilliwattHours);
            var Value = Convert.ToDouble(report.RemainingCapacityInMilliwattHours);
            var level = Value / Maximum;
    
            if (level <= 0.25)
            {
                action(true);
            }
    
        }
    }
    

    Usage

    BatteryUnpluggedTo25.Report((s) =>
    {
    
        if (s == true)
        {
          // do something
        }
    });