Initial commit
This commit is contained in:
commit
48f447bcbd
10 changed files with 237 additions and 0 deletions
23
config.example.yaml
Normal file
23
config.example.yaml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
vuserver:
|
||||||
|
api:
|
||||||
|
url: "http://localhost:5340"
|
||||||
|
password: "my_super_secret_password"
|
||||||
|
|
||||||
|
assets: "/home/user/Downloads/image_pack"
|
||||||
|
|
||||||
|
dials:
|
||||||
|
"0123456789ABCDEFGHIJKLMN":
|
||||||
|
aliases:
|
||||||
|
- "my_dial"
|
||||||
|
"RIBAILOFEE2CHOONGUVAHCAE":
|
||||||
|
aliases:
|
||||||
|
- "outside"
|
||||||
|
"ING6AHXOO3REI2WILAH8RAEW":
|
||||||
|
aliases:
|
||||||
|
- "inside"
|
||||||
|
|
||||||
|
config_sets:
|
||||||
|
"notebook":
|
||||||
|
"GPULoad": "my_dial"
|
||||||
|
"CPULoad": "inside"
|
||||||
|
"MEMUsage": "outside"
|
19
dial_configs/CPULoad.py
Normal file
19
dial_configs/CPULoad.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
from dial_configs.dial_config import DialConfig
|
||||||
|
|
||||||
|
class CPULoad(DialConfig):
|
||||||
|
def __init__(self, target_dial, asset_path):
|
||||||
|
super().__init__(target_dial, asset_path, "cpu-load.png")
|
||||||
|
|
||||||
|
def transform_color(self, value):
|
||||||
|
return super().Colors.get_threshold_color(self, value)
|
||||||
|
|
||||||
|
def transform_value(self, json_data):
|
||||||
|
v = int(json_data.get("fields", {}).get("usage_idle", 0))
|
||||||
|
value = 100 - v
|
||||||
|
return value
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
try:
|
||||||
|
return (other.get("name", "") == "cpu" and other.get("tages", {}).get("host", "") != "gameloader")
|
||||||
|
except Exception:
|
||||||
|
return False
|
14
dial_configs/GPULoad.py
Normal file
14
dial_configs/GPULoad.py
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
from dial_configs.dial_config import DialConfig
|
||||||
|
|
||||||
|
class GPULoad(DialConfig):
|
||||||
|
def __init__(self, target_dial, asset_path):
|
||||||
|
super().__init__(target_dial, asset_path, "gpu-load.png")
|
||||||
|
|
||||||
|
def transform_color(self, value):
|
||||||
|
return super().Colors.get_threshold_color(self, value)
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
try:
|
||||||
|
return (other.get("name", "") == "gpu_busy_percent")
|
||||||
|
except Exception:
|
||||||
|
return False
|
25
dial_configs/GameloaderGamescopeFPS.py
Normal file
25
dial_configs/GameloaderGamescopeFPS.py
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
from dial_configs.dial_config import DialConfig
|
||||||
|
from vu1 import RGBColor
|
||||||
|
|
||||||
|
class GameloaderGamescopeFPS(DialConfig):
|
||||||
|
def __init__(self, target_dial, asset_path):
|
||||||
|
super().__init__(target_dial, asset_path, "fps.png")
|
||||||
|
|
||||||
|
def transform_color(self, value):
|
||||||
|
if fps < 60:
|
||||||
|
color = RGBColor(1.0, 0, 0)
|
||||||
|
else:
|
||||||
|
color = super().Colors.get_gradient_color(self, value, 30, 0)
|
||||||
|
return color
|
||||||
|
|
||||||
|
def transform_value(self, json_data):
|
||||||
|
FPS_MAX = 120
|
||||||
|
fps = float(json_data.get("fields", {}).get("fps", 0))
|
||||||
|
value = int((fps/FPS_MAX)*100)
|
||||||
|
return value
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
try:
|
||||||
|
return (other.get("name", "") == "gamescope" and "fps" in other.get("fields", {}).keys() and other.get("tags", {}).get("host", "") == "gameloader")
|
||||||
|
except Exception:
|
||||||
|
return False
|
14
dial_configs/LastKnownDiskUsedPercent.py
Normal file
14
dial_configs/LastKnownDiskUsedPercent.py
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
from dial_configs.dial_config import DialConfig
|
||||||
|
|
||||||
|
class LastKnownDiskUsedPercent(DialConfig):
|
||||||
|
def __init__(self, target_dial, asset_path):
|
||||||
|
super().__init__(target_dial, asset_path, "disk-usage.png")
|
||||||
|
|
||||||
|
def transform_color(self, value):
|
||||||
|
return super().Colors.get_threshold_color(self, value)
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
try:
|
||||||
|
return (other.get("name", "") == "last_known_disk_used_percent" and other.get("fields", {}).get("path", "") == "/media") and other.get("fields", {}).get("from_host", "") == "companioncube"
|
||||||
|
except Exception:
|
||||||
|
return False
|
17
dial_configs/MEMUsage.py
Normal file
17
dial_configs/MEMUsage.py
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
from dial_configs.dial_config import DialConfig
|
||||||
|
|
||||||
|
class MEMUsage(DialConfig):
|
||||||
|
def __init__(self, target_dial, asset_path):
|
||||||
|
super().__init__(target_dial, asset_path, "mem.png")
|
||||||
|
|
||||||
|
def transform_color(self, value):
|
||||||
|
return super().Colors.get_gradient_color(self, value, 30, 0)
|
||||||
|
|
||||||
|
def transform_value(self, json_data):
|
||||||
|
return int(json_data.get("fields", {}).get("used_percent", 100))
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
try:
|
||||||
|
return (other.get("name", "") == "mem")
|
||||||
|
except Exception:
|
||||||
|
return False
|
23
dial_configs/ThinkPadFan.py
Normal file
23
dial_configs/ThinkPadFan.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
from dial_configs.dial_config import DialConfig
|
||||||
|
import functools
|
||||||
|
|
||||||
|
class ThinkPadFan(DialConfig):
|
||||||
|
def __init__(self, target_dial, asset_path):
|
||||||
|
super().__init__(target_dial, asset_path, "fan-speed.png")
|
||||||
|
self.other_fans = {}
|
||||||
|
|
||||||
|
def transform_color(self, value):
|
||||||
|
return super().Colors.get_threshold_color(self, value)
|
||||||
|
|
||||||
|
def transform_value(self, json_data):
|
||||||
|
FAN_MAX = 3500
|
||||||
|
self.other_fans[json_data["tags"]["feature"]] = json_data.get("fields", {}).get("input", FAN_MAX)
|
||||||
|
avg_rpm = functools.reduce(lambda x,y: x+y, self.other_fans.values()) / len(self.other_fans.values())
|
||||||
|
value = int((avg_rpm/FAN_MAX)*100)
|
||||||
|
return value
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
try:
|
||||||
|
return (other.get("name", "") == "sensors" and "fan" in other.get("tags", {}).get("feature", []))
|
||||||
|
except Exception:
|
||||||
|
return False
|
4
dial_configs/__init__.py
Normal file
4
dial_configs/__init__.py
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
from os.path import dirname, basename, isfile, join
|
||||||
|
import glob
|
||||||
|
modules = glob.glob(join(dirname(__file__), "*.py"))
|
||||||
|
__all__ = [basename(f)[:-3] for f in modules if isfile(f) and not f.endswith('__init__.py') and not f.endswith('dial_config.py')]
|
37
dial_configs/dial_config.py
Normal file
37
dial_configs/dial_config.py
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
from vu1 import RGBColor,HSVColor
|
||||||
|
from os.path import join as pathjoin
|
||||||
|
|
||||||
|
class DialConfig(object):
|
||||||
|
def __init__(self, target_dial, asset_path, bg_filename):
|
||||||
|
self.dial = target_dial
|
||||||
|
self.asset_path = asset_path
|
||||||
|
self.bg_filename = bg_filename
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
def background_image(self):
|
||||||
|
return pathjoin(self.asset_path, self.bg_filename)
|
||||||
|
|
||||||
|
def transform_value(self, json_data):
|
||||||
|
return json_data.get("fields", {}).get("value", 0)
|
||||||
|
|
||||||
|
def transform_color(self, value):
|
||||||
|
return self.Colors.get_gradient_color(self, value)
|
||||||
|
|
||||||
|
class Colors(object):
|
||||||
|
def get_threshold_color(self, value):
|
||||||
|
if value >= 0 and value <= 50:
|
||||||
|
return RGBColor(1.0, 1.0, 1.0)
|
||||||
|
if value > 50 and value < 75:
|
||||||
|
return RGBColor(0, 1.0, 0)
|
||||||
|
elif value > 75 and value < 90:
|
||||||
|
return RGBColor(1.0, 1.0, 0)
|
||||||
|
elif value >= 90:
|
||||||
|
return RGBColor(1.0, 0, 0)
|
||||||
|
|
||||||
|
def get_gradient_color(self, value, min_hue=0, max_hue=132):
|
||||||
|
hue = min_hue + (((max_hue-min_hue)/100)*value)
|
||||||
|
hue_float = (1/360)*hue
|
||||||
|
return HSVColor(hue=hue_float, saturation=1, value=1)
|
61
main.py
Executable file
61
main.py
Executable file
|
@ -0,0 +1,61 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import vu1
|
||||||
|
import sys
|
||||||
|
import pdb
|
||||||
|
import json
|
||||||
|
import yaml
|
||||||
|
import requests
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
from dial_configs import *
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('-c', '--config')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
def get_config(config_file_path="config.yaml"):
|
||||||
|
config = {}
|
||||||
|
with open(config_file_path, "r") as fd:
|
||||||
|
config = yaml.safe_load(fd.read())
|
||||||
|
return config
|
||||||
|
|
||||||
|
def find_dial(config, id_or_alias):
|
||||||
|
dials = config.get("dials", {})
|
||||||
|
if id_or_alias in dials:
|
||||||
|
return id_or_alias
|
||||||
|
else:
|
||||||
|
for k, dial in dials.items():
|
||||||
|
if id_or_alias in dial.get("aliases", []):
|
||||||
|
return k
|
||||||
|
return None
|
||||||
|
|
||||||
|
config = get_config(args.config)
|
||||||
|
print(config, flush=True)
|
||||||
|
|
||||||
|
api_config = config.get("vuserver", {}).get("api", {})
|
||||||
|
API = vu1.DialServer(api_config.get("url", "http://localhost:5340"), api_config.get("password", ""))
|
||||||
|
|
||||||
|
# generate objects with according dial objects based on user config
|
||||||
|
config_set = []
|
||||||
|
for metric, dial in config.get("config_sets", {}).get("notebook", []).items():
|
||||||
|
d = API.dials[API.dials.index(find_dial(config, dial))]
|
||||||
|
m = getattr(eval(metric), metric)(d, config.get("assets", "./assets")) # build instance of a matching dial_config class
|
||||||
|
config_set.append(m)
|
||||||
|
|
||||||
|
for line in sys.stdin:
|
||||||
|
metric = json.loads(line)
|
||||||
|
fields = metric.get("fields", {})
|
||||||
|
if metric in config_set:
|
||||||
|
dial_config = config_set[config_set.index(metric)]
|
||||||
|
#print("config for {metric_name} matched {conf}".format(metric_name=metric.get("name", "<noname>"), conf=type(dial_config)), flush=True)
|
||||||
|
value = dial_config.transform_value(metric)
|
||||||
|
image = dial_config.background_image
|
||||||
|
color = dial_config.transform_color(value)
|
||||||
|
dial = dial_config.dial
|
||||||
|
try:
|
||||||
|
dial.image = image
|
||||||
|
dial.value = value
|
||||||
|
dial.color = color
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
continue
|
Loading…
Add table
Reference in a new issue