- 步骤1: MacAddressLoginView 增强,返回 code=4010(未绑定)/4011(不存在),支持自动激活 - 步骤2: 新增 bind_status 接口,设备端轮询查询绑定状态(无需认证) - 步骤3: 新增 register 设备自注册接口,首次开机自动注册(无需认证) - 步骤4: UserDeviceSerializer 增加 mac_address 字段 - 步骤5: WebSocket 新增 device_info 消息类型,支持设备状态上报和广播 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
118 lines
4.9 KiB
Python
118 lines
4.9 KiB
Python
from rest_framework import serializers
|
||
from .models import DeviceType, DeviceBatch, Device, UserDevice
|
||
from django.utils import timezone
|
||
|
||
|
||
class DeviceTypeSerializer(serializers.ModelSerializer):
|
||
class Meta:
|
||
model = DeviceType
|
||
fields = '__all__'
|
||
|
||
|
||
class DeviceBatchSerializer(serializers.ModelSerializer):
|
||
device_type_name = serializers.ReadOnlyField(source='device_type.name')
|
||
|
||
class Meta:
|
||
model = DeviceBatch
|
||
fields = '__all__'
|
||
|
||
|
||
class DeviceSerializer(serializers.ModelSerializer):
|
||
device_type_name = serializers.ReadOnlyField(source='device_type.name')
|
||
batch_number = serializers.ReadOnlyField(source='batch.batch_number')
|
||
|
||
class Meta:
|
||
model = Device
|
||
fields = '__all__'
|
||
read_only_fields = ('device_code',)
|
||
|
||
|
||
class DeviceCreateSerializer(serializers.ModelSerializer):
|
||
firmware_version = serializers.CharField(max_length=50, required=False)
|
||
wifi_name = serializers.CharField(max_length=100, required=False)
|
||
wifi_password = serializers.CharField(max_length=100, required=False)
|
||
brightness = serializers.IntegerField(min_value=0, max_value=100, required=False)
|
||
|
||
class Meta:
|
||
model = Device
|
||
fields = [
|
||
'device_type', 'batch', 'serial_number', 'mac_address',
|
||
'firmware_version', 'wifi_name', 'wifi_password', 'brightness'
|
||
]
|
||
|
||
|
||
class DeviceBatchCreateSerializer(serializers.Serializer):
|
||
device_type = serializers.PrimaryKeyRelatedField(queryset=DeviceType.objects.all())
|
||
batch = serializers.PrimaryKeyRelatedField(queryset=DeviceBatch.objects.all())
|
||
start_serial = serializers.CharField(max_length=50)
|
||
count = serializers.IntegerField(min_value=1, max_value=1000)
|
||
mac_prefix = serializers.CharField(max_length=9, required=False) # 可选,MAC地址前缀
|
||
|
||
def validate(self, data):
|
||
# 检查批次数量是否足够
|
||
batch = data['batch']
|
||
if batch.device_type.id != data['device_type'].id:
|
||
raise serializers.ValidationError("所选批次不属于所选设备类型")
|
||
|
||
# 检查设备数量是否足够
|
||
existing_devices = Device.objects.filter(batch=batch).count()
|
||
if existing_devices + data['count'] > batch.quantity:
|
||
raise serializers.ValidationError(f"批次总量为{batch.quantity},已创建{existing_devices}台,无法再创建{data['count']}台")
|
||
|
||
return data
|
||
|
||
|
||
class UserDeviceSerializer(serializers.ModelSerializer):
|
||
device_code = serializers.ReadOnlyField(source='device.device_code')
|
||
mac_address = serializers.ReadOnlyField(source='device.mac_address')
|
||
device_type = serializers.ReadOnlyField(source='device.device_type.name')
|
||
device_status = serializers.ReadOnlyField(source='device.status')
|
||
battery_level = serializers.ReadOnlyField(source='device.battery_level')
|
||
firmware_version = serializers.ReadOnlyField(source='device.firmware_version')
|
||
wifi_name = serializers.ReadOnlyField(source='device.wifi_name')
|
||
wifi_password = serializers.ReadOnlyField(source='device.wifi_password')
|
||
brightness = serializers.ReadOnlyField(source='device.brightness')
|
||
|
||
class Meta:
|
||
model = UserDevice
|
||
fields = '__all__'
|
||
read_only_fields = ('user', 'bound_at')
|
||
|
||
|
||
class DeviceRegisterSerializer(serializers.Serializer):
|
||
mac_address = serializers.CharField(max_length=17)
|
||
device_type_code = serializers.CharField(max_length=10, required=False, default='T01')
|
||
firmware_version = serializers.CharField(max_length=50, required=False, default='')
|
||
|
||
def validate_mac_address(self, value):
|
||
if Device.objects.filter(mac_address=value).exists():
|
||
raise serializers.ValidationError("设备已注册")
|
||
return value
|
||
|
||
def validate_device_type_code(self, value):
|
||
if not DeviceType.objects.filter(code=value).exists():
|
||
raise serializers.ValidationError(f"设备类型 {value} 不存在")
|
||
return value
|
||
|
||
|
||
class DeviceBindSerializer(serializers.Serializer):
|
||
mac_address = serializers.CharField(max_length=17)
|
||
nickname = serializers.CharField(max_length=100, required=False)
|
||
is_primary = serializers.BooleanField(default=False, required=False)
|
||
|
||
def validate_mac_address(self, value):
|
||
try:
|
||
device = Device.objects.get(mac_address=value)
|
||
# 检查设备是否已被激活
|
||
if not device.is_active:
|
||
device.is_active = True
|
||
device.activated_at = timezone.now()
|
||
device.save()
|
||
except Device.DoesNotExist:
|
||
raise serializers.ValidationError("设备不存在")
|
||
|
||
# 检查设备是否已被其他用户绑定
|
||
if UserDevice.objects.filter(device=device).exists():
|
||
raise serializers.ValidationError("设备已被其他用户绑定")
|
||
|
||
return value |