Add FraI3mega/battery-graph (#115)
* feat(battery-graph): Initialize plugin files * feat(battery-graph): Add bar widget * feat(battery-graph): Implement logic * docs(battery-graph): Fill out the template README * feat(battery-graph): Improve panel * feat(battery-graph): Implement settings * feat(battery-graph): Improve panel styling * feat(battery-graph): Add desktop widget * docs(battery-graph): Improve wording * docs(battery-graph): Add image * docs(battery-graph): Add tags * docs(battery-graph): Improve README * fix(battery-graph): Fix translations * docs(battery-graph): Fix tags * fix(battery-graph): Fix author name * docs(battery-graph): Rename thumbnail * docs(battery-graph): Add dependencies * docs(battery-graph): Improve README * docs(battery-graph): Bump version to 1.0.0 * fix(battery-graph): Remove leftover log * fix(battery-graph): Wrap battery path in quotes * fix(battery-graph): Implement path validation * docs(battery-graph): Clarify setting * fix(battery-graph): Wrap grapth_time in quoutes * docs(battery-graph): Fix setting description
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
# Battery graph
|
||||
|
||||
Uses the Upowerd to display the historical charge of the battery on a graph.
|
||||
|
||||
## Plugin
|
||||
|
||||
|
||||
| Field | Value |
|
||||
| --- | --- |
|
||||
| ID | `frai3mega/battery-graph` |
|
||||
| Entries | Bar widget: `battery-graph-widget`; panel: `battery-panel`; Desktop widget: `battery-graph-desktop` |
|
||||
|
||||
## Requirements
|
||||
|
||||
Requires a running `upowerd` deamon.
|
||||
Install `gdbus` on `PATH`.
|
||||
|
||||
## Usage
|
||||
|
||||
You can use it as a desktop/locksreen widget or on the bar.
|
||||
|
||||
Show the panel using
|
||||
|
||||
```sh
|
||||
noctalia msg panel-toggle frai3mega/battery-graph:battery-panel
|
||||
```
|
||||
|
||||
|
||||
## Settings
|
||||
|
||||
|
||||
| Setting | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `graph_time` | `int` | `6` | Changes the timeframe of the graph |
|
||||
| `battery_path` | `string` | `/org/freedesktop/UPower/devices/battery_BAT0` | The path to the battery to be graphed |
|
||||
| `interpol_time` | `int` | `5` | The time beetween points on the graph. |
|
||||
|
||||
```
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
graph_time = 3600 * noctalia.getConfig("graph_time")
|
||||
battery_path = noctalia.getConfig("battery_path")
|
||||
interpol_time = 60 * noctalia.getConfig("interpol_time")
|
||||
|
||||
local function validate(s)
|
||||
if s:match("^/org/freedesktop/UPower/devices/[%a%d_]+$") ~= nil then
|
||||
return "'" .. tostring(s):gsub("'", "'\\''") .. "'"
|
||||
else
|
||||
noctalia.log("Invalid battery dbus path. Check that it is correct")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local cmd = table.concat({"gdbus call --system --dest org.freedesktop.UPower --object-path",validate(battery_path),"--method org.freedesktop.UPower.Device.GetHistory charge",graph_time, "1000"}, " ")
|
||||
|
||||
function update()
|
||||
noctalia.setUpdateInterval(interpol_time * 1000)
|
||||
noctalia.runAsync(cmd, parse)
|
||||
end
|
||||
|
||||
function parse(result)
|
||||
local points = {}
|
||||
for tuple in result.stdout:gmatch("%(([^%)]+)%)") do
|
||||
local fields = {}
|
||||
for field in tuple:gmatch("[^,]+") do
|
||||
field = field:match("^%s*(.-)%s*$") -- trim whitespace
|
||||
field = field:gsub("^%S+%s+", "") -- strip "uint32 " style prefix (only if followed by more content)
|
||||
table.insert(fields, field)
|
||||
end
|
||||
local ts, value = tonumber(fields[1]), tonumber(fields[2])
|
||||
if value ~= 0.0 then
|
||||
points[ts] = value
|
||||
end
|
||||
end
|
||||
|
||||
local interpolated_points = interpolate(points)
|
||||
render(table.concat(interpolated_points, " "), interpolated_points)
|
||||
end
|
||||
|
||||
function interpolate(points )
|
||||
local interpolated_points = {}
|
||||
|
||||
local tkeys = {}
|
||||
for k in pairs(points) do
|
||||
table.insert(tkeys, k)
|
||||
end
|
||||
table.sort(tkeys)
|
||||
-- use the keys to retrieve the values in the sorted order
|
||||
local prev_sample = 1
|
||||
local first_sample_time = tkeys[1]
|
||||
table.insert(interpolated_points, tonumber(points[tkeys[1]])/100)
|
||||
local time_done = 0
|
||||
while tkeys[prev_sample + 1] and time_done < graph_time do
|
||||
local cur_time = time_done + first_sample_time
|
||||
if cur_time > tkeys[prev_sample + 1] then
|
||||
prev_sample += 1
|
||||
end
|
||||
|
||||
table.insert(interpolated_points, tonumber(points[tkeys[prev_sample]])/100)
|
||||
time_done += interpol_time
|
||||
end
|
||||
return interpolated_points
|
||||
end
|
||||
|
||||
|
||||
function render(point_str,points)
|
||||
panel.render(ui.column({ gap = 8, radius = 8, align = "stretch", fill = "surface_variant" }, {
|
||||
ui.row( {paddingH= 10, paddingV = 6},{ ui.label({text = noctalia.tr("text.graph_name"), fontSize = 24, fontWeight = "heavy", textAlign = "center"}),}),
|
||||
ui.graph({
|
||||
values = points,
|
||||
color = "primary",
|
||||
lineWidth = 2,
|
||||
fillOpacity = 0.45,
|
||||
height = 200,
|
||||
width = 400
|
||||
}),
|
||||
}))
|
||||
end
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
function update()
|
||||
noctalia.setUpdateInterval(1000)
|
||||
barWidget.setGlyph("battery")
|
||||
end
|
||||
|
||||
function onClick()
|
||||
noctalia.togglePanel("frai3mega/battery-graph:battery-panel")
|
||||
end
|
||||
@@ -0,0 +1,82 @@
|
||||
graph_time = 3600 * noctalia.getConfig("graph_time")
|
||||
battery_path = noctalia.getConfig("battery_path")
|
||||
interpol_time = 60 * noctalia.getConfig("interpol_time")
|
||||
|
||||
local function quote(s)
|
||||
return "'" .. tostring(s):gsub("'", "'\\''") .. "'"
|
||||
end
|
||||
|
||||
local function validate(s)
|
||||
if s:match("^/org/freedesktop/UPower/devices/[%a%d_]+$") ~= nil then
|
||||
return quote(s)
|
||||
else
|
||||
noctalia.log("Invalid battery dbus path. Check that it is correct")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local cmd = table.concat({"gdbus call --system --dest org.freedesktop.UPower --object-path",validate(battery_path),"--method org.freedesktop.UPower.Device.GetHistory charge",quote( graph_time ), "1000"}, " ")
|
||||
|
||||
function onOpen()
|
||||
-- noctalia.setUpdateInterval(1000)
|
||||
noctalia.runAsync(cmd, parse)
|
||||
end
|
||||
|
||||
function parse(result)
|
||||
local points = {}
|
||||
for tuple in result.stdout:gmatch("%(([^%)]+)%)") do
|
||||
local fields = {}
|
||||
for field in tuple:gmatch("[^,]+") do
|
||||
field = field:match("^%s*(.-)%s*$") -- trim whitespace
|
||||
field = field:gsub("^%S+%s+", "") -- strip "uint32 " style prefix (only if followed by more content)
|
||||
table.insert(fields, field)
|
||||
end
|
||||
local ts, value = tonumber(fields[1]), tonumber(fields[2])
|
||||
if value ~= 0.0 then
|
||||
points[ts] = value
|
||||
end
|
||||
end
|
||||
|
||||
local interpolated_points = interpolate(points)
|
||||
render(table.concat(interpolated_points, " "), interpolated_points)
|
||||
end
|
||||
|
||||
function interpolate(points )
|
||||
local interpolated_points = {}
|
||||
|
||||
local tkeys = {}
|
||||
for k in pairs(points) do
|
||||
table.insert(tkeys, k)
|
||||
end
|
||||
table.sort(tkeys)
|
||||
-- use the keys to retrieve the values in the sorted order
|
||||
local prev_sample = 1
|
||||
local first_sample_time = tkeys[1]
|
||||
table.insert(interpolated_points, tonumber(points[tkeys[1]])/100)
|
||||
local time_done = 0
|
||||
while tkeys[prev_sample + 1] and time_done < graph_time do
|
||||
local cur_time = time_done + first_sample_time
|
||||
if cur_time > tkeys[prev_sample + 1] then
|
||||
prev_sample += 1
|
||||
end
|
||||
|
||||
table.insert(interpolated_points, tonumber(points[tkeys[prev_sample]])/100)
|
||||
time_done += interpol_time
|
||||
end
|
||||
return interpolated_points
|
||||
end
|
||||
|
||||
|
||||
function render(point_str,points)
|
||||
panel.render(ui.column({ gap = 8, radius = 8, align = "stretch", fill = "surface_variant" }, {
|
||||
ui.row( {paddingH= 10, paddingV = 6},{ ui.label({text = noctalia.tr("text.graph_name"), fontSize = 24, fontWeight = "heavy", textAlign = "center"}),}),
|
||||
ui.graph({
|
||||
values = points,
|
||||
color = "primary",
|
||||
lineWidth = 2,
|
||||
fillOpacity = 0.45,
|
||||
height = 200,
|
||||
}),
|
||||
}))
|
||||
end
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
id = "frai3mega/battery-graph"
|
||||
name = "Battery graph"
|
||||
version = "1.0.0"
|
||||
author = "frai3mega"
|
||||
license = "MIT"
|
||||
icon = "battery"
|
||||
description = "Plots battery level on a graph"
|
||||
plugin_api = 3
|
||||
tags = ["hardware", "utility", "desktop", "panel"]
|
||||
dependencies = ["upowerd", "gdbus"]
|
||||
|
||||
[[setting]]
|
||||
key = "graph_time"
|
||||
type = "int"
|
||||
label_key = "settings.graph_time.label"
|
||||
description_key = "settings.graph_time.description"
|
||||
default = 6
|
||||
|
||||
[[setting]]
|
||||
key = "battery_path"
|
||||
type = "string"
|
||||
label_key = "settings.battery_path.label"
|
||||
description_key = "settings.battery_path.description"
|
||||
default = "/org/freedesktop/UPower/devices/battery_BAT0"
|
||||
|
||||
[[setting]]
|
||||
key = "interpol_time"
|
||||
type = "int"
|
||||
label_key = "settings.interpol_time.label"
|
||||
description_key = "settings.interpol_time.description"
|
||||
default = 5
|
||||
|
||||
|
||||
[[widget]]
|
||||
id = "battery-graph-widget"
|
||||
entry = "battery-graph.luau"
|
||||
|
||||
[[panel]]
|
||||
id = "battery-panel"
|
||||
entry = "battery-panel.luau"
|
||||
|
||||
[[desktop_widget]]
|
||||
id = "battery-graph-desktop"
|
||||
entry = "battery-desktop.luau"
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"settings": {
|
||||
"graph_time": {
|
||||
"label": "Graph timeframe",
|
||||
"description": "How long of a timeframe does the graph plot in hours"
|
||||
},
|
||||
"battery_path": {
|
||||
"label": "Battery path",
|
||||
"description": "Dbus path to the upower battery device"
|
||||
},
|
||||
"interpol_time": {
|
||||
"label": "Time between points",
|
||||
"description": "How long should the thime between points be in minutes"
|
||||
}
|
||||
},
|
||||
"text": {
|
||||
"graph_name": "Battery"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user