# counter/log/ 添加 with_device 支持

This commit is contained in:
xianfx 2022-12-12 15:24:20 +08:00
parent fb907262be
commit 9d24ca6272
2 changed files with 113 additions and 25 deletions

View File

@ -1,12 +1,19 @@
import time import time
from typing import Optional
from django.db.models import Q, Min, Max from django.db.models import Q, Min, Max
from django.core.cache import cache from django.core.cache import cache
from rest_framework import serializers from rest_framework import serializers
from counter.models import DeviceCount, DeviceInfo from counter.models import DeviceCount, DeviceInfo
from mosquito.models import DeviceInfo as CelexDeviceInfo from mosquito.models import DeviceInfo as MosquitoDeviceInfo
from mosquito.models import MosqPostStatistic, DevicePostStatistic from mosquito.models import MosqPostStatistic, DevicePostStatistic
class DeviceSourceException(Exception):
"""
source should be counter | mosquito
"""
def get_vol(device_id, cur_vol): def get_vol(device_id, cur_vol):
vol_min_key = '{}_vol_min'.format(device_id) vol_min_key = '{}_vol_min'.format(device_id)
vol_max_key = '{}_vol_max'.format(device_id) vol_max_key = '{}_vol_max'.format(device_id)
@ -35,27 +42,59 @@ def get_latest(device_id):
return data return data
def get_device(device_id):
device_key = 'device_lon_{}'.format(device_id)
device = cache.get(device_key)
if device:
return device
qs = DeviceCount.objects.filter(~Q(longitude=0), device_id=device_id).order_by('-data_time')
if qs.count() == 0:
return None
device = qs.first()
s = DeviceCountBaseSerializer(device)
data = s.data
cache.set(device_key, data, 60 * 10)
return data
class DeviceCountBaseSerializer(serializers.ModelSerializer): class DeviceCountBaseSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = DeviceCount model = DeviceCount
fields = '__all__' fields = '__all__'
class DeviceInfoBaseSerializer(serializers.ModelSerializer):
class Meta:
model = MosquitoDeviceInfo
fields = '__all__'
device_source_map = {
'counter': DeviceCountBaseSerializer,
'mosquito': DeviceInfoBaseSerializer,
}
def get_device(device_id: str, source: str) -> Optional[dict]:
"""
Get device data serialized by DeviceCountBaseSerializer (counter) or DeviceInfoBaseSerializer (mosquito),
For source 'counter', we get device from device_counter table not device_info, because
the [lon, lat] info is located in device_counter.
For source 'mosquito', we get device from mosquito/DeviceInfo model,
due to the [point_x, point_y] is what we want.
params: device_id,
params: source, counter | mosquito
return: dict
"""
device_key = 'device_lon_{}'.format(device_id)
device = cache.get(device_key)
if device:
return device
if source == 'counter':
qs = DeviceCount.objects.filter(~Q(longitude=0),
device_id=device_id).order_by('-data_time')
elif source == 'mosquito':
qs = MosquitoDeviceInfo.objects.filter(device_id=device_id)
else:
raise DeviceSourceException("source should be counter or mosquito")
if qs.count() == 0:
return None
device = qs.first()
s = device_source_map[source](device)
data = s.data
cache.set(device_key, data, 60 * 10)
return data
class DeviceCountSerializer(serializers.ModelSerializer): class DeviceCountSerializer(serializers.ModelSerializer):
device_name = serializers.SerializerMethodField() device_name = serializers.SerializerMethodField()
mosq_count = serializers.SerializerMethodField() mosq_count = serializers.SerializerMethodField()
@ -103,7 +142,7 @@ class DeviceCountSerializer(serializers.ModelSerializer):
if device: if device:
self.device = device self.device = device
return device.device_name return device.device_name
qs = CelexDeviceInfo.objects.filter(device_id=device_id) qs = MosquitoDeviceInfo.objects.filter(device_id=device_id)
if qs.count() > 0: if qs.count() > 0:
device = qs[0] device = qs[0]
self.device = device self.device = device
@ -126,6 +165,50 @@ class DeviceCountSerializer(serializers.ModelSerializer):
return obj.latitude return obj.latitude
class DeviceCountWithInfoSerializer(DeviceCountSerializer):
location_id = serializers.SerializerMethodField()
point_x = serializers.SerializerMethodField()
point_y = serializers.SerializerMethodField()
class Meta:
model = DeviceCount
fields = [
'id',
'device_id',
'device_name',
'signal',
'mosq_count',
'energy',
'calc_time',
'longitude',
'latitude',
'location_id',
'point_x',
'point_y',
]
def get_location_id(self, obj):
device = self.device
if device:
if device.location_id:
return device.location_id
return None
def get_point_x(self, obj):
device = self.device
if device:
if device.point_x:
return device.point_x
return None
def get_point_y(self, obj):
device = self.device
if device:
if device.point_y:
return device.point_y
return None
class DeviceInfoSerializer(serializers.ModelSerializer): class DeviceInfoSerializer(serializers.ModelSerializer):
device_name = serializers.SerializerMethodField() device_name = serializers.SerializerMethodField()
status = serializers.SerializerMethodField() status = serializers.SerializerMethodField()
@ -154,7 +237,7 @@ class DeviceInfoSerializer(serializers.ModelSerializer):
self.cur_device = None self.cur_device = None
def get_device_name(self, obj): def get_device_name(self, obj):
qs = CelexDeviceInfo.objects.filter(device_id=obj.device_id) qs = MosquitoDeviceInfo.objects.filter(device_id=obj.device_id)
if qs.count() > 0: if qs.count() > 0:
device = qs[0] device = qs[0]
self.cur_device = device self.cur_device = device
@ -193,7 +276,7 @@ class DeviceInfoSerializer(serializers.ModelSerializer):
return [lon, lat] return [lon, lat]
# query = DeviceCount.objects.filter(~Q(longitude=0), device_id=obj.device_id).order_by('-data_time') # query = DeviceCount.objects.filter(~Q(longitude=0), device_id=obj.device_id).order_by('-data_time')
device = get_device(obj.device_id) device = get_device(obj.device_id, source='counter')
if device: if device:
return [device['longitude'], device['latitude']] return [device['longitude'], device['latitude']]
return None return None
@ -205,7 +288,6 @@ class DeviceInfoSerializer(serializers.ModelSerializer):
class LatestDailySerializer(serializers.ModelSerializer): class LatestDailySerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = MosqPostStatistic model = MosqPostStatistic
fields = [ fields = [
@ -216,7 +298,6 @@ class LatestDailySerializer(serializers.ModelSerializer):
class DeviceLogHistorySerializer(serializers.ModelSerializer): class DeviceLogHistorySerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = DevicePostStatistic model = DevicePostStatistic
fields = [ fields = [

View File

@ -21,6 +21,7 @@ from mosquito.api.pagination import (
) )
from .serializers import ( from .serializers import (
DeviceCountSerializer, DeviceCountSerializer,
DeviceCountWithInfoSerializer,
DeviceInfoSerializer, DeviceInfoSerializer,
LatestDailySerializer, LatestDailySerializer,
DeviceLogHistorySerializer, DeviceLogHistorySerializer,
@ -32,12 +33,18 @@ from mosquito.models import DeviceInfo as CelexDeviceInfo
class DeviceLogListAPIView(ListAPIView, RoleMixin, DeviceListMixin): class DeviceLogListAPIView(ListAPIView, RoleMixin, DeviceListMixin):
serializer_class = DeviceCountSerializer # serializer_class = DeviceCountSerializer
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
filter_backends = [SearchFilter, OrderingFilter] filter_backends = [SearchFilter, OrderingFilter]
pagination_class = DeviceLogListPagination pagination_class = DeviceLogListPagination
search_fields = ['device_id'] search_fields = ['device_id']
def get_serializer_class(self):
with_device = self.request.GET.get('with_device')
if with_device == 'true':
return DeviceCountWithInfoSerializer
return DeviceCountSerializer
def get_queryset(self, *args, **kwargs): def get_queryset(self, *args, **kwargs):
user_roles = self.get_role() user_roles = self.get_role()
device = self.request.GET.get('device') device = self.request.GET.get('device')