Compare commits

..
Author SHA1 Message Date
anthropic-code-agent[bot]andashaduri 37090a8556 Fix Type tooltip and FailTime condition per PR feedback
Co-authored-by: ashaduri <2302268+ashaduri@users.noreply.github.com>
Agent-Logs-Url: https://github.com/ashaduri/gsmartcontrol/sessions/b9ea2530-2c7d-4061-accb-eb7d7bb1dc16
2026-03-22 17:09:02 +00:00
anthropic-code-agent[bot]andashaduri 99d358396b Make Type bold only on pre-failure attribute failure
- Type column now shows bold text only when BOTH conditions are met:
  1. Attribute has actually failed (when_failed != None)
  2. Attribute type is pre-failure
- This provides visual emphasis for genuine pre-failure warnings
- Normal pre-failure attributes (not failed) remain normal weight

Co-authored-by: ashaduri <2302268+ashaduri@users.noreply.github.com>
2026-03-06 19:02:55 +00:00
anthropic-code-agent[bot]andashaduri d1d64693db Clarify Type attribute explanation and remove bold formatting
- Updated tooltip to clearly explain Type indicates alarm meaning
- Removed bold formatting for "pre-failure" to reduce visual alarm
- Changed text to emphasize Type is about alarm interpretation, not current status

Co-authored-by: ashaduri <2302268+ashaduri@users.noreply.github.com>
2026-03-06 14:52:28 +00:00
anthropic-code-agent[bot] 480e060682 Initial plan 2026-03-06 14:50:23 +00:00
4 changed files with 5 additions and 108 deletions
-1
View File
@@ -115,7 +115,6 @@ bool storage_property_autoset_description(StorageProperty& p, StorageDeviceDetec
found = auto_set(p, "ata_smart_attributes/revision", p.displayable_name.c_str());
if (!found) {
auto_set_ata_attribute_description(p, device_type);
storage_property_ata_attribute_humanize_ssd_writes(p);
found = true; // true, because auto_set_attr() may set "Unknown attribute", which is still "found".
}
break;
@@ -22,7 +22,6 @@ Copyright:
//#include "warning_colors.h"
#include "storage_property_descr_helpers.h"
#include "hz/string_num.h"
#include "hz/format_unit.h" // format_size
namespace {
@@ -1365,104 +1364,5 @@ void storage_property_ata_attribute_autoset_warning(StorageProperty& p)
void storage_property_ata_attribute_humanize_ssd_writes(StorageProperty& p)
{
if (p.section != StoragePropertySection::AtaAttributes || !p.is_value_type<AtaStorageAttribute>()) {
return;
}
const auto& attr = p.get_value<AtaStorageAttribute>();
// Skip if readable_value is already set (e.g., by parser or for GiB attributes)
if (!p.readable_value.empty()) {
return;
}
// Standard sector size (512 bytes)
constexpr uint64_t bytes_per_sector = 512;
constexpr uint64_t mib_32 = 32ULL * 1024ULL * 1024ULL;
constexpr uint64_t gib = 1024ULL * 1024ULL * 1024ULL;
// Match attribute by ID and reported name to handle vendor-specific attributes
const int32_t id = attr.id;
const std::string& name = p.reported_name;
std::optional<uint64_t> bytes;
// Write attributes - these need humanization most
// Attribute 199: Write_Sectors_Tot_Ct (Indilinx Barefoot SSDs)
// Total count of written sectors
if (id == 199 && name == "Write_Sectors_Tot_Ct") {
bytes = static_cast<uint64_t>(attr.raw_value_int) * bytes_per_sector;
}
// Attribute 225: Host_Writes_32MiB (Intel SSDs)
else if (id == 225 && name == "Host_Writes_32MiB") {
bytes = static_cast<uint64_t>(attr.raw_value_int) * mib_32;
}
// Attribute 241: Host_Writes_32MiB (various SSDs)
// Raw value increased by 1 for every 32 MiB written
else if (id == 241 && name == "Host_Writes_32MiB") {
bytes = static_cast<uint64_t>(attr.raw_value_int) * mib_32;
}
// Attribute 243: Host_Writes_32MiB (SanDisk SSDs)
else if (id == 243 && name == "Host_Writes_32MiB") {
bytes = static_cast<uint64_t>(attr.raw_value_int) * mib_32;
}
// Attribute 245: Flash_Writes_32MiB (Innodisk SSDs)
else if (id == 245 && name == "Flash_Writes_32MiB") {
bytes = static_cast<uint64_t>(attr.raw_value_int) * mib_32;
}
// Attribute 245: TLC_Writes_32MiB (SiliconMotion SSDs)
else if (id == 245 && name == "TLC_Writes_32MiB") {
bytes = static_cast<uint64_t>(attr.raw_value_int) * mib_32;
}
// Attribute 246: SLC_Writes_32MiB (SiliconMotion SSDs)
else if (id == 246 && name == "SLC_Writes_32MiB") {
bytes = static_cast<uint64_t>(attr.raw_value_int) * mib_32;
}
// Attribute 246: Total_Host_Sector_Write (Crucial/Micron SSDs)
// Total number of sectors written by the host system
else if (id == 246 && name == "Total_Host_Sector_Write") {
bytes = static_cast<uint64_t>(attr.raw_value_int) * bytes_per_sector;
}
// Attribute 249: NAND_Writes_1GiB (Intel SSDs)
// Note: The raw value is the count, not already in GiB
else if (id == 249 && name == "NAND_Writes_1GiB") {
bytes = static_cast<uint64_t>(attr.raw_value_int) * gib;
}
// Attribute 249: Total_NAND_Prog_Ct_GiB (OCZ SSDs)
else if (id == 249 && name == "Total_NAND_Prog_Ct_GiB") {
bytes = static_cast<uint64_t>(attr.raw_value_int) * gib;
}
// Read attributes - also humanize for consistency
// Attribute 198: Read_Sectors_Tot_Ct (Indilinx Barefoot SSDs)
else if (id == 198 && name == "Read_Sectors_Tot_Ct") {
bytes = static_cast<uint64_t>(attr.raw_value_int) * bytes_per_sector;
}
// Attribute 226: Host_Reads_32MiB (Intel SSDs)
else if (id == 226 && name == "Host_Reads_32MiB") {
bytes = static_cast<uint64_t>(attr.raw_value_int) * mib_32;
}
// Attribute 242: Host_Reads_32MiB (Intel SSDs)
else if (id == 242 && name == "Host_Reads_32MiB") {
bytes = static_cast<uint64_t>(attr.raw_value_int) * mib_32;
}
// Attribute 244: Flash_Reads_32MiB (Innodisk SSDs)
else if (id == 244 && name == "Flash_Reads_32MiB") {
bytes = static_cast<uint64_t>(attr.raw_value_int) * mib_32;
}
// Attribute 251: Total_NAND_Read_Ct_GiB (OCZ SSDs)
else if (id == 251 && name == "Total_NAND_Read_Ct_GiB") {
bytes = static_cast<uint64_t>(attr.raw_value_int) * gib;
}
// Set readable_value if we determined the byte count
if (bytes.has_value() && bytes.value() > 0) {
// Use binary units (KiB, MiB, GiB, TiB) for consistency with existing attributes
p.readable_value = hz::format_size(bytes.value(), false);
}
}
/// @}
@@ -26,11 +26,6 @@ void auto_set_ata_attribute_description(StorageProperty& p, StorageDeviceDetecte
void storage_property_ata_attribute_autoset_warning(StorageProperty& p);
/// Humanize SSD write statistics by converting raw values to readable byte counts.
/// Sets the readable_value field for applicable write-related attributes.
void storage_property_ata_attribute_humanize_ssd_writes(StorageProperty& p);
#endif
/// @}
+5 -2
View File
@@ -1139,7 +1139,7 @@ void GscInfoWindow::fill_ui_ata_attributes(const StoragePropertyRepository& prop
model_columns.add(columns_->ata_attribute_table_columns.type);
num_tree_col = app_gtkmm_create_tree_view_column(columns_->ata_attribute_table_columns.type, *treeview,
_("Type"), _("Alarm condition is reached when normalized value becomes less than or equal to threshold. Type indicates whether it's a signal of drive's pre-failure time or just an old age."), false, true);
_("Type"), _("Indicates whether an alarm for this attribute signals drive failure (pre-failure) or normal wear from drive age (old age)."), false, true);
// Doesn't carry that much info. Advanced users can look at the flags.
// model_columns.add(attribute_table_columns.updated);
@@ -2098,7 +2098,10 @@ void GscInfoWindow::cell_renderer_for_ata_attributes(Gtk::CellRenderer* cr,
crt->property_weight() = Pango::WEIGHT_BOLD;
}
if (column_index == columns_->ata_attribute_table_columns.type.index()) {
if (attribute.attr_type == AtaStorageAttribute::AttributeType::Prefail) {
// Bold only when attribute has failed AND it's pre-failure type
if ((attribute.when_failed == AtaStorageAttribute::FailTime::Past
|| attribute.when_failed == AtaStorageAttribute::FailTime::Now)
&& attribute.attr_type == AtaStorageAttribute::AttributeType::Prefail) {
crt->property_weight() = Pango::WEIGHT_BOLD;
} else { // reset to default value if reloading
crt->property_weight().reset_value();