Better manufactuerer detection and values
This commit is contained in:
@ -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:
|
||||
|
||||
Reference in New Issue
Block a user