Files
community-plugins/battery-graph/battery-desktop.luau
T
FraI3megaandGitHub 0319dc40f7 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
2026-07-27 13:31:04 -04:00

80 lines
2.4 KiB
Luau

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