Check in initial working version of client and server

This commit is contained in:
Kumi 2020-04-06 19:12:18 +02:00
commit 01a303b291
3 changed files with 147 additions and 0 deletions

48
README.md Normal file
View file

@ -0,0 +1,48 @@
# Kargos remote battery status indicator
For everyone who uses X2Go to work on a remote workstation from their physical laptop.
If you have X2Go in fullscreen, it also covers your local battery status indicator and sometimes even battery notifications.
These scripts will show your laptop's battery status in a Kargos widget on KDE. I would assume that it also works in GNOME Argos as well as macOS BitBar, but I have not tried either of those as remote operating systems.
I have also only tried Ubuntu as a local operating system (i.e. running directly on the laptop), but other (unixoid) operating systems should work fine if the "upower" application is available.
Use is not limited to X2Go, of course. Any setup where you can get both machines to access a shared file (e.g. using a manual sshfs or davfs mount) should do the trick.
## How to use
NB: "Client" refers to the machine displaying the remote battery status in a Kargos widget (i.e. the remote machine in an X2Go setup), "server" is the device sharing its battery status (i.e. your local laptop).
### Server
The server application reads the local machine's battery status and writes it to an outfile. Navigate to the directory containing battery2god in your terminal, then execute:
```./battery2god /path/to/outfile```
You should use an otherwise empty directory for the outfile and make sure that your user account has permissions to write to that directory. Then set up a shared folder in X2Go (or mount that folder into the remote filesystem in another way), allowing the remote machine to access that directory. X2Go shares automatically have read and write permissions - for other mounts, read-only permissions are sufficient. (You can also mount the remote filesystem into your local filesystem - of course, you need write permissions then.)
You can easily deamonize the server (i.e. move it to the background so you can use your terminal otherwise) by running this command instead:
```nohup ./battery2god /path/to/outfile```
Advanced users can also use cronjobs, systemd services, etc. to make sure the server starts automatically at boot - this is beyond the scope of this readme.
### Client
This assumes that you are running an operating system with a KDE Plasma 5 desktop environment. If you use GNOME, you will need to use Argon, if you're on macOS, use BitBar. Note that this is not tested and I will not be including instructions on how to do this. However, you should be able to find those instructions on the Internet rather easily.
Add a Kargon widget to your KDE environment by right clicking your system tray (where you can see your clock, application widgets, etc. - usually the bottom right corner of your screen in a default setup), clicking "Add Widgets" and dragging a Kargon widget to your system tray from the window that opens. Close that window, then right-click the new widget (should read "No command configured" at that point), then "Configure Kargos". In "Command line or executable path" add the absolute paths to the battery2go client as well as the outfile of the server.
```/path/to/battery2go /path/to/mountpoint/outfile```
If you use X2Go shared folders, the mountpoint will be located in /home/USERNAME/media/disk/, use a file browser to find out the exact name of the folder. If you are not sure if you got the command right, you can also just try executing it in a terminal - if you don't get an error message, you are good to go. Press OK, and the widget should display your laptop's battery status.
## Limitations / Issues
Writing this readme took longer than writing the client and server scripts - don't expect them to work perfectly in every setup.
* If your machine has more than one battery, this will not work properly. It will only report the status of one of those batteries.
* If you resize your X2Go remote workspace too much, sometimes the widget will stop updating. This is probably an issue with plasmashell itself. Running "plasmashell --replace" should temporarily fix this.
If you find any further issues or need help getting the scripts running, feel free to open an issue in the Github issue tracker.

40
client/battery2go Executable file
View file

@ -0,0 +1,40 @@
#!/usr/bin/env python3
import argparse
import configparser
import os
LOW = 0
MEDIUM = 1
HIGH = 2
LOW_THRESHOLD = 20
HIGH_THRESHOLD = 80
def generate_output(percentage: float, charging: bool, remaining: str):
if percentage >= 0:
status = LOW if percentage < LOW_THRESHOLD else MEDIUM if percentage < HIGH_THRESHOLD else HIGH
color = "green" if charging == True else "blue" if status == HIGH else "orange" if status == MEDIUM else "red"
icon = "battery-" + ("low" if status == LOW else "good" if status == MEDIUM else "full") + ("-charging" if charging else "")
print(f"{percentage:.0f}% | color={color} iconName={icon}")
print("---")
print("Time to %s: %s" % ("full" if charging else "empty", remaining))
else:
print("Error! | color=red iconName=battery-missing")
print("---")
print("Data file corrupted or not found")
def read_values(datafile: os.PathLike):
config = configparser.ConfigParser()
config.read(datafile)
return config.getfloat("BATTERY", "percentage"), config.getboolean("BATTERY", "charging"), config["BATTERY"]["remaining"]
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("datafile")
args = parser.parse_args()
try:
generate_output(*read_values(args.datafile))
except:
generate_output(-1, False, "")

59
server/battery2god Executable file
View file

@ -0,0 +1,59 @@
#!/usr/bin/env python3
import configparser
import argparse
import subprocess
import os
import time
upath=None
def read_values(output: str):
remaining = False
lines = [line.strip() for line in output.split("\n")]
for line in lines:
if line.startswith("time to"):
remaining = line.split(":")[-1].strip()
elif line.startswith("percentage"):
percentage = float(line.split(":")[-1].strip()[:-1])
elif line.startswith("state"):
charging = not "discharging" in line
return percentage, charging, remaining
def write_values(percentage: float, charging: bool, remaining: str, datafile: os.PathLike):
config = configparser.ConfigParser()
config["BATTERY"] = {
"percentage": percentage,
"charging": charging,
"remaining": remaining
}
with open(datafile, "w") as outfile:
config.write(outfile)
def run_upower(path=None):
global upath
if not (path or upath):
finder = subprocess.Popen(["upower", "-e"], stdout=subprocess.PIPE)
finder.wait()
for line in finder.stdout.read().decode().split("\n"):
if "BAT" in line:
upath = line
break
path = path or upath
info = subprocess.Popen(["upower", "-i", path], stdout=subprocess.PIPE)
info.wait()
return info.stdout.read().decode()
def run_loop(datafile):
while True:
write_values(*read_values(run_upower()), datafile)
time.sleep(1)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("datafile")
args = parser.parse_args()
run_loop(args.datafile)