demeter

Autonomous Hydroponic Intelligence

TimeSeries.py (1985B)


import numpy as np

class SensorEncoder:
    # 🔧 CONFIG: Define the maximum possible value for each sensor.
    # We divide raw values by this to get a 0-1 range.
    SCALERS = {
        "pH": 14.0,       # pH Scale is 0-14
        "EC": 5.0,        # EC rarely exceeds 3.0-4.0 in hydroponics
        "temp": 50.0,     # 50°C (122°F) is a safe max for plants
        "humidity": 100.0 # 0-100%
    }

    def encode(self, sensor_data: dict) -> np.ndarray:
        """
        Encodes sensor data into a NORMALIZED vector for balanced search.
        
        Example: 
          Input:  {'humidity': 72.0}
          Vector: [0.72] (Balanced for math)
          Payload: {'humidity': 72.0} (Readable for humans)
        """
        features = []
        
        # Sort keys to ensure vector consistency (EC, humidity, pH, temp)
        for key in sorted(sensor_data.keys()):
            raw_val = sensor_data[key]
            
            # Determine the divisor (Default to 100.0 if unknown sensor)
            max_val = self.SCALERS.get(key, 100.0)

            if isinstance(raw_val, list) and raw_val:
                # Handle Window (Mean, Std, Last)
                arr = np.array(raw_val, dtype=float)
                
                # Normalize each statistic
                mean_norm = np.mean(arr) / max_val
                std_norm = np.std(arr) / max_val
                last_norm = arr[-1] / max_val
                
                features.extend([mean_norm, std_norm, last_norm])

            elif isinstance(raw_val, (int, float)):
                # Handle Single Value
                norm_val = float(raw_val) / max_val
                
                # Clamp to ensure we never break the 0-1 scale (e.g. if temp is 55)
                norm_val = max(0.0, min(1.0, norm_val))
                
                features.append(norm_val)
            else:
                features.append(0.0)
                
        return np.array(features, dtype=np.float32)