user2612049
user2612049

Reputation:

Automatic battery level check in C#

I'm working on a speech recognition program in C# and I've compiled a few lines of code that speaks back the current battery level when I say "battery level".

if (e.Result.Text.ToLower() == "battery level")
{
System.Management.ManagementClass wmi = new System.Management.ManagementClass("Win32_Battery");
var allBatteries = wmi.GetInstances();
//String estimatedChargeRemaining = String.Empty;
int batteryLevel = 0;

foreach (var battery in allBatteries)
{
    batteryLevel = Convert.ToInt32(battery["EstimatedChargeRemaining"]);
}

if(batteryLevel < 25)       
   JARVIS.Speak("Warning, Battery level has dropped below 25%");
else //Guessing you want else
   JARVIS.Speak("The battery level is at: " + batteryLevel.ToString() + "%");
return;
}

Instead of this line happening only when I say "battery level" I want it to automatically check the battery level every 15mins and automatically report back to me via speech if the battery level has dropped bellow 25%:

if(batteryLevel < 25)       
   JARVIS.Speak("Warning, Battery level has dropped below 25%");

I am guessing I will require a timer but other than that I have no idea.

Thanks.

Upvotes: 0

Views: 1497

Answers (3)

Vimal CK
Vimal CK

Reputation: 3563

Loop call in every 15 minutes will cause MainUI thread to response poor and the application will get crashed. You can solve this by using Threading. Please check out the below code snippet which will help your needs. You can use SystemInformation class by referring System.Windows.Forms namespace instead of WMI query. Set Timer control interval by 900000 to execute the action every 15 minutes. Please mark the answer if useful

public delegate void DoAsync();

public void Main()
{
   timer1.Tick += new EventHandler(timer1_Tick);
   timer1.Interval = 900000;
   timer1.Start();
}

private void timer1_Tick(object sender, EventArgs e)
{
   DoAsync async = new DoAsync(GetBatteryDetails);
   async.BeginInvoke(null, null);
}

public void GetBatteryDetails()
{
   int i = 0;
   PowerStatus ps = SystemInformation.PowerStatus;
   if (ps.BatteryLifePercent <= 25)
   {
      if (this.InvokeRequired)
          this.Invoke(new Action(() => JARVIS.Speak("Warning, Battery level has dropped below 25%");      
      else
          JARVIS.Speak("Warning, Battery level has dropped below 25%");
   }
   i++;
}

Upvotes: 1

McAden
McAden

Reputation: 13972

One option is System.Threading.Timer. The pertinent pieces are the callback and the interval.

There is more information from that page though that dictate whether that is the right choice for you. Some highlights are:

System.Threading.Timer is a simple, lightweight timer that uses callback methods and is served by thread pool threads. It is not recommended for use with Windows Forms, because its callbacks do not occur on the user interface thread. System.Windows.Forms.Timer is a better choice for use with Windows Forms. For server-based timer functionality, you might consider using System.Timers.Timer, which raises events and has additional features.

and

As long as you are using a Timer, you must keep a reference to it. As with any managed object, a Timer is subject to garbage collection when there are no references to it. The fact that a Timer is still active does not prevent it from being collected.

Edit: Now that you've stated you're in WinForms you can see that MSDN recommends the System.Windows.Forms.Timer. That MSDN page gives an example. You'll see that subscribing to the Tick event is your callback and Interval is the time between ticks in milliseconds. You want to set it to the 15 minutes you stated which is going to be 1000 * 60 * 15 or 900000.

Adapted from the MSDN Example:

    private static readonly Timer batteryCheckTimer = new Timer();

    // This is the method to run when the timer is raised. 
    private static void CheckBattery(Object sender, EventArgs myEventArgs)
    {
        ManagementClass wmi = new ManagementClass("Win32_Battery");
        var allBatteries = wmi.GetInstances();
        foreach (var battery in allBatteries)
        {
            int batteryLevel = Convert.ToInt32(battery["EstimatedChargeRemaining"]);
            if (batteryLevel < 25)
            {
                JARVIS.Speak("Warning, Battery level has dropped below 25%");
            }
        }
    }

    [STAThread]
    public static void Main()
    {
        // Start the application.
        Application.Run(new Form1());
        batteryCheckTimer.Tick += new EventHandler(CheckBattery);
        batteryCheckTimer.Interval = 900000;
        batteryCheckTimer.Start();
    }

Upvotes: 1

Bob Claerhout
Bob Claerhout

Reputation: 821

As McAden said, timers can be used. An example of a timer can be found on the msdn website.

Upvotes: 0

Related Questions