counts_views.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. from django.core.paginator import Paginator
  2. import time
  3. import datetime
  4. from operator import itemgetter
  5. from django.db.models import Q, Sum, Count
  6. from django.conf import settings
  7. from rest_framework.views import APIView
  8. from rest_framework.response import Response
  9. from smartfarming.models.ascend import MongoBase, MongoLandInfo, MongoPlantInfo, MongoAreaJob, LandPlanInfo, CountryModel, PlanWeekend
  10. from smartfarming.models.user import DeviceUser
  11. from smartfarming.models.device import MongoDevice
  12. from smartfarming.models.worm_forecast import MongoCBDphoto
  13. from smartfarming.models.pest_count import MongoCBDPestWarning
  14. from smartfarming.models.weather import MongoQXZ_Alarm_Log_New
  15. from smartfarming.serializers.ascend_serializers import LandPlanInfoSerializers
  16. from smartfarming.serializers.pests_serializers import MongoCBDPestWarningSerializers, MongoQXZAlarmLogNewSerializers
  17. from smartfarming.utils import get_recent_month, get_weather
  18. from smartfarming.api.views.forecast.all_dict import insect_dict
  19. from smartfarming.models.device import MongoDevice
  20. from smartfarming.models.ascend import MongoBase
  21. class LandPlanInfoAPIView(APIView):
  22. def post(self, request):
  23. # 种植采收列表及统计信息
  24. request_data = request.data
  25. plan = request_data.get("plan")
  26. year = request_data.get("year")
  27. page_num = int(request_data.get("pagenum")) if request_data.get("pagenum") else 1
  28. page_size = int(request_data.get("pagesize")) if request_data.get("pagesize") else 10
  29. start_timestamp, end_timestatmp = 0, 0
  30. if year:
  31. start_timestamp = datetime.datetime(int(year), 1,1,0,0).timestamp()
  32. end_timestatmp = datetime.datetime(int(year), 12,31,23,59).timestamp()
  33. plan_ids_head = []
  34. if plan :
  35. plan_ids_head = MongoPlantInfo.objects.filter(plantname__icontains=plan).values_list("id", flat=True)
  36. if plan_ids_head and year:
  37. 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")
  38. elif year:
  39. queryset = LandPlanInfo.objects.filter(addtime__gte=start_timestamp, addtime__lte=end_timestatmp).filter(is_delete=1).exclude(recovery_time=0).order_by("-addtime")
  40. elif plan_ids_head:
  41. queryset = LandPlanInfo.objects.filter(plan_id__in = plan_ids_head).filter(is_delete=1).exclude(recovery_time=0).order_by("-addtime")
  42. else:
  43. queryset = LandPlanInfo.objects.filter(is_delete=1).exclude(recovery_time=0).order_by("-addtime")
  44. total_obj = queryset.count()
  45. paginator = Paginator(queryset, page_size)
  46. page_obj = paginator.get_page(page_num)
  47. serializers = LandPlanInfoSerializers(page_obj, many=True)
  48. # 折线图
  49. year_value = LandPlanInfo.objects.all().exclude(recovery_time=0).values_list("addtime", flat=True).order_by("-addtime")
  50. years = []
  51. for year in year_value:
  52. y = datetime.datetime.fromtimestamp(year).year
  53. if y not in years:
  54. years.append(y)
  55. years.reverse()
  56. # 获取最近5年的作物ID
  57. if years:
  58. end = datetime.datetime(int(years[-1]) -5, 12,31,23,59).timestamp()
  59. start = datetime.datetime(int(years[-1]), 12,31,23,59).timestamp()
  60. 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")
  61. counts = []
  62. # 组织具体数据
  63. for i in years:
  64. start_timestamp = datetime.datetime(i, 1,1,0,0).timestamp()
  65. end_timestatmp = datetime.datetime(i, 12,31,23,59).timestamp()
  66. plan_totals = LandPlanInfo.objects.filter(
  67. addtime__gte=start_timestamp,
  68. 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")
  69. inners = {}
  70. for k in plan_totals:
  71. inners[str(k[0])] = k[1]
  72. pid =[]
  73. for j in plan_ids:
  74. pid.append(inners.get(str(j), 0))
  75. counts.append(pid)
  76. transpose_matrix = [[row[i] for row in counts] for i in range(len(counts[0]))]
  77. plannames = []
  78. # 组织农作物
  79. for p in plan_ids:
  80. plan_obj = MongoPlantInfo.objects.filter(id=p)
  81. if plan_obj:
  82. planname = plan_obj.first().plantname +"-"+ plan_obj.first().planttype
  83. else:
  84. planname = ""
  85. plannames.append(planname)
  86. return Response({
  87. "code": 0,
  88. "msg": "success",
  89. "data": serializers.data,
  90. "count": total_obj,
  91. "charts": {
  92. "years": years,
  93. "data": transpose_matrix,
  94. "plan": plannames
  95. }
  96. })
  97. else:
  98. return Response({
  99. "code": 0,
  100. "msg": "success",
  101. "data": [],
  102. "count": 0,
  103. "charts": {
  104. "years": [],
  105. "data": [],
  106. "plan": []
  107. }
  108. })
  109. class PlanNameAPIView(APIView):
  110. def post(self, request):
  111. try:
  112. # 作物名字
  113. plan_ids = LandPlanInfo.objects.filter(is_delete=1).exclude(recovery_time=0).values_list("plan_id", flat=True).order_by("-addtime")
  114. plans = MongoPlantInfo.objects.filter(is_delete=1, id__in=plan_ids).values_list("plantname", flat=True).distinct()
  115. return Response({"code": 0, "msg": "success", "data": plans})
  116. except Exception as e:
  117. return Response({"code": 0, "msg": "success", "data": []})
  118. class PlanAreaAPIView(APIView):
  119. def post(self, request):
  120. # 种植面积与作物个数统计
  121. land_plan_ids = LandPlanInfo.objects.filter(status="采收").filter(recovery_kg=0).values("land_id", "plan_id")
  122. plan_land = []
  123. plans = []
  124. plan_area = 0
  125. for i in land_plan_ids:
  126. landarea = MongoLandInfo.objects.get(id=i.get("land_id")).landarea
  127. plant = MongoPlantInfo.objects.get(id=i.get("plan_id"))
  128. plantname = f"{plant.plantname}({plant.planttype})"
  129. plan_land.append(
  130. {
  131. "name": plantname,
  132. "value": round(float(landarea), 2)
  133. }
  134. )
  135. plans.append(plantname) if plantname not in plans else None
  136. plan_area += round(float(landarea), 2)
  137. return Response({"code": 0, "msg": "success", "data": {"lands_area": round(plan_area, 2), "plans_count": len(plans), "p_list": plan_land}})
  138. class DeviceCountAPIView(APIView):
  139. def post(self, request):
  140. # 统计设备在线或离线统计
  141. device_status = MongoDevice.objects.values("device_status").annotate(total=Count("id"))
  142. online = 0
  143. offline = 0
  144. for k in device_status:
  145. if k.get("device_status") == 1:
  146. online = k.get("total")
  147. if k.get("device_status") == 0:
  148. offline = k.get("total")
  149. # 设备分类
  150. device_type = MongoDevice.objects.values("device_type_id").annotate(total=Count("id"))
  151. config_dict = settings.CONFIG.get("device_type_zh")
  152. device_type = {config_dict.get(str(result["device_type_id"])): result["total"] for result in device_type}
  153. return Response({
  154. "code": 0,
  155. "msg": "success",
  156. "data": {
  157. "device_status": {"online": online, "offline": offline},
  158. "device_category": device_type
  159. }
  160. })
  161. class RecentPestCountAPIView(APIView):
  162. def post(self, request):
  163. # 统计最近一个月的害虫排名
  164. start = get_recent_month(1)
  165. data = MongoCBDphoto.objects.filter(uptime__gte=start).values_list("indentify_result", flat=True)
  166. try:
  167. pest_count = {}
  168. for i in data:
  169. tp_lst = i.split("#")
  170. for k in tp_lst:
  171. pest = k.split(",")
  172. p_0 = pest[0]
  173. p_1 = pest[1]
  174. p_name = insect_dict.get(p_0)
  175. if p_name not in pest_count.keys():
  176. pest_count[p_name] = int(p_1)
  177. else:
  178. pest_count[p_name] += int(p_1)
  179. result = sorted(pest_count.items(), key=itemgetter(1), reverse=False)
  180. result = {m[0]:m[1] for m in result[-10:]}
  181. return Response({"code": 0, "msg": "success", "data": result})
  182. except Exception as e:
  183. return Response({"code": 2, "msg": "数据有误,请核查"})
  184. # 网站顶部滚动预警信息
  185. class AlermNewsAPIView(APIView):
  186. def post(self, request):
  187. try:
  188. myuser = request.myuser
  189. try:
  190. ip = request.META['HTTP_X_FORWARDED_FOR']
  191. except Exception as e:
  192. ip = request.META['REMOTE_ADDR']
  193. # 获取天气预警
  194. weather_data = get_weather(ip)
  195. weather = []
  196. for i in weather_data:
  197. alarm = i.get("alarm")
  198. if alarm:
  199. for k in alarm:
  200. weather.append(k.get("alarm_content"))
  201. # 获取虫睛预警
  202. user_id = str(myuser.id)
  203. pest_query = MongoCBDPestWarning.objects.all().order_by("-id")[:3]
  204. pest = []
  205. for p in pest_query:
  206. content = p.warning_content
  207. pest.append(content.replace("【云飞科技】尊敬的用户:", "").replace(",(详情请登陆http://hnyfwlw.com查看)", "").replace(",请注意防范(详情请登陆http://hnyfwlw.com查看)", ""))
  208. # 气象预警
  209. qx_query = MongoQXZ_Alarm_Log_New.objects.filter(user_id=user_id).order_by('-id')[:3]
  210. qx = []
  211. for q in qx_query:
  212. qx.append(q.warning_content)
  213. data = []
  214. if weather:
  215. for i in weather:
  216. data.append(i)
  217. if pest:
  218. for i in pest:
  219. data.append(i)
  220. if qx:
  221. for i in qx:
  222. data.append(i)
  223. return Response({"code": 0,"msg":"success", "data": data})
  224. except Exception as e:
  225. print(e)
  226. return Response({"code": 2, "msg": "获取数据失败"})
  227. class APPAlarmAPIView(APIView):
  228. def post(self, request):
  229. # 气象站与测报预警
  230. request_data = request.data
  231. type_id = request_data.get("type_id")
  232. data = {}
  233. if type_id == "3":
  234. # 虫情
  235. query = MongoCBDPestWarning.objects.all().order_by("-upltime")
  236. pest_serializers = MongoCBDPestWarningSerializers(query, many=True)
  237. data = pest_serializers.data
  238. elif type_id == "5":
  239. query = MongoQXZ_Alarm_Log_New.objects.all().order_by("-upl_time")
  240. qxz_serializers = MongoQXZAlarmLogNewSerializers(query, many=True)
  241. data = qxz_serializers.data
  242. elif type_id == "8":
  243. query = MongoQXZ_Alarm_Log_New.objects.all().order_by("-upl_time")
  244. qxz_serializers = MongoQXZAlarmLogNewSerializers(query, many=True)
  245. data = qxz_serializers.data
  246. return Response({"code": 0, "msg": "success", "data": data})
  247. class QxzCameraList(APIView):
  248. permission_classes = []
  249. authentication_classes = []
  250. def post(self, request):
  251. # 气象与监控绑定列表
  252. qxz_ids = MongoDevice.objects.filter(device_type_id__in = [5, 8]).values("device_id")
  253. cam_ids = MongoDevice.objects.filter(device_type_id = 6).values_list("device_id", flat=True)
  254. return Response({"code": 0,"msg":"success", "data": {"qxz_ids": qxz_ids, "cam_ids": cam_ids}})
  255. class QxzCameraUpdate(APIView):
  256. permission_classes = []
  257. authentication_classes = []
  258. def post(self, request):
  259. # 气象与监控更新
  260. request_data = request.data
  261. try:
  262. qx_id = request_data.get("qx_id")
  263. ca_id = request_data.get("ca_id")
  264. qx_lng_lat = MongoDevice.objects.filter(device_id=qx_id).values_list("lng", "lat")
  265. ca_obj = MongoDevice.objects.get(device_id=ca_id)
  266. if qx_lng_lat:
  267. ca_obj.lng = float(qx_lng_lat[0][0]) + 0.00004
  268. ca_obj.lat = float(qx_lng_lat[0][1]) + 0.00004
  269. ca_obj.save()
  270. return Response({"code": 0,"msg":"success"})
  271. except Exception as e:
  272. return Response({"code": 2,"msg":"失败"})
  273. class KeDongOverAPIView(APIView):
  274. def post(self, request):
  275. # 我的信息
  276. country_count = CountryModel.objects.all().count()
  277. area = MongoBase.objects.all().first().base_area
  278. device = MongoDevice.objects.all().count()
  279. return Response({"code": 0,"msg":"success", "data": {"country_count": country_count, "area": area, "device": device}})