| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361 |
- from django.core.paginator import Paginator
- import logging
- import datetime
- from operator import itemgetter
- from django.db.models import Q, Sum, Count
- from django.db.models.functions import Cast
- from djongo import models
- from django.conf import settings
- from rest_framework.views import APIView
- from rest_framework.response import Response
- from smartfarming.models.ascend import MongoBase, MongoLandInfo, MongoPlantInfo, MongoAreaJob, LandPlanInfo, CountryModel, PlanWeekend
- from smartfarming.models.user import DeviceUser
- from smartfarming.models.device import MongoDevice
- from smartfarming.models.worm_forecast import MongoCBDphoto
- from smartfarming.models.pest_count import MongoCBDPestWarning
- from smartfarming.models.weather import MongoQXZ_Alarm_Log_New
- from smartfarming.serializers.ascend_serializers import LandPlanInfoSerializers
- from smartfarming.serializers.pests_serializers import MongoCBDPestWarningSerializers, MongoQXZAlarmLogNewSerializers
- from smartfarming.utils import get_recent_month, get_weather
- from smartfarming.api.views.forecast.all_dict import insect_dict
- from smartfarming.models.device import MongoDevice
- from smartfarming.models.ascend import MongoBase
- logger = logging.getLogger("myapp")
- class LandPlanInfoAPIView(APIView):
- def post(self, request):
- # 种植采收列表及统计信息
- request_data = request.data
- plan = request_data.get("plan")
- year = request_data.get("year")
- page_num = int(request_data.get("pagenum")) if request_data.get("pagenum") else 1
- page_size = int(request_data.get("pagesize")) if request_data.get("pagesize") else 10
- start_timestamp, end_timestatmp = 0, 0
- queryset = LandPlanInfo.objects.filter(is_delete=1).exclude(recovery_time=0).order_by("-addtime")
- if year:
- start_timestamp = datetime.datetime(int(year), 1,1,0,0).timestamp()
- end_timestatmp = datetime.datetime(int(year), 12,31,23,59).timestamp()
- queryset = queryset.filter(recovery_time__gte=start_timestamp, recovery_time__lte=end_timestatmp)
- if plan:
- ids_lst = MongoPlantInfo.objects.filter(plantname__icontains=plan).values_list("id", flat=True)
- queryset = queryset.filter(plan_id__in = ids_lst)
- total_obj = queryset.count()
- paginator = Paginator(queryset, page_size)
- page_obj = paginator.get_page(page_num)
- serializers = LandPlanInfoSerializers(page_obj, many=True)
- # 折线图
- # 获取最近5年年份列表
- current_year = datetime.datetime.now().year
- year_list = [year for year in range(current_year, current_year - 6, -1)]
- year_value = LandPlanInfo.objects.all().exclude(recovery_time=0).values_list("recovery_time", flat=True).order_by("-recovery_time")
- years = []
- all_year = []
- for year in year_value:
- y = datetime.datetime.fromtimestamp(year).year
- if y not in years and y in year_list:
- years.append(y)
- if y not in all_year:
- all_year.append(y)
- years.reverse()
- all_year.reverse()
- # 获取最近5年的作物ID
- if years:
- end = datetime.datetime(int(years[-1]) -6, 12,31,23,59).timestamp()
- start = datetime.datetime(int(years[-1]), 12,31,23,59).timestamp()
- plan_ids = LandPlanInfo.objects.filter(recovery_time__gte=end, recovery_time__lte=start).exclude(recovery_time=0).distinct().values_list("plan_id", flat=True).order_by("plan_id")
- counts = []
- # 组织具体数据
- for i in years:
- start_timestamp = datetime.datetime(i, 1,1,0,0).timestamp()
- end_timestatmp = datetime.datetime(i, 12,31,23,59).timestamp()
- plan_totals = LandPlanInfo.objects.filter(
- recovery_time__gte=start_timestamp,
- recovery_time__lte=end_timestatmp).exclude(recovery_time=0).values("plan_id").annotate(
- total=Sum(Cast('recovery_kg', output_field=models.FloatField()))).order_by("plan_id").values_list("plan_id", "total")
- # 作物 id:总质量
- inners = {}
- for k in plan_totals:
- inners[str(k[0])] = k[1]
- pid =[]
- for j in plan_ids:
- pid.append(inners.get(str(j), 0))
- counts.append(pid)
- transpose_matrix = [[row[i] for row in counts] for i in range(len(counts[0]))]
- plannames = []
- # 组织农作物
- for p in plan_ids:
- plan_obj = MongoPlantInfo.objects.filter(id=p)
- if plan_obj:
- planname = plan_obj.first().plantname +"-"+ plan_obj.first().planttype
- else:
- planname = ""
- plannames.append(planname)
- return Response({
- "code": 0,
- "msg": "success",
- "data": serializers.data,
- "years": all_year,
- "count": total_obj,
- "charts": {
- "years": years,
- "data": transpose_matrix,
- "plan": plannames
- }
- })
- else:
- return Response({
- "code": 0,
- "msg": "success",
- "data": [],
- "count": 0,
- "charts": {
- "years": [],
- "data": [],
- "plan": []
- }
- })
- class PlanNameAPIView(APIView):
- def post(self, request):
- try:
- # 作物名字
- plan_ids = LandPlanInfo.objects.filter(is_delete=1).exclude(recovery_time=0).values_list("plan_id", flat=True).order_by("-addtime")
- plans = MongoPlantInfo.objects.filter(is_delete=1, id__in=plan_ids).values_list("plantname", flat=True).distinct()
- return Response({"code": 0, "msg": "success", "data": plans})
- except Exception as e:
- logger.error(e)
- return Response({"code": 0, "msg": "success", "data": []})
-
- class PlanAreaAPIView(APIView):
- def post(self, request):
- # 种植面积与作物个数统计
- try:
- land_plan_ids = LandPlanInfo.objects.filter(status="采收").filter(recovery_kg=0).values("land_id", "plan_id")
- plan_land = []
- plans = []
- plan_area = 0
- for i in land_plan_ids:
- landarea = MongoLandInfo.objects.get(id=i.get("land_id")).landarea
- plant = MongoPlantInfo.objects.get(id=i.get("plan_id"))
- plantname = f"{plant.plantname}({plant.planttype})"
- plan_land.append(
- {
- "name": plantname,
- "value": round(float(landarea), 2)
- }
- )
- plans.append(plantname) if plantname not in plans else None
- plan_area += round(float(landarea), 2)
- return Response({"code": 0, "msg": "success", "data": {"lands_area": int(plan_area), "plans_count": len(plans), "p_list": plan_land}})
- except Exception as e:
- logger.error(e)
- return Response({"code": 0, "msg": "请检查数据"})
- class DeviceCountAPIView(APIView):
- def post(self, request):
- # 统计设备在线或离线统计
- device_status = MongoDevice.objects.values("device_status").annotate(total=Count("id"))
- online = 0
- offline = 0
- for k in device_status:
- if k.get("device_status") == 1:
- online = k.get("total")
- if k.get("device_status") == 0:
- offline = k.get("total")
- # 设备分类
- device_type = MongoDevice.objects.values("device_type_id").annotate(total=Count("id"))
- config_dict = settings.CONFIG.get("device_type_zh")
- device_type = {config_dict.get(str(result["device_type_id"])): result["total"] for result in device_type}
- return Response({
- "code": 0,
- "msg": "success",
- "data": {
- "device_status": {"online": online, "offline": offline},
- "device_category": device_type
- }
- })
- class RecentPestCountAPIView(APIView):
- def post(self, request):
- # 统计最近一个月的害虫排名
- start = get_recent_month(1)
- data = MongoCBDphoto.objects.filter(uptime__gte=start).values_list("indentify_result", flat=True)
- try:
- pest_count = {}
- for i in data:
- tp_lst = i.split("#")
- for k in tp_lst:
- if k:
- pest = k.split(",")
- if len(pest) == 2:
- p_0 = pest[0]
- p_1 = pest[1]
- p_name = insect_dict.get(p_0)
- if p_name not in pest_count.keys():
- pest_count[p_name] = int(p_1)
- else:
- pest_count[p_name] += int(p_1)
- else:
- logger.error(f"害虫识别格式有误:{k}")
- result = sorted(pest_count.items(), key=itemgetter(1), reverse=False)
- result = {m[0]:m[1] for m in result[-10:]}
- return Response({"code": 0, "msg": "success", "data": result})
- except Exception as e:
- logger.error(e)
- return Response({"code": 2, "msg": "数据有误,请核查"})
- # 网站顶部滚动预警信息
- class AlermNewsAPIView(APIView):
- def post(self, request):
- try:
- myuser = request.myuser
- try:
- ip = request.META['HTTP_X_FORWARDED_FOR']
- except Exception as e:
- ip = request.META['REMOTE_ADDR']
- # 获取天气预警
- weather_data = get_weather(ip)
- weather = []
- for i in weather_data:
- alarm = i.get("alarm")
- if alarm:
- for k in alarm:
- weather.append(k.get("alarm_content"))
- # 获取虫睛预警
- user_id = str(myuser.id)
- pest_query = MongoCBDPestWarning.objects.all().order_by("-id")[:3]
- pest = []
- for p in pest_query:
- content = p.warning_content
- pest.append(content.replace("【云飞科技】尊敬的用户:", "").replace(",(详情请登陆http://hnyfwlw.com查看)", "").replace(",请注意防范(详情请登陆http://hnyfwlw.com查看)", ""))
- # 气象预警
- qx_query = MongoQXZ_Alarm_Log_New.objects.filter(user_id=user_id).order_by('-id')[:3]
- qx = []
- for q in qx_query:
- qx.append(q.warning_content)
- data = []
- if weather:
- for i in weather:
- data.append(i)
- if pest:
- for i in pest:
- data.append(i)
- if qx:
- for i in qx:
- data.append(i)
- return Response({"code": 0,"msg":"success", "data": data})
- except Exception as e:
- logger.error(e)
- return Response({"code": 2, "msg": "获取数据失败"})
-
- class APPAlarmAPIView(APIView):
- def post(self, request):
- # 气象站与测报预警
- request_data = request.data
- type_id = request_data.get("type_id")
- device_id = request_data.get("device_id", "")
- page_num = int(request_data.get("page", 1)) if request_data.get("page") else 1
- page_size = int(request_data.get("page_size", 10)) if request_data.get("page_size") else 10
- data = {}
- total_obj = 0
- if type_id == "3":
- # 虫情
- queryset = MongoCBDPestWarning.objects.all().order_by("-upltime")
- if device_id:
- queryset = queryset.filter(device_id=device_id)
- total_obj = queryset.count()
- paginator = Paginator(queryset, page_size)
- page_obj = paginator.get_page(page_num)
- pest_serializers = MongoCBDPestWarningSerializers(page_obj, many=True)
- data = pest_serializers.data
- elif type_id == "5":
- queryset = MongoQXZ_Alarm_Log_New.objects.filter(warning_name="5").order_by("-upl_time")
- if device_id:
- d_id = MongoDevice.objects.get(device_id=device_id).id
- queryset = queryset.filter(device_id=d_id)
- total_obj = queryset.count()
- paginator = Paginator(queryset, page_size)
- page_obj = paginator.get_page(page_num)
- qxz_serializers = MongoQXZAlarmLogNewSerializers(page_obj, many=True)
- data = qxz_serializers.data
- elif type_id == "8":
- queryset = MongoQXZ_Alarm_Log_New.objects.filter(warning_name="8").order_by("-upl_time")
- if device_id:
- d_id = MongoDevice.objects.get(device_id=device_id).id
- queryset = queryset.filter(device_id=d_id)
- total_obj = queryset.count()
- paginator = Paginator(queryset, page_size)
- page_obj = paginator.get_page(page_num)
- qxz_serializers = MongoQXZAlarmLogNewSerializers(page_obj, many=True)
- data = qxz_serializers.data
- return Response({"code": 0, "msg": "success", "data": data, "nums": total_obj})
-
- class QxzCameraList(APIView):
- permission_classes = []
- authentication_classes = []
- def post(self, request):
- # 气象与监控绑定列表
- qxz_ids = MongoDevice.objects.filter(device_type_id__in = [5, 8]).values("device_id")
- cam_ids = MongoDevice.objects.filter(device_type_id = 6).values_list("device_id", flat=True)
- return Response({"code": 0,"msg":"success", "data": {"qxz_ids": qxz_ids, "cam_ids": cam_ids}})
-
- class QxzCameraUpdate(APIView):
- permission_classes = []
- authentication_classes = []
- def post(self, request):
- # 气象与监控更新
- request_data = request.data
- try:
- qx_id = request_data.get("qx_id")
- ca_id = request_data.get("ca_id")
- qx_lng_lat = MongoDevice.objects.filter(device_id=qx_id).values_list("lng", "lat")
- ca_obj = MongoDevice.objects.get(device_id=ca_id)
- if qx_lng_lat:
- ca_obj.lng = float(qx_lng_lat[0][0]) + 0.00004
- ca_obj.lat = float(qx_lng_lat[0][1]) + 0.00004
- ca_obj.save()
- return Response({"code": 0,"msg":"success"})
- except Exception as e:
- logger.error(e)
- return Response({"code": 2,"msg":"失败"})
-
-
- class KeDongOverAPIView(APIView):
- def post(self, request):
- # 我的信息
- try:
- country_count = CountryModel.objects.filter(is_delete=1).count()
- area = MongoBase.objects.all().first().base_area
- device = MongoDevice.objects.all().count()
- return Response({
- "code": 0,
- "msg":"success",
- "data": {
- "country_count": country_count,
- "area": area,
- "device": device
- }
- })
- except Exception as e:
- logger.error(e)
- return Response({"code": 2,"msg":"失败"})
|