关联WeatherLog和WeatherStationInfo

This commit is contained in:
VijayHuang 2022-12-14 11:04:55 +08:00
parent 9d24ca6272
commit 204acf9ab4
2 changed files with 152 additions and 2 deletions

View File

@ -1,3 +1,6 @@
import time
from typing import Optional
from django.db.models import Q, Min, Max
from rest_framework import serializers from rest_framework import serializers
from django.core.cache import cache from django.core.cache import cache
from mosquito.models import Mosquito, MosqPost, DeviceTempLog, WeatherLog, WeatherStationInfo, DeviceInfo from mosquito.models import Mosquito, MosqPost, DeviceTempLog, WeatherLog, WeatherStationInfo, DeviceInfo
@ -50,6 +53,66 @@ class DeviceTempLogSerializer(serializers.ModelSerializer):
return obj.last_time.strftime('%Y-%m-%d %H:%M:%S') return obj.last_time.strftime('%Y-%m-%d %H:%M:%S')
class DeviceSourceException(Exception):
"""
source should be counter | mosquito
"""
class WeatherLogBaseSerializer(serializers.ModelSerializer):
class Meta:
model = WeatherLog
fields = '__all__'
class WeatherStationInfoBaseSerializer(serializers.ModelSerializer):
class Meta:
model = WeatherStationInfo
fields = '__all__'
device_source_map = {
'counter': WeatherLogBaseSerializer,
'mosquito': WeatherStationInfoBaseSerializer,
}
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 = WeatherLog.objects.filter(~Q(longitude=0),
device_id=device_id).order_by('-data_time')
elif source == 'mosquito':
qs = WeatherStationInfo.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)
print(data)
return data
class WeatherLogSerializer(serializers.ModelSerializer): class WeatherLogSerializer(serializers.ModelSerializer):
power = serializers.SerializerMethodField() power = serializers.SerializerMethodField()
data_time = serializers.SerializerMethodField() data_time = serializers.SerializerMethodField()
@ -88,10 +151,90 @@ class WeatherLogSerializer(serializers.ModelSerializer):
def get_data_time(self, obj): def get_data_time(self, obj):
return obj.data_time.strftime('%Y-%m-%d %H:%M:%S') return obj.data_time.strftime('%Y-%m-%d %H:%M:%S')
def get_create_time(self, obj): def get_create_time(self, obj):
return obj.data_time.strftime('%Y-%m-%d %H:%M:%S') return obj.data_time.strftime('%Y-%m-%d %H:%M:%S')
class WeatherLogWithInfoSerializer(WeatherLogSerializer):
longitude = serializers.SerializerMethodField()
latitude = serializers.SerializerMethodField()
location_id = serializers.SerializerMethodField()
point_x = serializers.SerializerMethodField()
point_y = serializers.SerializerMethodField()
class Meta:
model = WeatherLog
fields = [
'data_time',
'device_id',
'device_name',
'env_temp',
'temperature1', 'temperature2', 'temperature3', 'temperature4', 'temperature5', 'dew_point_temp',
'env_humi', 'soil_humi1', 'soil_humi2', 'soil_humi3',
'co2', 'evaporation', 'air_pressure',
'total_radiation_1_ins', 'scat_radiation_ins', 'direct_radiation_ins', 'total_radiation_2_ins',
'net_radiation_ins', 'pho_radiation_ins', 'uv_radiation_ins',
'wind_direction', 'wind_speed_ins', 'wind_speed_2mins', 'wind_speed_10mins',
'rainfall_interval_cum', 'sunshine_time_interval_cum', 'total_radiation_1_interval_cum',
'scat_radiation_interval_cum', 'direct_radiation_interval_cum', 'total_radiation_2_interval_cum',
'net_radiation_interval_cum', 'pho_radiation_interval_cum', 'uv_radiation_interval_cum',
'rainfall_daily_cum', 'sunshine_time_daily_cum', 'total_radiation_1_daily_cum',
'scat_radiation_daily_cum', 'direct_radiation_daily_cum', 'total_radiation_2_daily_cum',
'net_radiation_daily_cum', 'pho_radiation_daily_cum', 'uv_radiation_daily_cum',
'light_intensity',
'power',
'pm25',
'create_time',
'longitude',
'latitude',
'location_id',
'point_x',
'point_y',
]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.device = None
def get_longitude(self, obj):
device = self.device
print(device)
if device:
if device.longitude:
return device.longitude
return None
def get_latitude(self, obj):
device = self.device
print(device)
if device:
if device.latitude:
return device.latitude
return None
def get_location_id(self, obj):
device = self.device
print(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 WeatherStationInfoSerializer(serializers.ModelSerializer): class WeatherStationInfoSerializer(serializers.ModelSerializer):
class Meta: class Meta:

View File

@ -28,6 +28,7 @@ from .serializers import (
MosqPostListSerializer, MosqPostListSerializer,
DeviceTempLogSerializer, DeviceTempLogSerializer,
WeatherLogSerializer, WeatherLogSerializer,
WeatherLogWithInfoSerializer,
DeviceInfoSerializer, DeviceInfoSerializer,
WeatherStationInfoSerializer, WeatherStationInfoSerializer,
) )
@ -115,7 +116,7 @@ class DeviceTempLogListAPIView(ListAPIView, RoleMixin, DeviceListMixin):
class WeatherLogListAPIView(ListAPIView, RoleMixin, WeatherStationListMixin): class WeatherLogListAPIView(ListAPIView, RoleMixin, WeatherStationListMixin):
serializer_class = WeatherLogSerializer #serializer_class = WeatherLogSerializer
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter) filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
pagination_class = WeatherlogHistoryPagination pagination_class = WeatherlogHistoryPagination
@ -123,6 +124,12 @@ class WeatherLogListAPIView(ListAPIView, RoleMixin, WeatherStationListMixin):
filterset_fields = ['device_id'] filterset_fields = ['device_id']
ordering_fields = ['data_time'] ordering_fields = ['data_time']
def get_serializer_class(self):
with_device = self.request.GET.get('with_device')
if with_device == 'true':
return WeatherLogWithInfoSerializer
return WeatherLogSerializer
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')