UPDATE
This commit is contained in:
@@ -6,7 +6,7 @@ from statistics import mean
|
||||
from typing import Any
|
||||
|
||||
from django.apps import apps
|
||||
from location_data.satellite_snapshot import build_location_satellite_snapshot
|
||||
from farm_data.services import get_ai_snapshot_metric
|
||||
|
||||
from crop_simulation.services import CropSimulationService
|
||||
|
||||
@@ -47,20 +47,9 @@ def _first_not_none(*values: Any) -> Any:
|
||||
return None
|
||||
|
||||
|
||||
def _sensor_metric(sensor: Any, metric: str) -> float | None:
|
||||
if sensor is None:
|
||||
return None
|
||||
if hasattr(sensor, metric):
|
||||
value = getattr(sensor, metric)
|
||||
return _safe_float(value, default=0.0) if value is not None else None
|
||||
|
||||
payload = getattr(sensor, "sensor_payload", None) or {}
|
||||
if not isinstance(payload, dict):
|
||||
return None
|
||||
for block in payload.values():
|
||||
if isinstance(block, dict) and block.get(metric) is not None:
|
||||
return _safe_float(block.get(metric), default=0.0)
|
||||
return None
|
||||
def _aggregated_metric(ai_snapshot: dict[str, Any] | None, metric: str) -> float | None:
|
||||
value = get_ai_snapshot_metric(ai_snapshot, metric)
|
||||
return _safe_float(value, default=0.0) if value is not None else None
|
||||
|
||||
|
||||
def _parse_temperature_range(plant: Any) -> tuple[float, float]:
|
||||
@@ -140,15 +129,9 @@ def _build_weather_records(forecasts: list[Any], *, latitude: float, longitude:
|
||||
return records
|
||||
|
||||
|
||||
def _build_soil_parameters(sensor: Any) -> tuple[dict[str, Any], dict[str, Any]]:
|
||||
moisture_pct = _sensor_metric(sensor, "soil_moisture")
|
||||
center_location = getattr(sensor, "center_location", None)
|
||||
satellite_metrics = (
|
||||
build_location_satellite_snapshot(center_location).get("resolved_metrics") or {}
|
||||
if center_location is not None
|
||||
else {}
|
||||
)
|
||||
ndwi = _safe_float(satellite_metrics.get("ndwi"), 0.34)
|
||||
def _build_soil_parameters(sensor: Any, ai_snapshot: dict[str, Any] | None = None) -> tuple[dict[str, Any], dict[str, Any]]:
|
||||
moisture_pct = _aggregated_metric(ai_snapshot, "soil_moisture")
|
||||
ndwi = _safe_float(_aggregated_metric(ai_snapshot, "ndwi"), 0.34)
|
||||
wv0033 = ndwi if ndwi > 0 else 0.34
|
||||
wv1500 = max(round(wv0033 * 0.45, 3), 0.14)
|
||||
|
||||
@@ -288,6 +271,7 @@ class SimulationRecommendationOptimizer:
|
||||
daily_water_needs: list[dict[str, Any]],
|
||||
growth_stage: str | None,
|
||||
irrigation_method: Any | None,
|
||||
ai_snapshot: dict[str, Any] | None = None,
|
||||
) -> dict[str, Any] | None:
|
||||
if sensor is None or plant is None or not forecasts:
|
||||
return None
|
||||
@@ -301,6 +285,7 @@ class SimulationRecommendationOptimizer:
|
||||
daily_water_needs=daily_water_needs,
|
||||
growth_stage=growth_stage,
|
||||
crop_blueprint=crop_blueprint,
|
||||
ai_snapshot=ai_snapshot,
|
||||
)
|
||||
if pcse_result is not None:
|
||||
return pcse_result
|
||||
@@ -312,6 +297,7 @@ class SimulationRecommendationOptimizer:
|
||||
daily_water_needs=daily_water_needs,
|
||||
growth_stage=growth_stage,
|
||||
irrigation_method=irrigation_method,
|
||||
ai_snapshot=ai_snapshot,
|
||||
)
|
||||
|
||||
def optimize_fertilization(
|
||||
@@ -321,6 +307,7 @@ class SimulationRecommendationOptimizer:
|
||||
plant: Any,
|
||||
forecasts: list[Any],
|
||||
growth_stage: str | None,
|
||||
ai_snapshot: dict[str, Any] | None = None,
|
||||
) -> dict[str, Any] | None:
|
||||
if sensor is None or plant is None:
|
||||
return None
|
||||
@@ -333,6 +320,7 @@ class SimulationRecommendationOptimizer:
|
||||
forecasts=forecasts,
|
||||
growth_stage=growth_stage,
|
||||
crop_blueprint=crop_blueprint,
|
||||
ai_snapshot=ai_snapshot,
|
||||
)
|
||||
if pcse_result is not None:
|
||||
return pcse_result
|
||||
@@ -342,6 +330,7 @@ class SimulationRecommendationOptimizer:
|
||||
plant=plant,
|
||||
forecasts=forecasts,
|
||||
growth_stage=growth_stage,
|
||||
ai_snapshot=ai_snapshot,
|
||||
)
|
||||
|
||||
def _optimize_irrigation_with_pcse(
|
||||
@@ -353,10 +342,11 @@ class SimulationRecommendationOptimizer:
|
||||
daily_water_needs: list[dict[str, Any]],
|
||||
growth_stage: str | None,
|
||||
crop_blueprint: tuple[dict[str, Any], list[dict[str, Any]]],
|
||||
ai_snapshot: dict[str, Any] | None = None,
|
||||
) -> dict[str, Any] | None:
|
||||
defaults = apps.get_app_config("irrigation").get_optimizer_defaults()
|
||||
crop_parameters, agromanagement = crop_blueprint
|
||||
soil, site = _build_soil_parameters(sensor)
|
||||
soil, site = _build_soil_parameters(sensor, ai_snapshot=ai_snapshot)
|
||||
weather = _build_weather_records(
|
||||
forecasts,
|
||||
latitude=_safe_float(sensor.center_location.latitude),
|
||||
@@ -572,10 +562,11 @@ class SimulationRecommendationOptimizer:
|
||||
forecasts: list[Any],
|
||||
growth_stage: str | None,
|
||||
crop_blueprint: tuple[dict[str, Any], list[dict[str, Any]]],
|
||||
ai_snapshot: dict[str, Any] | None = None,
|
||||
) -> dict[str, Any] | None:
|
||||
defaults = apps.get_app_config("fertilization").get_optimizer_defaults()
|
||||
crop_parameters, agromanagement = crop_blueprint
|
||||
soil, site = _build_soil_parameters(sensor)
|
||||
soil, site = _build_soil_parameters(sensor, ai_snapshot=ai_snapshot)
|
||||
weather = _build_weather_records(
|
||||
forecasts,
|
||||
latitude=_safe_float(sensor.center_location.latitude),
|
||||
|
||||
Reference in New Issue
Block a user