from django.core.paginator import Paginator import time import datetime from operator import itemgetter from django.db.models import Q, Sum, Count 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.utils import get_recent_month, get_weather from smartfarming.api.views.forecast.all_dict import insect_dict from smartfarming.models.device import MongoDevice 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 if year: start_timestamp = datetime.datetime(int(year), 1,1,0,0).timestamp() end_timestatmp = datetime.datetime(int(year), 12,31,23,59).timestamp() plan_ids_head = [] if plan : plan_ids_head = MongoPlantInfo.objects.filter(plantname__icontains=plan).values_list("id", flat=True) if plan_ids_head and year: queryset = LandPlanInfo.objects.filter(Q(plan_id__in = plan_ids_head) & Q(addtime__gte=start_timestamp, addtime__lte=end_timestatmp)).exclude(recovery_time=0).filter(is_delete=1).order_by("-addtime") elif year: queryset = LandPlanInfo.objects.filter(addtime__gte=start_timestamp, addtime__lte=end_timestatmp).filter(is_delete=1).exclude(recovery_time=0).order_by("-addtime") elif plan_ids_head: queryset = LandPlanInfo.objects.filter(plan_id__in = plan_ids_head).filter(is_delete=1).exclude(recovery_time=0).order_by("-addtime") else: queryset = LandPlanInfo.objects.filter(is_delete=1).exclude(recovery_time=0).order_by("-addtime") total_obj = queryset.count() paginator = Paginator(queryset, page_size) page_obj = paginator.get_page(page_num) serializers = LandPlanInfoSerializers(page_obj, many=True) # 折线图 year_value = LandPlanInfo.objects.all().exclude(recovery_time=0).values_list("addtime", flat=True).order_by("-addtime") years = [] for year in year_value: y = datetime.datetime.fromtimestamp(year).year if y not in years: years.append(y) years.reverse() # 获取最近5年的作物ID end = datetime.datetime(int(years[-1]) -5, 12,31,23,59).timestamp() start = datetime.datetime(int(years[-1]), 12,31,23,59).timestamp() plan_ids = LandPlanInfo.objects.filter(addtime__gte=end, addtime__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( addtime__gte=start_timestamp, addtime__lte=end_timestatmp).exclude(recovery_time=0).values("plan_id").annotate(total=Sum("recovery_kg")).order_by("plan_id").values_list("plan_id", "total") 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, "count": total_obj, "charts": { "years": years, "data": transpose_matrix, "plan": plannames } }) 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: return Response({"code": 0, "msg": "success", "data": []}) class PlanAreaAPIView(APIView): def post(self, request): # 种植面积与作物个数统计 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": round(plan_area, 2), "plans_count": len(plans), "p_list": plan_land}}) 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: pest = k.split(",") 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) 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: 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: print(e) return Response({"code": 2, "msg": "获取数据失败"}) 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: return Response({"code": 2,"msg":"失败"})