Skip to content

Commit 6c165ed

Browse files
authored
Create render.js
1 parent c39eab8 commit 6c165ed

File tree

1 file changed

+179
-0
lines changed

1 file changed

+179
-0
lines changed

render.js

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
const { exec } = require('child_process');
2+
const os = require('os');
3+
const fs = require('fs');
4+
5+
let prevNetStats = null;
6+
7+
function updateCpuTemp() {
8+
exec('sensors | grep -A 0 "Tctl:" | cut -c15-22', (error, stdout, stderr) => {
9+
let temp = 'N/A';
10+
if (!error && stdout) {
11+
temp = parseFloat(stdout.trim()).toFixed(1);
12+
} else {
13+
try {
14+
const raw = fs.readFileSync('/sys/class/thermal/thermal_zone0/temp', 'utf8');
15+
temp = (parseInt(raw) / 1000).toFixed(1);
16+
} catch (e) {
17+
console.error('Failed to read CPU temp');
18+
}
19+
}
20+
document.getElementById('cpu-temp').textContent = temp;
21+
});
22+
}
23+
24+
function updateCpuUsage() {
25+
exec('top -bn1 | grep "Cpu(s)" | sed "s/.*, *\\([0-9.]*\\)%* id.*/\\1/" | awk \'{print 100 - $1}\'', (error, stdout, stderr) => {
26+
let usage = 'N/A';
27+
if (!error && stdout) {
28+
usage = parseFloat(stdout.trim()).toFixed(1);
29+
}
30+
document.getElementById('cpu-usage').textContent = usage;
31+
});
32+
}
33+
34+
function updateCpuFreq() {
35+
exec('cat /proc/cpuinfo | grep "cpu MHz" | head -1 | awk \'{print $4}\'', (error, stdout, stderr) => {
36+
let freq = 'N/A';
37+
if (!error && stdout) {
38+
freq = parseFloat(stdout.trim()).toFixed(0);
39+
}
40+
document.getElementById('cpu-freq').textContent = freq;
41+
});
42+
}
43+
44+
function updateGpuTemp() {
45+
// NVIDIA
46+
exec('nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader', (error, stdout, stderr) => {
47+
let temp = 'N/A';
48+
if (!error && stdout) {
49+
temp = parseFloat(stdout.trim()).toFixed(1);
50+
} else {
51+
// Try AMD (assuming rocm-smi)
52+
exec('rocm-smi --showtemp | grep "GPU Temp" | awk \'{print $4}\'', (err, out) => {
53+
if (!err && out) {
54+
temp = parseFloat(out.trim()).toFixed(1);
55+
}
56+
// Could add Intel iGPU, but more complex
57+
});
58+
}
59+
document.getElementById('gpu-temp').textContent = temp;
60+
});
61+
}
62+
63+
function updateGpuUsage() {
64+
exec('nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader', (error, stdout, stderr) => {
65+
let usage = 'N/A';
66+
if (!error && stdout) {
67+
usage = parseFloat(stdout.trim()).toFixed(1);
68+
} else {
69+
exec('rocm-smi --showutil | grep "GPU use" | awk \'{print $4}\'', (err, out) => {
70+
if (!err && out) {
71+
usage = parseFloat(out.trim()).toFixed(1);
72+
}
73+
});
74+
}
75+
document.getElementById('gpu-usage').textContent = usage;
76+
});
77+
}
78+
79+
function updateGpuFan() {
80+
exec('nvidia-smi --query-gpu=fan.speed --format=csv,noheader', (error, stdout, stderr) => {
81+
let fan = 'N/A';
82+
if (!error && stdout) {
83+
fan = parseFloat(stdout.trim()).toFixed(1);
84+
} else {
85+
exec('rocm-smi --showfan | grep "Fan Level" | awk \'{print $4}\'', (err, out) => {
86+
if (!err && out) {
87+
fan = parseFloat(out.trim()).toFixed(1);
88+
}
89+
});
90+
}
91+
document.getElementById('gpu-fan').textContent = fan;
92+
});
93+
}
94+
95+
function updateGpuMem() {
96+
exec('nvidia-smi --query-gpu=memory.used,memory.total --format=csv,noheader', (error, stdout, stderr) => {
97+
let mem = 'N/A';
98+
if (!error && stdout) {
99+
const [used, total] = stdout.trim().split(',').map(s => s.trim().replace(' MiB', ''));
100+
mem = `${used}/${total}`;
101+
} else {
102+
exec('rocm-smi --showmeminfo vram | grep "Used" | awk \'{print $4 "/" $5}\'', (err, out) => {
103+
if (!err && out) {
104+
mem = out.trim();
105+
}
106+
});
107+
}
108+
document.getElementById('gpu-mem').textContent = mem;
109+
});
110+
}
111+
112+
function updateRamUsage() {
113+
const totalMem = os.totalmem();
114+
const freeMem = os.freemem();
115+
const usedMem = totalMem - freeMem;
116+
const usage = ((usedMem / totalMem) * 100).toFixed(1);
117+
document.getElementById('ram-usage').textContent = usage;
118+
}
119+
120+
function updateDiskUsage() {
121+
exec('df -h / | tail -1 | awk \'{print $5}\' | sed \'s/%//\'', (error, stdout, stderr) => {
122+
let usage = 'N/A';
123+
if (!error && stdout) {
124+
usage = stdout.trim();
125+
}
126+
document.getElementById('disk-usage').textContent = usage;
127+
});
128+
}
129+
130+
function updateBatteryLevel() {
131+
try {
132+
const batteryPath = '/sys/class/power_supply/BAT0/capacity'; // Assuming BAT0, may vary
133+
if (fs.existsSync(batteryPath)) {
134+
const level = fs.readFileSync(batteryPath, 'utf8').trim();
135+
document.getElementById('battery-level').textContent = level;
136+
} else {
137+
document.getElementById('battery-level').textContent = 'N/A';
138+
}
139+
} catch (e) {
140+
document.getElementById('battery-level').textContent = 'N/A';
141+
}
142+
}
143+
144+
function updateUptime() {
145+
const uptimeSeconds = os.uptime();
146+
const days = Math.floor(uptimeSeconds / (3600 * 24));
147+
const hours = Math.floor((uptimeSeconds % (3600 * 24)) / 3600);
148+
const minutes = Math.floor((uptimeSeconds % 3600) / 60);
149+
const seconds = Math.floor(uptimeSeconds % 60);
150+
document.getElementById('uptime').textContent = `${days}d ${hours}h ${minutes}m ${seconds}s`;
151+
}
152+
153+
// Update every 2 seconds
154+
setInterval(() => {
155+
updateCpuTemp();
156+
updateCpuUsage();
157+
updateCpuFreq();
158+
updateGpuTemp();
159+
updateGpuUsage();
160+
updateGpuFan();
161+
updateGpuMem();
162+
updateRamUsage();
163+
updateDiskUsage();
164+
updateBatteryLevel();
165+
updateUptime();
166+
}, 2000);
167+
168+
// Initial update
169+
updateCpuTemp();
170+
updateCpuUsage();
171+
updateCpuFreq();
172+
updateGpuTemp();
173+
updateGpuUsage();
174+
updateGpuFan();
175+
updateGpuMem();
176+
updateRamUsage();
177+
updateDiskUsage();
178+
updateBatteryLevel();
179+
updateUptime();

0 commit comments

Comments
 (0)