";
}
function duration(&$hrs) {
$time = ceil(time()/3600)*3600;
$now = new DateTime("@$time");
$poh = new DateTime("@".($time-$hrs*3600));
$age = date_diff($poh,$now);
$hrs = "$hrs (".($age->y?"{$age->y}y, ":"").($age->m?"{$age->m}m, ":"").($age->d?"{$age->d}d, ":"")."{$age->h}h)";
}
function spindownDelay($port) {
$disks = parse_ini_file('state/disks.ini',true);
foreach ($disks as $disk) {
$name = substr($disk['device'],-2)!='n1' ? $disk['device'] : substr($disk['device'],0,-2);
if ($name==$port) {file_put_contents("/var/tmp/diskSpindownDelay.{$disk['idx']}", $disk['spindownDelay']); break;}
}
}
function append(&$ref, &$info) {
if ($info) $ref .= ($ref ? " " : "").$info;
}
$disks = []; $var = [];
require_once "$docroot/webGui/include/CustomMerge.php";
$name = $_POST['name'] ?? '';
$port = $_POST['port'] ?? '';
if ($name) {
$disk = &$disks[$name];
$type = getVal($disk,'smType','');
if ($type) {
$ports = [];
if (!empty($disk['smDevice'])) $port = $disk['smDevice'];
if (!empty($disk['smPort1'])) $ports[] = $disk['smPort1'];
if (!empty($disk['smPort2'])) $ports[] = $disk['smPort2'];
if (!empty($disk['smPort3'])) $ports[] = $disk['smPort3'];
if ($ports) $type .= ','.implode($disk['smGlue'] ?? ',',$ports);
}
}
if (substr($port,-2)=='n1') $port = substr($port,0,-2);
switch ($_POST['cmd']) {
case "attributes":
require_once "$docroot/webGui/include/Wrappers.php";
require_once "$docroot/webGui/include/Preselect.php";
$select = getVal($disk,'smSelect',0);
$level = getVal($disk,'smLevel',1);
$events = explode('|',getVal($disk,'smEvents',$numbers));
$unraid = parse_plugin_cfg('dynamix',true);
$max = $disk['maxTemp'] ?? $unraid['display']['max'];
$hot = $disk['hotTemp'] ?? $unraid['display']['hot'];
exec("smartctl -A $type ".escapeshellarg("/dev/$port")."|awk 'NR>4'",$output);
if (strpos($output[0], 'SMART Attributes Data Structure')===0) {
$output = array_slice($output, 3);
$empty = true;
foreach ($output as $line) {
if (!$line) continue;
$info = explode(' ', trim(preg_replace('/\s+/',' ',$line)), 10);
$color = "";
$highlight = strpos($info[8],'FAILING_NOW')!==false || ($select ? $info[5]>0 && $info[3]<=$info[5]*$level : $info[9]>0);
if (in_array($info[0], $events) && $highlight) $color = " class='warn'";
elseif (in_array($info[0], [190,194])) {
if ($info[9]>=$max && $max>0) $color = " class='alert'"; elseif ($info[9]>=$hot && $hot>0) $color = " class='warn'";
}
if ($info[8]=='-') $info[8] = 'Never';
if ($info[0]==9 && is_numeric($info[9])) duration($info[9]);
echo "
".implode('',array_map('normalize', $info))."
";
$empty = false;
}
if ($empty) echo "
Can not read attributes
";
} else {
// probably a NMVe or SAS device that smartmontools doesn't know how to parse in to a SMART Attributes Data Structure
foreach ($output as $line) {
if (strpos($line,':')===false) continue;
list($name,$value) = explode(':', $line);
$name = ucfirst(strtolower($name));
$value = trim($value);
$color = '';
switch ($name) {
case 'Temperature':
$temp = strtok($value,' ');
if ($temp>=$max && $max>0) $color = " class='alert'"; elseif ($temp>=$hot && $hot>0) $color = " class='warn'";
break;
case 'Power on hours':
if (is_numeric($value)) duration($value);
break;
}
echo "