# -*- encoding: utf-8 -*- """ @File : DeviceReportController.py @Time : 2025/4/8 16:33 @Author : stephen @Email : zhangdongming@asj6.wecom.work @Software: PyCharm """ import logging import time from datetime import datetime, timezone from django.http import JsonResponse from django.views import View from django.core.exceptions import ValidationError from Model.models import DeviceDailyReport from Service.DevicePushService import DevicePushService TIME_LOGGER = logging.getLogger('time') ERROR_INFO_LOGGER = logging.getLogger('error_info') class DeviceReportView(View): def post(self, request, *args, **kwargs): operation = kwargs.get('operation') if operation == 'batteryLevel': return self.handle_battery_report(request.POST) return JsonResponse( {'code': 404, 'msg': 'Operation not found'}, status=404 ) def handle_battery_report(self, data): try: # 验证并解码设备令牌 etk = data.get('etk') TIME_LOGGER.info(f'设备电池报告参数:{data}') if not etk: raise ValidationError('Missing etk parameter') uid = DevicePushService.decode_uid(etk, None) if len(uid) not in (14, 20): raise ValidationError('Invalid device UID format') # 参数提取和类型转换 wake_sleep = self.parse_int_param(data, 'pirWakeupCount') + self.parse_int_param(data, 'mqttWakeupCount') report_params = { 'human_detection': self.parse_int_param(data, 'humanDetection'), 'pir_wakeup_count': self.parse_int_param(data, 'pirWakeupCount'), 'mqtt_wakeup_count': self.parse_int_param(data, 'mqttWakeupCount'), 'wake_sleep': wake_sleep, 'working_hours': self.parse_int_param(data, 'workingHours'), 'battery_level': self.parse_int_param(data, 'batteryLevel'), 'report_time': self.parse_int_param(data, 'reportTime') - 10800, } # 时间戳验证 report_date = datetime.fromtimestamp(report_params['report_time'], tz=timezone.utc) # 数据库操作 n_time = int(time.time()) DeviceDailyReport.objects.create( device_id=uid, type=1, report_date=report_date, **report_params, created_time=n_time, updated_time=n_time ) TIME_LOGGER.info(f'设备保存电池报告uid: {uid}') return JsonResponse({'code': 0, 'msg': 'Report saved successfully'}) except ValidationError as e: ERROR_INFO_LOGGER.warning(f'Validation error: {e.message}', exc_info=True) return JsonResponse({'code': 400, 'msg': e.message}, status=400) except Exception as e: ERROR_INFO_LOGGER.error(f'Unexpected error: {str(e)}', exc_info=True) return JsonResponse( {'code': 500, 'msg': 'Internal server error'}, status=500 ) @classmethod def parse_int_param(cls, data, param_name): """辅助方法:安全提取并转换整型参数""" value = data.get(param_name) if not value: raise ValidationError(f'Missing {param_name} parameter') try: return int(value) except ValueError: raise ValidationError(f'Invalid {param_name} format')