Report disk capacity in decimal GB so it matches Unraid and the drive label

The API mixes units per field — memory in bytes, disk size in KiB, fsSize and
fsUsed in kB — and one helper was guessing which from the magnitude of the
number, which also read any memory total under 100 GB as KB.
This commit is contained in:
Gmer4Lfe
2026-08-13 18:07:09 -04:00
parent 57e2b0d670
commit b358dfcf58
3 changed files with 48 additions and 23 deletions
+39 -19
View File
@@ -134,13 +134,26 @@ GQL;
// ── Disk data helpers ─────────────────────────────────────────────────────────
// API size fields (BigInt) are in bytes on this schema.
// Heuristic: if raw > 100 billion → bytes; else → KB (covers both possible encodings).
function _vv_api_bytes_to_gb(float $raw): float {
return $raw > 100_000_000_000
? round($raw / (1024 ** 3), 1)
: round($raw / (1024 ** 2), 1);
}
// The API mixes three units and never says so. Measured against df and /var/local/emhttp/disks.ini
// on 7.3.2, per field:
// metrics.memory.* real bytes
// disk size KiB — 1024-byte units, the raw device
// disk fsSize/fsUsed kB — 1000-byte units, the filesystem
// disks.ini fsSize * 1024 and API fsSize * 1000 agree to the digit, which is what pins it down.
//
// This replaced one helper that guessed the unit from magnitude — "> 100 billion means bytes,
// else KB". It was wrong three ways at once. Every filesystem size read 2.4% high because kB got
// a KiB divisor; any memory total under 100 GB fell down the KB branch, so HOST2's 64 GB would
// have reported as 65536 GB; and a disk is only ever one of these units regardless of its size,
// so magnitude was never evidence of anything. Convert by which field it came from, not how big
// the number is.
function _vv_api_bytes_to_gib(float $bytes): float { return round($bytes / (1024 ** 3), 1); }
// Capacity is reported the way drives are sold and the way Unraid's own Main page reports it —
// decimal GB. A 12 TB disk reads 12000 GB here, not 10914 GiB wearing a "GB" label. Memory stays
// binary above, because 128 GB of RAM genuinely is 125.8 GiB and every tool on the box says so.
function _vv_api_fs_gb(float $kb): float { return round($kb * 1000 / 1e9, 1); } // fsSize/fsUsed
function _vv_api_dev_gb(float $kib): float { return round($kib * 1024 / 1e9, 1); } // size, disks.ini
// Map ArrayDiskType enum → role string used by the rest of the plugin.
// Unraid 6.9 used CACHE; 6.10+ renamed pools to POOL. FLASH is the USB boot drive (skip).
@@ -164,19 +177,26 @@ function vv_api_disk_entry(array $d, string $role = '', int $ini_used_kb = 0): ?
// Parity disks have no filesystem — use raw size only.
$sizeRaw = (float)($d['size'] ?? 0);
if ($sizeRaw <= 0) return null;
$sizeGb = _vv_api_bytes_to_gb($sizeRaw);
$sizeGb = _vv_api_dev_gb($sizeRaw);
$usedGb = 0.0;
$pct = null;
} else {
// Data/cache disks: prefer fsSize/fsUsed; fall back to size if unmounted.
$sizeRaw = (float)($d['fsSize'] ?? $d['size'] ?? 0);
if ($sizeRaw <= 0) return null;
// Data/cache disks: prefer fsSize/fsUsed; fall back to size if unmounted. The fallback
// changes the unit as well as the source — fsSize is kB, size is KiB — so the two cannot
// collapse into one variable and share a conversion the way they used to.
$fsRaw = (float)($d['fsSize'] ?? 0);
if ($fsRaw > 0.0) {
$sizeGb = _vv_api_fs_gb($fsRaw);
} else {
$devRaw = (float)($d['size'] ?? 0);
if ($devRaw <= 0) return null;
$sizeGb = _vv_api_dev_gb($devRaw);
}
$usedRaw = (float)($d['fsUsed'] ?? 0);
$sizeGb = _vv_api_bytes_to_gb($sizeRaw);
if ($usedRaw > 0.0) {
$usedGb = _vv_api_bytes_to_gb($usedRaw);
$usedGb = _vv_api_fs_gb($usedRaw);
} elseif (!($d['isSpinning'] ?? true) && $ini_used_kb > 0) {
$usedGb = round($ini_used_kb / 1048576, 1);
$usedGb = _vv_api_dev_gb((float)$ini_used_kb); // disks.ini is KiB, not kB
} else {
$usedGb = 0.0;
}
@@ -211,8 +231,8 @@ function vv_api_node_metrics(?array $d): array {
if (!$d) return [];
$cpu = (int)round((float)($d['metrics']['cpu']['percentTotal'] ?? 0));
$mem = $d['metrics']['memory'] ?? [];
$ramUsed = isset($mem['used']) ? _vv_api_bytes_to_gb((float)$mem['used']) : null;
$ramTot = isset($mem['total']) ? _vv_api_bytes_to_gb((float)$mem['total']) : null;
$ramUsed = isset($mem['used']) ? _vv_api_bytes_to_gib((float)$mem['used']) : null;
$ramTot = isset($mem['total']) ? _vv_api_bytes_to_gib((float)$mem['total']) : null;
$disks = $d['array']['disks'] ?? [];
$caches = $d['array']['caches'] ?? [];
@@ -221,8 +241,8 @@ function vv_api_node_metrics(?array $d): array {
foreach (array_merge($disks, $caches) as $dk) {
$sz = (float)($dk['fsSize'] ?? 0);
if ($sz <= 0) continue;
$totGb += _vv_api_bytes_to_gb($sz);
$usedGb += _vv_api_bytes_to_gb((float)($dk['fsUsed'] ?? 0));
$totGb += _vv_api_fs_gb($sz);
$usedGb += _vv_api_fs_gb((float)($dk['fsUsed'] ?? 0));
}
$temps = array_filter(
array_merge(array_column($disks,'temp'), array_column($caches,'temp'), array_column($pars,'temp')),
@@ -264,7 +284,7 @@ function vv_local_host_stats(): array {
$tot = (float)($mem['total'] ?? 0); $avail = (float)($mem['available'] ?? 0);
$memPct = $tot > 0 ? (int)round(($tot - $avail) / $tot * 100) : 0;
}
$memTotalGb = isset($mem['total']) ? _vv_api_bytes_to_gb((float)$mem['total']) : 0;
$memTotalGb = isset($mem['total']) ? _vv_api_bytes_to_gib((float)$mem['total']) : 0;
$uptimeRaw = $os['uptime'] ?? '';
if (is_numeric($uptimeRaw)) {