22 KiB
مستندات کامل API های farm_hub
این فایل بر اساس پیادهسازی واقعی اپ farm_hub در فایلهای farm_hub/urls.py, farm_hub/views.py, farm_hub/serializers.py, farm_hub/models.py و farm_hub/services.py تهیه شده است.
نکته مهم: فایل farm_hub/apps.py فقط برای ثبت Django app استفاده میشود و خودِ APIها داخل آن تعریف نشدهاند. APIهای این ماژول در farm_hub/urls.py و farm_hub/views.py قرار دارند.
مشخصات کلی
- Base path:
/api/farm-hub/
- احراز هویت:
تمام endpointهای این ماژول نیاز به کاربر لاگینشده دارند.
Authorization: Bearer <token>
- فرمت کلی پاسخ موفق:
{
"code": 200,
"msg": "success",
"data": {}
}
- فرمت کلی پاسخ خطا:
{
"code": 404,
"msg": "Farm not found."
}
یا در خطاهای validation:
{
"field_name": [
"error message"
]
}
لیست endpointها
| Method | URL | توضیح |
|---|---|---|
| GET | /api/farm-hub/ |
دریافت لیست مزارع کاربر جاری |
| POST | /api/farm-hub/ |
ساخت مزرعه جدید |
| GET | /api/farm-hub/farm-types/ |
دریافت لیست نوع مزرعهها |
| GET | /api/farm-hub/farm-types/{farm_type_uuid}/products/ |
دریافت محصولات مربوط به یک نوع مزرعه |
| GET | /api/farm-hub/{farm_uuid}/ |
دریافت جزئیات یک مزرعه |
| PATCH | /api/farm-hub/{farm_uuid}/ |
ویرایش مزرعه |
| DELETE | /api/farm-hub/{farm_uuid}/ |
حذف مزرعه |
| POST | /api/farm-hub/active/ |
فعالکردن مزرعه |
| POST | /api/farm-hub/deactive/ |
غیرفعالکردن مزرعه |
1) دریافت لیست مزارع
Request
GET /api/farm-hub/
Authorization: Bearer <token>
رفتار
- فقط مزارع متعلق به کاربر جاری برگردانده میشوند.
- برای هر مزرعه، اطلاعات
farm_type، لیستproducts، لیستsensorsوarea_uuidبرگردانده میشود.
Response 200
{
"code": 200,
"msg": "success",
"data": [
{
"farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
"area_uuid": "0c7dfd7f-94bf-46f3-b2f9-30a89f0a1111",
"name": "مزرعه شماره 1",
"is_active": true,
"farm_type": {
"uuid": "11111111-1111-1111-1111-111111111111",
"name": "زراعی",
"description": "",
"metadata": {}
},
"products": [
{
"uuid": "22222222-2222-2222-2222-222222222222",
"name": "گندم",
"description": "",
"metadata": {},
"light": "",
"watering": "",
"soil": "",
"temperature": "",
"planting_season": "پاییز",
"harvest_time": "بهار",
"spacing": "",
"fertilizer": "",
"health_profile": {
"moisture": {
"ideal_value": 65
}
},
"irrigation_profile": {},
"growth_profile": {}
}
],
"sensors": [
{
"uuid": "33333333-3333-3333-3333-333333333333",
"sensor_catalog_uuid": "44444444-4444-4444-4444-444444444444",
"physical_device_uuid": "55555555-5555-5555-5555-555555555555",
"name": "Station 1",
"sensor_type": "weather_station",
"is_active": true,
"specifications": {
"model": "FH-1"
},
"power_source": {
"type": "battery"
},
"last_updated": "2025-02-18T12:00:00Z"
}
],
"last_updated": "2025-02-18T12:00:00Z"
}
]
}
2) ساخت مزرعه جدید
Request
POST /api/farm-hub/
Authorization: Bearer <token>
Content-Type: application/json
Body
{
"name": "مزرعه شماره 1",
"is_active": true,
"farm_type_uuid": "11111111-1111-1111-1111-111111111111",
"product_uuids": [
"22222222-2222-2222-2222-222222222222"
],
"sensors": [
{
"sensor_catalog_uuid": "44444444-4444-4444-4444-444444444444",
"physical_device_uuid": "55555555-5555-5555-5555-555555555555",
"name": "Station 1",
"sensor_type": "weather_station",
"is_active": true,
"specifications": {
"model": "FH-1"
},
"power_source": {
"type": "battery"
}
}
],
"farm_boundary": {
"corners": [
{"lat": 35.70, "lon": 51.39},
{"lat": 35.70, "lon": 51.41},
{"lat": 35.72, "lon": 51.41},
{"lat": 35.72, "lon": 51.39}
]
},
"sensor_key": "sensor-7-1",
"sensor_payload": {
"soil_moisture": 45.2,
"soil_temperature": 22.5
},
"irrigation_method_id": 3
}
برای farm_boundary هر دو فرم زیر پشتیبانی میشوند:
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[51.418934, 35.706815],
[51.423054, 35.691062],
[51.384258, 35.689389],
[51.418934, 35.706815]
]
]
}
}
فیلدهای ورودی
| فیلد | نوع | اجباری | توضیح |
|---|---|---|---|
name |
string | بله | نام مزرعه |
is_active |
boolean | خیر | وضعیت فعال بودن مزرعه؛ پیشفرض مدل true است |
farm_type_uuid |
uuid | بله | UUID نوع مزرعه |
product_uuids |
array[uuid] | بله | لیست UUID محصولات؛ خالی بودن مجاز نیست |
sensors |
array | خیر | لیست سنسورهای مزرعه |
area_geojson |
object | خیر | محدوده زمین به صورت GeoJSON از نوع Polygon؛ اگر farm_boundary هم ارسال شود، این فیلد override میشود |
farm_boundary |
object | خیر | alias برای محدوده مزرعه؛ هم Polygon و هم فرم corners را میپذیرد |
sensor_key |
string | خیر | کلید سنسور برای normalize کردن sensor_payload؛ پیش فرض sensor-7-1 |
sensor_payload |
object | خیر | داده سنسور که همراه ساخت مزرعه به Farm Data sync میشود |
irrigation_method_id |
integer/null | خیر | شناسه روش آبیاری که همراه ساخت مزرعه به Farm Data sync میشود |
فیلدهای هر سنسور در sensors
| فیلد | نوع | اجباری | توضیح |
|---|---|---|---|
sensor_catalog_uuid |
uuid | خیر | اگر ارسال شود باید در SensorCatalog وجود داشته باشد |
physical_device_uuid |
uuid | خیر | شناسه دستگاه فیزیکی؛ اگر داده نشود مدل خودش مقدار تولید میکند |
name |
string | وابسته به ورودی | نام سنسور؛ اگر sensor_catalog_uuid معتبر باشد و name نفرستید، از نام catalog استفاده میشود، ولی اگر sensor_catalog_uuid هم نداشته باشید عملا باید name را بفرستید |
sensor_type |
string | خیر | نوع سنسور |
is_active |
boolean | خیر | وضعیت فعال بودن سنسور |
specifications |
object | خیر | مشخصات فنی |
power_source |
object | خیر | نوع یا جزئیات منبع تغذیه |
اعتبارسنجیها
farm_uuidاگر از سمت کلاینت ارسال شود نادیده گرفته میشود.- اگر
farm_boundaryبه فرمcornersارسال شود، به Polygon تبدیل میشود. sensor_payloadباید object باشد، وگرنه خطای validation برمیگردد.farm_type_uuidباید معتبر باشد، وگرنه:
{
"farm_type_uuid": [
"Farm type not found."
]
}
product_uuidsباید همگی وجود داشته باشند:
{
"product_uuids": [
"One or more products were not found."
]
}
- همه محصولات باید متعلق به همان
farm_typeباشند:
{
"product_uuids": [
"Products must belong to farm type `زراعی`."
]
}
sensor_catalog_uuidاگر ارسال شود باید معتبر باشد:
{
"sensors": [
{
"sensor_catalog_uuid": [
"Sensor catalog not found."
]
}
]
}
رفتار داخلی
-
بعد از ساخت مزرعه و zoning، backend درخواست
POST /api/farm-data/را نیز باfarm_uuid،farm_boundary،plant_idsو در صورت وجودsensor_payload/irrigation_method_idارسال میکند. -
اگر sync با Farm Data شکست بخورد، پاسخ endpoint با کد
502برمیگردد. -
area_geojsonباید object معتبر باشد. -
اگر
area_geojson.type == "Feature"باشد، مقدارgeometryبررسی میشود. -
geometry.typeفقط بایدPolygonباشد. -
coordinatesباید ساختار polygon ring داشته باشد.
نمونه خطاهای area_geojson:
{
"area_geojson": [
"`area_geojson` must be a GeoJSON object."
]
}
{
"area_geojson": [
"`area_geojson.geometry.type` must be `Polygon`."
]
}
رفتار داخلی مهم
- اگر
area_geojsonارسال نشود، سیستم ازget_default_area_feature()استفاده میکند. - بعد از ساخت مزرعه، فرآیند zoning اجرا میشود.
- خروجی zoning به
current_crop_areaوصل میشود. - اگر zoning با موفقیت ساخته شود، در response فیلد
zoningهم برگردانده میشود.
Response 201
{
"code": 201,
"msg": "success",
"data": {
"farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
"area_uuid": "0c7dfd7f-94bf-46f3-b2f9-30a89f0a1111",
"name": "مزرعه شماره 1",
"is_active": true,
"farm_type": {
"uuid": "11111111-1111-1111-1111-111111111111",
"name": "زراعی",
"description": "",
"metadata": {}
},
"products": [
{
"uuid": "22222222-2222-2222-2222-222222222222",
"name": "گندم",
"description": "",
"metadata": {},
"light": "",
"watering": "",
"soil": "",
"temperature": "",
"planting_season": "پاییز",
"harvest_time": "بهار",
"spacing": "",
"fertilizer": "",
"health_profile": {},
"irrigation_profile": {},
"growth_profile": {}
}
],
"sensors": [
{
"uuid": "33333333-3333-3333-3333-333333333333",
"sensor_catalog_uuid": "44444444-4444-4444-4444-444444444444",
"physical_device_uuid": "55555555-5555-5555-5555-555555555555",
"name": "Station 1",
"sensor_type": "weather_station",
"is_active": true,
"specifications": {
"model": "FH-1"
},
"power_source": {
"type": "battery"
},
"last_updated": "2025-02-18T12:00:00Z"
}
],
"last_updated": "2025-02-18T12:00:00Z",
"zoning": {
"zone_count": 4
}
}
}
Response 500
در صورتی که سرویس لازم برای zoning/config بهدرستی تنظیم نشده باشد:
{
"code": 500,
"msg": "..."
}
3) دریافت لیست نوع مزرعهها
Request
GET /api/farm-hub/farm-types/
Authorization: Bearer <token>
Response 200
{
"code": 200,
"msg": "success",
"data": [
{
"uuid": "11111111-1111-1111-1111-111111111111",
"name": "زراعی",
"description": "",
"metadata": {}
},
{
"uuid": "22222222-2222-2222-2222-222222222222",
"name": "درختی",
"description": "",
"metadata": {}
}
]
}
نکته
- خروجی بر اساس
nameمرتب میشود.
4) دریافت محصولات یک نوع مزرعه
Request
GET /api/farm-hub/farm-types/{farm_type_uuid}/products/
Authorization: Bearer <token>
Path Params
| پارامتر | نوع | توضیح |
|---|---|---|
farm_type_uuid |
uuid | شناسه نوع مزرعه |
Response 200
{
"code": 200,
"msg": "success",
"data": [
{
"uuid": "22222222-2222-2222-2222-222222222222",
"name": "گندم",
"description": "",
"metadata": {},
"light": "",
"watering": "",
"soil": "",
"temperature": "",
"planting_season": "پاییز",
"harvest_time": "بهار",
"spacing": "",
"fertilizer": "",
"health_profile": {
"moisture": {
"ideal_value": 65
}
},
"irrigation_profile": {},
"growth_profile": {}
}
]
}
Response 404
{
"code": 404,
"msg": "Farm type not found."
}
نکته
- محصولات با ترتیب
nameبرگردانده میشوند.
5) دریافت جزئیات یک مزرعه
Request
GET /api/farm-hub/{farm_uuid}/
Authorization: Bearer <token>
Path Params
| پارامتر | نوع | توضیح |
|---|---|---|
farm_uuid |
uuid | شناسه مزرعه |
رفتار
- فقط اگر مزرعه متعلق به کاربر جاری باشد برگردانده میشود.
- اگر UUID وجود داشته باشد ولی متعلق به کاربر دیگری باشد، عملا مثل not found رفتار میشود.
Response 200
ساختار data دقیقا مثل آیتمهای خروجی لیست مزرعهها است.
Response 404
{
"code": 404,
"msg": "Farm not found."
}
6) ویرایش مزرعه
Request
PATCH /api/farm-hub/{farm_uuid}/
Authorization: Bearer <token>
Content-Type: application/json
Path Params
| پارامتر | نوع | توضیح |
|---|---|---|
farm_uuid |
uuid | شناسه مزرعه |
Body
این endpoint از partial update استفاده میکند؛ یعنی میتوانید فقط بخشی از فیلدها را بفرستید.
نمونه:
{
"name": "مزرعه اصلاح شده",
"is_active": false,
"farm_type_uuid": "11111111-1111-1111-1111-111111111111",
"product_uuids": [
"22222222-2222-2222-2222-222222222222"
],
"sensors": [
{
"sensor_catalog_uuid": "44444444-4444-4444-4444-444444444444",
"physical_device_uuid": "55555555-5555-5555-5555-555555555555",
"name": "Station Updated",
"sensor_type": "weather_station",
"is_active": true,
"specifications": {
"model": "FH-2"
},
"power_source": {
"type": "solar"
}
}
],
"farm_boundary": {
"corners": [
{"lat": 35.70, "lon": 51.39},
{"lat": 35.70, "lon": 51.41},
{"lat": 35.72, "lon": 51.41},
{"lat": 35.72, "lon": 51.39}
]
},
"sensor_payload": {
"soil_moisture": 45.2
},
"irrigation_method_id": 3
}
رفتار update
nameوis_activeدر صورت ارسال تغییر میکنند.- اگر
farm_type_uuidارسال شود، نوع مزرعه بهروزرسانی میشود. - اگر
product_uuidsارسال شود، همه محصولات مزرعه با لیست جدید جایگزین میشوند. - اگر
sensorsارسال شود، همه سنسورهای قبلی حذف و سپس سنسورهای جدید از نو ساخته میشوند. - اگر
area_geojsonیاfarm_boundaryارسال شود، zoning مجدد انجام میشود وcurrent_crop_areaبهروزرسانی میشود. - در هر update نیز درخواست sync به
POST /api/farm-data/باfarm_uuid،farm_boundary،plant_idsو در صورت وجودsensor_payload/irrigation_method_idارسال میشود.
اعتبارسنجی
همان قوانین create اینجا هم برقرار است، با این تفاوت:
- در update، اگر
farm_type_uuidارسال نشود، ازfarm_typeفعلی استفاده میشود. - در update، اگر
product_uuidsارسال نشود، محصولات فعلی حفظ میشوند. - در update، اگر
sensorsارسال نشود، سنسورهای فعلی حفظ میشوند. - در update نیز
sensor_payloadباید object باشد.
Response 200
{
"code": 200,
"msg": "success",
"data": {
"farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
"area_uuid": "0c7dfd7f-94bf-46f3-b2f9-30a89f0a1111",
"name": "مزرعه اصلاح شده",
"is_active": false,
"farm_type": {
"uuid": "11111111-1111-1111-1111-111111111111",
"name": "زراعی",
"description": "",
"metadata": {}
},
"products": [],
"sensors": [],
"last_updated": "2025-02-18T13:00:00Z"
}
}
Response 404
{
"code": 404,
"msg": "Farm not found."
}
Response 502
{
"code": 502,
"msg": "Farm data API returned status 400: ..."
}
7) حذف مزرعه
Request
DELETE /api/farm-hub/{farm_uuid}/
Authorization: Bearer <token>
Response 200
{
"code": 200,
"msg": "success"
}
Response 404
{
"code": 404,
"msg": "Farm not found."
}
نکته
- فقط مزرعه متعلق به کاربر جاری حذف میشود.
8) فعالکردن مزرعه
Request
POST /api/farm-hub/active/
Authorization: Bearer <token>
Content-Type: application/json
Body
{
"farm_uuid": "550e8400-e29b-41d4-a716-446655440000"
}
Response 200
{
"code": 200,
"msg": "success"
}
Response 404
{
"code": 404,
"msg": "Farm not found."
}
خطای validation
اگر farm_uuid ارسال نشود یا فرمت آن درست نباشد، خطای serializer برگردانده میشود. نمونه:
{
"farm_uuid": [
"This field is required."
]
}
9) غیرفعالکردن مزرعه
Request
POST /api/farm-hub/deactive/
Authorization: Bearer <token>
Content-Type: application/json
Body
{
"farm_uuid": "550e8400-e29b-41d4-a716-446655440000"
}
Response 200
{
"code": 200,
"msg": "success"
}
Response 404
{
"code": 404,
"msg": "Farm not found."
}
ساختار آبجکتها
آبجکت FarmType
{
"uuid": "11111111-1111-1111-1111-111111111111",
"name": "زراعی",
"description": "",
"metadata": {}
}
آبجکت Product
{
"uuid": "22222222-2222-2222-2222-222222222222",
"name": "گندم",
"description": "",
"metadata": {},
"light": "",
"watering": "",
"soil": "",
"temperature": "",
"planting_season": "",
"harvest_time": "",
"spacing": "",
"fertilizer": "",
"health_profile": {},
"irrigation_profile": {},
"growth_profile": {}
}
توضیح فیلدهای پروفایل محصول
health_profile: برای KPIها و سلامت محصولirrigation_profile: برای محاسبات آبیاری و ETcgrowth_profile: برای مدل رشد مانند GDD
نمونه ساختار health_profile:
{
"moisture": {
"ideal_value": 65,
"min_range": 45,
"max_range": 75,
"weight": 0.4
}
}
نمونه ساختار irrigation_profile:
{
"kc_initial": 0.6,
"kc_mid": 1.15,
"kc_end": 0.8,
"growth_stage_duration": {
"initial": 20,
"mid": 30,
"late": 25
}
}
نمونه ساختار growth_profile:
{
"base_temperature": 10,
"required_gdd_for_maturity": 1200,
"stage_thresholds": {
"flowering": 500,
"fruiting": 850
},
"current_cumulative_gdd": 320
}
آبجکت FarmSensor
{
"uuid": "33333333-3333-3333-3333-333333333333",
"sensor_catalog_uuid": "44444444-4444-4444-4444-444444444444",
"physical_device_uuid": "55555555-5555-5555-5555-555555555555",
"name": "Station 1",
"sensor_type": "weather_station",
"is_active": true,
"specifications": {},
"power_source": {},
"last_updated": "2025-02-18T12:00:00Z"
}
آبجکت FarmHub
{
"farm_uuid": "550e8400-e29b-41d4-a716-446655440000",
"area_uuid": "0c7dfd7f-94bf-46f3-b2f9-30a89f0a1111",
"name": "مزرعه شماره 1",
"is_active": true,
"farm_type": {},
"products": [],
"sensors": [],
"last_updated": "2025-02-18T12:00:00Z"
}
نکات مهم برای فرانتاند
- برای ساخت مزرعه، ابتدا
GET /api/farm-hub/farm-types/را صدا بزنید. - سپس برای نوع انتخابشده،
GET /api/farm-hub/farm-types/{farm_type_uuid}/products/را بگیرید. - برای ساخت یا ویرایش مزرعه،
product_uuidsباید باfarm_type_uuidهمخوانی داشته باشند. - اگر در update فیلد
sensorsرا بفرستید، لیست قبلی کامل جایگزین میشود. - اگر در create،
area_geojsonنفرستید، سیستم خودش یک محدوده پیشفرض میسازد. - endpointهای detail/update/delete/active/deactive فقط روی مزرعههای خود کاربر عمل میکنند.
منبع پیادهسازی
- رجیستر اپ:
farm_hub/apps.py - تعریف routeها:
farm_hub/urls.py - منطق APIها:
farm_hub/views.py - serializerها و validation:
farm_hub/serializers.py - مدلها:
farm_hub/models.py - منطق ساخت zoning:
farm_hub/services.py - نمونه requestها:
farm_hub/postman/farm_hub.json