# 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
from typing import Optional
from django.db.models import Q, Min, Max
from django.core.cache import cache
from rest_framework import serializers
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
class DeviceSourceException(Exception):
"""
source should be counter | mosquito
"""
def get_vol(device_id, cur_vol):
vol_min_key = '{}_vol_min'.format(device_id)
vol_max_key = '{}_vol_max'.format(device_id)
@ -35,27 +42,59 @@ def get_latest(device_id):
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 Meta:
model = DeviceCount
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):
device_name = serializers.SerializerMethodField()
mosq_count = serializers.SerializerMethodField()
@ -103,7 +142,7 @@ class DeviceCountSerializer(serializers.ModelSerializer):
if device:
self.device = device
return device.device_name
qs = CelexDeviceInfo.objects.filter(device_id=device_id)
qs = MosquitoDeviceInfo.objects.filter(device_id=device_id)
if qs.count() > 0:
device = qs[0]
self.device = device
@ -126,6 +165,50 @@ class DeviceCountSerializer(serializers.ModelSerializer):
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):
device_name = serializers.SerializerMethodField()
status = serializers.SerializerMethodField()
@ -154,7 +237,7 @@ class DeviceInfoSerializer(serializers.ModelSerializer):
self.cur_device = None
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:
device = qs[0]
self.cur_device = device
@ -164,7 +247,7 @@ class DeviceInfoSerializer(serializers.ModelSerializer):
def get_status(self, obj):
return obj.online
def get_count(self, obj) ->str:
def get_count(self, obj) -> str:
try:
# self.latest = DeviceCount.objects.filter(device_id=obj.device_id).order_by('-data_time')[0]
self.latest = get_latest(obj.device_id)
@ -174,12 +257,12 @@ class DeviceInfoSerializer(serializers.ModelSerializer):
return self.latest['count']
return '0'
def get_signal(self, obj) ->str:
def get_signal(self, obj) -> str:
if self.latest:
return self.latest['csq']
return '0'
def get_energy(self, obj) ->str:
def get_energy(self, obj) -> str:
if self.latest:
if float(self.latest['vol']) <= 100:
return '{}{}'.format(round(float(self.latest['vol']), 1), '%')
@ -193,7 +276,7 @@ class DeviceInfoSerializer(serializers.ModelSerializer):
return [lon, lat]
# 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:
return [device['longitude'], device['latitude']]
return None
@ -205,7 +288,6 @@ class DeviceInfoSerializer(serializers.ModelSerializer):
class LatestDailySerializer(serializers.ModelSerializer):
class Meta:
model = MosqPostStatistic
fields = [
@ -216,7 +298,6 @@ class LatestDailySerializer(serializers.ModelSerializer):
class DeviceLogHistorySerializer(serializers.ModelSerializer):
class Meta:
model = DevicePostStatistic
fields = [

View File

@ -21,6 +21,7 @@ from mosquito.api.pagination import (
)
from .serializers import (
DeviceCountSerializer,
DeviceCountWithInfoSerializer,
DeviceInfoSerializer,
LatestDailySerializer,
DeviceLogHistorySerializer,
@ -32,12 +33,18 @@ from mosquito.models import DeviceInfo as CelexDeviceInfo
class DeviceLogListAPIView(ListAPIView, RoleMixin, DeviceListMixin):
serializer_class = DeviceCountSerializer
# serializer_class = DeviceCountSerializer
permission_classes = [IsAuthenticated]
filter_backends = [SearchFilter, OrderingFilter]
pagination_class = DeviceLogListPagination
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):
user_roles = self.get_role()
device = self.request.GET.get('device')