factory/apps/enp/serializers.py

178 lines
5.6 KiB
Python

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", "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 running_state != 50 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 in (20, 30, 40) 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
TIMEX >= '{today}' -- 替换成想查询的开始时间
AND TIMEX <= '{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__"
def to_representation(self, instance):
representation = super().to_representation(instance)
for field_name in ("dust_rtd", "dust_zs", "temperature", "pressure", "speed", "humidity", "flux", "pm25", "pm10", "tsp", "wind_speed", "so2_rtd", "so2_zs", "nox_rtd", "nox_zs", "o2"):
if representation[field_name]:
representation[field_name] = round(representation[field_name], 4)
return representation
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").select_related("equipment").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__"