Skip to content
mkdirlife edited this page Apr 16, 2024 · 5 revisions

Alarm

Alarm 앱은 Safe Eye 프로젝트에서 알람 기능을 제공하는 앱입니다. 이 앱은 CCTV 영상 분석 결과에 따라 알람을 생성하고 관리할 수 있는 기능을 제공합니다. 알람에는 태그와 상태를 추가하여 분류하고 관리할 수 있습니다.

Models

AlarmType 모델

AlarmType 모델은 알람의 유형을 정의하는 모델입니다. 알람 유형은 codename으로 구성되며, Alarm 모델과 외래 키로 연결됩니다.

Risk 모델

Risk 모델은 알람의 위험 수준을 정의하는 모델입니다. 위험 수준은 ('VL', '매우 낮음'), ('LO', '낮음'), ('ME', '보통'), ('HI', '높음'), ('VH', '매우 높음') 중 하나의 값을 가질 수 있으며, Alarm 모델과 외래 키로 연결됩니다.

Alarm 모델

Alarm 모델은 알람 데이터를 저장하는 모델입니다. 알람은 관리자(admin), 카메라 ID(camera_id), 알람 유형(alarm_type), 알람 내용(alarm_content), 위험 수준(risk), 사용자 정의 메시지(custom_message) 등의 필드로 구성됩니다. 또한 TagMixinStatusMixin을 상속받아 태그와 상태 기능을 추가할 수 있습니다.

Views

AlarmViewSet

AlarmViewSetAlarm 모델에 대한 CRUD 작업을 수행하는 ViewSet입니다. 이 ViewSetutils 앱의 Custom404Mixin을 사용하여 사용자 정의 404 에러 처리를 지원하고, IsAuthorOrReadOnly 권한 클래스를 사용하여 인증된 사용자만 알람을 생성하고 수정할 수 있도록 합니다. 또한 Django REST FrameworkDjangoFilterBackendSearchFilter를 사용하여 알람 데이터에 대한 필터링과 검색 기능을 제공합니다.

RiskViewSet

RiskViewSetRisk 모델에 대한 CRUD 작업을 수행하는 ViewSet입니다.

AlarmTypeViewSet

AlarmTypeViewSetAlarmType 모델에 대한 CRUD 작업을 수행하는 ViewSet입니다.

예시 코드

# alarm/views.py
from utils.mixins import Custom404Mixin, IsAuthorOrReadOnly
from utils.views import CustomPageNumberPagination

class AlarmViewSet(Custom404Mixin, viewsets.ModelViewSet):
    queryset = Alarm.objects.order_by("-created_at")
    serializer_class = AlarmSerializer
    permission_classes = [IsAuthorOrReadOnly]
    pagination_class = CustomPageNumberPagination
    filter_fields = ["id", "alarm_type", "user"]
    custom_404_message = "해당 알람을 찾을 수 없습니다."

    def perform_create(self, serializer):
        if self.request.user.is_superuser:
            serializer.save(user=self.request.user)
        else:
            serializer.save()

AlarmViewSet에서 Custom404MixinIsAuthorOrReadOnly 권한 클래스를 사용하여 404 에러 처리와 권한 관리를 커스터마이징하였습니다. 그리고 perform_create 메서드를 오버라이드하여 슈퍼유저인 경우에만 알람 작성자를 설정할 수 있도록 하였습니다.

API

AlarmViewSet

GET /alarms/ Alarm 객체의 목록을 조회합니다. 페이지네이션, 필터링, 검색을 지원합니다.
POST /alarms/ 새로운 Alarm 객체를 생성합니다.
GET /alarms/{id}/ 특정 Alarm 객체의 상세 정보를 조회합니다.
PUT /alarms/{id}/ 특정 Alarm 객체를 수정합니다.
PATCH /alarms/{id}/ 특정 Alarm 객체를 부분적으로 수정합니다.
DELETE /alarms/{id}/ 특정 Alarm 객체를 삭제합니다.
GET /alarms/?camera_id={camera_id} 특정 카메라 ID에 해당하는 Alarm 객체만 조회합니다.
GET /alarms/?alarm_type__code={alarm_type_code} 특정 알람 유형 코드에 해당하는 Alarm 객체만 조회합니다.
GET /alarms/?risk__level={risk_level} 특정 위험 수준에 해당하는 Alarm 객체만 조회합니다.
GET /alarms/?search={search_query} 알람 내용 또는 사용자 정의 메시지에서 검색어를 포함하는 Alarm 객체를 조회합니다.
GET /alarms/?page={page_number}&page_size={page_size} 지정된 페이지 번호와 페이지 크기로 Alarm 객체를 조회합니다.
POST /receive-alarm-data/ GPT 모델 앱에서 알람 데이터를 받아 처리합니다.

필터링
GET /alarms/?camera_id=1 카메라 ID가 1인 Alarm 객체만 조회합니다.
GET /alarms/?alarm_type__code=FI 알람 유형 코드가 'FI'인 Alarm 객체만 조회합니다.
GET /alarms/?risk__level=HI 위험 수준이 'HI'인 Alarm 객체만 조회합니다.
GET /alarms/?search=화재 '화재'를 알람 내용 또는 사용자 정의 메시지에 포함하는 Alarm 객체를 조회합니다.

RiskViewSet

GET /risks/ Risk 객체의 목록을 조회합니다.
POST /risks/ 새로운 Risk 객체를 생성합니다.
GET /risks/{id}/ 특정 Risk 객체의 상세 정보를 조회합니다.
PUT /risks/{id}/ 특정 Risk 객체를 수정합니다.
PATCH /risks/{id}/ 특정 Risk 객체를 부분적으로 수정합니다.
DELETE /risks/{id}/ 특정 Risk 객체를 삭제합니다.

AlarmTypeViewSet

GET /alarm-types/ AlarmType 객체의 목록을 조회합니다.
POST /alarm-types/ 새로운 AlarmType 객체를 생성합니다.
GET /alarm-types/{id}/ 특정 AlarmType 객체의 상세 정보를 조회합니다.
PUT /alarm-types/{id}/ 특정 AlarmType 객체를 수정합니다.
PATCH /alarm-types/{id}/ 특정 AlarmType 객체를 부분적으로 수정합니다.
DELETE /alarm-types/{id}/ 특정 AlarmType 객체를 삭제합니다.

Uses

* 알람 생성 및 관리

CCTV 영상 분석 결과에 따라 알람을 생성하고 관리할 수 있습니다.

# media/views.py
from alarm.models import Alarm
from alarm.serializers import AlarmSerializer

class MediaFileViewSet(viewsets.ModelViewSet):
    # ...

    @action(detail=True, methods=["post"])
    def detect_objects(self, request, pk=None):
        media_file = self.get_object()
        # 객체 탐지 로직 수행
        # ...

        # 탐지된 객체에 따라 알람 생성
        if detected_objects:
            for obj in detected_objects:
                alarm_type = self.get_alarm_type(obj)
                alarm_content = f"{obj} 객체가 탐지되었습니다."
                alarm = Alarm.objects.create(alarm_type=alarm_type, alarm_content=alarm_content)
                alarm.tags.create(tag_type="media", tag_content=str(media_file.id))

        return Response({"message": "객체 탐지 완료"})

    def get_alarm_type(self, obj):
        # 탐지된 객체에 따라 알람 유형 결정
        if obj == "person":
            return "FD"  # 전도
        elif obj == "fire":
            return "AR"  # 방화
        elif obj == "smoke":
            return "SM"  # 흡연
        # 추가적인 알람 유형 판단 로직
        # ...
        else:
            return "OT"  # 기타

MediaFileViewSetdetect_objects 액션을 추가하여 미디어 파일에 대한 객체 탐지를 수행합니다. 탐지된 객체에 따라 알람을 생성하고, 해당 알람에 미디어 파일의 ID를 태그로 추가합니다. get_alarm_type 메서드를 통해 탐지된 객체에 따라 적절한 알람 유형을 결정합니다.

* 알람 필터링 및 검색

알람을 유형, 사용자 등으로 필터링하여 조회할 수 있습니다.

# alarm/views.py
from django_filters import rest_framework as filters

class AlarmFilter(filters.FilterSet):
    alarm_type = filters.CharFilter(lookup_expr="exact")
    user = filters.NumberFilter(lookup_expr="exact")
    created_at_min = filters.DateTimeFilter(field_name="created_at", lookup_expr="gte")
    created_at_max = filters.DateTimeFilter(field_name="created_at", lookup_expr="lte")

    class Meta:
        model = Alarm
        fields = ["alarm_type", "user", "created_at_min", "created_at_max"]

class AlarmViewSet(Custom404Mixin, viewsets.ModelViewSet):
    queryset = Alarm.objects.order_by("-created_at")
    serializer_class = AlarmSerializer
    permission_classes = [IsAuthorOrReadOnly]
    pagination_class = CustomPageNumberPagination
    filter_backends = [DjangoFilterBackend]
    filter_class = AlarmFilter
    custom_404_message = "해당 알람을 찾을 수 없습니다."

AlarmFilter 클래스를 정의하여 알람을 필터링할 수 있는 필드를 지정합니다. alarm_typeuser 필드를 사용하여 알람 유형과 사용자로 필터링할 수 있으며, created_at_mincreated_at_max 필드를 사용하여 생성 날짜 범위로 필터링할 수 있습니다. AlarmViewSet에서 filter_class 속성에 AlarmFilter를 지정하여 필터링 기능을 활성화합니다.

* 알람 통계 및 대시보드

알람 데이터를 기반으로 통계 정보를 생성하고 대시보드에 표시할 수 있습니다.

# alarm/views.py
from django.db.models import Count
from rest_framework.decorators import action
from rest_framework.response import Response

class AlarmViewSet(Custom404Mixin, viewsets.ModelViewSet):
    # ...

    @action(detail=False, methods=["get"])
    def stats(self, request):
        alarm_stats = Alarm.objects.values("alarm_type").annotate(count=Count("id"))
        return Response(alarm_stats)

# dashboard/views.py
from alarm.models import Alarm
from django.db.models import Count
from rest_framework.views import APIView
from rest_framework.response import Response

class DashboardView(APIView):
    def get(self, request):
        total_alarms = Alarm.objects.count()
        alarm_stats = Alarm.objects.values("alarm_type").annotate(count=Count("id"))
        latest_alarms = Alarm.objects.order_by("-created_at")[:5]

        data = {
            "total_alarms": total_alarms,
            "alarm_stats": alarm_stats,
            "latest_alarms": AlarmSerializer(latest_alarms, many=True).data,
        }
        return Response(data)

AlarmViewSetstats 액션을 추가하여 알람 유형별 개수를 반환하는 API를 제공합니다. DashboardView에서는 전체 알람 개수, 알람 유형별 통계, 최신 알람 목록 등의 정보를 조합하여 대시보드에 필요한 데이터를 반환합니다.

Clone this wiki locally