From 413ac262af4743c2e7e6973783a7b5992af68ec6 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 16 May 2024 10:24:33 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20mpointstat=20=E5=A2=9E=E5=8A=A0correct?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../enm/migrations/0037_auto_20240516_1016.py | 23 ++++ apps/enm/models.py | 2 + apps/enm/serializers.py | 6 + apps/enm/tasks.py | 129 +++++++++++------- apps/enm/views.py | 25 +++- 5 files changed, 138 insertions(+), 47 deletions(-) create mode 100644 apps/enm/migrations/0037_auto_20240516_1016.py diff --git a/apps/enm/migrations/0037_auto_20240516_1016.py b/apps/enm/migrations/0037_auto_20240516_1016.py new file mode 100644 index 00000000..dc9a36d8 --- /dev/null +++ b/apps/enm/migrations/0037_auto_20240516_1016.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.12 on 2024-05-16 02:16 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('enm', '0036_auto_20240515_1037'), + ] + + operations = [ + migrations.AddField( + model_name='mpointstat', + name='val_correct', + field=models.FloatField(blank=True, null=True, verbose_name='统计矫正值'), + ), + migrations.AddField( + model_name='mpointstat', + name='val_origin', + field=models.FloatField(default=0, verbose_name='统计原始值'), + ), + ] diff --git a/apps/enm/models.py b/apps/enm/models.py index 3f97ebf0..79c76e7b 100644 --- a/apps/enm/models.py +++ b/apps/enm/models.py @@ -91,6 +91,8 @@ class MpointStat(CommonADModel): mgroup = models.ForeignKey(Mgroup, verbose_name="关联测点集", on_delete=models.CASCADE, null=True, blank=True) mpoint = models.ForeignKey(Mpoint, verbose_name="关联测点", on_delete=models.CASCADE) val = models.FloatField("统计值", default=0) + val_origin = models.FloatField("统计原始值", default=0) + val_correct = models.FloatField("统计矫正值", null=True, blank=True) total_production = models.FloatField("总产量", default=0, help_text="t") elec_consume_unit = models.FloatField("单位产品电耗", default=0, help_text="kw·h/t") diff --git a/apps/enm/serializers.py b/apps/enm/serializers.py index b7a9b7bd..ceb13ccd 100644 --- a/apps/enm/serializers.py +++ b/apps/enm/serializers.py @@ -162,3 +162,9 @@ class EnStat2Serializer(CustomModelSerializer): class ReCalSerializer(serializers.Serializer): start_time = serializers.DateTimeField(label="开始时间") end_time = serializers.DateTimeField(label="结束时间") + + +class MpointStatCorrectSerializer(CustomModelSerializer): + class Meta: + model = MpointStat + fields = ['val_correct', 'id'] \ No newline at end of file diff --git a/apps/enm/tasks.py b/apps/enm/tasks.py index 3fd2ecdf..450631a5 100644 --- a/apps/enm/tasks.py +++ b/apps/enm/tasks.py @@ -131,29 +131,41 @@ def cal_mpointstat_hour(mpointId: str, year: int, month: int, day: int, hour: in else: return ms, _ = MpointStat.objects.get_or_create(**params, defaults=params) - ms.val = val + ms.val = ms.val_correct if ms.val_correct is not None else val ms.save() # 更新更高级别的值 if cascade or hour == 23: - sum_dict_day = MpointStat.objects.filter(type="hour", mpoint=mpoint, year=year, month=month, day=day).aggregate(sum=Sum("val")) params_day = {"type": "day", "mpoint": mpoint, "year": year, "month": month, "day": day} ms_day, _ = MpointStat.objects.get_or_create(**params_day, defaults=params_day) - ms_day.val = sum_dict_day['sum'] if sum_dict_day['sum'] is not None else 0 + if ms_day.val_correct is not None: + ms_day.val = ms_day.val_correct + else: + sum_dict_day = MpointStat.objects.filter(type="hour", mpoint=mpoint, year=year, month=month, day=day).aggregate(sum=Sum("val")) + ms_day.val = sum_dict_day['sum'] if sum_dict_day['sum'] is not None else 0 + ms_day.val_origin = ms_day.val ms_day.save() if cascade or day in [28, 29, 30, 31]: - sum_dict_month = MpointStat.objects.filter(type="day", mpoint=mpoint, year=year, month=month).aggregate(sum=Sum("val")) params_month = {"type": "month", "mpoint": mpoint, "year": year, "month": month} ms_month, _ = MpointStat.objects.get_or_create(**params_month, defaults=params_month) - ms_month.val = sum_dict_month['sum'] if sum_dict_month['sum'] is not None else 0 + if ms_month.val_correct is not None: + ms_month.val = ms_month.val_correct + else: + sum_dict_month = MpointStat.objects.filter(type="day", mpoint=mpoint, year=year, month=month).aggregate(sum=Sum("val")) + ms_month.val = sum_dict_month['sum'] if sum_dict_month['sum'] is not None else 0 + ms_month.val_origin = ms_month.val ms_month.save() if cascade or month == 12: - sum_dict_year = MpointStat.objects.filter(type="month", mpoint=mpoint, year=year).aggregate(sum=Sum("val")) params_year = {"type": "year", "mpoint": mpoint, "year": year} ms_year, _ = MpointStat.objects.get_or_create(**params_year, defaults=params_year) - ms_year.val = sum_dict_year['sum'] if sum_dict_year['sum'] is not None else 0 + if ms_year.val_correct is not None: + ms_year.val = ms_year.val_correct + else: + sum_dict_year = MpointStat.objects.filter(type="month", mpoint=mpoint, year=year).aggregate(sum=Sum("val")) + ms_year.val = sum_dict_year['sum'] if sum_dict_year['sum'] is not None else 0 + ms_year.val_origin = ms_year.val ms_year.save() mgroup = mpoint.mgroup @@ -177,14 +189,18 @@ def cal_mpointstat_hour(mpointId: str, year: int, month: int, day: int, hour: in "hour": hour, } ms_hour_s, _ = MpointStat.objects.get_or_create(**params_hour_s, defaults=params_hour_s) - ms_hour_s.val = ms.val + ms_hour_s.val = ms_hour_s.val_correct if ms_hour_s.val_correct is not None else ms.val ms_hour_s.save() # 开始往上计算 - sum_dict_sflog_s = MpointStat.objects.filter(type="hour_s", mpoint=mpoint, year_s=year_s, month_s=month_s, day_s=day_s, sflog=sflog).aggregate(sum=Sum("val")) params_sflog_s = {"type": "sflog", "mpoint": mpoint, "sflog": sflog, "year_s": year_s, "month_s": month_s, "day_s": day_s, "mgroup": mgroup} ms_sflog_s, _ = MpointStat.objects.get_or_create(**params_sflog_s, defaults=params_sflog_s) - ms_sflog_s.val = sum_dict_sflog_s['sum'] if sum_dict_sflog_s['sum'] is not None else 0 + if ms_sflog_s.val_correct is not None: + ms_sflog_s.val = ms_sflog_s.val_correct + else: + sum_dict_sflog_s = MpointStat.objects.filter(type="hour_s", mpoint=mpoint, year_s=year_s, month_s=month_s, day_s=day_s, sflog=sflog).aggregate(sum=Sum("val")) + ms_sflog_s.val = sum_dict_sflog_s['sum'] if sum_dict_sflog_s['sum'] is not None else 0 + ms_sflog_s.val_origin = ms_sflog_s.val ms_sflog_s.save() # next_cal_dict = [mpoint.material.id, sflog.id, year, month, day, hour, year_s, month_s, day_s] @@ -272,29 +288,53 @@ def cal_mpointstat_manual(mpointId: str, sflogId: str, mgroupId: str, year: int, """ mpoint = Mpoint.objects.get(id=mpointId) mgroup = Mgroup.objects.get(id=mgroupId) - sum_dict_day_s = MpointStat.objects.filter(type="sflog", mpoint=mpoint, year_s=year_s, month_s=month_s, day_s=day_s, mgroup=mgroup).aggregate(sum=Sum("val")) - params_day_s = {"type": "day_s", "mpoint": mpoint, "year_s": year_s, "month_s": month_s, "day_s": day_s, "mgroup": mgroup} - ms_day_s, _ = MpointStat.objects.get_or_create(**params_day_s, defaults=params_day_s) - ms_day_s.val = sum_dict_day_s['sum'] if sum_dict_day_s['sum'] is not None else 0 - ms_day_s.save() + if sflogId: + params_day_s = {"type": "day_s", "mpoint": mpoint, "year_s": year_s, "month_s": month_s, "day_s": day_s, "mgroup": mgroup} + ms_day_s, _ = MpointStat.objects.get_or_create(**params_day_s, defaults=params_day_s) + if ms_day_s.val_correct is not None: + ms_day_s.val = ms_day_s.val_correct + else: + sum_dict_day_s = MpointStat.objects.filter(type="sflog", mpoint=mpoint, year_s=year_s, month_s=month_s, day_s=day_s, mgroup=mgroup).aggregate(sum=Sum("val")) + ms_day_s.val = sum_dict_day_s['sum'] if sum_dict_day_s['sum'] is not None else 0 + ms_day_s.val_origin = ms_day_s.val + ms_day_s.save() - sum_dict_month_s = MpointStat.objects.filter(type="day_s", mpoint=mpoint, year_s=year_s, month_s=month_s, mgroup=mgroup).aggregate(sum=Sum("val")) - params_month_s = {"type": "month_s", "mpoint": mpoint, "year_s": year_s, "month_s": month_s, "mgroup": mgroup} - ms_month_s, _ = MpointStat.objects.get_or_create(**params_month_s, defaults=params_month_s) - ms_month_s.val = sum_dict_month_s['sum'] if sum_dict_month_s['sum'] is not None else 0 - ms_month_s.save() - - sum_dict_year_s = MpointStat.objects.filter(type="month_s", mpoint=mpoint, year_s=year_s, mgroup=mgroup).aggregate(sum=Sum("val")) - params_year_s = {"type": "year_s", "mpoint": mpoint, "year_s": year_s, "mgroup": mgroup} - ms_year_s, _ = MpointStat.objects.get_or_create(**params_year_s, defaults=params_year_s) - ms_year_s.val = sum_dict_year_s['sum'] if sum_dict_year_s['sum'] is not None else 0 - ms_year_s.save() + if day_s: + params_month_s = {"type": "month_s", "mpoint": mpoint, "year_s": year_s, "month_s": month_s, "mgroup": mgroup} + ms_month_s, _ = MpointStat.objects.get_or_create(**params_month_s, defaults=params_month_s) + if ms_month_s.val_correct is not None: + ms_month_s.val = ms_month_s.val_correct + else: + sum_dict_month_s = MpointStat.objects.filter(type="day_s", mpoint=mpoint, year_s=year_s, month_s=month_s, mgroup=mgroup).aggregate(sum=Sum("val")) + ms_month_s.val = sum_dict_month_s['sum'] if sum_dict_month_s['sum'] is not None else 0 + ms_month_s.val_origin = ms_month_s.val + ms_month_s.save() + + if month_s: + params_year_s = {"type": "year_s", "mpoint": mpoint, "year_s": year_s, "mgroup": mgroup} + ms_year_s, _ = MpointStat.objects.get_or_create(**params_year_s, defaults=params_year_s) + if ms_year_s.val_correct is not None: + ms_year_s.val = ms_year_s.val_correct + else: + sum_dict_year_s = MpointStat.objects.filter(type="month_s", mpoint=mpoint, year_s=year_s, mgroup=mgroup).aggregate(sum=Sum("val")) + ms_year_s.val = sum_dict_year_s['sum'] if sum_dict_year_s['sum'] is not None else 0 + ms_year_s.val_origin = ms_year_s.val + ms_year_s.save() if next_cal: # 计算工段级数据,手动录入时调用 + start_cal_type = 'hour_s' if hour: - cal_enstat("hour_s", sflogId, mgroupId, year, month, day, hour, year_s, month_s, day_s) - else: - cal_enstat("sflog", sflogId, mgroupId, year, month, day, hour, year_s, month_s, day_s) + start_cal_type = 'hour_s' + elif sflogId: + start_cal_type = 'sflog' + elif day_s: + start_cal_type = 'day_s' + elif month_s: + start_cal_type = 'month_s' + elif year_s: + start_cal_type = 'year_s' + cal_enstat(start_cal_type, sflogId, mgroupId, year, month, day, hour, year_s, month_s, day_s) + types_list = ["hour_s", "sflog", "day_s", "month_st", "month_s", "year_s"] @@ -451,26 +491,23 @@ def cal_enstat(type, sflogId, mgroupId, year, month, day, hour, year_s, month_s, MpointStat.objects.filter( mgroup=enstat.mgroup, mpoint__material__code="elec", type=enstat.type, year_s=enstat.year_s, month_s=enstat.month_s, day_s=enstat.day_s, hour=enstat.hour ).exclude(mpoint__ep_monitored=None).update(total_production=total_production, elec_consume_unit=elec_consume_unit) - if enstat.mgroup.cate == "section": - if "material" in this_cal_attrs: - # 算能耗 - if enstat.mgroup.name != "回转窑": - try: - enstat.en_consume_unit = enstat.elec_coal_consume / enstat.total_production - except ZeroDivisionError: - enstat.en_consume_unit = 0 + # 更新余热发电的production_elec_unit + if mgroup.name == "回转窑": + EnStat.objects.filter(type=enstat.type, year_s=enstat.year_s, month_s=enstat.month_s, day_s=enstat.day_s, hour=enstat.hour, mgroup__name="余热发电").update( + production_elec_unit=F("total_production") / enstat.total_production + ) + + # 其他一些触发计算 + if mgroup.cate == "section": + if "material" in this_cal_attrs and mgroup.name != "回转窑": + try: + enstat.en_consume_unit = enstat.elec_coal_consume / enstat.total_production + except ZeroDivisionError: + enstat.en_consume_unit = 0 enstat.save() # 计算一些其他数据 if type == "month_st" and "material" in this_cal_attrs: # 如果计算的是班月,把主要设备电耗数据拉过来, 方便查询 - # res = MpointStat.objects.filter(type='sflog', year_s=year_s, month_s=month_s, sflog__team=enstat.team, mpoint__ep_monitored__power_kw__gte=100).values( - # equipment=F('mpoint__ep_monitored__id'), equipment_name=F('mpoint__ep_monitored__name')).annotate(consume=Sum('val')) - # res = list(res) - # for item in res: - # try: - # item['consume_unit'] = item['consume'] / enstat.total_production - # except ZeroDivisionError: - # item['consume_unit'] = None - res = MpointStat.objects.filter(type="sflog", year_s=year_s, month_s=month_s, sflog__team=enstat.team, mpoint__ep_monitored__power_kw__gte=100).values( + res = MpointStat.objects.filter(type="sflog", year_s=year_s, month_s=month_s, sflog__team=enstat.team, mpoint__ep_monitored__isnull=False).values( "elec_consume_unit", equipment=F("mpoint__ep_monitored__id"), equipment_name=F("mpoint__ep_monitored__name") ) enstat.equip_elec_data = list(res) diff --git a/apps/enm/views.py b/apps/enm/views.py index 5ea5826e..79e77c71 100644 --- a/apps/enm/views.py +++ b/apps/enm/views.py @@ -3,7 +3,7 @@ from django.conf import settings from apps.enm.models import Mpoint, MpointStat, EnStat, EnStat2, MpLogx from apps.utils.viewsets import CustomModelViewSet, CustomGenericViewSet from apps.utils.mixins import BulkCreateModelMixin, BulkDestroyModelMixin, CustomListModelMixin -from apps.enm.serializers import MpointSerializer, MpLogxSerializer, MpointStatSerializer, EnStatSerializer, EnStat2Serializer, ReCalSerializer +from apps.enm.serializers import MpointSerializer, MpLogxSerializer, MpointStatSerializer, EnStatSerializer, EnStat2Serializer, ReCalSerializer, MpointStatCorrectSerializer from apps.enm.filters import MpointStatFilter, EnStatFilter, EnStat2Filter from apps.enm.tasks import cal_mpointstat_manual from rest_framework.response import Response @@ -118,6 +118,29 @@ class MpointStatViewSet(BulkCreateModelMixin, BulkDestroyModelMixin, CustomListM 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=False, perms_map={"post": "mpointstat.correct"}, serializer_class=MpointStatCorrectSerializer) + def correct(self, request, *args, **kwargs): + """修正测点统计记录及统计值 + + 修正测点统计记录及统计值 + """ + instance = self.get_object() + sr = MpointStatCorrectSerializer(data=request.data) + sr.is_valid(raise_exception=True) + vdata = sr.validated_data + val_correct = vdata["val_correct"] + if val_correct: + instance.val = val_correct + instance.save() + mpoint, sflog, mgroup, year_s, month_s, day_s = instance.mpoint, instance.sflog, instance.mgroup, instance.year_s, instance.month_s, instance.day_s + # sflog 可能为None + if sflog is None: + sflogId = None + else: + sflogId = sflog.id + cal_mpointstat_manual.delay(mpoint.id, sflogId, mgroup.id, None, None, None, None, year_s, month_s, day_s, next_cal=1) + return Response() + @action(methods=["post"], detail=False, perms_map={"post": "mpointstat.create"}, serializer_class=ReCalSerializer) def recal(self, request, *args, **kwargs): """重新运行某段时间的enm计算