Files
snapraid_smart_logging/test_backblaze_calc.py
T
WesandClaude Sonnet 4.5 27afedb32e Complete rewrite: SnapRAID SMART logger with BackBlaze algorithm
Fetches SMART data from Scrutiny's InfluxDB and calculates failure
probabilities using the exact BackBlaze tables from SnapRAID source.

Key features:
- Calculates both v12 (with attr 193) and v13 (without attr 193) algorithms
- v12 matches SnapRAID pre-v13.0 (includes Load Cycle Count)
- v13 matches modern SnapRAID v13.0+ (excludes Load Cycle Count)
- Stores both values for trending and comparison
- Correctly applies bit masks (16-bit for 187/188, 32-bit for others)
- Annualizes monthly rates and applies Poisson distribution
- Logs to PostgreSQL with device metadata

Solved the mystery: SnapRAID v12 uses attribute 193 which was removed
in v13.0. Load cycle count has massive impact on failure predictions
for some drives (80% vs 4% difference).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-07 06:55:39 -05:00

45 lines
1.5 KiB
Python

#!/usr/bin/env python3
"""Test BackBlaze calculation with different values"""
import math
from backblaze_tables import SMART_5_R, SMART_187_R, SMART_188_R, SMART_197_R, SMART_198_R
def poisson_prob(rate):
"""Calculate P(at least 1 failure) = 1 - e^(-rate)"""
return 1 - math.exp(-rate)
def test_calculation(attr_value):
"""Test with a given attribute value"""
# Scale monthly to annual (like snapraid does)
afr_5 = (365.0 / 30.0) * SMART_5_R[min(attr_value, 255)]
afr_187 = (365.0 / 30.0) * SMART_187_R[min(attr_value, 255)]
afr_188 = (365.0 / 30.0) * SMART_188_R[min(attr_value, 255)]
afr_197 = (365.0 / 30.0) * SMART_197_R[min(attr_value, 255)]
afr_198 = (365.0 / 30.0) * SMART_198_R[min(attr_value, 255)]
# Take maximum (like snapraid)
max_afr = max(afr_5, afr_187, afr_188, afr_197, afr_198)
# Apply Poisson
prob = poisson_prob(max_afr) * 100
return max_afr, prob
print("Testing different attribute values:")
print("=" * 80)
for test_val in [0, 50, 100, 150, 200, 255]:
afr, prob = test_calculation(test_val)
print(f"Attribute value {test_val:3d}: AFR={afr:.4f}, Probability={prob:.2f}%")
print("\n" + "=" * 80)
print("What we're seeing from /dev/sdc:")
print(" All critical attributes: RAW_VALUE=0, VALUE=100")
print(" SnapRAID reports: 81%")
print(" Our calculation with value=0: ", end="")
afr0, prob0 = test_calculation(0)
print(f"{prob0:.2f}%")
print(" Our calculation with value=100:", end="")
afr100, prob100 = test_calculation(100)
print(f"{prob100:.2f}%")