from apps.utils.serializers import CustomModelSerializer from apps.utils.constants import EXCLUDE_FIELDS_BASE, EXCLUDE_FIELDS_DEPT 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): """Serializer for Drain model""" mgroup_name = serializers.CharField(source='mgroup.name', read_only=True) class Meta: model = Drain fields = "__all__" read_only_fields = EXCLUDE_FIELDS_DEPT def validate(self, attrs): attrs['belong_dept'] = attrs['mgroup'].belong_dept return super().validate(attrs) class Drain2Serializer(CustomModelSerializer): equip_data = serializers.SerializerMethodField() mgroup_name = serializers.CharField(source='mgroup.name', read_only=True) 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', 'is_online', 'running_state') 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": 0, "total_duration_run": 0, "total_duration_standby": 0, "last_running_state": 50, })) return odata class DrainEquipSerializer(CustomModelSerializer): equipment_type = serializers.CharField( source='equipment.type', read_only=True) equipment_name = serializers.CharField( source='equipment.name', read_only=True) class Meta: model = DrainEquip fields = "__all__" read_only_fields = EXCLUDE_FIELDS_BASE class EnvDataSerializer(CustomModelSerializer): """Serializer for EnvData model""" class Meta: model = EnvData fields = "__all__" class DrainEquipEnvSerializer(CustomModelSerializer): equipment_number = serializers.CharField( source='equipment.number', read_only=True) equipment_type = serializers.CharField( source='equipment.type', read_only=True) equipment_name = serializers.CharField( source='equipment.name', read_only=True) equipment_envdata = serializers.SerializerMethodField() equipment_ = EquipmentSerializer(source='equipment', read_only=True) drain_ = DrainSerializer(source='drain', read_only=True) def get_equipment_envdata(self, obj): now = timezone.now() now_10_before = now - timezone.timedelta(minutes=10) obj = EnvData.objects.filter( equipment=obj.equipment, time__gte=now_10_before, time__lte=now).order_by('-time').first() if obj: return EnvDataSerializer(instance=obj).data else: return {} class Meta: model = DrainEquip fields = "__all__" class VehicleAccessSerializer(CustomModelSerializer): """Serializer for VehicleAccess model""" class Meta: model = VehicleAccess fields = "__all__" read_only_fields = EXCLUDE_FIELDS_BASE class EnvDataExportSerializer(serializers.Serializer): time = serializers.DateTimeField(label='时间') type = serializers.ChoiceField( label='导出类型', choices=['hour', 'day', 'week', 'month', 'season', 'year']) class CarWashSerializer(CustomModelSerializer): station_name = serializers.CharField(source='station.name', read_only=True) class Meta: model = CarWash fields = "__all__"