"""KFS Smart Farm — configuration. Every value can be overridden with an environment variable.""" import os from pathlib import Path BASE_DIR = Path(__file__).resolve().parent def env(name, default): return os.environ.get(name, default) SECRET_KEY = env("SF_SECRET_KEY", "change-me-in-production") # Flask session signing NODE_API_KEY = env("SF_NODE_API_KEY", "kfs-farm-node-key") # sent by the ESP32 nodes in X-API-Key ADMIN_USER = env("SF_ADMIN_USER", "admin") ADMIN_PASSWORD = env("SF_ADMIN_PASSWORD", "kfs-farm-2026") # change before the field deployment! DB_PATH = Path(env("SF_DB_PATH", str(BASE_DIR / "farm.db"))) MODEL_PATH = Path(env("SF_MODEL_PATH", str(BASE_DIR.parent / "ai" / "outputs" / "irrigation_model.joblib"))) # Farm location (Faculty of Agriculture — Kafr El-Sheikh University) FARM_LAT = float(env("SF_FARM_LAT", "31.1047")) FARM_LON = float(env("SF_FARM_LON", "30.9436")) # Decision threshold for the irrigation model (session 16: chosen with the agronomist from the FN/FP costs) IRRIGATION_THRESHOLD = float(env("SF_IRRIGATION_THRESHOLD", "0.4")) # Capacitive sensor calibration: soil_moisture_pct (0 % = dry, 100 % = water) -> volumetric water content VWC_AT_0_PCT = float(env("SF_VWC_AT_0", "0.15")) VWC_AT_100_PCT = float(env("SF_VWC_AT_100", "0.45")) # Alert rules (session 18) SOIL_DRY_PCT = float(env("SF_SOIL_DRY_PCT", "30")) # irrigate below this SOIL_WET_PCT = float(env("SF_SOIL_WET_PCT", "75")) # never irrigate above this AIR_HOT_C = float(env("SF_AIR_HOT_C", "38")) # heat stress alert GREENHOUSE_HUMID_PCT = float(env("SF_GH_HUMID_PCT", "90")) # fungal disease risk -> turn the fan on NODE_OFFLINE_MIN = int(env("SF_NODE_OFFLINE_MIN", "15")) BATTERY_LOW_V = float(env("SF_BATTERY_LOW_V", "3.5")) PUMP_MAX_MIN = int(env("SF_PUMP_MAX_MIN", "30")) # safety: maximum pump run time # Notifications (optional) TELEGRAM_TOKEN = env("SF_TELEGRAM_TOKEN", "") TELEGRAM_CHAT_ID = env("SF_TELEGRAM_CHAT_ID", "")