From cc8aacc56315d590841e39a4b419e32975182294 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 4 Oct 2021 14:52:55 +0200 Subject: [statistics] stuf --- inc/arrayutil.inc.php | 8 +- .../statistics/inc/hardwareparser.inc.php | 10 +- .../statistics/inc/hardwareparserlegacy.inc.php | 186 +++++++++------------ modules-available/statistics/pages/machine.inc.php | 183 ++++++++++++++++++-- .../statistics/templates/machine-hdds.html | 46 ++--- .../statistics/templates/machine-main.html | 13 +- 6 files changed, 290 insertions(+), 156 deletions(-) diff --git a/inc/arrayutil.inc.php b/inc/arrayutil.inc.php index 490b5a4f..c1306ac7 100644 --- a/inc/arrayutil.inc.php +++ b/inc/arrayutil.inc.php @@ -12,13 +12,7 @@ class ArrayUtil */ public static function flattenByKey(array $list, string $key) { - $ret = []; - foreach ($list as $item) { - if (array_key_exists($key, $item)) { - $ret[] = $item[$key]; - } - } - return $ret; + return array_column($list, $key); } /** diff --git a/modules-available/statistics/inc/hardwareparser.inc.php b/modules-available/statistics/inc/hardwareparser.inc.php index f2ebe335..0217835e 100644 --- a/modules-available/statistics/inc/hardwareparser.inc.php +++ b/modules-available/statistics/inc/hardwareparser.inc.php @@ -96,7 +96,7 @@ class HardwareParser } // Count, size (unitless) if (is_numeric($val) && preg_match('/^-?[0-9]+$/', $val) - && preg_match('/used|occupied|count|number|size|temperature/', $key)) { + && preg_match('/used|occupied|count|number|size|temperature|_start|_value|_thresh|_worst|_time/', $key)) { return (int)$val; } // Date @@ -413,8 +413,8 @@ class HardwareParser 'size' => $size, 'physical_block_size' => $smart['physical_block_size'] ?? $lsblk['phy-sec'] ?? 0, 'logical_block_size' => $smart['logical_block_size'] ?? $lsblk['log-sec'] ?? 0, - ] + self::propsFromArray($smart, - 'rotation_rate', 'sata_version//string', 'interface_speed//max//string')); + ] + self::propsFromArray($smart, 'rotation_rate', 'sata_version//string', + 'interface_speed//max//string', 'model_family')); // Mangle smart attribute table // TODO: Handle used endurance indicator for (SATA) SSDs $table = []; @@ -497,10 +497,12 @@ class HardwareParser } } $table['unused'] = $size - $used; + $table['dev'] = $dev['readlink']; $table += self::propsFromArray($smart + ($lsblk ?? []), 'serial_number', 'firmware_version', 'interface_speed//current//string', - 'smart_status//passed', 'temperature//current', 'temperature//min', 'temperature//max'); + 'smart_status//passed', 'temperature//current', 'temperature//min', 'temperature//max', + 'power_on_time//hours'); $mappingId = self::writeLocalHardwareData($uuid, $hwid, $dev['readlink'], $table); // Delete old partition and smart attribute entries diff --git a/modules-available/statistics/inc/hardwareparserlegacy.inc.php b/modules-available/statistics/inc/hardwareparserlegacy.inc.php index 1bee23f9..4d8a8502 100644 --- a/modules-available/statistics/inc/hardwareparserlegacy.inc.php +++ b/modules-available/statistics/inc/hardwareparserlegacy.inc.php @@ -5,66 +5,71 @@ class HardwareParserLegacy public static function parseHdd(&$row, $data) { - $hdds = array(); + $hdds = []; // Could have more than one disk - linear scan $lines = preg_split("/[\r\n]+/", $data); $i = 0; - $mbrToMbFactor = $sectorToMbFactor = 0; + $mbrToByteFactor = $sectorToByteFactor = 0; foreach ($lines as $line) { if (preg_match('/^Disk (\S+):.* (\d+) bytes/i', $line, $out)) { // --- Beginning of MBR disk --- unset($hdd); if ($out[2] < 10000) // sometimes vmware reports lots of 512byte disks continue; - if (substr($out[1], 0, 8) === '/dev/dm-') // Ignore device mapper + if (preg_match('#^/dev/(dm-|x?loop|d?nbd)#', $out[1])) // Ignore device mapper etc. continue; // disk total size and name - $mbrToMbFactor = 0; // This is != 0 for mbr - $sectorToMbFactor = 0; // This is != for gpt - $hdd = array( + $mbrToByteFactor = 0; // This is != 0 for mbr + $sectorToByteFactor = 0; // This is != for gpt + $hdd = [ 'devid' => 'devid-' . ++$i, 'dev' => $out[1], 'sectors' => 0, - 'size' => round($out[2] / (1024 * 1024 * 1024)), + 'size' => $out[2], 'used' => 0, - 'partitions' => array(), - 'json' => array(), - ); + 'partitions' => [], + ]; $hdds[] = &$hdd; } elseif (preg_match('/^Disk (\S+):\s+(\d+)\s+sectors,/i', $line, $out)) { // --- Beginning of GPT disk --- unset($hdd); if ($out[2] < 1000) // sometimes vmware reports lots of 512byte disks continue; - if (substr($out[1], 0, 8) === '/dev/dm-') // Ignore device mapper + if (preg_match('#^/dev/(dm-|x?loop|d?nbd)#', $out[1])) // Ignore device mapper etc. continue; // disk total size and name - $mbrToMbFactor = 0; // This is != 0 for mbr - $sectorToMbFactor = 0; // This is != for gpt - $hdd = array( + $mbrToByteFactor = 0; // This is != 0 for mbr + $sectorToByteFactor = 0; // This is != for gpt + $hdd = [ 'devid' => 'devid-' . ++$i, 'dev' => $out[1], 'sectors' => $out[2], 'size' => 0, 'used' => 0, - 'partitions' => array(), - 'json' => array(), - ); + 'partitions' => [], + ]; $hdds[] = &$hdd; } elseif (preg_match('/^Units =.*= (\d+) bytes/i', $line, $out)) { // --- MBR: Line that tells us how to interpret units for the partition lines --- // Unit for start and end - $mbrToMbFactor = $out[1] / (1024 * 1024); // Convert so that multiplying by unit yields MiB + $mbrToByteFactor = $out[1]; // Convert so that multiplying by unit yields MiB } elseif (preg_match('/^Logical sector size:\s*(\d+)/i', $line, $out)) { // --- GPT: Line that tells us the logical sector size used everywhere --- - $sectorToMbFactor = $out[1] / (1024 * 1024); + $sectorToByteFactor = $out[1]; } elseif (isset($hdd) && preg_match('/^First usable sector.* is (\d+)$/i', $line, $out)) { // --- Some fdisk versions are messed up and report 2^32 as the sector count in the first line, // but the correct value in the "last usable sector is xxxx" line below --- if ($out[1] > $hdd['sectors']) { $hdd['sectors'] = $out[1]; } - } elseif (isset($hdd) && $mbrToMbFactor !== 0 && preg_match(',^/dev/(\S+)\s+.*\s(\d+)[+\-]?\s+(\d+)[+\-]?\s+\d+[+\-]?\s+([0-9a-f]+)\s+(.*)$,i', $line, $out)) { + } elseif (isset($hdd) && $mbrToByteFactor !== 0 && preg_match(', + ^/dev/(\S+) # device + \s+.*\s(\d+)[+\-]? # start + \s+(\d+)[+\-]? # end + \s+\d+[+\-]? # size + \s+([0-9a-f]+) # typeid + \s+(.*)$ # type name + ,ix', $line, $out)) { // --- MBR: Partition entry --- // Some partition $type = strtolower($out[4]); @@ -72,81 +77,58 @@ class HardwareParserLegacy continue; } elseif ($type === '44') { $out[5] = 'OpenSLX-ID44'; - $color = '#5c1'; } elseif ($type === '45') { $out[5] = 'OpenSLX-ID45'; - $color = '#0d7'; - } elseif ($type === '82') { - $color = '#48f'; - } else { - $color = '#e55'; } - $partsize = round(($out[3] - $out[2]) * $mbrToMbFactor); - $hdd['partitions'][] = array( + $start = $out[2] * $mbrToByteFactor; + $partsize = ($out[3] - $out[2]) * $mbrToByteFactor; + $hdd['partitions'][] = [ 'id' => $out[1], - 'name' => $out[1], - 'size' => round($partsize / 1024, $partsize < 1024 ? 1 : 0), - 'type' => $out[5], - ); - $hdd['json'][] = array( - 'label' => $out[1], - 'value' => $partsize, - 'color' => $color, - ); + 'index' => $out[1], + 'start' => $start, + 'size' => $partsize, + 'name' => $out[5], + 'slxtype' => $type, + ]; $hdd['used'] += $partsize; - } elseif (isset($hdd) && $sectorToMbFactor !== 0 && preg_match(',^\s*(\d+)\s+(\d+)[+\-]?\s+(\d+)[+\-]?\s+\S+\s+([0-9a-f]+)\s+(.*)$,i', $line, $out)) { + } elseif (isset($hdd) && $sectorToByteFactor !== 0 && preg_match(', + ^\s*(\d+) # index + \s+(\d+)[+\-]? # start + \s+(\d+)[+\-]? # end + \s+\S+ # human readable size + \s+([0-9a-f]{2})[0-9a-f]* # pseudo-type-id + \s+(.*)$ # PartLabel + ,ix', $line, $out)) { // --- GPT: Partition entry --- // Some partition - $type = $out[5]; - if ($type === 'OpenSLX-ID44') { - $color = '#5c1'; - } elseif ($type === 'OpenSLX-ID45') { - $color = '#0d7'; - } elseif ($type === 'Linux swap') { - $color = '#48f'; - } else { - $color = '#e55'; + $slxtype = $out[4]; + if ($out[5] === 'OpenSLX-ID44') { + $slxtype = '44'; + } elseif ($out[5] === 'OpenSLX-ID45') { + $slxtype = '45'; + } elseif ($out[5] === 'Linux swap') { + $slxtype = '82'; } $id = $hdd['devid'] . '-' . $out[1]; - $partsize = round(($out[3] - $out[2]) * $sectorToMbFactor); - $hdd['partitions'][] = array( + $start = $out[2] * $sectorToByteFactor; + $partsize = ($out[3] - $out[2]) * $sectorToByteFactor; + $hdd['partitions'][] = [ 'id' => $id, - 'name' => $out[1], - 'size' => round($partsize / 1024, $partsize < 1024 ? 1 : 0), - 'type' => $type, - ); - $hdd['json'][] = array( - 'label' => $id, - 'value' => $partsize, - 'color' => $color, - ); + 'index' => $out[1], + 'start' => $start, + 'size' => $partsize, + 'name' => $out[5], + 'slxtype' => $slxtype, + ]; $hdd['used'] += $partsize; } } unset($hdd); - $i = 0; foreach ($hdds as &$hdd) { - $hdd['used'] = round($hdd['used'] / 1024); if ($hdd['size'] === 0 && $hdd['sectors'] !== 0) { - $hdd['size'] = round(($hdd['sectors'] * $sectorToMbFactor) / 1024); + $hdd['size'] = round($hdd['sectors'] * $sectorToByteFactor); } - $free = $hdd['size'] - $hdd['used']; - if ($hdd['size'] > 0 && ($free > 5 || ($free / $hdd['size']) > 0.1)) { - $hdd['partitions'][] = array( - 'id' => 'free-id-' . $i, - 'name' => Dictionary::translate('unused'), - 'size' => $free, - 'type' => '-', - ); - $hdd['json'][] = array( - 'label' => 'free-id-' . $i, - 'value' => $free * 1024, - 'color' => '#aaa', - ); - ++$i; - } - $hdd['json'] = json_encode($hdd['json']); } unset($hdd); $row['hdds'] = &$hdds; @@ -213,32 +195,28 @@ class HardwareParserLegacy } if (preg_match('/^([A-Z][^:]+):\s*(.*)$/', $line, $out)) { $key = preg_replace('/\s|-|_/', '', $out[1]); - if ($key === 'ModelNumber') { - $key = 'DeviceModel'; - } - $dev['s_' . $key] = $out[2]; - } elseif (preg_match('/^\s*\d+\s+(\S+)\s+\S+\s+\d+\s+\d+\s+\S+\s+\S+\s+(\d+)(\s|$)/', $line, $out)) { - $dev['s_' . preg_replace('/\s|-|_/', '', $out[1])] = $out[2]; - } - } - // Format strings - foreach ($hdds as &$hdd) { - if (isset($hdd['s_PowerOnHours'])) { - $hdd['PowerOnTime'] = ''; - $val = (int)str_replace('.', '', $hdd['s_PowerOnHours']); - if ($val > 8760) { - $hdd['PowerOnTime'] .= floor($val / 8760) . 'Y, '; - $val %= 8760; + if ($key === 'ModelNumber' || $key === 'DeviceModel') { + $dev['model'] = $out[2]; + } elseif ($key === 'ModelFamily') { + $dev['model_family'] = $out[2]; + } elseif ($key === 'SerialNumber') { + $dev['serial_number'] = $out[2]; } - if ($val > 720) { - $hdd['PowerOnTime'] .= floor($val / 720) . 'M, '; - $val %= 720; + } elseif (preg_match('/ + ^\s*(?\d+)\s+\S+ # flags + \s+\S+\s+(?\d+) + \s+(?\d+) + \s+(?\S+)\s+\S+ # fail + \s+(?\d+)(\s|$)/x', $line, $out)) { + $dev['attr_' . $out['id']] = [ + 'value' => $out['v'], + 'worst' => $out['w'], + 'thresh' => $out['t'], + 'raw' => $out['raw'], + ]; + if ($out['id'] == 194) { + $dev['temperature'] = $out['raw']; } - if ($val > 24) { - $hdd['PowerOnTime'] .= floor($val / 24) . 'd, '; - $val %= 24; - } - $hdd['PowerOnTime'] .= $val . 'h'; } } } @@ -309,14 +287,12 @@ class HardwareParserLegacy } } elseif ($section === 'Memory Device') { if (preg_match('/^\s*Size:\s*(.*?)\s*$/i', $line, $out)) { - $row['extram'] = true; if (preg_match('/(\d+)\s*(\w)i?B/i', $out[1])) { if (HardwareParser::convertSize($out[1], 'M', false) < 35) continue; // TODO: Parsing this line by line is painful. Check for other indicators, like Locator $ramslot['Size'] = HardwareParser::convertSize($out[1], 'G'); } - } - if (preg_match('/^\s*Manufacturer:\s*(.*?)\s*$/i', $line, $out) && $out[1] !== 'Unknown') { + } elseif (preg_match('/^\s*Manufacturer:\s*(.*?)\s*$/i', $line, $out) && $out[1] !== 'Unknown') { $ramslot['Manufacturer'] = HardwareParser::decodeJedec($out[1]); } elseif (preg_match('/^\s*Form Factor:\s*(.*?)\s*$/i', $line, $out) && $out[1] !== 'Unknown') { $ramForm = $out[1]; @@ -325,7 +301,7 @@ class HardwareParserLegacy } elseif (preg_match('/^\s*Configured Memory Speed:\s*(.*?)\s*$/i', $line, $out) && $out[1] !== 'Unknown') { $ramslot['Configured Clock Speed'] = $out[1]; } elseif (preg_match('/^\s*([^:]+):\s*(.*?)\s*$/i', $line, $out) - && $out[2] !== 'Unknown' && $out[2] !== '' && $out[2] !== 'Not Specified') { + && $out[2] !== 'Unknown' && $out[2] !== '' && $out[2] !== 'Not Specified' && $out[2] !== 'None') { $ramslot[$out[1]] = $out[2]; } } elseif ($section === 'BIOS Information') { diff --git a/modules-available/statistics/pages/machine.inc.php b/modules-available/statistics/pages/machine.inc.php index e1133338..fdb04023 100644 --- a/modules-available/statistics/pages/machine.inc.php +++ b/modules-available/statistics/pages/machine.inc.php @@ -54,13 +54,31 @@ class SubPage $client = Database::queryFirst('SELECT machineuuid, locationid, macaddr, clientip, firstseen, lastseen, logintime, lastboot, state, mbram, live_tmpsize, live_tmpfree, live_id45size, live_id45free, live_swapsize, live_swapfree, live_memsize, live_memfree, live_cpuload, live_cputemp, - Length(position) AS hasroomplan, kvmstate, cpumodel, id44mb, data, hostname, currentuser, currentsession, notes + Length(position) AS hasroomplan, kvmstate, cpumodel, id44mb, id45mb, data, hostname, currentuser, currentsession, notes FROM machine WHERE machineuuid = :uuid', array('uuid' => $uuid)); if ($client === false) { Message::addError('unknown-machine', $uuid); return; } + // Parse data + $hdds = array(); + if ($client['data'][0] === '{') { + $json = json_decode($client['data'], true); + if (is_array($json)) { + $client += self::parseJson($uuid, $json); + $hdds['hdds'] = self::parseJsonHdd($uuid); + } + } else { + self::parseLegacy($client, $hdds); + } + unset($client['data']); + // Get rid of configured speed, if equal to maximum speed + foreach ($client['ram'] as &$ram) { + if (isset($ram['Configured Memory Speed']) && $ram['Configured Memory Speed'] === $ram['Speed']) { + unset($ram['Configured Memory Speed']); + } + } if (Module::isAvailable('locations') && !Location::isLeaf($client['locationid'])) { $client['hasroomplan'] = false; } @@ -121,6 +139,7 @@ class SubPage } $client['gbram'] = round(ceil($client['mbram'] / 512) / 2, 1); $client['gbtmp'] = round($client['id44mb'] / 1024); + $client['gbid45'] = round($client['id45mb'] / 1024); foreach (['tmp', 'id45', 'swap', 'mem'] as $item) { if ($client['live_' . $item . 'size'] == 0) continue; @@ -135,28 +154,25 @@ class SubPage $client['ramclass'] = StatisticsStyling::ramColorClass($client['mbram']); $client['kvmclass'] = StatisticsStyling::kvmColorClass($client['kvmstate']); $client['hddclass'] = StatisticsStyling::hddColorClass($client['gbtmp']); - // - $hdds = array(); - if ($client['data'][0] === '{') { - $json = json_decode($client['data'], true); - if (is_array($json)) { - $client += self::parseJson($uuid, $json); - } - } else { - self::parseLegacy($client, $hdds); + // Format HDD data to strings + foreach ($hdds['hdds'] as &$hdd) { + $hdd['smart_status_failed'] = !($client['smart_status//passed'] ?? 1); + self::mangleHdd($hdd); } - unset($client['data']); // BIOS update check - if (!empty($client['biosrevision'])) { - $mainboard = $client['mobomanufacturer'] . '##' . $client['mobomodel']; - $system = $client['pcmanufacturer'] . '##' . $client['pcmodel']; - $ret = self::checkBios($mainboard, $system, $client['biosdate'], $client['biosrevision']); + if (!empty($client['bios']['BIOS Revision']) || !empty($client['bios']['Release Date'])) { + if (preg_match('#^(\d{1,2})/(\d{1,2})/(\d{4})#', $client['bios']['Release Date'], $out)) { + $client['bios']['Release Date'] = $out[2] . '.' . $out[1] . '.' . $out[3]; + } + $mainboard = $client['mainboard']['Manufacturer'] . '##' . $client['mainboard']['Product Name']; + $system = $client['system']['Manufacturer'] . '##' . $client['system']['Product Name']; + $ret = self::checkBios($mainboard, $system, $client['bios']['Release Date'], $client['bios']['BIOS Revision']); if ($ret === false) { // Not loaded, use AJAX $params = [ 'mainboard' => $mainboard, 'system' => $system, - 'date' => $client['biosdate'], - 'revision' => $client['biosrevision'], + 'date' => $client['bios']['Release Date'], + 'revision' => $client['bios']['BIOS Revision'], ]; $client['biosurl'] = '?do=statistics&action=bios&' . http_build_query($params); } elseif (!isset($ret['status']) || $ret['status'] !== 0) { @@ -391,7 +407,120 @@ class SubPage return $return; } - private static function eventToIconName($event) + private static function parseJsonHdd(string $uuid): array + { + $hdds = []; + $ret = Database::simpleQuery("SELECT mp.`machinehwid`, mp.`prop`, mp.`value`, mp.`numeric` + FROM machine_x_hw_prop mp + INNER JOIN machine_x_hw mxhw ON (mp.machinehwid = mxhw.machinehwid AND mxhw.machineuuid = :uuid AND mxhw.disconnecttime = 0) + INNER JOIN statistic_hw sh ON (mxhw.hwid = sh.hwid AND sh.hwtype = :type) + UNION SELECT mxhw.`machinehwid`, hwp.`prop`, hwp.`value`, hwp.`numeric` + FROM statistic_hw_prop hwp + INNER JOIN machine_x_hw mxhw ON (hwp.hwid = mxhw.hwid AND mxhw.machineuuid = :uuid AND mxhw.disconnecttime = 0) + INNER JOIN statistic_hw sh ON (mxhw.hwid = sh.hwid AND sh.hwtype = :type) + ", + ['type' => HardwareInfo::HDD, 'uuid' => $uuid]); + foreach ($ret as $row) { + if (!isset($hdds[$row['machinehwid']])) { + $hdds[$row['machinehwid']] = ['partitions' => []]; + } + $hdd =& $hdds[$row['machinehwid']]; + if (preg_match('/^(attr_[0-9]+)_(.*)$/', $row['prop'], $out)) { + // SMART attributes + if (!isset($hdd[$out[1]])) { + $hdd[$out[1]] = []; + } + $hdd[$out[1]][$out[2]] = $row['numeric'] ?? $row['value']; + } elseif (preg_match('/^part_([0-9]+)_(.*)$/', $row['prop'], $out)) { + // Partitions + if (!isset($hdd['partitions'][$out[1]])) { + $hdd['partitions'][$out[1]] = ['id' => 'dev-' . count($hdds) . '-' . $out[1], 'index' => $out[1] + 1]; + } + $hdd['partitions'][$out[1]][$out[2]] = $row['numeric'] ?? $row['value']; + } else { + $hdd[$row['prop']] = $row['numeric'] ?? $row['value']; + } + } + foreach ($hdds as $k => &$hdd) { + $hdd['devid'] = 'k' . $k; + $hdd['partitions'] = array_values($hdd['partitions']); + } + return array_values($hdds); + } + + private static function mangleHdd(array &$hdd) + { + $hours = $hdd['power_on_time//hours'] ?? $hdd['attr_9']['raw'] ?? $hdd['power_on_hours'] + ?? $hdd['power_on_time']['hours'] ?? null; + if ($hours !== null) { + $hdd['PowerOnTime'] = ''; + $val = (int)str_replace('.', '', $hours); + if ($val > 8760) { + $hdd['PowerOnTime'] .= floor($val / 8760) . 'Y, '; + $val %= 8760; + } + if ($val > 720) { + $hdd['PowerOnTime'] .= floor($val / 720) . 'M, '; + $val %= 720; + } + if ($val > 24) { + $hdd['PowerOnTime'] .= floor($val / 24) . 'd, '; + $val %= 24; + } + $hdd['PowerOnTime'] .= $val . 'h'; + } + // Sort by start for building pie-chart + $xx = array_column($hdd['partitions'], 'start'); + array_multisort($xx, SORT_ASC, SORT_NUMERIC, + $hdd['partitions']); + $used = 0; + $json = []; + $lastEnd = 0; + $minDisplaySize = $hdd['size'] / 150; + foreach ($hdd['partitions'] as &$part) { + $dist = $part['start'] - $lastEnd; + if ($dist > $minDisplaySize) { + error_log('Dist: ' . Util::readableFileSize($dist)); + $json[] = ['value' => $dist, 'color' => '#aaa']; + } + if ($part['size'] > $minDisplaySize) { + $json[] = ['value' => $part['size'], 'color' => self::typeToColor($part), 'label' => $part['id']]; + } + $part['size_s'] = Util::readableFileSize($part['size']); + $used += $part['size']; + $lastEnd = $part['start'] + $part['size']; + if (!isset($part['name'])) { + $part['name'] = self::mbrType($part['slxtype'] ?? $part['type']); + } + } + $dist = $hdd['size'] - $lastEnd; + if ($dist > $minDisplaySize) { + $json[] = ['value' => $dist, 'color' => '#aaa']; + } + $hdd['json'] = json_encode($json); + $hdd['size_s'] = Util::readableFileSize($hdd['size']); + if ($hdd['size'] - $used > 1000000000) { + $hdd['unused_s'] = Util::readableFileSize($hdd['size'] - $used); + } + // Finally sort by index for table display + array_multisort(array_column($hdd['partitions'], 'index'), SORT_ASC, + $hdd['partitions']); + } + + private static function typeToColor(array $part): string + { + switch ($part['slxtype'] ?? $part['type']) { + case 44: + return '#5c1'; + case 45: + return '#0d7'; + case 82: + return '#48f'; + } + return '#e55'; + } + + private static function eventToIconName($event): string { switch ($event) { case 'session-open': @@ -484,4 +613,22 @@ class SubPage return $retval; } + private static function mbrType(string $type): string + { + switch ($type) { + case '44': + case '45': + return 'OpenSLX-ID' . $type; + case '82': + return 'Linux Swap'; + case '83': + return 'Linux'; + case '7': + return 'NTFS/Windows'; + case 'ef': + return 'EFI'; + } + return $type; + } + } \ No newline at end of file diff --git a/modules-available/statistics/templates/machine-hdds.html b/modules-available/statistics/templates/machine-hdds.html index 4d0409f9..84feccfd 100644 --- a/modules-available/statistics/templates/machine-hdds.html +++ b/modules-available/statistics/templates/machine-hdds.html @@ -4,24 +4,27 @@
- {{s_ModelFamily}} {{dev}} + {{model_family}}{{^model_family}}{{model}}{{/model_family}} {{dev}}
- {{#s_DeviceModel}} -
{{lang_modelNo}}: {{s_DeviceModel}}, {{lang_serialNo}}: {{s_SerialNumber}}
- {{/s_DeviceModel}} - {{#s_ReallocatedSectorCt}} -
{{lang_reallocatedSectors}}: {{s_ReallocatedSectorCt}}
- {{/s_ReallocatedSectorCt}} - {{#s_CurrentPendingSector}} -
{{lang_pendingSectors}}: {{s_CurrentPendingSector}}
- {{/s_CurrentPendingSector}} - {{#s_PowerOnHours}} -
{{lang_powerOnTime}}: {{s_PowerOnHours}} {{lang_hours}} ({{PowerOnTime}})
- {{/s_PowerOnHours}} - {{#s_MediaandDataIntegrityErrors}} -
{{lang_mediaIntegrityErrors}}: {{s_MediaandDataIntegrityErrors}}
- {{/s_MediaandDataIntegrityErrors}} + {{#model}} +
{{lang_modelNo}}: {{model}}, {{lang_serialNo}}: {{serial_number}}
+ {{/model}} + {{#smart_status_failed}} +
{{lang_smartSelfTestFailed}}
+ {{/smart_status_failed}} + {{#attr_5.raw}} +
{{lang_reallocatedSectors}}: {{attr_5.raw}}
+ {{/attr_5.raw}} + {{#attr_197.raw}} +
{{lang_pendingSectors}}: {{attr_197.raw}}
+ {{/attr_197.raw}} + {{#PowerOnTime}} +
{{lang_powerOnTime}}: {{PowerOnTime}}
+ {{/PowerOnTime}} + {{#media_errors}} +
{{lang_mediaIntegrityErrors}}: {{media_errors}}
+ {{/media_errors}}
@@ -32,13 +35,16 @@ {{#partitions}} + + - - {{/partitions}}
{{index}}{{size_s}} {{name}}{{size}} GiB{{type}}
-
{{lang_total}}: {{size}} GiB
+
{{lang_total}}: {{size_s}}
+ {{#unused_s}} +
{{lang_unused}}: {{unused_s}}
+ {{/unused_s}}
@@ -46,7 +52,7 @@ document.addEventListener("DOMContentLoaded", function() { var data = {{{json}}}; var sel = false; - new Chart(document.getElementById('{{devid}}-chart').getContext('2d')).Pie(data, { + new Chart(document.getElementById('{{devid}}-chart').getContext('2d')).Pie(data, { animation: false, tooltipTemplate: "<%if (label){%><%=label%><%}%>", customTooltips: function(tooltip) { diff --git a/modules-available/statistics/templates/machine-main.html b/modules-available/statistics/templates/machine-main.html index 29d63a73..0509a646 100644 --- a/modules-available/statistics/templates/machine-main.html +++ b/modules-available/statistics/templates/machine-main.html @@ -292,16 +292,25 @@ + + + + + + + + + {{#ram}} {{#Speed}} - + -- cgit v1.2.3-55-g7522
{{lang_slot}}{{lang_speed}}{{lang_vendor}}{{lang_serialNo}}
{{Locator}}, {{Bank Locator}} - {{^Bank Locator}}Set {{Set}}{{/Bank Locator}} + {{^Bank Locator}}{{#Set}}Set {{Set}}{{/Set}}{{/Bank Locator}} {{Size}}{{#Configured Speed}}{{Configured Speed}} / {{/Configured Speed}}{{Speed}}{{#Configured Memory Speed}}{{Configured Memory Speed}} / {{/Configured Memory Speed}}{{Speed}} {{Manufacturer}} {{Serial Number}}