import json import os from datetime import datetime, timedelta from django.http import HttpResponse, HttpResponseBadRequest from django.contrib.auth.decorators import permission_required from .models import MbTankRecord from .apps import LogsServiceConfig @permission_required(perm='logs_service.view_mbtankrecord', raise_exception=True) def view_stats(request): print(f"Executing view_stats in process with pid={os.getpid()}") # данные резервуара tank = {} if request.user.has_perm('logs_service.view_mbtankrecord'): if LogsServiceConfig.mb_pump_service is not None and LogsServiceConfig.mb_pump_service_enable: tank = MbTankRecord.load_stats() # данные насосной pump = {} if request.user.has_perm('logs_service.view_pump_stats'): if LogsServiceConfig.mb_pump_service is not None and LogsServiceConfig.mb_pump_service_enable: pump = LogsServiceConfig.mb_pump_service.get_stats() # данные HART-модема, он же расходометр hart = {} if request.user.has_perm('logs_service.view_accumulated_flow'): if LogsServiceConfig.mb_hart_service is not None and LogsServiceConfig.mb_hart_service_enable: hart = LogsServiceConfig.mb_hart_service.get_stats() out = { 'stats': { 'tank': tank, 'pump': pump, 'hart': hart } } response = HttpResponse(json.dumps(out)) response.headers["Content-type"] = response.headers["Content-type"] return response @permission_required(perm='logs_service.view_mbtankrecord', raise_exception=True) def view_tank_chart(request): try: days = int(request.GET.get('days', '7')) except ValueError: return HttpResponseBadRequest() # ограничения времени if days < 1: days = 1 elif days > 31: days = 31 # select dt, level from tcs where datetime >= (NOW() - INTERVAL $days DAY) order by dt query = MbTankRecord.objects.filter(dt__gt=(datetime.now() - timedelta(days=days))).order_by('dt') q_len = len(query) # тот самый оптимизирующий алгоритм, в худшем случае (31 день) он отрабатывает за 64мс tank_chart = [] max_seconds = (3600 * 24 * days) / 50 last_time = None last_value = None for i in range(0, q_len): need_push = False curr_t = query[i].dt.timestamp() curr_v = query[i].level # нужно пушить, если предыдущее время пустое if last_time is None: last_time, last_value = curr_t, curr_v need_push = True if not need_push: # дальнейшие проверки имеют смысл, если есть переменная last_time if i + 1 < q_len: if last_value != curr_v: # случай первый: если значение процентов изменилось need_push = True # сбросим еще последнее время, возьмем его на следующем цикле last_time = None elif query[i + 1].dt.timestamp() - last_time > max_seconds: # случай третий: если следующее время выходит за границу в установленное количество секунд need_push = True last_time = curr_t else: # случай второй - больше значений нет, последнее значение тоже нужно need_push = True if need_push: tank_chart.append((int(curr_t), curr_v)) response = HttpResponse(json.dumps({'tank_chart': tank_chart})) response.headers["Content-type"] = response.headers["Content-type"] return response