72 lines
2.9 KiB
Python
72 lines
2.9 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.core.exceptions import ConflictException, NotFoundException
|
|
from app.models.mariadb.device import Device
|
|
from app.repositories.device_repo import DeviceRepository
|
|
from app.schemas.device import DeviceCreate, DeviceRead, DeviceUpdate
|
|
|
|
|
|
class DeviceService:
|
|
def __init__(self, session: AsyncSession):
|
|
self.device_repo = DeviceRepository(session)
|
|
|
|
async def get_device(self, device_id: int) -> DeviceRead:
|
|
device = await self.device_repo.get_by_id(device_id)
|
|
if not device or device.is_deleted:
|
|
raise NotFoundException("Device not found")
|
|
return DeviceRead.model_validate(device)
|
|
|
|
async def get_device_by_uid(self, device_uid: str) -> DeviceRead:
|
|
device = await self.device_repo.get_by_uid(device_uid)
|
|
if not device:
|
|
raise NotFoundException("Device not found")
|
|
return DeviceRead.model_validate(device)
|
|
|
|
async def list_devices(self, skip: int = 0, limit: int = 20) -> list[DeviceRead]:
|
|
devices = await self.device_repo.get_all(
|
|
skip=skip, limit=limit, filters={"is_deleted": False}
|
|
)
|
|
return [DeviceRead.model_validate(d) for d in devices]
|
|
|
|
async def count_devices(self) -> int:
|
|
return await self.device_repo.count(filters={"is_deleted": False})
|
|
|
|
async def create_device(self, data: DeviceCreate) -> DeviceRead:
|
|
existing = await self.device_repo.get_by_uid(data.device_uid)
|
|
if existing:
|
|
raise ConflictException("Device UID already registered")
|
|
|
|
device = Device(**data.model_dump())
|
|
device = await self.device_repo.create(device)
|
|
return DeviceRead.model_validate(device)
|
|
|
|
async def update_device(self, device_id: int, data: DeviceUpdate) -> DeviceRead:
|
|
device = await self.device_repo.get_by_id(device_id)
|
|
if not device or device.is_deleted:
|
|
raise NotFoundException("Device not found")
|
|
|
|
update_data = data.model_dump(exclude_none=True)
|
|
device = await self.device_repo.update(device, update_data)
|
|
return DeviceRead.model_validate(device)
|
|
|
|
async def delete_device(self, device_id: int) -> None:
|
|
device = await self.device_repo.get_by_id(device_id)
|
|
if not device or device.is_deleted:
|
|
raise NotFoundException("Device not found")
|
|
await self.device_repo.update(
|
|
device, {"is_deleted": True, "deleted_at": datetime.utcnow()}
|
|
)
|
|
|
|
async def update_device_status(self, device_uid: str, status: str) -> DeviceRead:
|
|
device = await self.device_repo.get_by_uid(device_uid)
|
|
if not device:
|
|
raise NotFoundException("Device not found")
|
|
device = await self.device_repo.update(
|
|
device, {"status": status, "last_seen_at": datetime.utcnow()}
|
|
)
|
|
return DeviceRead.model_validate(device)
|