статус с резервуара теперь берется из бд сайта

This commit is contained in:
VladislavOstapov 2024-01-23 13:48:05 +03:00
parent f7dbad696a
commit 71e9fc37e9
8 changed files with 93 additions and 69 deletions

View File

@ -18,8 +18,5 @@ from django.urls import path
from . import views
urlpatterns = [
path('', views.view_index, name='index'),
path('fetch/stats', views.view_stats, name='fetch-stats'),
path('fetch/tank-chart', views.view_tank_chart, name='fetch-tank-chart'),
# path('methods/<str:method_name>', views.call_method, name='call_method')
path('', views.view_index, name='index')
]

View File

@ -1,36 +1,9 @@
import os
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden
from django.shortcuts import render
# from django.db.models import Manager
from django.contrib.auth.decorators import login_required, permission_required
# только для тестирования!
import requests
TEST_BASE_FETCH = "https://test.wawaa.ru/dev-fetch.php"
from django.contrib.auth.decorators import login_required
@login_required
def view_index(request):
return render(request, 'index.html')
@permission_required(perm='view_logs', raise_exception=True)
def view_stats(request):
# TODO: вставить использование привилегий для получения данных
# только для тестирования!
res = requests.get(TEST_BASE_FETCH + "?stats", headers={'Authorization': os.getenv("TEST_AUTH")})
response = HttpResponse(res.content)
response.headers["Content-type"] = response.headers["Content-type"]
return response
@permission_required(perm='view_logs', raise_exception=True)
def view_tank_chart(request):
# только для тестирования!
days = request.GET.get('days', '7')
res = requests.get(TEST_BASE_FETCH + "?tank_chart=" + days, headers={'Authorization': os.getenv("TEST_AUTH")})
response = HttpResponse(res.content)
response.headers["Content-type"] = response.headers["Content-type"]
return response

View File

@ -1,5 +1,5 @@
from django.db import models
from datetime import datetime
from datetime import datetime, timedelta
# select UNIX_TIMESTAMP(datetime), level_percentage, radar_low_reg, status_reg from tcs
@ -12,6 +12,26 @@ class MbTankRecord(models.Model):
def __str__(self):
return f"({self.id}) {self.dt}: radar={self.radar_raw}, level={self.level}"
@staticmethod
def load_stats():
result = {
'last_update': None, # последнее обновление, unix time
'level': None, # текущее показание, пересчитанное в %
'radar': None, # текущее показание с радара
'status': None, # статусный регистр
'last_radar_values': [] # последние показания за 15 минут
}
last_save = MbTankRecord.objects.order_by('-dt').first()
if last_save is not None:
result['last_update'] = last_save.dt.timestamp()
result['level'] = last_save.level
result['radar'] = last_save.radar_raw
result['status'] = last_save.status
query = MbTankRecord.objects.filter(dt__gt=(datetime.now() - timedelta(minutes=15))).order_by('dt')
result['last_radar_values'] = [(int(item.dt.timestamp()), item.radar_raw) for item in query]
return result
class MbPumpRecord(models.Model):
dt = models.DateTimeField(verbose_name="Время записи", default=datetime.now)

View File

@ -14,7 +14,7 @@ class MbClearHistoryService(Thread):
def run(self):
while True:
self.model.objects.filter(dt__lt=(timezone.now() - timezone.timedelta(days=60))).delete()
self.model.objects.filter(dt__lt=(datetime.now() - timedelta(days=60))).delete()
time.sleep(10)
@ -79,21 +79,10 @@ class MbService(Thread):
else:
last_query = datetime.now()
def to_json(self):
return {}
class MbTankService(MbService):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.registers = {}
# {
# 'last_update': None, # последнее обновление, unix time
# 'level': None, # текущее показание, пересчитанное в %
# 'radar': None, # текущее показание с радара
# 'status': None, # статусный регистр
# 'last_radar_values': [] # последние показания за 15 минут
# }
self._curr_state = None
# {
@ -102,23 +91,8 @@ class MbTankService(MbService):
# "radar": int
# }
# для фильтрации уровня, чтобы его в бд писать
self.level_filter = []
def _update_last_radar_values(self):
res = [[item.dt.timestamp(), item.radar_raw]
for item in MbTankRecord.objects.filter(dt__gt=(datetime.now() - timedelta(minutes=15))).order_by('-dt')]
self.registers['last_radar_values'] = res
def _init_state(self):
self.last_save = MbTankRecord.objects.order_by('-dt').first()
print(f"Initializing MbTankService: last_save={self.last_save}")
if self.last_save is not None:
self.registers['last_update'] = self.last_save.dt
self.registers['level'] = self.last_save.level
self.registers['radar'] = self.last_save.radar_raw
self.registers['status'] = self.last_save.status
self._update_last_radar_values()
pass
def _push_current_state(self):
record = MbTankRecord(radar_raw=self._curr_state['radar'],
@ -137,14 +111,10 @@ class MbTankService(MbService):
"status": values[5],
"radar": (values[1] << 16) | values[2]
}
self.registers['last_update'] = datetime.now()
def _check_need_save(self):
return True
def to_json(self):
return self.registers
class MbPumpService(MbService):
_config = {

23
logs_service/urls.py Normal file
View File

@ -0,0 +1,23 @@
"""logs_service URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.urls import path
from . import views
urlpatterns = [
path('stats', views.view_stats, name='fetch-stats'),
path('tank-chart', views.view_tank_chart, name='fetch-tank-chart'),
]

40
logs_service/views.py Normal file
View File

@ -0,0 +1,40 @@
import json
from django.shortcuts import render
import os
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden
from django.contrib.auth.decorators import login_required, permission_required
from .models import MbTankRecord
# только для тестирования!
import requests
TEST_BASE_FETCH = "https://test.wawaa.ru/dev-fetch.php"
@permission_required(perm='logs_service.view_mbtankrecord', raise_exception=True)
def view_stats(request):
# TODO: вставить использование привилегий для получения данных
# только для тестирования!
ext_stats = requests.get(TEST_BASE_FETCH + "?stats", headers={'Authorization': os.getenv("TEST_AUTH")})
out = {
'stats': {
'tank': MbTankRecord.load_stats(),
'pump': ext_stats.json()['stats']['pump']
}
}
response = HttpResponse(json.dumps(out))
response.headers["Content-type"] = response.headers["Content-type"]
return response
@permission_required(perm='view_logs', raise_exception=True)
def view_tank_chart(request):
# только для тестирования!
days = request.GET.get('days', '7')
res = requests.get(TEST_BASE_FETCH + "?tank_chart=" + days, headers={'Authorization': os.getenv("TEST_AUTH")})
response = HttpResponse(res.content)
response.headers["Content-type"] = response.headers["Content-type"]
return response

View File

@ -22,5 +22,6 @@ from django.contrib.staticfiles.views import serve
urlpatterns = [
path('', include('index.urls')),
path('account/', include('users.urls')),
path('fetch/', include('logs_service.urls')),
path('admin/', admin.site.urls),
]

View File

@ -133,22 +133,22 @@ const updateFunctions = {
// Текущий уровень воды: <span id="tank-level-now"></span>%
'tank-level-now': (element, dataset) => {
element.innerHTML = dataset['tank']['last_percentage']
element.innerHTML = dataset['tank']['level']
// тут все хорошо если влезаем в установленные рамки +-2% (69-80%)
_setIndicatorClass(element, 67 <= dataset['tank']['last_percentage'] <= 82)
},
// Текущее значение с радара
'tank-raw-now': (element, dataset) => {
element.innerHTML = dataset['tank']['last_radar']
element.innerHTML = dataset['tank']['radar']
},
// Статус: <span id="tank-status"></span>
'tank-status': (element, dataset) => {
const shur_status_bits = ['нужна вода', 'поплавок нижний', 'поплавок верхний', 'поплавок аварийный']
element.innerHTML = unpackBits(dataset['tank']['status_reg'], shur_status_bits) + " (" + dataset['tank']['status_reg'] + ")"
element.innerHTML = unpackBits(dataset['tank']['status'], shur_status_bits) + " (" + dataset['tank']['status'] + ")"
// тут все хорошо, пока нет аварийного поплавка
_setIndicatorClass(element, (dataset['tank']['status_reg'] & 0x8) === 0)
_setIndicatorClass(element, (dataset['tank']['status'] & 0x8) === 0)
},
// Частота ПЧ: <span id="pump-vfd-freq"></span>Гц