
# ============================================================================
# ELECTRIC FIELD SENSOR CALIBRATION - FINAL CORRECTED VERSION
# Snow Dust Project - Phase 2.5
# Generated: 2026-01-30
# ============================================================================

class SensorCalibration:
    """Complete sensor calibration system"""
    
    # ================= CURRENT OFFSET CORRECTIONS =================
    # Measured at 20°C, reference current = 10.00 mA
    # Apply to POWER MEASUREMENTS only
    CURRENT_OFFSETS = {
        1: -0.960,   # mA (add this to measured current)
        2: -0.680,
        3: -0.520,
        4: +0.700,
    }
    
    # ================= FIELD GAIN CORRECTIONS =====================
    # Measured at known 1000 V/m field
    # Apply to FIELD MEASUREMENTS only
    FIELD_FACTORS = {
        1: 1.0981,   # Multiply measured field by this
        2: 1.0650,
        3: 1.0510,
        4: 0.9280,
    }
    
    # ================= TEMPERATURE COMPENSATION ===================
    # Temperature coefficient: 0.10 %/°C for all sensors
    TEMP_COEFFICIENT = 0.0010  # per °C (0.10%/°C)
    
    @staticmethod
    def calibrate_current(sensor_id, measured_current, temperature=20.0):
        """Calibrate current measurement with offset and temperature"""
        # 1. Apply offset correction
        offset = SensorCalibration.CURRENT_OFFSETS.get(sensor_id, 0.0)
        calibrated = measured_current + offset
        
        # 2. Apply temperature compensation if not at 20°C
        if temperature != 20.0:
            temp_correction = 1.0 + (SensorCalibration.TEMP_COEFFICIENT * (temperature - 20.0))
            calibrated *= temp_correction
        
        return calibrated
    
    @staticmethod
    def calibrate_field(sensor_id, measured_field, temperature=20.0):
        """Calibrate field measurement with gain and temperature"""
        # 1. Apply field gain correction
        factor = SensorCalibration.FIELD_FACTORS.get(sensor_id, 1.0)
        calibrated = measured_field * factor
        
        # 2. Apply temperature compensation
        if temperature != 20.0:
            # Field sensors typically have negative TC
            field_temp_correction = 1.0 - (0.0005 * (temperature - 20.0))
            calibrated *= field_temp_correction
        
        return calibrated
    
    @staticmethod
    def calibrate_all(sensor_id, measured_current, measured_field, temperature=20.0):
        """Complete calibration of both current and field"""
        cal_current = SensorCalibration.calibrate_current(sensor_id, measured_current, temperature)
        cal_field = SensorCalibration.calibrate_field(sensor_id, measured_field, temperature)
        
        return {
            'calibrated_current': cal_current,
            'calibrated_field': cal_field,
            'sensor_id': sensor_id,
            'temperature': temperature,
            'calibration_applied': True
        }

# ============================================================================
# EEPROM CONFIGURATION FOR EMBEDDED SYSTEM
# ============================================================================

# EEPROM address map
EEPROM_CONFIG = {
    'CURRENT_OFFSETS_START': 0x00,   # 16 bytes (4 floats)
    'FIELD_FACTORS_START':   0x10,   # 16 bytes (4 floats)
    'CALIBRATION_DATE':      0x20,   # 8 bytes (timestamp)
    'SERIAL_NUMBERS':        0x28,   # 16 bytes (4 ints)
}

def load_calibration_from_eeprom():
    """Load calibration parameters from EEPROM at boot"""
    import machine  # For MicroPython
    import ustruct
    
    i2c = machine.I2C(0, scl=machine.Pin(22), sda=machine.Pin(21))
    
    # Read current offsets
    i2c.writeto(0x50, bytes([EEPROM_CONFIG['CURRENT_OFFSETS_START']]))
    data = i2c.readfrom(0x50, 16)
    current_offsets = ustruct.unpack('4f', data)
    
    # Read field factors
    i2c.writeto(0x50, bytes([EEPROM_CONFIG['FIELD_FACTORS_START']]))
    data = i2c.readfrom(0x50, 16)
    field_factors = ustruct.unpack('4f', data)
    
    return current_offsets, field_factors

