factory/apps/enm/views.py

315 lines
12 KiB
Python

from django.conf import settings
from rest_framework.exceptions import ParseError
from apps.enm.models import Mpoint, MpointStat, EnStat, EnStat2, MpLogx, Xscript
from apps.utils.viewsets import CustomModelViewSet, CustomGenericViewSet
from apps.utils.mixins import BulkCreateModelMixin, BulkDestroyModelMixin, CustomListModelMixin, BulkUpdateModelMixin
from apps.enm.serializers import (MpointSerializer, MpLogxSerializer, MpointStatSerializer,
EnStatSerializer, EnStat2Serializer, ReCalSerializer,
MpointStatCorrectSerializer,
EnStatAnaSerializer, EnStatUpdateSerializer, XscriptSerializer, XscriptDetailSerializer)
from apps.enm.filters import MpointStatFilter, EnStatFilter, EnStat2Filter
from apps.enm.tasks import cal_mpointstat_manual
from rest_framework.response import Response
from rest_framework.serializers import Serializer
from rest_framework.decorators import action
from apps.enm.tasks import cal_mpointstats_duration
from apps.enm.services import king_sync, MpointCache
from django.db import transaction
from datetime import datetime
from django.utils.timezone import localtime
from apps.enm.services import get_analyse_data_mgroups_duration
from django.db.models import Sum
import logging
from django.core.cache import cache
myLogger = logging.getLogger('log')
class MpointViewSet(CustomModelViewSet):
"""
list:测点
测点
"""
queryset = Mpoint.objects.all()
serializer_class = MpointSerializer
select_related_fields = ["create_by", "belong_dept", "ep_monitored", "ep_belong", "mgroup", "material"]
filterset_fields = {
"belong_dept": ["exact"],
"ep_monitored": ["exact", "isnull"],
"ep_monitored__power_kw": ["exact", "gte"],
"ep_belong": ["exact"],
"mgroup": ["exact"],
"is_rep_mgroup": ["exact"],
"type": ["exact"],
"mgroup__name": ["exact"],
"val_type": ["exact"],
"enabled": ["exact"],
"need_display": ["exact"],
"formula": ["exact", "contains"],
"material": ["exact", "isnull"],
"material__code": ["exact", "in"],
"code": ["exact", "contains", "in"],
"need_change_cal_coefficient": ["exact"],
}
search_fields = ["name", "code", "nickname", "material__code", "material__name", "ep_rs_expr", "formula"]
ordering = ["create_time", "name", "code"]
@transaction.atomic
def perform_create(self, serializer):
instance = serializer.save()
if instance.code:
MpointCache(instance.code).get(True)
@transaction.atomic
def perform_update(self, serializer):
old_code = serializer.instance.code
instance: Mpoint = serializer.save()
if instance.code:
if old_code != instance.code:
cache.delete(Mpoint.cache_key(old_code))
MpointCache(instance.code).get(True)
if instance.enabled is False:
mc = MpointCache(instance.code)
now = localtime()
mc.set_fail(-2, now)
@action(methods=["post"], detail=False, perms_map={"post": "mpoint.create"}, serializer_class=Serializer)
def king_sync(self, request, *args, **kwargs):
"""同步亚控采集点
同步亚控采集点
"""
king_sync(getattr(settings, "KING_PROJECTNAME", ""))
return Response()
class XscriptViewSet(CustomModelViewSet):
"""
list:执行脚本
执行脚本
"""
queryset = Xscript.objects.all()
serializer_class = XscriptSerializer
select_related_fields = ["myschedule", "periodictask"]
retrieve_serializer_class = XscriptDetailSerializer
search_fields = ['name']
@action(methods=['put'], detail=True, perms_map={'put': 'xscript.update'})
def toggle(self, request, pk=None):
"""修改启用禁用状态
修改启用禁用状态
"""
obj = self.get_object()
periodictask = obj.periodictask
periodictask.enabled = False if periodictask.enabled else True
periodictask.save()
return Response()
@action(methods=['put'], detail=True, perms_map={'put': 'xscript.update'})
def change_data(self, request, pk=None):
"""修改变动数据
修改变动数据
"""
obj: Xscript = self.get_object()
obj.change_data = request.data.get('change_data', {})
obj.save(update_fields=['change_data'])
return Response()
@transaction.atomic
def perform_destroy(self, instance):
periodictask = instance.periodictask
instance.delete()
periodictask.delete()
# class MpLogViewSet(ListModelMixin, CustomGenericViewSet):
# """
# list:测点原始记录
# 测点原始记录
# """
# perms_map = {'get': '*'}
# queryset = MpLog.objects.all()
# serializer_class = MpLogSerializer
# select_related_fields = ['mpoint']
# filterset_fields = ['mpoint', 'mpoint__mgroup', 'mpoint__mgroup__belong_dept']
class MpLogxViewSet(CustomListModelMixin, CustomGenericViewSet):
"""
list: 测点采集数据
测点采集数据
"""
perms_map = {"get": "*"}
queryset = MpLogx.objects.all()
serializer_class = MpLogxSerializer
filterset_fields = {
"timex": ["exact", "gte", "lte", "year", "month", "day"],
"mpoint": ["exact"],
}
ordering_fields = ["timex"]
ordering = ["-timex"]
class MpointStatViewSet(BulkCreateModelMixin, BulkDestroyModelMixin, CustomListModelMixin, CustomGenericViewSet):
"""
list:测点统计记录
测点统计记录
"""
perms_map = {"get": "*", "post": "mpointstat.create", "delete": "mpointstat.delete"}
queryset = MpointStat.objects.all()
serializer_class = MpointStatSerializer
select_related_fields = ["mpoint", "mpoint__ep_monitored", "mpoint__ep_belong", "mgroup", "mgroup__belong_dept"]
filterset_class = MpointStatFilter
ordering_fields = ['mpoint__report_sortstr', 'year', 'month', 'day', 'hour', 'year_s', 'month_s', 'day_s', 'mgroup__sort', 'create_time', "update_time"]
ordering = ["mpoint__report_sortstr", "-year", "-month", "-day", "-year_s", "-month_s", "-day_s", "-create_time", "mgroup__sort"]
def perform_create(self, serializer):
ins = serializer.save()
cal_mpointstat_manual.delay(ins.mpoint.id, ins.sflog.id, ins.mgroup.id, None, None, None, None, ins.year_s, ins.month_s, ins.day_s, next_cal=1)
def perform_destroy(self, instance):
mpoint, sflog, mgroup, year_s, month_s, day_s = instance.mpoint, instance.sflog, instance.mgroup, instance.year_s, instance.month_s, instance.day_s
instance.delete()
cal_mpointstat_manual.delay(mpoint.id, sflog.id, mgroup.id, None, None, None, None, year_s, month_s, day_s, next_cal=1)
@action(methods=["post"], detail=True, perms_map={"post": "mpointstat.correct"}, serializer_class=MpointStatCorrectSerializer)
def correct(self, request, *args, **kwargs):
"""修正测点统计记录及统计值
修正测点统计记录及统计值
"""
instance_id = kwargs.get("pk")
if not instance_id:
return Response({"detail": "ID not provided in the URL"}, status=400)
instance: MpointStat = self.get_object()
sr = MpointStatCorrectSerializer(data=request.data)
sr.is_valid(raise_exception=True)
last_record = None
# 校正班月和月的统计值
if instance.type in ['month_s', 'month']:
last_record = MpointStat.objects.filter(mpoint=instance.mpoint,
type=instance.type,
mgroup=instance.mgroup,
year_s=instance.year_s,
year = instance.year
).order_by(instance.type).values("id").last()
# 校正班天和天的统计值
elif instance.type in ['day_s', 'day']:
last_record = MpointStat.objects.filter(mpoint=instance.mpoint,
type=instance.type,
year = instance.year,
year_s=instance.year_s,
month_s=instance.month_s,
month = instance.month
).order_by(instance.type).values("id").last()
last_id = last_record["id"] if last_record else None
if str(last_id) == str(instance_id):
raise ParseError("不能修正当日或当月数据")
vdata = sr.validated_data
val_correct = vdata["val_correct"]
instance.val_correct = val_correct
instance.val = val_correct
instance.update_by = request.user
instance.save()
(mpoint, sflog, mgroup, year_s, month_s, day_s, year, month, day, hour) = (
instance.mpoint, instance.sflog, instance.mgroup,
instance.year_s, instance.month_s, instance.day_s, instance.hour,
instance.year, instance.month, instance.day)
# sflog 可能为None
if sflog is None:
sflogId = None
else:
sflogId = sflog.id
if mgroup is None:
mgroupId = None
else:
mgroupId = mgroup.id
myLogger.info(f'{mpoint.id}--{sflogId}--{mgroupId}--{year}--{month}--{day}--{hour}--{year_s}--{month_s}--{day_s}')
cal_mpointstat_manual.delay(mpoint.id, sflogId, mgroupId, year, month, day, hour, year_s, month_s, day_s, next_cal=1)
return Response()
@action(methods=["post"], detail=False, perms_map={"post": "mpointstat.correct"}, serializer_class=ReCalSerializer)
def recal(self, request, *args, **kwargs):
"""重新运行某段时间的enm计算
重新运行某段时间的enm计算
"""
data = request.data
sr = ReCalSerializer(data=data)
sr.is_valid(raise_exception=True)
task = cal_mpointstats_duration.delay(data["start_time"], data["end_time"])
return Response({"task_id": task.task_id})
@action(methods=["get"], detail=False, perms_map={"get": "*"})
def group_values(self, request, *args, **kwargs):
"""
测点统计数据聚合查询
"""
qs = self.filter_queryset(self.get_queryset())
group_by = request.query_params.get("group_by", "")
group_by_list = group_by.split(",")
if "" in group_by_list:
group_by_list.remove("")
if 'mpoint' not in group_by_list:
group_by_list.append('mpoint')
qs = qs.values()
qs = qs.order_by()
display_fields = ['mpoint__name', 'total_val', 'mpoint__nickname', 'mpoint__unit'] + group_by_list
aggreagte_qs = qs.values(*group_by_list).annotate(total_val = Sum('val')).values(*display_fields)
result = list(aggreagte_qs)
return Response(result)
class EnStatViewSet(CustomListModelMixin, BulkUpdateModelMixin, CustomGenericViewSet):
"""
list:能耗统计记录
能耗统计记录
"""
perms_map = {"get": "*", "put": "enstat.update"}
queryset = EnStat.objects.all()
serializer_class = EnStatSerializer
update_serializer_class = EnStatUpdateSerializer
select_related_fields = ["mgroup", "team", "mgroup__belong_dept"]
filterset_class = EnStatFilter
ordering = ["mgroup__sort", "year_s", "month_s", "day_s", "team__create_time", "create_time"]
ordering_fields = ["mgroup__sort", "year_s", "month_s", "day_s", "hour", "update_time", "create_time", "team__create_time"]
@action(methods=["post"], detail=False, perms_map={"post": "*"}, serializer_class=EnStatAnaSerializer)
def analyze(self, request, *args, **kwargs):
"""一段时间范围的工段分析数据
一段时间范围的工段分析数据(工段对比)
"""
data = request.data
sr = EnStatAnaSerializer(data=data)
sr.is_valid(raise_exception=True)
vdata = sr.validated_data
start_date: datetime = vdata["start_date"]
end_date: datetime = vdata["end_date"]
ret = get_analyse_data_mgroups_duration(start_date, end_date)
return Response(ret)
class EnStat2ViewSet(CustomListModelMixin, CustomGenericViewSet):
"""
list:全厂统计记录
全厂统计记录
"""
perms_map = {"get": "*"}
queryset = EnStat2.objects.all()
serializer_class = EnStat2Serializer
filterset_class = EnStat2Filter