Track initial and current SMART attributes

Addresses issue #194
This commit is contained in:
2Shirt 2022-10-08 19:26:20 -07:00
parent 4465caa9fd
commit 7714b3436f
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C
2 changed files with 45 additions and 20 deletions

View file

@ -1,6 +1,7 @@
"""WizardKit: Disk object and functions"""
# vim: sts=2 sw=2 ts=2
import copy
import logging
import pathlib
import platform
@ -36,26 +37,27 @@ WK_LABEL_REGEX = re.compile(
class Disk:
# pylint: disable=too-many-instance-attributes
"""Object for tracking disk specific data."""
attributes: dict[Any, dict] = field(init=False, default_factory=dict)
bus: str = field(init=False)
children: list[dict] = field(init=False, default_factory=list)
description: str = field(init=False)
filesystem: str = field(init=False)
known_attributes: dict[Any, dict] = field(init=False, default_factory=dict)
log_sec: int = field(init=False)
model: str = field(init=False)
name: str = field(init=False)
notes: list[str] = field(init=False, default_factory=list)
attributes: dict[Any, dict] = field(init=False, default_factory=dict)
bus: str = field(init=False)
children: list[dict] = field(init=False, default_factory=list)
description: str = field(init=False)
filesystem: str = field(init=False)
initial_attributes: dict[Any, dict] = field(init=False)
known_attributes: dict[Any, dict] = field(init=False, default_factory=dict)
log_sec: int = field(init=False)
model: str = field(init=False)
name: str = field(init=False)
notes: list[str] = field(init=False, default_factory=list)
path: Union[pathlib.Path, str]
parent: str = field(init=False)
phy_sec: int = field(init=False)
raw_details: dict[str, Any] = field(init=False)
raw_smartctl: dict[str, Any] = field(init=False)
serial: str = field(init=False)
size: int = field(init=False)
ssd: bool = field(init=False)
tests: list[Test] = field(init=False, default_factory=list)
use_sat: bool = field(init=False, default=False)
parent: str = field(init=False)
phy_sec: int = field(init=False)
raw_details: dict[str, Any] = field(init=False)
raw_smartctl: dict[str, Any] = field(init=False)
serial: str = field(init=False)
size: int = field(init=False)
ssd: bool = field(init=False)
tests: list[Test] = field(init=False, default_factory=list)
use_sat: bool = field(init=False, default=False)
def __post_init__(self) -> None:
self.path = pathlib.Path(self.path).resolve()
@ -71,6 +73,7 @@ class Disk:
self.use_sat = True
enable_smart(self)
update_smart_details(self)
self.initial_attributes = copy.deepcopy(self.attributes)
if not self.is_4k_aligned():
self.add_note('One or more partitions are not 4K aligned', 'YELLOW')

View file

@ -158,7 +158,7 @@ def generate_attribute_report(dev) -> list[str]:
# Build colored string and append to report
line = color_string(
[label, value['raw_str'], note],
[label, get_attribute_value_string(dev, attr), note],
[None, value_color, 'YELLOW'],
)
report.append(line)
@ -167,6 +167,28 @@ def generate_attribute_report(dev) -> list[str]:
return report
def get_attribute_value_string(dev, attr) -> str:
"""Get attribute value string and report if it has changed."""
current_value = dev.attributes.get(attr, {})
initial_value = dev.initial_attributes.get(attr, {})
value_str = current_value.get('raw_str', '')
# Compare current value against initial value
if (
current_value.get('raw', None) is None
or initial_value.get('raw', None) is None
):
return value_str
if current_value['raw'] != initial_value['raw']:
value_str = (
f'{initial_value.get("raw_str", "?")} --> '
f'{current_value.get("raw_str", "?")}'
)
# Done
return value_str
def get_known_disk_attributes(model) -> None:
"""Get known disk attributes based on the device model."""
known_attributes = copy.deepcopy(KNOWN_DISK_ATTRIBUTES)