This commit is contained in:
2026-04-25 17:22:41 +03:30
parent 569d520a5c
commit aa24fc22b0
124 changed files with 8491 additions and 2582 deletions
+177 -1
View File
@@ -1,5 +1,7 @@
from __future__ import annotations
from django.apps import apps
from drf_spectacular.utils import OpenApiExample, extend_schema
from rest_framework import status
from rest_framework.response import Response
@@ -13,9 +15,15 @@ from config.openapi import (
from .growth_simulation import MAX_PAGE_SIZE, paginate_growth_stages
from .serializers import (
CurrentFarmChartRequestSerializer,
CurrentFarmChartResponseSerializer,
GrowthSimulationQueuedSerializer,
GrowthSimulationRequestSerializer,
GrowthSimulationResultSerializer,
HarvestPredictionRequestSerializer,
HarvestPredictionResponseSerializer,
YieldPredictionRequestSerializer,
YieldPredictionResponseSerializer,
)
from .tasks import run_growth_simulation_task
@@ -99,7 +107,7 @@ class PlantGrowthSimulationView(APIView):
value={
"plant_name": "گوجه‌فرنگی",
"dynamic_parameters": ["DVS", "LAI", "TAGP"],
"farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
"farm_uuid": "11111111-1111-1111-1111-111111111111",
},
request_only=True,
),
@@ -173,3 +181,171 @@ class PlantGrowthSimulationStatusView(APIView):
{"code": 200, "msg": "success", "data": payload},
status=status.HTTP_200_OK,
)
CurrentFarmChartEnvelopeSerializer = build_envelope_serializer(
"CurrentFarmChartEnvelopeSerializer",
CurrentFarmChartResponseSerializer,
)
HarvestPredictionEnvelopeSerializer = build_envelope_serializer(
"HarvestPredictionEnvelopeSerializer",
HarvestPredictionResponseSerializer,
)
YieldPredictionEnvelopeSerializer = build_envelope_serializer(
"YieldPredictionEnvelopeSerializer",
YieldPredictionResponseSerializer,
)
class CurrentFarmSimulationChartView(APIView):
@extend_schema(
tags=["Crop Simulation"],
summary="chart شبیه سازی وضعیت فعلی مزرعه",
description=(
"با دریافت farm_uuid، یک شبیه سازی از وضعیت فعلی مزرعه اجرا می کند و داده chart شامل برگ، وزن، بیوماس، رطوبت و خروجی روزانه را برمی گرداند."
),
request=CurrentFarmChartRequestSerializer,
responses={
200: build_response(
CurrentFarmChartEnvelopeSerializer,
"خروجی chart شبیه سازی وضعیت فعلی مزرعه.",
),
400: build_response(
GrowthSimulationErrorSerializer,
"داده ورودی نامعتبر است.",
),
500: build_response(
GrowthSimulationErrorSerializer,
"خطا در اجرای chart شبیه سازی مزرعه.",
),
},
examples=[
OpenApiExample(
"نمونه درخواست chart",
value={
"farm_uuid": "11111111-1111-1111-1111-111111111111",
"plant_name": "گوجه‌فرنگی",
},
request_only=True,
),
],
)
def post(self, request):
serializer = CurrentFarmChartRequestSerializer(data=request.data)
if not serializer.is_valid():
return Response(
{"code": 400, "msg": "داده نامعتبر.", "data": serializer.errors},
status=status.HTTP_400_BAD_REQUEST,
)
simulator = apps.get_app_config("crop_simulation").get_current_farm_chart_simulator()
try:
result = simulator.simulate(**serializer.validated_data)
except Exception as exc:
return Response(
{"code": 500, "msg": f"خطا در اجرای chart شبیه سازی مزرعه: {exc}", "data": None},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
)
return Response(
{"code": 200, "msg": "success", "data": result},
status=status.HTTP_200_OK,
)
class HarvestPredictionView(APIView):
@extend_schema(
tags=["Crop Simulation"],
summary="پیش بینی زمان تقریبی برداشت",
description=(
"با دریافت farm_uuid، از شبیه ساز رشد برای برآورد زمان باقی مانده تا برداشت استفاده می کند "
"و تاریخ تقریبی برداشت را برمی گرداند."
),
request=HarvestPredictionRequestSerializer,
responses={
200: build_response(
HarvestPredictionEnvelopeSerializer,
"خروجی پیش بینی زمان برداشت مزرعه.",
),
400: build_response(
GrowthSimulationErrorSerializer,
"داده ورودی نامعتبر است.",
),
500: build_response(
GrowthSimulationErrorSerializer,
"خطا در پیش بینی زمان برداشت.",
),
},
examples=[
OpenApiExample(
"نمونه درخواست harvest prediction",
value={
"farm_uuid": "11111111-1111-1111-1111-111111111111",
"plant_name": "گوجه‌فرنگی",
},
request_only=True,
),
],
)
def post(self, request):
serializer = HarvestPredictionRequestSerializer(data=request.data)
if not serializer.is_valid():
return Response(
{"code": 400, "msg": "داده نامعتبر.", "data": serializer.errors},
status=status.HTTP_400_BAD_REQUEST,
)
service = apps.get_app_config("crop_simulation").get_harvest_prediction_service()
try:
result = service.get_harvest_prediction(**serializer.validated_data)
except Exception as exc:
return Response(
{"code": 500, "msg": f"خطا در پیش بینی زمان برداشت: {exc}", "data": None},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
)
return Response(
{"code": 200, "msg": "success", "data": result},
status=status.HTTP_200_OK,
)
class YieldPredictionView(APIView):
@extend_schema(
tags=["Crop Simulation"],
summary="پیش بینی عملکرد مزرعه",
description="با دریافت farm_uuid، خروجی شبیه ساز رشد را به برآورد عملکرد قابل استفاده در KPI تبدیل می کند.",
request=YieldPredictionRequestSerializer,
responses={
200: build_response(YieldPredictionEnvelopeSerializer, "خروجی پیش بینی عملکرد مزرعه."),
400: build_response(GrowthSimulationErrorSerializer, "داده ورودی نامعتبر است."),
500: build_response(GrowthSimulationErrorSerializer, "خطا در پیش بینی عملکرد."),
},
examples=[
OpenApiExample(
"نمونه درخواست yield prediction",
value={
"farm_uuid": "11111111-1111-1111-1111-111111111111",
"plant_name": "گوجه‌فرنگی",
},
request_only=True,
),
],
)
def post(self, request):
serializer = YieldPredictionRequestSerializer(data=request.data)
if not serializer.is_valid():
return Response(
{"code": 400, "msg": "داده نامعتبر.", "data": serializer.errors},
status=status.HTTP_400_BAD_REQUEST,
)
service = apps.get_app_config("crop_simulation").get_yield_prediction_service()
try:
result = service.get_yield_prediction(**serializer.validated_data)
except Exception as exc:
return Response(
{"code": 500, "msg": f"خطا در پیش بینی عملکرد: {exc}", "data": None},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
)
return Response({"code": 200, "msg": "success", "data": result}, status=status.HTTP_200_OK)