diff --git a/apps/enp/serializers.py b/apps/enp/serializers.py index 329d6056..d813e04d 100644 --- a/apps/enp/serializers.py +++ b/apps/enp/serializers.py @@ -4,6 +4,8 @@ from .models import Drain, DrainEquip, EnvData, VehicleAccess, CarWash from apps.em.serializers import EquipmentSerializer from rest_framework import serializers from django.utils import timezone +from datetime import datetime +from apps.utils.sql import query_all_dict class DrainSerializer(CustomModelSerializer): @@ -20,6 +22,86 @@ class DrainSerializer(CustomModelSerializer): return super().validate(attrs) +class Drain2Serializer(CustomModelSerializer): + equip_data = serializers.SerializerMethodField() + + class Meta: + model = Drain + fields = "__all__" + read_only_fields = EXCLUDE_FIELDS_DEPT + + def get_equip_data(self, obj): + equips = obj.equipments.all() + now = datetime.now() + today = str(now)[:10]+' 00:00:00' + today_last = str(now)[:10]+' 23:59:59' + odata = equips.values('id', 'name', 'type') + eids = [f"'{e['id']}'" for e in odata] + eids_str = ','.join(eids) + sql_str = f''' +SELECT + equipment_id, + AVG ( tsp ) AS avg_tsp, + SUM ( duration_online ) AS total_duration_online, + SUM ( duration_run ) AS total_duration_run, + SUM ( duration_standby ) AS total_duration_standby, + MAX ( last_running_state ) AS last_running_state +FROM + ( + SELECT + equipment_id, + tsp, + running_state, + CASE + + WHEN is_online = 1 THEN + TIME - LAG ( TIME ) OVER ( PARTITION BY equipment_id ORDER BY TIME ) ELSE'0' + END AS duration_online, + CASE + + WHEN running_state = 10 THEN + TIME - LAG ( TIME ) OVER ( PARTITION BY equipment_id ORDER BY TIME ) ELSE'0' + END AS duration_run, + CASE + + WHEN running_state = 20 THEN + TIME - LAG ( TIME ) OVER ( PARTITION BY equipment_id ORDER BY TIME ) ELSE'0' + END AS duration_standby, + CASE + + WHEN ROW_NUMBER ( ) OVER ( PARTITION BY equipment_id ORDER BY TIME DESC ) = 1 THEN + running_state ELSE NULL + END AS last_running_state + FROM + enp_envdata + WHERE + running_state IN ( 10, 20 ) + AND TIME >= '{today}' -- 替换成想查询的开始时间 + + AND TIME <= '{today_last}' -- 替换成想查询的结束时间 + + AND equipment_id IN ( {eids_str} ) + ) AS durations +GROUP BY + equipment_id; + ''' + res = query_all_dict(sql_str) + data = {} + for i in res: + data[i['equipment_id']] = i + + for i in odata: + i.update(data.get(i['id'], { + "avg_tsp": None, + "total_duration_online": None, + "total_duration_run": None, + "total_duration_standby": None, + "last_running_state": None, + })) + + return odata + + class DrainEquipSerializer(CustomModelSerializer): equipment_type = serializers.CharField( source='equipment.type', read_only=True) diff --git a/apps/enp/views.py b/apps/enp/views.py index d5fd7c57..cbe6f294 100644 --- a/apps/enp/views.py +++ b/apps/enp/views.py @@ -1,7 +1,7 @@ from django.shortcuts import render from apps.utils.viewsets import CustomModelViewSet, CustomGenericViewSet, ListModelMixin from apps.utils.mixins import BulkCreateModelMixin, BulkDestroyModelMixin -from .serializers import DrainSerializer, DrainEquipSerializer, DrainEquipEnvSerializer, VehicleAccessSerializer, EnvDataSerializer, EnvDataExportSerializer, CarWashSerializer +from .serializers import DrainSerializer, DrainEquipSerializer, DrainEquipEnvSerializer, VehicleAccessSerializer, EnvDataSerializer, EnvDataExportSerializer, CarWashSerializer, Drain2Serializer from .models import Drain, DrainEquip, VehicleAccess, EnvData, CarWash from rest_framework.decorators import action from apps.utils.sql import query_all_dict @@ -21,6 +21,19 @@ class DrainViewSet(CustomModelViewSet): serializer_class = DrainSerializer filterset_fields = ['type', 'cate', 'mgroup'] + def get_serializer_class(self): + has_equipdata = self.request.query_params.get('has_equipdata', 'no') + if self.request.method == 'GET' and has_equipdata == 'yes': + return Drain2Serializer + return super().get_serializer_class() + + @swagger_auto_schema(manual_parameters=[ + openapi.Parameter(name="has_equipdata", in_=openapi.IN_QUERY, description="Include equip data in the response", + type=openapi.TYPE_STRING, enum=["yes", "no"], required=False), + ]) + def list(self, request, *args, **kwargs): + return super().list(request, *args, **kwargs) + class DrainEquipViewSet(ListModelMixin, BulkCreateModelMixin, BulkDestroyModelMixin, CustomGenericViewSet): """ @@ -37,7 +50,7 @@ class DrainEquipViewSet(ListModelMixin, BulkCreateModelMixin, BulkDestroyModelMi def get_serializer_class(self): has_envdata = self.request.query_params.get('has_envdata', 'no') - if has_envdata == 'yes': + if self.request.method == 'GET' and has_envdata == 'yes': return DrainEquipEnvSerializer return super().get_serializer_class() @@ -102,3 +115,4 @@ class CarWashViewSet(ListModelMixin, CustomGenericViewSet): "station": ['exact'], "start_time": ['exact', 'gte', 'lte', 'year', 'month', 'day'], } + ordering = ['-start_time']