85 lines
3.3 KiB
Python
85 lines
3.3 KiB
Python
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 = 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()
|
||
|
||
out = {
|
||
'stats': {
|
||
'tank': tank,
|
||
'pump': pump
|
||
}
|
||
}
|
||
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
|