import pytz from enum import Enum from typing import Optional from django.utils.timezone import datetime from rest_framework import serializers from counter.models import DeviceCount, DeviceInfo from mosquito.models import DeviceInfo as MosquitoDeviceInfo class LedHealthStatus(Enum): Good = '良好' General = '一般' Bad = '较差' Unknown = '未知' def __repr__(self): return self.value def __str__(self): return self.value class DeviceInfoMobileSerializer(serializers.ModelSerializer): device_name = serializers.SerializerMethodField() status = serializers.SerializerMethodField() csq = serializers.SerializerMethodField() count = serializers.SerializerMethodField() vol = serializers.SerializerMethodField() coordinate = serializers.SerializerMethodField() location = serializers.SerializerMethodField() led_status = serializers.SerializerMethodField() led_health = serializers.SerializerMethodField() class Meta: model = DeviceInfo fields = [ 'device_id', 'device_name', 'status', 'count', 'csq', 'vol', 'led_status', 'led_health', 'coordinate', 'location', ] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.latest = None self.mosq_device = None self.counter_device = None def get_device_name(self, obj) -> Optional[str]: qs = MosquitoDeviceInfo.objects.filter(device_id=obj.device_id) if qs.count() > 0: device = qs.first() self.mosq_device = device return device.device_name return None def get_status(self, obj) -> int: return obj.online def get_coordinate(self, obj): if self.mosq_device: lon, lat = [self.mosq_device.longitude, self.mosq_device.latitude] if lon and lat: return [lon, lat] return None def get_location(self, obj): if self.mosq_device: return self.mosq_device.location return None def get_count(self, obj): device = DeviceCount.objects.filter( device_id=self.mosq_device.device_id).order_by('-data_time').first() if device: self.counter_device = device return device.count return None def get_csq(self, obj): if self.counter_device: return self.counter_device.csq return None def get_vol(self, obj): if self.counter_device: return self.counter_device.vol return None def get_led_status(self, obj): if self.mosq_device: return self.mosq_device.led_status return None def get_led_health(self, obj): if self.mosq_device: diff = datetime.now(tz=pytz.timezone('UTC')) - self.mosq_device.launch_time hours = diff.days * 24 + int(diff.seconds / 3600) rate = hours / self.mosq_device.led_lifetime if rate <= 0.3: return LedHealthStatus.Good.value if 0.3 < rate <= 0.6: return LedHealthStatus.General.value return LedHealthStatus.Bad.value return LedHealthStatus.Unknown.value