138 lines
3.7 KiB
TypeScript
138 lines
3.7 KiB
TypeScript
import { exec, execAsync, interval, Variable } from "astal";
|
|
|
|
const FETCH_INTERVAL = 2000;
|
|
const cpuUtil = Variable("0%");
|
|
const ramUtil = Variable("0%");
|
|
const ramUsed = Variable("0MiB");
|
|
const gpuUtil = Variable("0%");
|
|
let gpuName = "card1";
|
|
let enabled = true;
|
|
|
|
const getStats = (): Stats => {
|
|
gpuName = exec(`/bin/bash -c "ls /sys/class/drm/ | grep '^card[0-9]*$'"`);
|
|
const cpuNameInSensors = "CPUTIN";
|
|
const stats = {
|
|
kernel: exec("uname -sr"),
|
|
cpuTemp: exec(
|
|
`/bin/bash -c "sensors | grep -m1 ${cpuNameInSensors} | awk '{print $2}'"`,
|
|
),
|
|
cpuClk: exec(
|
|
`awk '/cpu MHz/ {sum+=$4; ++n} END {print sum/n " MHz"}' /proc/cpuinfo`,
|
|
),
|
|
gpuTemp: exec(
|
|
`/bin/bash -c "sensors | grep -E 'edge' | awk '{print $2}'"`,
|
|
),
|
|
gpuClk: exec(
|
|
`/bin/bash -c "cat /sys/class/drm/${gpuName}/device/pp_dpm_sclk | grep '\\*' | awk '{print $2 $3}'"`,
|
|
),
|
|
vram:
|
|
Math.round(
|
|
parseInt(
|
|
exec(
|
|
`cat /sys/class/drm/${gpuName}/device/mem_info_vram_used`,
|
|
),
|
|
) /
|
|
1024 /
|
|
1024,
|
|
) + "MiB",
|
|
availableVRAM:
|
|
Math.round(
|
|
parseInt(
|
|
exec(
|
|
`cat /sys/class/drm/${gpuName}/device/mem_info_vram_total`,
|
|
),
|
|
) /
|
|
1024 /
|
|
1024,
|
|
) + "MiB",
|
|
};
|
|
|
|
return stats;
|
|
};
|
|
|
|
const systemStats: Variable<Stats> = Variable(getStats());
|
|
const availableFeatures = {
|
|
cpu: true,
|
|
ram: true,
|
|
};
|
|
|
|
const refreshStats = () => {
|
|
systemStats.set(getStats());
|
|
}
|
|
|
|
const featureTest = () => {
|
|
print('[SysInfo] Feature test started...');
|
|
// Check if awk & sed are available
|
|
try {
|
|
exec("awk -V");
|
|
exec("sed --version");
|
|
} catch (e) {
|
|
printerr(
|
|
"[ SysInfo ] AWK or SED missing! No system info will be available",
|
|
);
|
|
enabled = false;
|
|
return;
|
|
}
|
|
|
|
// Check if mpstat is available
|
|
try {
|
|
exec("mpstat -V");
|
|
} catch (e) {
|
|
availableFeatures.cpu = false;
|
|
printerr(
|
|
"[ SysInfo ] Feature Test for CPU info failed. mpstat from the sysstat package missing!",
|
|
);
|
|
}
|
|
print('[SysInfo] Feature test complete');
|
|
};
|
|
|
|
const sysInfoFetcher = () => {
|
|
if (enabled) {
|
|
if (availableFeatures.cpu) {
|
|
execAsync(`/bin/fish -c cpu-utilization`).then(v => {
|
|
cpuUtil.set("" + Math.round(parseFloat(v)));
|
|
}).catch(e => {
|
|
console.error(e);
|
|
});
|
|
}
|
|
if (availableFeatures.ram) {
|
|
execAsync(
|
|
`/bin/bash -c "free | awk '/Mem:/ {print $3 \\" \\" $2}'"`,
|
|
).then(v => {
|
|
const util = parseInt(v.split(' ')[0]);
|
|
const available = parseInt(v.split(' ')[1]);
|
|
ramUtil.set("" + Math.round(util / available * 100));
|
|
ramUsed.set(`${Math.round(util / 1024 / 1024 * 10) / 10} GiB of ${Math.round(available / 1024 / 1024 * 10) / 10} GiB used`);
|
|
}).catch(e => {
|
|
console.error(e);
|
|
});
|
|
}
|
|
gpuUtil.set(exec("cat /sys/class/drm/card1/device/gpu_busy_percent"));
|
|
}
|
|
};
|
|
|
|
let sysInfoFetcherRunning = false;
|
|
const startSysInfoFetcher = () => {
|
|
if (!sysInfoFetcherRunning) {
|
|
sysInfoFetcherRunning = true;
|
|
|
|
featureTest();
|
|
|
|
if (enabled) {
|
|
// Start interval
|
|
interval(FETCH_INTERVAL, sysInfoFetcher);
|
|
}
|
|
}
|
|
}
|
|
|
|
export default {
|
|
startSysInfoFetcher,
|
|
enabled,
|
|
gpuUtil,
|
|
cpuUtil,
|
|
ramUsed,
|
|
ramUtil,
|
|
refreshStats,
|
|
systemStats
|
|
}
|