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)