idea170-agrimesh-federated-.../src/idea170_agrimesh_federated_.../canonical.py

45 lines
1.9 KiB
Python

from __future__ import annotations
from .models import CatOptConstraint, CatOptProblem, CatOptVariable, LocalProblem, PlanDelta, RegionalConstraint
class AgriMeshCanonicalMapper:
def to_catopt(self, local_problem: LocalProblem, regional_constraint: RegionalConstraint) -> CatOptProblem:
need = max(local_problem.target_soil_moisture_pct - local_problem.current_soil_moisture_pct, 0.0)
return CatOptProblem(
problem_id=f"{local_problem.farm_id}:{regional_constraint.regional_water_quota_id}",
variables=[
CatOptVariable(
name="irrigation_liters",
lower=0.0,
upper=local_problem.irrigation_budget_liters,
target=min(local_problem.irrigation_budget_liters, need * local_problem.plot_area_hectares * 10.0),
)
],
constraints=[
CatOptConstraint(
name="water_quota",
expression=f"irrigation_liters <= {regional_constraint.water_quota_liters}",
),
CatOptConstraint(
name="energy_cap",
expression=f"energy_kwh <= {regional_constraint.energy_cap_kwh}",
),
],
objective="minimize squared deviation from target soil moisture",
metadata={
"farm_id": local_problem.farm_id,
"drought_target_moisture_pct": regional_constraint.drought_target_moisture_pct,
"plot_area_hectares": local_problem.plot_area_hectares,
},
)
def from_plan_delta(self, delta: PlanDelta) -> dict[str, float | str]:
return {
"farm_id": delta.farm_id,
"irrigation_liters": delta.irrigation_liters,
"fertilizer_kg": delta.fertilizer_kg,
"energy_kwh": delta.energy_kwh,
"tag": delta.tag,
}