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
 | 
						|
}
 |