From f5d204e5b273562a6eb4759d80492e816af71719 Mon Sep 17 00:00:00 2001
From: SimonFair <39065407+SimonFair@users.noreply.github.com>
Date: Sun, 28 Sep 2025 09:54:41 +0100
Subject: [PATCH 1/7] Add power placeholder and Split physical CPUS
---
emhttp/plugins/dynamix/DashStats.page | 34 +++++++++++++---------
emhttp/plugins/dynamix/include/Helpers.php | 17 +++++++++++
2 files changed, 37 insertions(+), 14 deletions(-)
diff --git a/emhttp/plugins/dynamix/DashStats.page b/emhttp/plugins/dynamix/DashStats.page
index b959f60bf..68ca33c79 100755
--- a/emhttp/plugins/dynamix/DashStats.page
+++ b/emhttp/plugins/dynamix/DashStats.page
@@ -94,7 +94,7 @@ foreach ($devs as $disk) {
}
$array_percent = number_format(100*$array_used/($array_size ?: 1),1,$dot,'');
-exec('cat /sys/devices/system/cpu/*/topology/thread_siblings_list|sort -nu', $cpus);
+$cpus=get_cpu_packages();
$wg_up = $wireguard ? exec("wg show interfaces") : '';
$wg_up = $wg_up ? explode(' ',$wg_up) : [];
$up = count($wg_up);
@@ -345,6 +345,9 @@ switch ($themeHelper->getThemeName()) { // $themeHelper set in DefaultPageLayout
|
+
+ _(Total Power)_: N/A
+
@@ -395,20 +398,23 @@ switch ($themeHelper->getThemeName()) { // $themeHelper set in DefaultPageLayout
|
- foreach ($cpus as $pair) {
- [$cpu1, $cpu2] = my_preg_split('/[,-]/',$pair);
- echo "";
- if ($is_intel_cpu && count($core_types) > 0)
- $core_type = "({$core_types[$cpu1]})";
- else
- $core_type = "";
+ foreach ($cpus as $cpu_index=>$package) {
+ echo "| "._("Physical")." CPU $cpu_index "._("Power").": N/A |
";
+ foreach ($package as $pair) {
+ [$cpu1, $cpu2] = my_preg_split('/[,-]/',$pair);
+ echo "";
+ if ($is_intel_cpu && count($core_types) > 0)
+ $core_type = "({$core_types[$cpu1]})";
+ else
+ $core_type = "";
- if ($cpu2)
- echo "| CPU $cpu1 $core_type - HT $cpu2 0% 0%
| ";
- else
- echo "CPU $cpu1 $core_type0%
| ";
- echo "
";
- }
+ if ($cpu2)
+ echo "CPU $cpu1 $core_type - HT $cpu2 0% 0%
| ";
+ else
+ echo "CPU $cpu1 $core_type0%
| ";
+ echo "";
+ }
+ }
?>
|
diff --git a/emhttp/plugins/dynamix/include/Helpers.php b/emhttp/plugins/dynamix/include/Helpers.php
index 5c3dfacc5..75b152448 100644
--- a/emhttp/plugins/dynamix/include/Helpers.php
+++ b/emhttp/plugins/dynamix/include/Helpers.php
@@ -857,4 +857,21 @@ HTML;
return $html;
}
+
+function get_cpu_packages(string $separator = ','): array {
+ $packages = [];
+ foreach (glob("/sys/devices/system/cpu/cpu[0-9]*/topology/thread_siblings_list") as $path) {
+ $pkg_id = (int)file_get_contents(dirname($path) . "/physical_package_id");
+ $siblings = str_replace(",", $separator, trim(file_get_contents($path)));
+ if (!in_array($siblings, $packages[$pkg_id] ?? [])) {
+ $packages[$pkg_id][] = $siblings;
+ }
+ }
+ foreach ($packages as &$list) {
+ $keys = array_map(fn($s) => (int)explode($separator, $s)[0], $list);
+ array_multisort($keys, SORT_ASC, SORT_NUMERIC, $list);
+ }
+ unset($list);
+ return $packages;
+}
?>
From e64211b8e5d083f99c0dbfae6ec8319b0c752e91 Mon Sep 17 00:00:00 2001
From: SimonFair <39065407+SimonFair@users.noreply.github.com>
Date: Sun, 28 Sep 2025 10:11:26 +0100
Subject: [PATCH 2/7] Add icon to total power.
---
emhttp/plugins/dynamix/DashStats.page | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/emhttp/plugins/dynamix/DashStats.page b/emhttp/plugins/dynamix/DashStats.page
index 68ca33c79..f03d557a9 100755
--- a/emhttp/plugins/dynamix/DashStats.page
+++ b/emhttp/plugins/dynamix/DashStats.page
@@ -346,7 +346,7 @@ switch ($themeHelper->getThemeName()) { // $themeHelper set in DefaultPageLayout
|
- _(Total Power)_: N/A
+ _(Total Power)_: N/A
From e4ed5896f6e5fd3c7022f47c3ca0f91b1a6c0f27 Mon Sep 17 00:00:00 2001
From: SimonFair <39065407+SimonFair@users.noreply.github.com>
Date: Sun, 28 Sep 2025 10:17:16 +0100
Subject: [PATCH 3/7] Fix placeholder index
---
emhttp/plugins/dynamix/DashStats.page | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/emhttp/plugins/dynamix/DashStats.page b/emhttp/plugins/dynamix/DashStats.page
index f03d557a9..42ccf33a8 100755
--- a/emhttp/plugins/dynamix/DashStats.page
+++ b/emhttp/plugins/dynamix/DashStats.page
@@ -399,7 +399,7 @@ switch ($themeHelper->getThemeName()) { // $themeHelper set in DefaultPageLayout
foreach ($cpus as $cpu_index=>$package) {
- echo " | "._("Physical")." CPU $cpu_index "._("Power").": N/A |
";
+ echo ""._("Physical")." CPU $cpu_index "._("Power").": N/A | ";
foreach ($package as $pair) {
[$cpu1, $cpu2] = my_preg_split('/[,-]/',$pair);
echo "";
From 2f66cd3d021f225767ed0bc62520b01a7f1b6ee8 Mon Sep 17 00:00:00 2001
From: SimonFair <39065407+SimonFair@users.noreply.github.com>
Date: Tue, 21 Oct 2025 20:30:49 +0100
Subject: [PATCH 4/7] Changes for power and temp.
---
emhttp/plugins/dynamix/DashStats.page | 96 ++++++++++++++++++++++++++-
1 file changed, 93 insertions(+), 3 deletions(-)
diff --git a/emhttp/plugins/dynamix/DashStats.page b/emhttp/plugins/dynamix/DashStats.page
index 42ccf33a8..09b63a7d2 100755
--- a/emhttp/plugins/dynamix/DashStats.page
+++ b/emhttp/plugins/dynamix/DashStats.page
@@ -346,11 +346,13 @@ switch ($themeHelper->getThemeName()) { // $themeHelper set in DefaultPageLayout
|
- _(Total Power)_: N/A
+ _(Total)_ _(Power)_: N/A
+
-
+ _(Temp)_:
+
_(Load)_:
0%
@@ -399,7 +401,11 @@ switch ($themeHelper->getThemeName()) { // $themeHelper set in DefaultPageLayout
foreach ($cpus as $cpu_index=>$package) {
- echo " | "._("Physical")." CPU $cpu_index "._("Power").": N/A |
";
+ if (count($cpus) > 1) {
+ echo ""._("Physical")." CPU $cpu_index "._("Power").": N/A ";
+ if (count($cpus)>1) echo _("Temp").": N/A";
+ echo " | ";
+ }
foreach ($package as $pair) {
[$cpu1, $cpu2] = my_preg_split('/[,-]/',$pair);
echo "";
@@ -1696,6 +1702,36 @@ function addChartNet(rx, tx) {
txTimeSeries.append(now, Math.floor(tx / 1000));
}
+function updateCPUPower() {
+ if (!cpupower) return;
+
+ // Update total power
+ const totalEl = document.getElementById('cpu-total-power');
+ const totalPower = cpupower.totalPower ?? 0;
+ if (totalEl) {
+ totalEl.innerHTML = ` _(Total)_ _(Power)_: ${totalPower.toFixed(2)} W`;
+ }
+
+ // Update each core's span
+ const cpuspower = cpupower.power ?? [];
+ cpuspower.forEach((power, index) => {
+ const coreEl = document.getElementById(`cpu-power${index}`);
+ const coreTempEl = document.getElementById(`cpu-temp${index}`);
+ if (coreEl) {
+ coreEl.innerHTML = `${power.toFixed(2)} W`;
+ }
+ });
+
+ const cpustemps = cpupower.temp ?? [];
+ cpustemps.forEach((temp, index) => {
+ const coreTempEl = document.getElementById(`cpu-temp${index}`);
+ if (coreTempEl) {
+ coreTempEl.innerHTML = `${temp.toFixed(0)} C`;;
+ }
+ });
+
+}
+
// Cache for last values to avoid unnecessary DOM updates
var lastCpuValues = {
load: -1,
@@ -2771,6 +2807,60 @@ $(function() {
setTimeout(function() {
// Charts initialized
},500);
+
+
+
+ // Start GraphQL CPU power subscription with retry logic
+ let cpuInitPWRAttempts = 0, cpuPWRRetryMs = 100;
+ function initPwrCpuSubscription() {
+
+
+ if (window.gql && window.apolloClient) {
+ // Define the subscription query when GraphQL is available
+ // corepower has the temps currently.
+ CPU_POWER_SUBSCRIPTION = window.gql(`
+ subscription SystemMetricsCpuTelemetry {
+ systemMetricsCpuTelemetry {
+ totalPower,
+ power,
+ temp,
+ }
+ }
+ `);
+ cpuPowerSubscription = window.apolloClient.subscribe({
+ query: CPU_POWER_SUBSCRIPTION
+ }).subscribe({
+ next: (result) => {
+
+
+ if (result.data?.systemMetricsCpuTelemetry){
+ cpupower = result.data.systemMetricsCpuTelemetry;
+
+ updateCPUPower();
+ }
+ },
+ error: (err) => {
+ console.error('CPU power subscription error:', err);
+ // Try to resubscribe with capped backoff
+ if (cpuPowerSubscription) { try { cpuPowerSubscription.unsubscribe(); } catch(e){} }
+ setTimeout(initPwrCpuSubscription, Math.min(cpuPWRRetryMs *= 2, 5000));
+ }
+ });
+ } else {
+ // Retry with capped backoff if GraphQL client not ready
+ cpuPWRInitAttempts++;
+ setTimeout(initPwrCpuSubscription, Math.min(cpuPWRRetryMs *= 2, 2000));
+ }
+ }
+ initPwrCpuSubscription();
+ // Cleanup GraphQL subscription on page unload
+ $(window).on('beforeunload', function() {
+ if (cpuPowerSubscription) {
+ cpuPowerSubscription.unsubscribe();
+ }
+ });
+
+
// Cleanup GraphQL subscription on page unload
$(window).on('beforeunload', function() {
From e799c9144d925a3a0c139fec038f12f93a7f3185 Mon Sep 17 00:00:00 2001
From: SimonFair <39065407+SimonFair@users.noreply.github.com>
Date: Wed, 22 Oct 2025 21:53:07 +0100
Subject: [PATCH 5/7] Layout change and fixes
---
emhttp/plugins/dynamix/DashStats.page | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/emhttp/plugins/dynamix/DashStats.page b/emhttp/plugins/dynamix/DashStats.page
index c4b08fbde..c2863c20e 100755
--- a/emhttp/plugins/dynamix/DashStats.page
+++ b/emhttp/plugins/dynamix/DashStats.page
@@ -95,6 +95,7 @@ foreach ($devs as $disk) {
$array_percent = number_format(100*$array_used/($array_size ?: 1),1,$dot,'');
$cpus=get_cpu_packages();
+$cpus[] = ["16,17"];
$wg_up = $wireguard ? exec("wg show interfaces") : '';
$wg_up = $wg_up ? explode(' ',$wg_up) : [];
$up = count($wg_up);
@@ -351,11 +352,11 @@ switch ($themeHelper->getThemeName()) { // $themeHelper set in DefaultPageLayout
|
- _(Total)_ _(Power)_: N/A
+ _(Total)_ _(Power)_: N/A
- _(Temp)_:
+ _(Temperature)_: N/A
@@ -403,12 +404,12 @@ switch ($themeHelper->getThemeName()) { // $themeHelper set in DefaultPageLayout
|
-
+
foreach ($cpus as $cpu_index=>$package) {
if (count($cpus) > 1) {
- echo "| "._("Physical")." CPU $cpu_index "._("Power").": N/A ";
- if (count($cpus)>1) echo _("Temp").": N/A";
+ echo " | "._("Physical")." CPU $cpu_index "._("Power").": N/A ";
+ if (count($cpus)>1) echo " "._("Temperature").": N/A";
echo " |
";
}
foreach ($package as $pair) {
@@ -1453,6 +1454,8 @@ var startup = true;
var stopgap = ' |
';
var recall = null;
var recover = null;
+var tempunit="=_var($display,'unit','C');?>";
+
// Helper function to calculate millisPerPixel based on container width
function getMillisPerPixel(timeInSeconds, containerId) {
@@ -1721,7 +1724,6 @@ function updateCPUPower() {
const cpuspower = cpupower.power ?? [];
cpuspower.forEach((power, index) => {
const coreEl = document.getElementById(`cpu-power${index}`);
- const coreTempEl = document.getElementById(`cpu-temp${index}`);
if (coreEl) {
coreEl.innerHTML = `${power.toFixed(2)} W`;
}
@@ -1731,7 +1733,11 @@ function updateCPUPower() {
cpustemps.forEach((temp, index) => {
const coreTempEl = document.getElementById(`cpu-temp${index}`);
if (coreTempEl) {
- coreTempEl.innerHTML = `${temp.toFixed(0)} C`;;
+ tempdisplay = temp.toFixed(0);
+ if (tempunit === "F") {
+ tempdisplay = ((temp.toFixed(0))* 9 / 5) + 32;
+ }
+ coreTempEl.innerHTML = Math.round(tempdisplay)+` °`+tempunit;;
}
});
@@ -2853,7 +2859,7 @@ $(function() {
});
} else {
// Retry with capped backoff if GraphQL client not ready
- cpuPWRInitAttempts++;
+ cpuPInitPWRAttempts++;
setTimeout(initPwrCpuSubscription, Math.min(cpuPWRRetryMs *= 2, 2000));
}
}
From 5083f85d8a298ba71f1cf4ca9a5a6aef70f9102c Mon Sep 17 00:00:00 2001
From: SimonFair <39065407+SimonFair@users.noreply.github.com>
Date: Wed, 22 Oct 2025 22:00:41 +0100
Subject: [PATCH 6/7] Remove test code
---
emhttp/plugins/dynamix/DashStats.page | 2 --
emhttp/plugins/dynamix/include/cpulist.php | 22 ++++++++++++++++++++++
2 files changed, 22 insertions(+), 2 deletions(-)
create mode 100644 emhttp/plugins/dynamix/include/cpulist.php
diff --git a/emhttp/plugins/dynamix/DashStats.page b/emhttp/plugins/dynamix/DashStats.page
index c2863c20e..1259ff11b 100755
--- a/emhttp/plugins/dynamix/DashStats.page
+++ b/emhttp/plugins/dynamix/DashStats.page
@@ -95,7 +95,6 @@ foreach ($devs as $disk) {
$array_percent = number_format(100*$array_used/($array_size ?: 1),1,$dot,'');
$cpus=get_cpu_packages();
-$cpus[] = ["16,17"];
$wg_up = $wireguard ? exec("wg show interfaces") : '';
$wg_up = $wg_up ? explode(' ',$wg_up) : [];
$up = count($wg_up);
@@ -1456,7 +1455,6 @@ var recall = null;
var recover = null;
var tempunit="=_var($display,'unit','C');?>";
-
// Helper function to calculate millisPerPixel based on container width
function getMillisPerPixel(timeInSeconds, containerId) {
var container = document.getElementById(containerId);
diff --git a/emhttp/plugins/dynamix/include/cpulist.php b/emhttp/plugins/dynamix/include/cpulist.php
new file mode 100644
index 000000000..8d1db3573
--- /dev/null
+++ b/emhttp/plugins/dynamix/include/cpulist.php
@@ -0,0 +1,22 @@
+ (int)explode($separator, $s)[0], $list);
+ array_multisort($keys, SORT_ASC, SORT_NUMERIC, $list);
+ }
+ unset($list);
+
+ return $packages;
+}
From 117a49491a2595f3f18267461baf18d9357df8b7 Mon Sep 17 00:00:00 2001
From: SimonFair <39065407+SimonFair@users.noreply.github.com>
Date: Thu, 23 Oct 2025 12:09:13 +0100
Subject: [PATCH 7/7] Update DashStats.page
---
emhttp/plugins/dynamix/DashStats.page | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/emhttp/plugins/dynamix/DashStats.page b/emhttp/plugins/dynamix/DashStats.page
index 1259ff11b..60fbc8f96 100755
--- a/emhttp/plugins/dynamix/DashStats.page
+++ b/emhttp/plugins/dynamix/DashStats.page
@@ -2857,7 +2857,7 @@ $(function() {
});
} else {
// Retry with capped backoff if GraphQL client not ready
- cpuPInitPWRAttempts++;
+ cpuInitPWRAttempts++;
setTimeout(initPwrCpuSubscription, Math.min(cpuPWRRetryMs *= 2, 2000));
}
}