Files
Ai/location_data/ndvi.py
T
2026-04-25 17:22:41 +03:30

93 lines
3.2 KiB
Python

from __future__ import annotations
from typing import Any
from farm_data.models import SensorData
from .remote_sensing import fetch_or_get_ndvi_observation
def _ndvi_explanation(observation, ai_bundle: dict | None = None) -> str:
ai_bundle = ai_bundle or {}
ai_payload = ai_bundle.get("ndviHealthCard", {}) if isinstance(ai_bundle, dict) else {}
explanation = ai_payload.get("explanation")
if isinstance(explanation, str) and explanation.strip():
return explanation.strip()
return (
f"میانگین NDVI مزرعه {observation.mean_ndvi} ثبت شده و کلاس سلامت پوشش گیاهی "
f"در وضعیت {observation.vegetation_health_class} قرار دارد."
)
def _build_ndvi_health_card(location: Any, ai_bundle: dict | None = None) -> dict[str, Any]:
if location is None:
return {
"mean_ndvi": None,
"ndvi_map": {},
"vegetation_health_class": None,
"observation_date": None,
"satellite_source": None,
"healthData": [],
}
observation = fetch_or_get_ndvi_observation(location)
if observation is None:
return {
"mean_ndvi": None,
"ndvi_map": {},
"vegetation_health_class": "Unavailable",
"observation_date": None,
"satellite_source": None,
"healthData": [
{
"title": "وضعیت NDVI",
"value": "داده ماهواره‌ای موجود نیست",
"color": "warning",
"icon": "tabler-satellite-off",
},
],
}
mean_value = round(observation.mean_ndvi, 2)
vegetation_class = observation.vegetation_health_class
return {
"ndviIndex": mean_value,
"mean_ndvi": mean_value,
"ndvi_map": observation.ndvi_map,
"vegetation_health_class": vegetation_class,
"observation_date": observation.observation_date.isoformat(),
"satellite_source": observation.satellite_source,
"healthData": [
{
"title": "سلامت پوشش گیاهی",
"value": vegetation_class,
"color": "success" if mean_value > 0.6 else "warning" if mean_value >= 0.4 else "error",
"icon": "tabler-plant",
},
{
"title": "تاریخ مشاهده",
"value": observation.observation_date.isoformat(),
"color": "info",
"icon": "tabler-calendar",
},
{
"title": "تفسیر",
"value": _ndvi_explanation(observation, ai_bundle=ai_bundle),
"color": "primary",
"icon": "tabler-message-2",
},
],
}
class NdviHealthService:
def get_ndvi_health(self, *, farm_uuid: str) -> dict[str, Any]:
sensor = (
SensorData.objects.select_related("center_location")
.filter(farm_uuid=farm_uuid)
.first()
)
if sensor is None:
raise ValueError("Farm not found.")
return _build_ndvi_health_card(sensor.center_location, ai_bundle=None)