+
$stats
|
$layout
- |
- _(GPU not available bound to VFIO or inuse in a VM.)_ |
+ |
+ _(GPU not available bound to VFIO or inuse in a VM.)_ |
+ |
EOT;
- $multigpus[$id]["panel"] = $i ;
$i++ ; #GPU Number
$j++ ; #Default Column
if ($j >3) { $j=1 ; $k++ ;} #Plugin name in array. Only 3 Dashboards per name.
}
-function GPULayout($count,$vendor,$gpustat_cfg) {
- $apps = [
- 'plex', 'jellyfin', 'handbrake', 'emby', 'tdarr', 'unmanic', 'dizquetv', 'ersatztv',
- 'fileflows', 'frigate', 'deepstack', 'nsfminer', 'shinobipro', 'foldinghome','threadfin', 'codeproject', 'compreface',
-];
+function GPULayout($vendor,$gpustat_cfg) {
$gpu_nv = $gpu_intel = $gpu_amd = $gpu_unknown = false;
switch ($vendor) {
case "nvidia":
@@ -134,262 +126,249 @@ $gpu_nv = $gpu_intel = $gpu_amd = $gpu_unknown = false;
}
$page_render = '' ;
- $page_render .= " " ;
+ $page_render .= " " ;
- # No GPU Set
+ # No GPU Set
- if ($gpu_unknown) $page_render .= " |
_(No GPUs selected - Select GPU(s) in GPUStat settings page and apply.)_ |
" ;
+ if ($gpu_unknown) $page_render .= "_(No GPUs selected - Select GPU(s) in GPUStat settings page and apply.)_ |
" ;
# Nvidia GPUs
if ($gpu_nv) {
if($gpustat_cfg['DISPPCIUTIL']) {
- $page_render .= " PCIe Gen (Max): ()" ;
- $page_render .= " Lanes (Max): ()" ;
+ $page_render .= " PCIe Gen (Max): ()" ;
+ $page_render .= " Lanes (Max): ()" ;
}
if ($gpu_nv) {
- $page_render .= "_(Load - Memory)_" ;
- $page_render .= "0% " ;
+ $page_render .= " |
_(Load - Memory)_" ;
+ $page_render .= "0% " ;
if($gpustat_cfg['DISPMEMUTIL']) {
- $page_render .= "0% " ;
+ $page_render .= "0% " ;
}
$page_render .= " |
" ;
}
if($gpustat_cfg['DISPENCDEC']) {
- $page_render .= "_(Encoder - Decoder)_" ;
- $page_render .= "0% " ;
- $page_render .= "0% " ;
+ $page_render .= " |
_(Encoder - Decoder)_" ;
+ $page_render .= "0% " ;
+ $page_render .= "0% " ;
$page_render .= " |
" ;
}
-
+
if($gpustat_cfg['DISPCLOCKS']) {
- $page_render .= "_(GPU - Memory (MHz))_" ;
- $page_render .= "0% " ;
- $page_render .= "0% " ;
+ $page_render .= " |
_(GPU - Memory (MHz))_" ;
+ $page_render .= "0% " ;
+ $page_render .= "0% " ;
$page_render .= " |
" ;
}
if($gpustat_cfg['DISPFAN'] || $gpustat_cfg['DISPPWRDRAW']) {
- $page_render .= "_(Fan - Power)_" ;
+ $page_render .= " |
_(Fan - Power)_" ;
if($gpustat_cfg['DISPFAN']) {
- $page_render .= "0% " ;
+ $page_render .= "0% " ;
}
if($gpustat_cfg['DISPPWRDRAW']) {
- $page_render .= "0% " ;
+ $page_render .= "0% " ;
}
$page_render .= " |
" ;
}
if($gpustat_cfg['DISPPCIUTIL']) {
- $page_render .= "_(PCI Bus Rx/Tx (MB/s))_" ;
- $page_render .= "0% " ;
- $page_render .= "0% " ;
+ $page_render .= " |
_(PCI Bus Rx/Tx (MB/s))_" ;
+ $page_render .= "0% " ;
+ $page_render .= "0% " ;
$page_render .= " |
" ;
}
if($gpustat_cfg['DISPTHROTTLE'] || $gpustat_cfg['DISPPWRSTATE']) {
- $page_render .= "_(Power State - Throttling)_" ;
+ $page_render .= " |
_(Power State - Throttling)_" ;
if($gpustat_cfg['DISPPWRSTATE']) {
- $page_render .= "" ;
+ $page_render .= "" ;
}
if($gpustat_cfg['DISPTHROTTLE']) {
- $page_render .= " " ;
+ $page_render .= " " ;
}
$page_render .= " |
" ;
}
-
+
if($gpustat_cfg['DISPSESSIONS']) {
- $page_render .= "_(Active Apps)_" ;
- foreach($apps as $app) {
- $page_render .= "" ;
- $page_render .= "" ;
- $page_render .= "" ;
- }
- $page_render .= " |
" ;
- }
+ $page_render .= "_(Active Apps)_ |
" ;
+ }
}
if ($gpu_intel) {
if($gpustat_cfg['DISP3DRENDER']) {
- $page_render .= "_(3D Render Load)_" ;
- $page_render .= "0% " ;
- $page_render .= " |
" ;
+ $page_render .= "_(3D Render Load)_" ;
+ $page_render .= "0% " ;
+ $page_render .= " |
" ;
}
if($gpustat_cfg['DISPBLITTER']) {
- $page_render .="_(Blitter Load)_" ;
- $page_render .=" " ;
- $page_render .=" |
" ;
+ $page_render .="_(Blitter Load)_" ;
+ $page_render .=" " ;
+ $page_render .=" |
" ;
}
if($gpustat_cfg['DISPVIDEO']) {
- $page_render .="_(Video Load)_" ;
- $page_render .=" " ;
- $page_render .=" |
" ;
+ $page_render .="_(Video Load)_" ;
+ $page_render .=" " ;
+ $page_render .=" |
" ;
}
if($gpustat_cfg['DISPVIDENH']) {
- $page_render .= "_(Video Enhance Load)_" ;
- $page_render .=" " ;
- $page_render .=" |
" ;
+ $page_render .= "_(Video Enhance Load)_" ;
+ $page_render .=" " ;
+ $page_render .=" |
" ;
}
- if($gpustat_cfg['DISPPWRDRAW']) {
- $page_render .="_(Power Draw)_" ;
- $page_render .=" " ;
- $page_render .=" |
" ;
+ if($gpustat_cfg['DISPPWRDRAW']) {
+ $page_render .="_(Power Draw)_" ;
+ $page_render .=" " ;
+ $page_render .=" |
" ;
}
if($gpustat_cfg['DISPPCIUTIL']) {
- $page_render .="_(IMC Bus Utilization)_" ;
- $page_render .="Receive: Transmit: |
" ;
+ $page_render .="_(IMC Bus Utilization)_" ;
+ $page_render .="Receive: Transmit: |
" ;
}
if($gpustat_cfg['DISPCLOCKS']) {
- $page_render .="_(GPU Clock (MHz))_" ;
- $page_render .=" |
" ;
+ $page_render .="_(GPU Clock (MHz))_" ;
+ $page_render .=" |
" ;
}
if($gpustat_cfg['DISPINTERRUPT']) {
- $page_render .="_(Interrupts/Sec)_" ;
- $page_render .=" |
" ;
+ $page_render .="_(Interrupts/Sec)_" ;
+ $page_render .=" |
" ;
}
-
+
}
- // AMD GPUs
+ // AMD GPUs
if ($gpu_amd) {
- $page_render .="_(GPU Load)_" ;
- $page_render .="0%
|
" ;
-
+ $page_render .="_(GPU Load)_" ;
+ $page_render .="0%
|
" ;
+
if($gpustat_cfg['DISPGFXTRANS'] || $gpustat_cfg['DISPMEMUTIL']) {
- $page_render .= "_(Translate - Memory (MB))_" ;
+ $page_render .= " |
_(Translate - Memory (MB))_" ;
if($gpustat_cfg['DISPGFXTRANS']) {
- $page_render .= "0% " ;
- $page_render .= " " ;
+ $page_render .= "0%" ;
+ $page_render .= " " ;
}
if($gpustat_cfg['DISPMEMUTIL']) {
- $page_render .= "0%" ;
- $page_render .= " ";
+ $page_render .= "0%" ;
+ $page_render .= " ";
}
$page_render .= " |
" ;
}
if($gpustat_cfg['DISPEVENT'] || $gpustat_cfg['DISPVERTEX']) {
- $page_render .= "_(Event - Vertex (MB))_" ;
+ $page_render .= " |
_(Event - Vertex (MB))_" ;
if($gpustat_cfg['DISPEVENT']) {
- $page_render .= " " ;
- $page_render .= " " ;
+ $page_render .= "" ;
+ $page_render .= " " ;
}
if($gpustat_cfg['DISPVERTEX']) {
- $page_render .= "" ;
- $page_render .= " " ;
+ $page_render .= "" ;
+ $page_render .= " " ;
}
}
if($gpustat_cfg['DISPTEXTURE'] || $gpustat_cfg['DISPSEQUENCER']) {
- $page_render .= " |
_(Texture - Sequencer)_" ;
+ $page_render .= " |
_(Texture - Sequencer)_" ;
if($gpustat_cfg['DISPTEXTURE']) {
- $page_render .= " " ;
- $page_render .= " " ;
+ $page_render .= "" ;
+ $page_render .= " " ;
}
if($gpustat_cfg['DISPSEQUENCER']) {
- $page_render .= "" ;
- $page_render .= " " ;
+ $page_render .= "" ;
+ $page_render .= " " ;
}
$page_render .= " |
" ;
}
if($gpustat_cfg['DISPSHADEREXP'] || $gpustat_cfg['DISPSHADERINTER']) {
- $page_render .= "_(Shader Export - Interpol)_" ;
+ $page_render .= " |
_(Shader Export - Interpol)_" ;
if($gpustat_cfg['DISPSHADEREXP']) {
- $page_render .= " " ;
- $page_render .= " " ;
+ $page_render .= "" ;
+ $page_render .= " " ;
}
if($gpustat_cfg['DISPSHADERINTER']) {
- $page_render .= "" ;
- $page_render .= " " ;
+ $page_render .= "" ;
+ $page_render .= " " ;
}
$page_render .= " |
" ;
}
if($gpustat_cfg['DISPSCANCON'] || $gpustat_cfg['DISPPRIMASSEM']) {
- $page_render .= "_(Scan Conv - Prim Assem)_" ;
+ $page_render .= " |
_(Scan Conv - Prim Assem)_" ;
if($gpustat_cfg['DISPSCANCON']) {
- $page_render .= " " ;
- $page_render .= " " ;
+ $page_render .= "" ;
+ $page_render .= " " ;
}
if($gpustat_cfg['DISPPRIMASSEM']) {
- $page_render .= "" ;
- $page_render .= " " ;
+ $page_render .= "" ;
+ $page_render .= " " ;
}
$page_render .= " |
" ;
}
if($gpustat_cfg['DISPDEPTHBLK'] || $gpustat_cfg['DISPCOLORBLK']) {
- $page_render .= "_(Blocks: Depth - Color)_" ;
- if($gpustat_cfg['DISPDEPTHBLK']) {
- $page_render .= " " ;
- $page_render .= " " ;
+ $page_render .= " |
_(Blocks: Depth - Color)_" ;
+ if($gpustat_cfg['DISPDEPTHBLK']) {
+ $page_render .= " " ;
+ $page_render .= " " ;
}
if($gpustat_cfg['DISPCOLORBLK']) {
- $page_render .= "" ;
- $page_render .= " " ;
+ $page_render .= "" ;
+ $page_render .= " " ;
}
$page_render .= " |
" ;
}
if($gpustat_cfg['DISPFAN'] || $gpustat_cfg['DISPPWRDRAW']) {
- $page_render .= "_(Fan - Power)_" ;
+ $page_render .= " |
_(Fan - Power)_" ;
if($gpustat_cfg['DISPFAN']) {
- $page_render .= " " ;
- $page_render .= " " ;
+ $page_render .= "" ;
+ $page_render .= " " ;
}
if($gpustat_cfg['DISPPWRDRAW']) {
- $page_render .= "" ;
- $page_render .= " |
" ;
+ $page_render .= "" ;
+ $page_render .= "
" ;
}
-
+
}
if($gpustat_cfg['DISPCLOCKS']) {
- $page_render .= "_(Clocks: Shader - Mem (GHz))_" ;
- $page_render .= " " ;
- $page_render .= " " ;
- $page_render .= "" ;
- $page_render .= " " ;
+ $page_render .= " |
_(Clocks: Shader - Mem (GHz))_" ;
+ $page_render .= " " ;
+ $page_render .= " " ;
+ $page_render .= "" ;
+ $page_render .= " " ;
$page_render .= " |
" ;
}
}
- return($page_render) ;
+ return($page_render) ;
}
-
?>
-
diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmulti.php b/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmulti.php
deleted file mode 100644
index b58ad0b..0000000
--- a/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmulti.php
+++ /dev/null
@@ -1,94 +0,0 @@
-getInventorym(), (new Intel($gpustat_cfg))->getInventory(), (new AMD($gpustat_cfg))->getInventorym());
- file_put_contents("/tmp/gpuinv",json_encode($gpustat_data)) ;
-} else {
-
-
-$array=json_decode($_GET['gpus'],true) ;
-
-
- $data = array() ;
- foreach ($array as $gpu) {
- $gpustat_cfg["VENDOR"] = $gpu['vendor'] ;
- $gpustat_cfg["GPUID"] = $gpu['guid'] ;
- $gpustat_cfg["PCIID"] = $gpu['id'] ;
-
- switch ($gpu['vendor']) {
- case 'amd':
- $return=(new AMD($gpustat_cfg))->getStatistics();
- $decode = json_decode($return,true);
- $decode["panel"] = $gpu['panel'] ;
- $data[$gpu["id"]] = $decode;
- break;
- case 'intel':
- $return=(new Intel($gpustat_cfg))->getStatistics();
- $decode = json_decode($return,true);
- $decode["panel"] = $gpu['panel'] ;
- $data[$gpu["id"]] = $decode;
- break;
- case 'nvidia':
- $return = (new Nvidia($gpustat_cfg))->getStatistics() ;
- $decode = json_decode($return,true);
- $decode["panel"] = $gpu['panel'] ;
- $data[$gpu["id"]] = $decode;
- break;
- default:
- print_r(Error::get(Error::CONFIG_SETTINGS_NOT_VALID));
- }
-}
-$json=json_encode($data) ;
-#Test data
-#$json='{"00:02.0":{"clock":100,"fan":50,"memclock":500,"memutil":55,"memused":55,"power":"100W","powermax":500,"rxutil":50,"txutil":60,"temp":50,"tempmax":200,"util":"40%","vendor":"Intel","name":"AlderLake-S GT1","3drender":"50%","blitter":"50%","interrupts":100,"powerutil":"10%","video":"20%","videnh":"30%","panel":1},"03:00.0":{"clock":0,"fan":"N\/A","memclock":"N\/A","memutil":"N\/A","memused":"N\/A","power":"N\/A","powermax":"N\/A","rxutil":"N\/A","txutil":"N\/A","temp":"N\/A","tempmax":"N\/A","util":"0%","vendor":"Intel","name":"DG2 [Arc A770]","3drender":"0%","blitter":"0%","interrupts":0,"powerutil":"0%","video":"0%","videnh":"0%","panel":2},"08:00.0":{"clock":"810","fan":"30%","memclock":"2808","memutil":"50%","memused":"50","power":"28W","powermax":"87","rxutil":50,"txutil":60,"temp":"41 \u00b0C","tempmax":"101 \u00b0C","util":"77%","vendor":"NVIDIA","name":"Quadro K4000","clockmax":"810","memclockmax":"2808","memtotal":"3018","encutil":"50%","decutil":"50%","pciemax":500,"perfstate":"P0","throttled":"No","thrtlrsn":"","pciegen":2,"pciegenmax":2,"pciewidth":1,"pciewidthmax":16,"sessions":0,"uuid":"GPU-ef6c0299-f1bc-7b5c-5291-7cd1a012f8bd","plexusing":true,"plexmem":0,"plexcount":0,"jellyfinusing":true,"jellyfinmem":100,"jellyfincount":2,"handbrakeusing":false,"handbrakemem":0,"handbrakecount":0,"embyusing":false,"embymem":0,"embycount":0,"tdarrusing":false,"tdarrmem":0,"tdarrcount":0,"unmanicusing":true,"unmanicmem":0,"unmaniccount":0,"dizquetvusing":false,"dizquetvmem":0,"dizquetvcount":0,"ersatztvusing":false,"ersatztvmem":0,"ersatztvcount":0,"fileflowsusing":false,"fileflowsmem":0,"fileflowscount":0,"frigateusing":false,"frigatemem":0,"frigatecount":0,"deepstackusing":false,"deepstackmem":0,"deepstackcount":0,"nsfminerusing":false,"nsfminermem":0,"nsfminercount":0,"shinobiprousing":false,"shinobipromem":0,"shinobiprocount":0,"foldinghomeusing":false,"foldinghomemem":0,"foldinghomecount":0,"appssupp":["plex","jellyfin","handbrake","emby","tdarr","unmanic","dizquetv","ersatztv","fileflows","frigate","deepstack","nsfminer","shinobipro","foldinghome"],"panel":3},"0c:00.0":{"clock":2110.5,"fan":200,"memclock":2220.1,"memutil":"21.2%","memused":47.51,"power":50,"powermax":200,"rxutil":"N\/A","txutil":67,"temp":"38 \u00b0C","tempmax":105,"util":"90%","vendor":"AMD","name":"Radeon RX 6400\/6500 XT\/6500M","event":"80%","vertex":"70%","texture":"60%","shaderexp":"50%","sequencer":"40%","shaderinter":"30%","scancon":"30%","primassem":"30%","depthblk":"30%","colorblk":"30%","gfxtrans":"44.1%","transused":11.57,"memclockutil":"9.6%","clockutil":"21.6%","tempunit":"C","fanmax":5550,"voltage":77.7,"voltageunit":"V","panel":4}}' ;
-header('Content-Type: application/json');
-header('Content-Length:' . ES . strlen($json));
-echo $json;
-file_put_contents("/tmp/gpujson","Time = ".date(DATE_RFC2822)."\n") ;
-file_put_contents("/tmp/gpujson",$json."\n",FILE_APPEND) ;
-}
diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/lib/Nvidia.php b/src/gpustat/usr/local/emhttp/plugins/gpustat/lib/Nvidia.php
index b78900b..3580fc5 100644
--- a/src/gpustat/usr/local/emhttp/plugins/gpustat/lib/Nvidia.php
+++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/lib/Nvidia.php
@@ -88,7 +88,7 @@ private function detectApplication (SimpleXMLElement $process)
foreach ($commands as $command) {
if (strpos($process->process_name, $command) !== false) {
// For Handbrake/ffmpeg: arguments tell us which application called it
- if (in_array($command, ['ffmpeg', 'HandbrakeCLI', 'python3.8','python3'])) {
+ if (in_array($command, ['ffmpeg', 'HandbrakeCLI', 'python3.8', 'python3'])) {
if (isset($process->pid)) {
$pid_info = $this->getFullCommand((int) $process->pid);
if (!empty($pid_info) && strlen($pid_info) > 0) {
@@ -113,9 +113,19 @@ private function detectApplication (SimpleXMLElement $process)
}
}
}
- $this->pageData[$app . 'using'] = true;
- $this->pageData[$app . 'mem'] += (int)$this->stripText(' MiB', $process->used_memory);
- $this->pageData[$app . 'count']++;
+
+ $usedMemory = (int) $this->stripText(' MiB', $process->used_memory);
+ $index = array_search($app, array_column($this->pageData['active_apps'], 'name'));
+ if ($index === false) {
+ $this->pageData['active_apps'][] = [
+ 'name' => $app,
+ 'mem' => $usedMemory,
+ 'count' => 1,
+ ];
+ } else {
+ $this->pageData['active_apps'][$index]['mem'] += $usedMemory;
+ $this->pageData['active_apps'][$index]['count']++;
+ }
// If we match a more specific command/app to a process, continue on to the next process
break 2;
}
@@ -197,11 +207,11 @@ public function getInventorym(): array
}
foreach($result as $gpu) {
$cmd =self::CMD_UTILITY . ES . sprintf(self::INVENTORY_PARM_PCI, $gpu['guid']) ;
- $cmdres = $this->stdout = shell_exec($cmd);
+ $cmdres = $this->stdout = shell_exec($cmd);
$pci = substr($cmdres,14,12);
$gpu['id'] = substr($pci,5) ;
$gpu['vendor'] = 'nvidia' ;
- $result2[$pci] = $gpu ;
+ $result2[$pci] = $gpu ;
}
if (empty($result)) $result2=$this->getPCIInventory() ;
}
@@ -263,7 +273,7 @@ private function getProductName (string $name)
if (strlen($name) > 20 && str_word_count($name) > 2) {
$words = explode(" ", $name);
if ($words[0] == "GeForce") {
- array_shift($words) ;
+ array_shift($words) ;
$words2 = implode(" ", $words) ;
if (strlen($words2) <= 20) $this->pageData['name'] = $words2;
} else $this->pageData['name'] = sprintf("%0s %1s", $words[0], $words[1]);
@@ -360,7 +370,7 @@ public function getStatistics()
if (!empty($this->stdout) && strlen($this->stdout) > 0) {
$this->parseStatistics();
} else {
-
+
$this->pageData['error'][] = Error::get(Error::VENDOR_DATA_NOT_RETURNED);
}
} else {
@@ -377,7 +387,7 @@ public function getStatistics()
$this->pageData["vfio"] = false ;
$this->pageData["vfiochk"] = $this->checkVFIO("0000:".$this->settings['PCIID']) ;
$this->pageData["vfiochkid"] = "0000:".$this->settings['PCIID'] ;
-
+
} else {
$this->pageData["vfio"] = true ;
$this->pageData["vendor"] = "Nvidia" ;
@@ -454,12 +464,7 @@ private function parseStatistics()
'uuid' => 'N/A',
];
- // Set App HW Usage Defaults
- foreach (self::SUPPORTED_APPS AS $app => $process) {
- $this->pageData[$app . "using"] = false;
- $this->pageData[$app . "mem"] = 0;
- $this->pageData[$app . "count"] = 0;
- }
+ $this->pageData['active_apps'] = [];
if (isset($data->product_name)) {
$this->getProductName($data->product_name);
}
@@ -484,7 +489,6 @@ private function parseStatistics()
}
// For some reason, encoder_sessions->session_count is not reliable on my install, better to count processes
if ($this->settings['DISPSESSIONS']) {
- $this->pageData['appssupp'] = array_keys(self::SUPPORTED_APPS);
if (isset($data->processes->process_info)) {
$this->pageData['sessions'] = count($data->processes->process_info);
if ($this->pageData['sessions'] > 0) {
diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/nchan/gpustat b/src/gpustat/usr/local/emhttp/plugins/gpustat/nchan/gpustat
new file mode 100755
index 0000000..d752cd6
--- /dev/null
+++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/nchan/gpustat
@@ -0,0 +1,113 @@
+#!/usr/bin/php -q
+
+');
+
+while (true) {
+ $gpustat_cfg = Main::getSettings();
+ $data = array();
+
+ if ($gpustat_multi_enable) {
+ $multi = urldecode($gpustat_cfg["MULTIGPUJSON"]);
+ $multigpus = json_decode($multi, true);
+ } else {
+ $multigpus = [
+ [
+ 'vendor' => $gpustat_cfg["VENDOR"],
+ 'guid' => $gpustat_cfg["GPUID"],
+ 'id' => null,
+ ],
+ ];
+ }
+
+ foreach ($multigpus as $gpu) {
+ if ($gpustat_multi_enable) {
+ $gpustat_cfg["VENDOR"] = $gpu['vendor'];
+ $gpustat_cfg["GPUID"] = $gpu['guid'];
+ $gpustat_cfg["PCIID"] = $gpu['id'];
+ }
+
+ switch ($gpu['vendor']) {
+ case 'amd':
+ $return = (new AMD($gpustat_cfg))->getStatistics();
+ break;
+ case 'intel':
+ $return = (new Intel($gpustat_cfg))->getStatistics();
+ break;
+ case 'nvidia':
+ $return = (new Nvidia($gpustat_cfg))->getStatistics();
+ break;
+ default:
+ print_r(Error::get(Error::CONFIG_SETTINGS_NOT_VALID));
+ }
+
+ if ($gpustat_multi_enable) {
+ $decode = json_decode($return, true);
+
+ if ($decode != NULL) {
+ $data[$gpu["id"]] = $decode;
+ }
+
+ // Test data
+ // $data = array_merge($data, json_decode('{"00:02.0": {"clock": 100, "fan": 50, "memclock": 500, "memutil": 55, "memused": 55, "power": "100W", "powermax": 500, "rxutil": 50, "txutil": 60, "temp": 50, "tempmax": 200, "util": "40%", "vendor": "Intel", "name": "AlderLake-S GT1", "3drender": "50%", "blitter": "50%", "interrupts": 100, "powerutil": "10%", "video": "20%", "videnh": "30%"}, "09:00.0": {"clock": 0, "fan": "N\/A", "memclock": "N\/A", "memutil": "N\/A", "memused": "N\/A", "power": "N\/A", "powermax": "N\/A", "rxutil": "N\/A", "txutil": "N\/A", "temp": "N\/A", "tempmax": "N\/A", "util": "0%", "vendor": "Intel", "name": "DG2 [Arc A770]", "3drender": "0%", "blitter": "0%", "interrupts": 0, "powerutil": "0%", "video": "0%", "videnh": "0%"}, "08:00.0": {"active_apps":[{"name": "plex", "mem": 214, "count": 2}], "clock": "810", "fan": "30%", "memclock": "2808", "memutil": "50%", "memused": "50", "power": "28W", "powermax": "87", "rxutil": 50, "txutil": 60, "temp": "41 \u00b0C", "tempmax": "101 \u00b0C", "util": "77%", "vendor": "NVIDIA", "name": "Quadro K4000", "clockmax": "810", "memclockmax": "2808", "memtotal": "3018", "encutil": "50%", "decutil": "50%", "pciemax": 500, "perfstate": "P0", "throttled": "No", "thrtlrsn": "", "pciegen": 2, "pciegenmax": 2, "pciewidth": 1, "pciewidthmax": 16, "sessions": 2, "uuid": "GPU-ef6c0299-f1bc-7b5c-5291-7cd1a012f8bd"}, "0c:00.0": {"clock": 2110.5, "fan": 200, "memclock": 2220.1, "memutil": "21.2%", "memused": 47.51, "power": 50, "powermax": 200, "rxutil": "N\/A", "txutil": 67, "temp": "38 \u00b0C", "tempmax": 105, "util": "90%", "vendor": "AMD", "name": "Radeon RX 6400\/6500 XT\/6500M", "event": "80%", "vertex": "70%", "texture": "60%", "shaderexp": "50%", "sequencer": "40%", "shaderinter": "30%", "scancon": "30%", "primassem": "30%", "depthblk": "30%", "colorblk": "30%", "gfxtrans": "44.1%", "transused": 11.57, "memclockutil": "9.6%", "clockutil": "21.6%", "tempunit": "C", "fanmax": 5550, "voltage": 77.7, "voltageunit": "V"}}', true));
+
+ $json = json_encode($data);
+ } else {
+ $json = $return;
+ }
+ }
+
+ publish('gpustat', $json);
+
+ file_put_contents("/tmp/gpujson", "Time = " . date(DATE_RFC2822) . PHP_EOL . $json . PHP_EOL);
+
+ // Stop nchan gpustat if refresh setting set to No and remove it from /var/run/nchan.pid
+ if ($gpustat_cfg['UIREFRESH'] != '1') {
+ exec('sed -i "/plugins\/gpustat\/nchan\/gpustat/d" /var/run/nchan.pid');
+ exit;
+ }
+
+ sleep(round($gpustat_cfg['UIREFRESHINT'] / 1000));
+}
diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustat.js b/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustat.js
index 828f12f..a2bce3a 100644
--- a/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustat.js
+++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustat.js
@@ -22,63 +22,93 @@
SOFTWARE.
*/
-const gpustat_status = () => {
- $.getJSON('/plugins/gpustat/gpustatus.php', (data) => {
- if (data) {
- switch (data["vendor"]) {
- case 'NVIDIA':
- // Nvidia Slider Bars
- $('.gpu-memclockbar').removeAttr('style').css('width', data["memclock"] / data["memclockmax"] * 100 + "%");
- $('.gpu-gpuclockbar').removeAttr('style').css('width', data["clock"] / data["clockmax"] * 100 + "%");
- $('.gpu-powerbar').removeAttr('style').css('width', parseInt(data["power"].replace("W","") / data["powermax"] * 100) + "%");
- $('.gpu-rxutilbar').removeAttr('style').css('width', parseInt(data["rxutil"] / data["pciemax"] * 100) + "%");
- $('.gpu-txutilbar').removeAttr('style').css('width', parseInt(data["txutil"] / data["pciemax"] * 100) + "%");
+const parseStats = (data) => {
+ if (data) {
+ switch (data["vendor"]) {
+ case 'NVIDIA':
+ // Nvidia Slider Bars
+ $('.gpu-memclockbar').removeAttr('style').css('width', data["memclock"] / data["memclockmax"] * 100 + "%");
+ $('.gpu-gpuclockbar').removeAttr('style').css('width', data["clock"] / data["clockmax"] * 100 + "%");
+ $('.gpu-powerbar').removeAttr('style').css('width', parseInt(data["power"].replace("W","") / data["powermax"] * 100) + "%");
+ $('.gpu-rxutilbar').removeAttr('style').css('width', parseInt(data["rxutil"] / data["pciemax"] * 100) + "%");
+ $('.gpu-txutilbar').removeAttr('style').css('width', parseInt(data["txutil"] / data["pciemax"] * 100) + "%");
- let nvidiabars = ['util', 'memutil', 'encutil', 'decutil', 'fan'];
- nvidiabars.forEach(function (metric) {
- $('.gpu-'+metric+'bar').removeAttr('style').css('width', data[metric]);
- });
+ let nvidiabars = ['util', 'memutil', 'encutil', 'decutil', 'fan'];
+ nvidiabars.forEach(function (metric) {
+ $('.gpu-'+metric+'bar').removeAttr('style').css('width', data[metric]);
+ });
- if (data["appssupp"]) {
- data["appssupp"].forEach(function (app) {
- if (data[app + "using"]) {
- $('.gpu-img-span-'+app).css('display', "inline");
- $('#gpu-'+app).attr('title', "Count: " + data[app+"count"] + " Memory: " + data[app+"mem"] + "MB");
- } else {
- $('.gpu-img-span-'+app).css('display', "none");
- $('#gpu-'+app).attr('title', "");
- }
- });
- }
- break;
- case 'Intel':
- // Intel Slider Bars
- let intelbars = ['3drender', 'blitter', 'video', 'videnh', 'powerutil'];
- intelbars.forEach(function (metric) {
- $('.gpu-'+metric+'bar').removeAttr('style').css('width', data[metric]);
+ if (data["appssupp"]) {
+ data["appssupp"].forEach(function (app) {
+ if (data[app + "using"]) {
+ $('.gpu-img-span-'+app).css('display', "inline");
+ $('#gpu-'+app).attr('title', "Count: " + data[app+"count"] + " Memory: " + data[app+"mem"] + "MB");
+ } else {
+ $('.gpu-img-span-'+app).css('display', "none");
+ $('#gpu-'+app).attr('title', "");
+ }
});
- break;
- case 'AMD':
- $('.gpu-powerbar').removeAttr('style').css('width', parseInt(data["power"] / data["powermax"] * 100) + "%");
- $('.gpu-fanbar').removeAttr('style').css('width', parseInt(data["fan"] / data["fanmax"] * 100) + "%");
- let amdbars = [
- 'util', 'event', 'vertex',
- 'texture', 'shaderexp', 'sequencer',
- 'shaderinter', 'scancon', 'primassem',
- 'depthblk', 'colorblk', 'memutil',
- 'gfxtrans', 'memclockutil', 'clockutil'
- ];
- amdbars.forEach(function (metric) {
- $('.gpu-'+metric+'bar').removeAttr('style').css('width', data[metric]);
- });
- break;
- }
+ }
+ break;
+ case 'Intel':
+ // Intel Slider Bars
+ let intelbars = ['3drender', 'blitter', 'video', 'videnh', 'powerutil'];
+ intelbars.forEach(function (metric) {
+ $('.gpu-'+metric+'bar').removeAttr('style').css('width', data[metric]);
+ });
+ break;
+ case 'AMD':
+ $('.gpu-powerbar').removeAttr('style').css('width', parseInt(data["power"] / data["powermax"] * 100) + "%");
+ $('.gpu-fanbar').removeAttr('style').css('width', parseInt(data["fan"] / data["fanmax"] * 100) + "%");
+ let amdbars = [
+ 'util', 'event', 'vertex',
+ 'texture', 'shaderexp', 'sequencer',
+ 'shaderinter', 'scancon', 'primassem',
+ 'depthblk', 'colorblk', 'memutil',
+ 'gfxtrans', 'memclockutil', 'clockutil'
+ ];
+ amdbars.forEach(function (metric) {
+ $('.gpu-'+metric+'bar').removeAttr('style').css('width', data[metric]);
+ });
+ break;
+ }
- $.each(data, function (key, data) {
- $('.gpu-'+key).html(data);
- })
+ if (data["active_apps"]) {
+ const appList = [];
+ const active_apps = [];
+ $('.gpu-active-apps .gpu-img-span').each(function () {
+ const name = $(this).data('name');
+ if (!appList.includes(name)) {
+ appList.push(name);
+ }
+ });
+ data["active_apps"].forEach(function (app) {
+ active_apps.push(app.name);
+ const title = 'Count: ' + app.count + ' - Memory: ' + app.mem + 'MB';
+ if (appList.includes(app.name)) {
+ $('.gpu-active-apps span[data-name="' + app.name + '"] img').attr('title', title);
+ } else {
+ const img = $('');
+ const span = $('');
+ span.append(img);
+ $('.gpu-active-apps').append(span);
+ }
+ });
+ $('.gpu-active-apps .gpu-img-span').each(function () {
+ if (!active_apps.includes($(this).data('name'))) {
+ $(this).remove();
+ }
+ });
}
- });
+
+ $.each(data, function (key, data) {
+ $('.gpu-'+key).html(data);
+ })
+ }
+};
+
+const gpustat_status = () => {
+ $.getJSON('/plugins/gpustat/gpustatus.php', (data) => parseStats(data));
};
const gpustat_dash = () => {
diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustatmulti.js b/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustatmulti.js
index e321b54..c7ef023 100644
--- a/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustatmulti.js
+++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustatmulti.js
@@ -23,60 +23,74 @@
*/
-function toggleVFIO(vfio,panel) {
+function toggleVFIO(vfio, panel) {
if (vfio) {
- $('.vfio_inuse'+panel).show();
- $('.vfio_notinuse'+panel).hide();
- $('.vfio_status'+panel).text(_("GPU not available bound to VFIO or inuse in a VM."));
+ $('.vfio_inuse', panel).show();
+ $('.vfio_notinuse', panel).hide();
+ $('.vfio_status', panel).text(_("GPU not available bound to VFIO or inuse in a VM."));
} else {
- $('.vfio_inuse'+panel).hide();
- $('.vfio_notinuse'+panel).show();
+ $('.vfio_inuse', panel).hide();
+ $('.vfio_notinuse', panel).show();
}
- }
+}
-const gpustat_statusm = (input) => {
- $.getJSON('/plugins/gpustat/gpustatusmulti.php?gpus='+JSON.stringify(input), (data2) => {
- if (data2) {
+const parseStats = (data2) => {
+ if (data2) {
$.each(data2, function (key2, data) {
- panel = data["panel"] ;
+ panel = 'tbody[data-gpu-id="' + key2 + '"]';
if (!data['vfio']) {
- toggleVFIO(false,panel) ;
+ toggleVFIO(false, panel);
switch (data["vendor"]) {
case 'NVIDIA':
// Nvidia Slider Bars
- $('.gpu-memclockbar'+panel).removeAttr('style').css('width', data["memclock"] / data["memclockmax"] * 100 + "%");
- $('.gpu-gpuclockbar'+panel ).removeAttr('style').css('width', data["clock"] / data["clockmax"] * 100 + "%");
- $('.gpu-powerbar'+panel ).removeAttr('style').css('width', parseInt(data["power"].replace("W","") / data["powermax"] * 100) + "%");
- $('.gpu-rxutilbar'+panel).removeAttr('style').css('width', parseInt(data["rxutil"] / data["pciemax"] * 100) + "%");
- $('.gpu-txutilbar'+panel).removeAttr('style').css('width', parseInt(data["txutil"] / data["pciemax"] * 100) + "%");
+ $('.gpu-memclockbar', panel).removeAttr('style').css('width', data["memclock"] / data["memclockmax"] * 100 + "%");
+ $('.gpu-gpuclockbar', panel).removeAttr('style').css('width', data["clock"] / data["clockmax"] * 100 + "%");
+ $('.gpu-powerbar', panel).removeAttr('style').css('width', parseInt(data["power"].replace("W", "") / data["powermax"] * 100) + "%");
+ $('.gpu-rxutilbar', panel).removeAttr('style').css('width', parseInt(data["rxutil"] / data["pciemax"] * 100) + "%");
+ $('.gpu-txutilbar', panel).removeAttr('style').css('width', parseInt(data["txutil"] / data["pciemax"] * 100) + "%");
let nvidiabars = ['util', 'memutil', 'encutil', 'decutil', 'fan'];
nvidiabars.forEach(function (metric) {
- $('.gpu-'+metric+'bar'+panel).removeAttr('style').css('width', data[metric]);
+ $('.gpu-' + metric + 'bar', panel).removeAttr('style').css('width', data[metric]);
});
- if (data["appssupp"]) {
- data["appssupp"].forEach(function (app) {
- if (data[app + "using"]) {
- $('.gpu-img-span-'+app+panel).css('display', "inline");
- $('#gpu-'+app+panel).attr('title', "Count: " + data[app+"count"] + " Memory: " + data[app+"mem"] + "MB");
+ if (data["active_apps"]) {
+ const appList = [];
+ const active_apps = [];
+ $('.gpu-active-apps .gpu-img-span', panel).each(function () {
+ const name = $(this).data('name');
+ if (!appList.includes(name)) {
+ appList.push(name);
+ }
+ });
+ data["active_apps"].forEach(function (app) {
+ active_apps.push(app.name);
+ const title = 'Count: ' + app.count + ' - Memory: ' + app.mem + 'MB';
+ if (appList.includes(app.name)) {
+ $('.gpu-active-apps span[data-name="' + app.name + '"] img', panel).attr('title', title);
} else {
- $('.gpu-img-span-'+app+panel).css('display', "none");
- $('#gpu-'+app+panel).attr('title', "");
+ const img = $('');
+ const span = $('');
+ span.append(img);
+ $('.gpu-active-apps td', panel).append(span);
}
});
+ $('.gpu-active-apps .gpu-img-span', panel).each(function () {
+ if (!active_apps.includes($(this).data('name')))
+ $(this).remove();
+ });
}
break;
case 'Intel':
// Intel Slider Bars
let intelbars = ['3drender', 'blitter', 'video', 'videnh', 'powerutil'];
intelbars.forEach(function (metric) {
- $('.gpu-'+metric+'bar'+panel).removeAttr('style').css('width', data[metric]);
+ $('.gpu-' + metric + 'bar', panel).removeAttr('style').css('width', data[metric]);
});
break;
case 'AMD':
- $('.gpu-powerbar'+panel).removeAttr('style').css('width', parseInt(data["power"] / data["powermax"] * 100) + "%");
- $('.gpu-fanbar'+panel).removeAttr('style').css('width', parseInt(data["fan"] / data["fanmax"] * 100) + "%");
+ $('.gpu-powerbar', panel).removeAttr('style').css('width', parseInt(data["power"] / data["powermax"] * 100) + "%");
+ $('.gpu-fanbar', panel).removeAttr('style').css('width', parseInt(data["fan"] / data["fanmax"] * 100) + "%");
let amdbars = [
'util', 'event', 'vertex',
'texture', 'shaderexp', 'sequencer',
@@ -85,39 +99,36 @@ const gpustat_statusm = (input) => {
'gfxtrans', 'memclockutil', 'clockutil'
];
amdbars.forEach(function (metric) {
- $('.gpu-'+metric+'bar'+panel).removeAttr('style').css('width', data[metric]);
+ $('.gpu-' + metric + 'bar', panel).removeAttr('style').css('width', data[metric]);
});
break;
}
$.each(data, function (key, data) {
if (key == "error") {
- toggleVFIO(true,panel) ;
- var error_text = data[0]["message"] ;
- $('.vfio_status'+panel).text(_(error_text));
+ toggleVFIO(true, panel);
+ var error_text = data[0]["message"];
+ $('.vfio_status', panel).text(_(error_text));
}
- $('.gpu-'+key+panel).html(data);
- })
+ $('.gpu-' + key, panel).html(data);
+ })
} else {
- toggleVFIO(true,panel) ;
- $('.gpu-name'+panel).html(data["name"]);
- $('.gpu-vendor'+panel).html(data["vendor"]);
+ toggleVFIO(true, panel);
+ $('.gpu-name', panel).html(data["name"]);
+ $('.gpu-vendor', panel).html(data["vendor"]);
}
var hidden = $.cookie('hidden_content');
if (hidden) {
hidden = hidden.split(';');
- if (hidden.includes($("#tblGPUDash" + panel).attr('title').md5()))
- $("#tblGPUDash" + panel ).mixedView(0);
+ if (hidden.includes($("#tblGPUDash", panel).attr('title').md5()))
+ $("#tblGPUDash", panel).mixedView(0);
}
-
- })
- }
-
- });
-};
+ })
+ }
+}
/*