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