|
@@ -1,386 +1,58 @@
|
|
|
<?php
|
|
|
-include_once '../auth.php';
|
|
|
-?>
|
|
|
-<html>
|
|
|
-<head>
|
|
|
- <link rel="stylesheet" href="../script/tocas/tocas.css">
|
|
|
- <script src="../script/tocas/tocas.js"></script>
|
|
|
- <script src="../script/jquery.min.js"></script>
|
|
|
- <script src="../script/ao_module.js"></script>
|
|
|
- <meta name="viewport" content="width=device-width, initial-scale=0.6, shrink-to-fit=no">
|
|
|
- <style>
|
|
|
- body{
|
|
|
- overflow-y: hidden;
|
|
|
- }
|
|
|
- .item{
|
|
|
- text-align: center;
|
|
|
- }
|
|
|
- .ts.mini.input{
|
|
|
- padding: .48571em 1em;
|
|
|
- }
|
|
|
- .ts.horizontal.form .field.field>label{
|
|
|
- top: 0.5em;
|
|
|
- }
|
|
|
- </style>
|
|
|
- </head>
|
|
|
-<body>
|
|
|
-<div class="ts tabbed menu" id="menu">
|
|
|
-</div>
|
|
|
-<div class="ts grid">
|
|
|
- <div class="sixteen wide column"><h3 class="ts center aligned header" id="drivename" data-tooltip="">----</h3></div>
|
|
|
- <div class="sixteen wide column">
|
|
|
- <div class="ts narrow container">
|
|
|
- <div class="ts grid">
|
|
|
- <div class="two wide column">
|
|
|
- <div class="tablet or large device only">
|
|
|
- <h5 class="ts center aligned header">Health Status</h5>
|
|
|
- <div class="ts card" id="health_c">
|
|
|
- <div class="content">
|
|
|
- <div class="header" style="text-align: center;" id="health_status">----</div>
|
|
|
- <div class="description" style="text-align: center;" id="health_prec">
|
|
|
- ----
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <h5 class="ts center aligned header">Temperature</h5>
|
|
|
- <div class="ts card" id="temperature_c">
|
|
|
- <div class="content">
|
|
|
- <div class="description" style="text-align: center;" id="temperature">
|
|
|
-
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="fourteen wide column">
|
|
|
- <div class="ts grid">
|
|
|
- <div class="sixteen wide column">
|
|
|
- <div class="ts grid">
|
|
|
- <div class="eight wide column">
|
|
|
- <div class="ts horizontal form" style="opacity: 1;">
|
|
|
- <div class="disabled field" style="opacity: 1;">
|
|
|
- <label style="color:black">Firmware</label>
|
|
|
- <input id="firmware" class="ts mini input" style="color:black" type="text" value="----"></input>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="eight wide column">
|
|
|
- <div class="ts horizontal form" style="opacity: 1;">
|
|
|
- <div class="disabled field" style="opacity: 1;">
|
|
|
- <label id="col1" style="color:black">----</label>
|
|
|
- <input id="col1_v" class="ts mini input" style="color:black" type="text" value="----"></input>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="sixteen wide column">
|
|
|
- <div class="ts grid">
|
|
|
- <div class="eight wide column">
|
|
|
- <div class="ts horizontal form" style="opacity: 1;">
|
|
|
- <div class="disabled field" style="opacity: 1;">
|
|
|
- <label style="color:black">Serial Number</label>
|
|
|
- <input id="serial" class="ts mini input" style="color:black" type="text" value="----"></input>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="eight wide column">
|
|
|
- <div class="ts horizontal form" style="opacity: 1;">
|
|
|
- <div class="disabled field" style="opacity: 1;">
|
|
|
- <label id="col2" style="color:black">----</label>
|
|
|
- <input id="col2_v" class="ts mini input" style="color:black" type="text" value="----"></input>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="sixteen wide column">
|
|
|
- <div class="ts grid">
|
|
|
- <div class="eight wide column">
|
|
|
- <div class="ts horizontal form" style="opacity: 1;">
|
|
|
- <div class="disabled field" style="opacity: 1;">
|
|
|
- <label style="color:black">Interface</label>
|
|
|
- <input id="interface" class="ts mini input" style="color:black" type="text" value="----"></input>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="eight wide column">
|
|
|
- <div class="ts horizontal form" style="opacity: 1;">
|
|
|
- <div class="disabled field" style="opacity: 1;">
|
|
|
- <label id="col3" style="color:black">----</label>
|
|
|
- <input id="col3_v" class="ts mini input" style="color:black" type="text" value="----"></input>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="sixteen wide column">
|
|
|
- <div class="ts grid">
|
|
|
- <div class="eight wide column">
|
|
|
- <div class="ts horizontal form" style="opacity: 1;">
|
|
|
- <div class="disabled field" style="opacity: 1;">
|
|
|
- <label style="color:black">Transfer Mode</label>
|
|
|
- <input id="transfer" class="ts mini input" style="color:black" type="text" value="----"></input>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="eight wide column">
|
|
|
- <div class="ts horizontal form" style="opacity: 1;">
|
|
|
- <div class="disabled field" style="opacity: 1;">
|
|
|
- <label style="color:black">Power On Count</label>
|
|
|
- <input id="powercount" class="ts mini input" style="color:black" type="text" value="----"></input>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="sixteen wide column">
|
|
|
- <div class="ts grid">
|
|
|
- <div class="eight wide column">
|
|
|
- <div class="ts horizontal form" style="opacity: 1;">
|
|
|
- <div class="disabled field" style="opacity: 1;">
|
|
|
- <label style="color:black">Drive Letter</label>
|
|
|
- <input id="driveleter" class="ts mini input" style="color:black" type="text" value="----"></input>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="eight wide column">
|
|
|
- <div class="ts horizontal form" style="opacity: 1;">
|
|
|
- <div class="disabled field" style="opacity: 1;">
|
|
|
- <label style="color:black">Power On Hours</label>
|
|
|
- <input id="powerhour" class="ts mini input" style="color:black" type="text" value="----"></input>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- Below is full width-->
|
|
|
- <div class="sixteen wide column">
|
|
|
- <div class="ts horizontal form" style="opacity: 1;">
|
|
|
- <div class="disabled field" style="opacity: 1;">
|
|
|
- <label style="color:black">Standard</label>
|
|
|
- <input id="standard" class="ts mini input" style="color:black" type="text" value="----"></input>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="sixteen wide column" style="height: 37vh;overflow-y: scroll;right: 5px;">
|
|
|
- <br>
|
|
|
- <div class="ts narrow container">
|
|
|
- <table class="ts very basic table">
|
|
|
- <thead>
|
|
|
- <tr>
|
|
|
- <th>Stat</th>
|
|
|
- <th>ID</th>
|
|
|
- <th>Attribute Name</th>
|
|
|
- <th>Current</th>
|
|
|
- <th>Worst</th>
|
|
|
- <th>Threshold</th>
|
|
|
- <th>Raw Values</th>
|
|
|
- </tr>
|
|
|
- </thead>
|
|
|
- <tbody id="tbody">
|
|
|
- </tbody>
|
|
|
- </table>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-</div>
|
|
|
-</body>
|
|
|
-<script>
|
|
|
-var active = "<?php echo isset($_GET["drive"])?$_GET["drive"]:"" ?>";
|
|
|
-var smartstat = [];
|
|
|
+header("Access-Control-Allow-Origin: *");
|
|
|
+// for linux user, you might need chmod 0777 smartctl_x86_64 && chmod 0777 smartctl_armv6
|
|
|
+// you need smartctl 7.0.0 above to support JSON output
|
|
|
|
|
|
-if(ao_module_virtualDesktop){
|
|
|
- ao_module_setWindowSize(980,580);
|
|
|
+$ok = false;
|
|
|
+preg_match('/smartmontools release ([0-9])\.([0-9])/', shell_exec(' sudo smartctl --version | grep "release"'), $filter);
|
|
|
+if(isset($filter[1])){
|
|
|
+ if($filter[1] > 6){
|
|
|
+ $binary = "smartctl";
|
|
|
+ $ok = true;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-$.get( "opr.php?opr=scan", function( data ) {
|
|
|
- //arr = scan result
|
|
|
- //scan first
|
|
|
- var arr = JSON.parse(data);
|
|
|
- //check if something is selected, if no then redirect to first drive.
|
|
|
- if(active == ""){
|
|
|
- window.location = "index.php?drive=" + arr["devices"][0]["info_name"];
|
|
|
- }
|
|
|
- //for loop all devices out and check SMART
|
|
|
- $(arr["devices"]).each(function(index, element) {
|
|
|
- //call infomation for further deeper result
|
|
|
- $.get( "opr.php?opr=info&drive=" + element["info_name"], function( data ) {
|
|
|
- //check if something exists on return
|
|
|
- if(data.length > 0){
|
|
|
- smartstat[element["info_name"]] = "Unknown";
|
|
|
- //find for SMART bad, here do the for loop
|
|
|
- var table = JSON.parse(data);
|
|
|
- //check for SMART table exists
|
|
|
- if(table["ata_smart_attributes"]["table"].length > 0){
|
|
|
- //for loop to find if something failed, then show warning
|
|
|
- $(table["ata_smart_attributes"]["table"]).each(function(tindex, telement) {
|
|
|
- if(typeof telement["when_failed"] === "undefined"){
|
|
|
- }else{
|
|
|
- if(telement["when_failed"] !== ""){
|
|
|
- smartstat[element["info_name"]] = "Warning";
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- // if nothing happen, then changed to GOOD
|
|
|
- if(smartstat[element["info_name"]] == "Unknown"){
|
|
|
- smartstat[element["info_name"]] = "Good";
|
|
|
- }
|
|
|
- }else{
|
|
|
- // if nothing exists, then show Unknown
|
|
|
- smartstat[element["info_name"]] = "Unknown";
|
|
|
- }
|
|
|
- //append it to nav bar
|
|
|
- if(active == element["info_name"]){
|
|
|
- //append if active selected
|
|
|
- $( "#menu" ).append('<a class="active item" href="?drive=' + element["info_name"] + '">' + smartstat[element["info_name"]] + '<br>' + table["temperature"]["current"] + '°C<br>' + element["info_name"] + '</a>');
|
|
|
- }else{
|
|
|
- $( "#menu" ).append('<a class="item" href="?drive=' + element["info_name"] + '">' + smartstat[element["info_name"]] + '<br>' + table["temperature"]["current"] + '°C<br>' + element["info_name"] + '</a>');
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- });
|
|
|
-});
|
|
|
-//get the selected drive infomation
|
|
|
-$.get( "opr.php?opr=info&drive=" + active, function( data ) {
|
|
|
- //parse data;
|
|
|
- var arr = JSON.parse(data);
|
|
|
-
|
|
|
- //append all shit here
|
|
|
- $("#drivename").html(arr["model_name"] + " " + formatSizeUnits(arr["user_capacity"]["bytes"]));
|
|
|
- $("#drivename").attr("data-tooltip",arr["model_family"]);
|
|
|
- $("#firmware").attr("value",arr["firmware_version"]);
|
|
|
- $("#serial").attr("value",arr["serial_number"]);
|
|
|
- $("#interface").attr("value",arr["device"]["protocol"]);
|
|
|
- $("#transfer").attr("value",arr["interface_speed"]["current"]["string"] + " | " + arr["interface_speed"]["max"]["string"]);
|
|
|
- $("#driveleter").attr("value",arr["device"]["name"]);
|
|
|
- $("#standard").attr("value",arr["ata_version"]["string"]);
|
|
|
- $("#features").attr("value","S.M.A.R.T.");
|
|
|
- //check if it is SSD
|
|
|
- if(arr["rotation_rate"] > 0){
|
|
|
- $("#col1").html("----");
|
|
|
- $("#col1_v").attr("value","----");
|
|
|
-
|
|
|
- $("#col2").html("----");
|
|
|
- $("#col2_v").attr("value","----");
|
|
|
- $("#col3").html("Rotation Rate");
|
|
|
- $("#col3_v").attr("value",arr["rotation_rate"] + " rpm");
|
|
|
+if($ok == false){
|
|
|
+ if(strcasecmp(substr(PHP_OS, 0, 3), 'WIN') == 0){
|
|
|
+ $binary = "cd bin && smartctl";
|
|
|
}else{
|
|
|
- $("#col1").html("Total Host Reads");
|
|
|
- $("#col1_v").attr("value","----");
|
|
|
-
|
|
|
- $("#col2").html("Total Host Writes");
|
|
|
- $("#col2_v").attr("value","----");
|
|
|
- $("#col3").html("Total NAND Writes");
|
|
|
- $("#col3_v").attr("value","----");
|
|
|
- }
|
|
|
- $("#powercount").attr("value",arr["power_cycle_count"] + " count");
|
|
|
- $("#powerhour").attr("value",arr["power_on_time"]["hours"] + " hours");
|
|
|
-
|
|
|
- //check if SMART bad
|
|
|
- smartstat[active] = "Unknown";
|
|
|
- $(arr["ata_smart_attributes"]["table"]).each(function(index, element) {
|
|
|
- if(typeof element["when_failed"] === "undefined"){
|
|
|
- var stat = "OK";
|
|
|
- }else{
|
|
|
- if(element["when_failed"] == ""){
|
|
|
- var stat = "OK";
|
|
|
- }else{
|
|
|
- var stat = "Failed";
|
|
|
- smartstat[active] = "Warning";
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //prevent element undefined, check first
|
|
|
- if(typeof element["id"] === "undefined"){
|
|
|
- var id = 0;
|
|
|
- }else{
|
|
|
- var id = element["id"];
|
|
|
- }
|
|
|
- if(typeof element["name"] === "undefined"){
|
|
|
- var name = 0;
|
|
|
- }else{
|
|
|
- var name = element["name"];
|
|
|
- }
|
|
|
- if(typeof element["value"] === "undefined"){
|
|
|
- var value = 0;
|
|
|
+ if(strpos(exec('uname -m'), 'arm') !== false){
|
|
|
+ $binary = "sudo ./smartctl_armv6";
|
|
|
}else{
|
|
|
- var value = element["value"];
|
|
|
- }
|
|
|
- if(typeof element["worst"] === "undefined"){
|
|
|
- var worst = 0;
|
|
|
- }else{
|
|
|
- var worst = element["worst"];
|
|
|
- }
|
|
|
- if(typeof element["thresh"] === "undefined"){
|
|
|
- var thresh = 0;
|
|
|
- }else{
|
|
|
- var thresh = element["thresh"];
|
|
|
- }
|
|
|
- if(typeof element["raw"]["value"] === "undefined"){
|
|
|
- var rvalue = 0;
|
|
|
- }else{
|
|
|
- var rvalue = element["raw"]["value"];
|
|
|
- }
|
|
|
- //apend
|
|
|
- $("#tbody").append('<tr><td>' + stat + '</td><td>' + id + '</td><td>' + name + '</td><td>' + value + '</td><td>' + worst + '</td><td>' + thresh + '</td><td>' + rvalue + '</td></tr>');
|
|
|
-
|
|
|
- if(element["name"] == "SSD_Life_Left"){
|
|
|
- $("#health_prec").html(element["value"] + "%");
|
|
|
- }
|
|
|
- });
|
|
|
- //check if SMART exists and Not in warning, then shows GOOD
|
|
|
- if(arr["ata_smart_attributes"]["table"].length > 0){
|
|
|
- if(smartstat[active] == "Unknown"){
|
|
|
- smartstat[active] = "Good";
|
|
|
+ $binary = "sudo ./smartctl_x86_64";
|
|
|
}
|
|
|
}
|
|
|
+}
|
|
|
+if($_GET["opr"] == "scan"){
|
|
|
+ echo shell_exec($binary.' --scan -j');
|
|
|
+ //echo file_get_contents("scan.txt");
|
|
|
+}else if($_GET["opr"] == "info"){
|
|
|
+ //smartctl -H /dev/sdb -j
|
|
|
+ //echo shell_exec('sudo ./smartctl_i386 -i '.$_GET["drive"].' -j -A');
|
|
|
+ $DiskData = [];
|
|
|
+ $DiskData["model_name"] = "Unknown";
|
|
|
+ $DiskData["user_capacity"]["bytes"] = 0;
|
|
|
+ $DiskData["temperature"]["current"] = 0;
|
|
|
+ $DiskData["model_family"] = "Unknown";
|
|
|
+ $DiskData["device"]["info_name"] = "Unknown";
|
|
|
+ $DiskData["firmware_version"] = "0.0.0";
|
|
|
+ $DiskData["serial_number"] = "Unknown";
|
|
|
+ $DiskData["power_on_time"]["hours"] = 0;
|
|
|
+ $DiskData["power_cycle_count"] = 0;
|
|
|
+ $DiskData["sata_version"]["string"] = "Unknown";
|
|
|
+ $DiskData["interface_speed"]["current"]["string"] = "Unknown";
|
|
|
+ $DiskData["interface_speed"]["max"]["string"] = "Unknown";
|
|
|
+ $DiskData["ata_version"]["string"] = "Unknown";
|
|
|
+ $DiskData["rotation_rate"] = 0;
|
|
|
+ $DiskData["device"]["protocol"] = "Unknown";
|
|
|
+ $DiskData["ata_smart_attributes"]["table"] = [];
|
|
|
|
|
|
- //change color
|
|
|
- if(smartstat[active] == "Warning"){
|
|
|
- $("#health_c").attr("class","ts inverted warning card");
|
|
|
- }else if(smartstat[active] == "Good"){
|
|
|
- $("#health_c").attr("class","ts inverted primary card");
|
|
|
- }else if(smartstat[active] == "Unknown"){
|
|
|
- $("#health_c").attr("class","ts card");
|
|
|
+ $execResult = json_decode(shell_exec($binary.' -i '.$_GET["drive"].' -j -A'),true);
|
|
|
+ //$execResult = json_decode(file_get_contents(explode("/",$_GET["drive"])[2].".txt"),true);
|
|
|
+ if($execResult == null){
|
|
|
+ die("");
|
|
|
}
|
|
|
-
|
|
|
- //if temp more than 40C, then warning
|
|
|
- if(arr["temperature"]["current"] > 40){
|
|
|
- $("#temperature_c").attr("class","ts inverted warning card");
|
|
|
- }else if(arr["temperature"]["current"] > 0 && arr["temperature"]["current"] < 40){
|
|
|
- $("#temperature_c").attr("class","ts inverted primary card");
|
|
|
- }else{
|
|
|
- $("#temperature_c").attr("class","ts card");
|
|
|
- }
|
|
|
- $("#health_status").html(smartstat[active]);
|
|
|
- $("#temperature").html(arr["temperature"]["current"] + "°C");
|
|
|
-});
|
|
|
-
|
|
|
-//from https://stackoverflow.com/questions/5501427/php-filesize-mb-kb-conversion/5501447
|
|
|
- function formatSizeUnits(bytes)
|
|
|
- {
|
|
|
- if(bytes >= 1000000000000){
|
|
|
- bytes = Math.round(bytes / 1000000000000) + 'TB';
|
|
|
- }else if(bytes >= 1000000000){
|
|
|
- bytes = Math.round(bytes / 1000000000) + 'GB';
|
|
|
- }else if (bytes >= 1000000){
|
|
|
- bytes = Math.round(bytes / 1000000) + 'MB';
|
|
|
- }else if (bytes >= 1000){
|
|
|
- bytes = Math.round(bytes / 1000) + 'KB';
|
|
|
- }else if (bytes > 1){
|
|
|
- bytes = bytes + 'bytes';
|
|
|
- }else if (bytes == 1){
|
|
|
- bytes = bytes + 'byte';
|
|
|
- }else{
|
|
|
- bytes = '0bytes';
|
|
|
- }
|
|
|
-
|
|
|
- return bytes;
|
|
|
+ $DiskData = array_merge($DiskData,$execResult);
|
|
|
+ echo json_encode($DiskData);
|
|
|
}
|
|
|
-</script>
|
|
|
-</html>
|
|
|
+?>
|