-
Notifications
You must be signed in to change notification settings - Fork 5
Alarm
Alarm 앱은 Safe Eye 프로젝트에서 알람 기능을 제공하는 앱입니다. 이 앱은 CCTV 영상 분석 결과에 따라 알람을 생성하고 관리할 수 있는 기능을 제공합니다. 알람에는 태그와 상태를 추가하여 분류하고 관리할 수 있습니다.
AlarmType 모델은 알람의 유형을 정의하는 모델입니다. 알람 유형은 code와 name으로 구성되며, Alarm 모델과 외래 키로 연결됩니다.
Risk 모델은 알람의 위험 수준을 정의하는 모델입니다. 위험 수준은 ('VL', '매우 낮음'), ('LO', '낮음'), ('ME', '보통'), ('HI', '높음'), ('VH', '매우 높음') 중 하나의 값을 가질 수 있으며, Alarm 모델과 외래 키로 연결됩니다.
Alarm 모델은 알람 데이터를 저장하는 모델입니다. 알람은 관리자(admin), 카메라 ID(camera_id), 알람 유형(alarm_type), 알람 내용(alarm_content), 위험 수준(risk), 사용자 정의 메시지(custom_message) 등의 필드로 구성됩니다. 또한 TagMixin과 StatusMixin을 상속받아 태그와 상태 기능을 추가할 수 있습니다.
AlarmViewSet은 Alarm 모델에 대한 CRUD 작업을 수행하는 ViewSet입니다. 이 ViewSet은 utils 앱의 Custom404Mixin을 사용하여 사용자 정의 404 에러 처리를 지원하고, IsAuthorOrReadOnly 권한 클래스를 사용하여 인증된 사용자만 알람을 생성하고 수정할 수 있도록 합니다. 또한 Django REST Framework의 DjangoFilterBackend와 SearchFilter를 사용하여 알람 데이터에 대한 필터링과 검색 기능을 제공합니다.
RiskViewSet은 Risk 모델에 대한 CRUD 작업을 수행하는 ViewSet입니다.
AlarmTypeViewSet은 AlarmType 모델에 대한 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에서 Custom404Mixin과 IsAuthorOrReadOnly 권한 클래스를 사용하여 404 에러 처리와 권한 관리를 커스터마이징하였습니다. 그리고 perform_create 메서드를 오버라이드하여 슈퍼유저인 경우에만 알람 작성자를 설정할 수 있도록 하였습니다.
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 객체를 조회합니다.
GET /risks/ Risk 객체의 목록을 조회합니다.
POST /risks/ 새로운 Risk 객체를 생성합니다.
GET /risks/{id}/ 특정 Risk 객체의 상세 정보를 조회합니다.
PUT /risks/{id}/ 특정 Risk 객체를 수정합니다.
PATCH /risks/{id}/ 특정 Risk 객체를 부분적으로 수정합니다.
DELETE /risks/{id}/ 특정 Risk 객체를 삭제합니다.
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 객체를 삭제합니다.
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" # 기타MediaFileViewSet에 detect_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_type과 user 필드를 사용하여 알람 유형과 사용자로 필터링할 수 있으며, created_at_min과 created_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)AlarmViewSet에 stats 액션을 추가하여 알람 유형별 개수를 반환하는 API를 제공합니다. DashboardView에서는 전체 알람 개수, 알람 유형별 통계, 최신 알람 목록 등의 정보를 조합하여 대시보드에 필요한 데이터를 반환합니다.