add support for some samsung drives

This commit is contained in:
2026-06-03 12:54:18 -07:00
parent 2333cb36bc
commit 9096e7adde
7 changed files with 125 additions and 26 deletions

View File

@ -51,9 +51,9 @@ sector_size: "512"
sleep_time: "5"
install_kiosk: false
quick_refresh: false
service_only: false
service_only: true
armcpu_check: false
service_mode: false
service_mode: true
install_docker: true
...

View File

@ -37,29 +37,26 @@ function fetchSSDData() {
Search for disk:<br>
<input id="search" type="text" placeholder="Search by ID, model, serial…" /><p>
<?php
$ssdData = fetchSSDData(); // Fetch data from the API
// Start the table
$ssdData = fetchSSDData();
echo '<table class="ssd-list" style="border-collapse:collapse;width:100%;">';
// Table header (optional but handy)
echo '<thead>
<tr>
<th>Disk ID</th>
<th>Model String</th>
<th>Serial Number</th>
<th>GB Written</th>
<th>Disk Capacity</th>
<th>Disk Flavor</th>
<th>SMART Result</th>
<th data-sort="id">Disk ID</th>
<th data-sort="model">Model String</th>
<th data-sort="serial">Serial Number</th>
<th data-sort="gb_written">GB Written</th>
<th data-sort="capacity">Disk Capacity</th>
<th data-sort="flavor">Disk Flavor</th>
<th data-sort="smart">SMART Result</th>
</tr>
</thead>';
// Table body - one row per SSD
echo '<tbody id="ssd-body">';
foreach ($ssdData as $ssd) {
// Escape the values so the page stays safe
$id = htmlspecialchars($ssd['id']);
$model = htmlspecialchars($ssd['model']);
$serial = htmlspecialchars($ssd['serial']);
$tbw = htmlspecialchars($ssd['gb_written']);
$gbw = htmlspecialchars($ssd['gb_written']);
$cap = htmlspecialchars($ssd['capacity']);
$flavor = htmlspecialchars($ssd['flavor']);
$smart = htmlspecialchars($ssd['smart']);
@ -68,7 +65,7 @@ function fetchSSDData() {
<td>{$id}</td>
<td>{$model}</td>
<td>{$serial}</td>
<td>{$tbw}</td>
<td>{$gbw}</td>
<td>{$cap}</td>
<td>{$flavor}</td>
<td>{$smart}</td>
@ -112,4 +109,82 @@ document.addEventListener('DOMContentLoaded', () => {
});
</script>
<script>
document.addEventListener('DOMContentLoaded', () => {
/* ----- Search filter ----- */
const searchInput = document.getElementById('search');
const tbody = document.getElementById('ssd-body');
const rowsSnapshot = Array.from(tbody.rows); // keep a static snapshot
const debounce = (fn, delay) => {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
};
const filterRows = debounce(() => {
const q = searchInput.value.trim().toLowerCase();
rowsSnapshot.forEach(r => {
const rowText = Array.from(r.cells)
.map(c => c.textContent.trim().toLowerCase())
.join(' ');
r.style.display = rowText.includes(q) ? '' : 'none';
});
}, 200);
searchInput.addEventListener('input', filterRows);
/* ----- Table sorting ----- */
const table = document.querySelector('.ssd-list');
const headerCells = table.querySelectorAll('th[data-sort]');
const bodyRows = Array.from(tbody.rows);
headerCells.forEach((th, index) => {
th.classList.add('sortable'); // gives the arrow styling
th.style.cursor = 'pointer';
th.addEventListener('click', () => {
const currentSort = th.dataset.currentSort || 'none';
const ascending = currentSort !== 'asc';
// reset other headers
headerCells.forEach(h => {
h.dataset.currentSort = 'none';
h.classList.remove('asc', 'desc');
});
// set current header state
th.dataset.currentSort = ascending ? 'asc' : 'desc';
th.classList.toggle('asc', ascending);
th.classList.toggle('desc', !ascending);
// sort
bodyRows.sort((a, b) => {
const aText = a.cells[index].textContent.trim();
const bText = b.cells[index].textContent.trim();
// try numeric comparison
const aNum = parseFloat(aText.replace(/,/g, ''));
const bNum = parseFloat(bText.replace(/,/g, ''));
if (!isNaN(aNum) && !isNaN(bNum)) {
return ascending ? aNum - bNum : bNum - aNum;
}
// fallback to localeCompare (caseinsensitive)
return ascending
? aText.localeCompare(bText, undefined, { sensitivity: 'base' })
: bText.localeCompare(aText, undefined, { sensitivity: 'base' });
});
// reattach sorted rows
bodyRows.forEach(r => tbody.appendChild(r));
});
});
});
</script>
</html>

View File

@ -129,3 +129,17 @@ li {
background-color: #2c3e50; /* Dark background for meter */
}
/* Sort arrow */
th.sortable::after {
content: '';
float: right;
margin-left: 4px;
border: 4px solid transparent;
}
th.sortable.asc::after {
border-bottom-color: #333; /* ▲ */
}
th.sortable.desc::after {
border-top-color: #333; /* ▼ */
}

View File

@ -138,13 +138,23 @@ def return_sector_size(drive_id):
sector_size_result = subprocess.run(sector_size_command, shell=True, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return int(sector_size_result.stdout.decode("utf-8"))
# this had to be updated to allow for inconsistent SMART data
def return_ls_written(data):
if "ata_device_statistics" in data:
pages = data.get("ata_device_statistics", {}).get("pages", [])
for page in pages:
for entry in page.get("table", []):
if entry.get("name") == "Logical Sectors Written":
return entry.get("value")
if "ata_smart_attributes" in data:
print("type two")
pages = data.get("ata_smart_attributes", [])
for entry in pages.get("table", []):
if entry.get("name") == "Total_LBAs_Written":
print(entry.get("value").get("raw", {}))
return entry.get("raw").get("value")
# Function to return all drive records in database
def get_all_drive_records():
get_all_drives = "SELECT * FROM drive_records"

View File

@ -88,9 +88,9 @@ if __name__ == '__main__':
scheduler.start()
if secure_api:
app.run(debug=True, host='172.17.0.1', port=5000)
app.run(debug=False, host='172.17.0.1', port=5000)
else:
app.run(debug=True, host='0.0.0.0', port=5000)
app.run(debug=False, host='0.0.0.0', port=5000)

View File

@ -391,9 +391,9 @@ if __name__ == '__main__':
print(result)
if secure_api:
app.run(debug=True, host='172.17.0.1', port=5000)
app.run(debug=False, host='172.17.0.1', port=5000)
else:
app.run(debug=True, host='0.0.0.0', port=5000)
app.run(debug=False, host='0.0.0.0', port=5000)

View File

@ -17,10 +17,10 @@
when: not install_kiosk | bool and not service_only | bool and not armcpu_check | bool
include_tasks: autologin.yaml
# disablep autologin
# disable autologin
- name: Drive health - disable autologin
when: install_kiosk | bool or service_only | bool
include_tasks: autologin.yaml
include_tasks: no_autologin.yaml
# Install chrome kiosk
- name: install chromium kiosk