Better manufactuerer detection and values

This commit is contained in:
2025-09-03 13:14:43 -04:00
parent 4b68b0b525
commit 0ab728da47

View File

@ -116,6 +116,28 @@ class SystemHealthMonitor:
}
MANUFACTURER_SMART_PROFILES = {
'Western Digital': {
'aliases': ['WDC', 'Western Digital', 'HGST', 'Ultrastar'],
'attributes': {
'Raw_Read_Error_Rate': {
'monitor': False,
'description': 'WD drives use this as operation counter, not error count'
},
'Seek_Error_Rate': {
'monitor': False,
'description': 'WD drives use this as operation counter, not error count'
}
}
},
'Seagate': {
'aliases': ['Seagate', 'ST'],
'attributes': {
'Raw_Read_Error_Rate': {
'monitor': False,
'description': 'Seagate drives use this as operation counter'
}
}
},
'Ridata': {
'aliases': ['Ridata', 'Ritek', 'RIDATA', 'RITEK', 'SSD 512GB'],
'firmware_patterns': ['HT3618B7', 'HT36'],
@ -608,9 +630,9 @@ class SystemHealthMonitor:
# Drive-type specific temperature thresholds - ADJUSTED TO BE LESS SENSITIVE
if drive_type == 'SSD':
temp_thresholds = {'warning': 70, 'critical': 85, 'optimal_max': 65} # Raised from 60
temp_thresholds = {'warning': 70, 'critical': 85, 'optimal_max': 65}
else: # HDD
temp_thresholds = {'warning': 60, 'critical': 70, 'optimal_max': 55} # Raised from 45/55/65
temp_thresholds = {'warning': 60, 'critical': 70, 'optimal_max': 55}
if temperature >= temp_thresholds['critical']:
issues.append(f"CRITICAL: Drive temperature {temperature}°C exceeds safe operating limit for {drive_type}")
@ -1498,10 +1520,56 @@ class SystemHealthMonitor:
logger.debug(f"Could not parse SMART value: {raw_value}")
return 0
def _detect_manufacturer(self, model: str, serial: str = None) -> str:
"""Enhanced manufacturer detection based on model and serial patterns."""
if not model:
return 'Unknown'
model_upper = model.upper()
# Western Digital patterns (including HGST which WD acquired)
if any(pattern in model_upper for pattern in ['WDC', 'WD-', 'HGST', 'WESTERN DIGITAL']):
return 'Western Digital'
# Seagate patterns
elif any(pattern in model_upper for pattern in ['ST', 'SEAGATE']):
return 'Seagate'
# Samsung patterns
elif 'SAMSUNG' in model_upper:
return 'Samsung'
# Intel patterns
elif any(pattern in model_upper for pattern in ['INTEL', 'SSDSC']):
return 'Intel'
# Micron/Crucial patterns
elif any(pattern in model_upper for pattern in ['CRUCIAL', 'MICRON', 'CT']):
return 'Micron'
# Toshiba patterns
elif 'TOSHIBA' in model_upper:
return 'Toshiba'
# Ridata/Ritek patterns (for your existing special handling)
elif any(pattern in model_upper for pattern in ['RIDATA', 'RITEK']):
return 'Ridata'
# OOS patterns (for your existing special handling)
elif 'OOS' in model_upper:
return 'OOS'
return 'Unknown'
def _get_manufacturer_profile(self, model: str, manufacturer: str = None, firmware: str = None) -> Dict[str, Any]:
"""Get manufacturer-specific SMART profile based on drive model/manufacturer/firmware."""
logger.debug(f"Looking for profile - Model: '{model}', Manufacturer: '{manufacturer}', Firmware: '{firmware}'")
# First, try to detect manufacturer if not provided
if not manufacturer:
manufacturer = self._detect_manufacturer(model)
logger.debug(f"Auto-detected manufacturer: {manufacturer}")
# Check each manufacturer profile
for mfg, profile in self.MANUFACTURER_SMART_PROFILES.items():
# Check firmware patterns first (most specific for OEM drives like RiData)
@ -1511,14 +1579,19 @@ class SystemHealthMonitor:
logger.debug(f"Matched manufacturer profile: {mfg} for firmware pattern '{pattern}' in '{firmware}'")
return profile
# Check model/manufacturer aliases
# Check if detected manufacturer matches this profile
if manufacturer and manufacturer in profile['aliases']:
logger.debug(f"Matched manufacturer profile: {mfg} for detected manufacturer '{manufacturer}'")
return profile
# Check model/manufacturer aliases (fallback)
for alias in profile['aliases']:
if alias.lower() in model.lower() or (manufacturer and alias.lower() in manufacturer.lower()):
logger.debug(f"Matched manufacturer profile: {mfg} for model alias '{alias}' in '{model}'")
return profile
# Return generic profile if no match
logger.debug(f"No specific profile found for Model: '{model}', Firmware: '{firmware}', using Generic profile")
logger.debug(f"No specific profile found for Model: '{model}', Manufacturer: '{manufacturer}', Firmware: '{firmware}', using Generic profile")
return self.MANUFACTURER_SMART_PROFILES['Generic']
def _should_monitor_attribute(self, attr_name: str, manufacturer_profile: dict) -> bool: