mirror of
https://github.com/morgan9e/gnome-shell-extension-freon
synced 2026-04-14 00:14:14 +09:00
120 lines
3.5 KiB
JavaScript
120 lines
3.5 KiB
JavaScript
import Gio from 'gi://Gio';
|
|
import GLib from 'gi://GLib';
|
|
|
|
export default class WattdUtil {
|
|
|
|
constructor(intervalSeconds = 5) {
|
|
this._powerDir = '/run/power';
|
|
this._readings = [];
|
|
this._updated = false;
|
|
this._available = GLib.file_test(this._powerDir, GLib.FileTest.IS_DIR);
|
|
this._intervalUsec = 0;
|
|
this._lastUpdateUsec = 0;
|
|
this.interval = intervalSeconds;
|
|
}
|
|
|
|
get available() {
|
|
return this._available;
|
|
}
|
|
|
|
get updated() {
|
|
return this._updated;
|
|
}
|
|
|
|
set updated(updated) {
|
|
this._updated = updated;
|
|
}
|
|
|
|
execute(callback) {
|
|
const nowUsec = GLib.get_monotonic_time();
|
|
const remaining = this._intervalUsec - (nowUsec - this._lastUpdateUsec);
|
|
if (this._intervalUsec > 0 && this._lastUpdateUsec !== 0 && remaining > 0) {
|
|
if (callback)
|
|
callback();
|
|
return;
|
|
}
|
|
|
|
this._updated = false;
|
|
this._readings = [];
|
|
|
|
try {
|
|
this._available = GLib.file_test(this._powerDir, GLib.FileTest.IS_DIR);
|
|
if (!this._available) {
|
|
return;
|
|
}
|
|
|
|
const directory = Gio.File.new_for_path(this._powerDir);
|
|
let enumerator = null;
|
|
|
|
try {
|
|
enumerator = directory.enumerate_children('standard::name,standard::type', Gio.FileQueryInfoFlags.NONE, null);
|
|
|
|
let info;
|
|
while ((info = enumerator.next_file(null)) !== null) {
|
|
if (info.get_file_type() !== Gio.FileType.REGULAR)
|
|
continue;
|
|
|
|
const name = info.get_name();
|
|
const file = directory.get_child(name);
|
|
|
|
try {
|
|
const [ok, contents] = file.load_contents(null);
|
|
if (!ok)
|
|
continue;
|
|
|
|
const value = parseFloat(new TextDecoder('utf-8').decode(contents).trim());
|
|
if (isNaN(value))
|
|
continue;
|
|
|
|
const feature = {
|
|
label: this._formatLabel(name),
|
|
power: Math.abs(value),
|
|
};
|
|
|
|
this._readings.push(feature);
|
|
} catch (e) {
|
|
logError(e, `[FREON] Failed to read wattd metric ${name}`);
|
|
}
|
|
}
|
|
} finally {
|
|
if (enumerator !== null)
|
|
enumerator.close(null);
|
|
}
|
|
|
|
this._readings.sort((a, b) => a.label.localeCompare(b.label, undefined, {numeric: true}));
|
|
} catch (e) {
|
|
logError(e, '[FREON] Failed to enumerate wattd metrics');
|
|
this._available = false;
|
|
this._readings = [];
|
|
} finally {
|
|
this._lastUpdateUsec = nowUsec;
|
|
this._updated = true;
|
|
if (callback)
|
|
callback();
|
|
}
|
|
}
|
|
|
|
get power() {
|
|
return this._readings;
|
|
}
|
|
|
|
destroy() {
|
|
this._readings = [];
|
|
this._lastUpdateUsec = 0;
|
|
}
|
|
|
|
set interval(seconds) {
|
|
const clamped = Math.max(1, seconds | 0);
|
|
this._intervalUsec = clamped * 1000000;
|
|
this._lastUpdateUsec = 0;
|
|
}
|
|
|
|
_formatLabel(name) {
|
|
const parts = name.split(/[-_]/).filter(part => part.length > 0);
|
|
if (parts.length === 0)
|
|
return name;
|
|
|
|
return parts.map(part => part[0].toUpperCase() + part.slice(1)).join(' ');
|
|
}
|
|
}
|