demeter
Autonomous Hydroponic Intelligencegit clone https://github.com/maydayv7/demeter
agent/Sentinel/Encoders/TimeSeries.py (1985B)
1import numpy as np
2
3class SensorEncoder:
4 # 🔧 CONFIG: Define the maximum possible value for each sensor.
5 # We divide raw values by this to get a 0-1 range.
6 SCALERS = {
7 "pH": 14.0, # pH Scale is 0-14
8 "EC": 5.0, # EC rarely exceeds 3.0-4.0 in hydroponics
9 "temp": 50.0, # 50°C (122°F) is a safe max for plants
10 "humidity": 100.0 # 0-100%
11 }
12
13 def encode(self, sensor_data: dict) -> np.ndarray:
14 """
15 Encodes sensor data into a NORMALIZED vector for balanced search.
16
17 Example:
18 Input: {'humidity': 72.0}
19 Vector: [0.72] (Balanced for math)
20 Payload: {'humidity': 72.0} (Readable for humans)
21 """
22 features = []
23
24 # Sort keys to ensure vector consistency (EC, humidity, pH, temp)
25 for key in sorted(sensor_data.keys()):
26 raw_val = sensor_data[key]
27
28 # Determine the divisor (Default to 100.0 if unknown sensor)
29 max_val = self.SCALERS.get(key, 100.0)
30
31 if isinstance(raw_val, list) and raw_val:
32 # Handle Window (Mean, Std, Last)
33 arr = np.array(raw_val, dtype=float)
34
35 # Normalize each statistic
36 mean_norm = np.mean(arr) / max_val
37 std_norm = np.std(arr) / max_val
38 last_norm = arr[-1] / max_val
39
40 features.extend([mean_norm, std_norm, last_norm])
41
42 elif isinstance(raw_val, (int, float)):
43 # Handle Single Value
44 norm_val = float(raw_val) / max_val
45
46 # Clamp to ensure we never break the 0-1 scale (e.g. if temp is 55)
47 norm_val = max(0.0, min(1.0, norm_val))
48
49 features.append(norm_val)
50 else:
51 features.append(0.0)
52
53 return np.array(features, dtype=np.float32)