Reason:
Sometimes my cable of the charger of my laptop is either lose or forgotten to connect. Instead of waiting until the laptop dies during a gig, I want to see fast feedback. Since GP is normally maximized, I don’t see the battery icon (and even then, it’s really small).
Solution
An external (C#) application writes a single line text with battery status information to a dedicated file. The code is shown later.
Two widgets are shown only when the charger is disconnected, and shows the battery percentage and how many hours are remaining.
Default rackspace
I built in the solution in my default rackspace, but here I only put the necessary parts. Note that the gig file will follow when I finished my default rackspace. Or at least have it to a certain ‘good’ state (this can take many months).
Screenshot
Below a screenshot is shown when the charger is disconnected, see the orange oval
External application
This is a WinForms C# application with the following source code for the Forms.cs file.
For this, a (free) Visual Studio installation is needed. It does not have to be created on the GP laptop you are using. However, to use the application on the GP laptop, a library with the DotNet library needs to be installed (running the application will automatically handle this).
using System;
using System.IO;
using System.Windows.Forms;
// Writes file with content: <state>,<percentage in 0.00-1.00>,<seconds remaining>
// PC : Online,NoSystemBattery,1,-1 (No battery, 100%, -1 (infinite) sec)
// Laptop connected : Online,High,1,-1 (High, 100%, -1 (infinite) sec)
// Laptop charging : Online,Charging,0,2,-1
// Laptop unconnected : Offline,High,0,97,7094 (High, 97%, 7094 sec)
// Offline,High,0,96,7151 (High, 96%, 7151 sec)
// Offline,0,0,54,... (100-75%: High, 75-25%: -, 25-0%: Low)
// Offline,Low,0,24,1753 (Low, 24%, 1753 sec)
// Sec
namespace WinFormsAppBattery
{
public partial class Form1 : Form
{
const string FILE_NAME = @"D:\Info\battery_status.txt";
const int INTERVAL_TIME = 60 * 1000; // in ms
static readonly System.Windows.Forms.Timer myTimer = new Timer();
private static string CreateBatteryStatusString(PowerStatus pw)
{
return
pw.PowerLineStatus.ToString() + "," +
pw.BatteryChargeStatus.ToString() + "," +
pw.BatteryLifePercent.ToString() + "," +
pw.BatteryLifeRemaining.ToString();
}
private static async void TimerEventProcessor(object myObject, EventArgs myEventArgs)
{
string newBatteryStatus = CreateBatteryStatusString(SystemInformation.PowerStatus);
string fileBatteryStatus = File.ReadAllLines(FILE_NAME)[0];
if (newBatteryStatus != fileBatteryStatus)
{
await File.WriteAllLinesAsync(FILE_NAME, new string[] { newBatteryStatus } );
}
}
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
myTimer.Tick += new EventHandler(TimerEventProcessor);
myTimer.Interval = INTERVAL_TIME;
myTimer.Start();
}
}
}
Change the file path in the external file above and in the GP Script equally.
Rackspace (Panel) Changes
Create two widgets with the names according to shown in the GP Script.
GP Script
var
WarningBatteryPowered, WarningBatteryStatus : Widget
BATTERY_WIDGETS : Widget array = [ WarningBatteryPowered, WarningBatteryStatus ]
LastBatteryCheckTime : double = 0.0
function SecondsToHours(totalSeconds : integer) returns String
var hours : integer
minutes : integer
seconds : integer
hours = totalSeconds / 60 / 60
minutes = (totalSeconds - hours * 60 * 60) / 60
seconds = totalSeconds % 60
result = IntToString(hours) + ":"
if minutes < 10 then
result = result + "0"
end
result = result + IntToString(minutes) + ":"
if seconds < 10 then
result = result + "0"
end
result = result + IntToString(seconds)
end
on TimerTick(ns : double)
var
fileName : string
batteryStatus : string
batteryStatusParts : string array
batteryLabel : string
if ns > LastBatteryCheckTime + 1000 then
fileName = "D:/Info/battery_status.txt"
batteryStatus = LoadStringFromTextFile(fileName)
batteryStatusParts = SplitString(batteryStatus, ",")
select batteryStatusParts[0] == "Online" do
ShowWidgets(BATTERY_WIDGETS, false)
end
select batteryStatusParts[0] == "Offline" do
ShowWidgets(BATTERY_WIDGETS, true)
if batteryStatusParts[2] == "1" then
batteryLabel = "100%"
if batteryStatusParts[3] != "-1" then
batteryLabel = batteryLabel + " " +
SecondsToHours(StringToInt(batteryStatusParts[3])) + " remaining"
end
else
batteryLabel =
IntToString(StringToInt(batteryStatusParts[3])) + "%"
if batteryStatusParts[4] != "-1" then
batteryLabel = batteryLabel + " " +
SecondsToHours(StringToInt(batteryStatusParts[4])) + " remaining"
end
end
SetWidgetLabel(WarningBatteryStatus, batteryLabel)
end
LastBatteryCheckTime = ns
end
end
Improvements
Improve some duplicated code, and automatically make the external application start.
Disclaimer
Note that this script is not tested much.
Solution Comparison
Solution Author Advantages Disadvantages
---------- -------------- ---------------------- -------------------------
Ext. utility npudar Easy installation No direct GP interaction
possible
No scripting needed Hardcoded GUI
Extension library Frank1119 Encapsulated in library
Ext. app with OSC Spav OSC flexibility External app needed
Ext. app with file I/O Michelkeijzers - External app needed
File I/O