Toggle navigation
Toggle navigation
This project
Loading...
Sign in
cse437_e
/
smartdoorlock-backend
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
김유현
2020-11-19 12:33:15 +0900
Browse Files
Options
Browse Files
Download
Plain Diff
Commit
0dbcf4b44327aa97a4c8effb8907cc9d3637ab0c
0dbcf4b4
2 parents
b2d600c3
c75022af
Add RFIDProcess, RemoteProcess & Add 기기추가요청api, 원격잠금해제api
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
258 additions
and
67 deletions
.gitignore
api/admin.py
api/migrations/0001_initial.py
api/models.py
api/serializers.py
api/views.py
process/doorlock.py
src/urls.py
.gitignore
View file @
0dbcf4b
...
...
@@ -5,3 +5,5 @@ db.sqlite3
/static
.DS_Store
*.json
venv/
.idea/
...
...
api/admin.py
View file @
0dbcf4b
from
django.contrib
import
admin
from
.models
import
Video
,
Device
,
History
,
Lock
,
Record
,
Door
from
.models
import
Video
,
Device
,
Remote
History
,
Lock
,
Record
,
Door
# Register your models here.
admin
.
site
.
register
(
Door
)
admin
.
site
.
register
(
Video
)
admin
.
site
.
register
(
Device
)
admin
.
site
.
register
(
History
)
admin
.
site
.
register
(
Remote
History
)
admin
.
site
.
register
(
Lock
)
admin
.
site
.
register
(
Record
)
\ No newline at end of file
...
...
api/migrations/0001_initial.py
View file @
0dbcf4b
...
...
@@ -15,7 +15,8 @@ class Migration(migrations.Migration):
migrations
.
CreateModel
(
name
=
'Device'
,
fields
=
[
(
'rfid_id'
,
models
.
CharField
(
max_length
=
255
,
primary_key
=
True
,
serialize
=
False
)),
(
'device_id'
,
models
.
AutoField
(
primary_key
=
True
,
serialize
=
False
)),
(
'rfid_id'
,
models
.
CharField
(
max_length
=
255
)),
(
'created'
,
models
.
DateTimeField
(
default
=
django
.
utils
.
timezone
.
now
)),
],
),
...
...
@@ -26,14 +27,6 @@ class Migration(migrations.Migration):
],
),
migrations
.
CreateModel
(
name
=
'History'
,
fields
=
[
(
'id'
,
models
.
AutoField
(
auto_created
=
True
,
primary_key
=
True
,
serialize
=
False
,
verbose_name
=
'ID'
)),
(
'device_name'
,
models
.
CharField
(
max_length
=
255
)),
(
'ctrtime'
,
models
.
DateTimeField
(
default
=
django
.
utils
.
timezone
.
now
)),
],
),
migrations
.
CreateModel
(
name
=
'Lock'
,
fields
=
[
(
'id'
,
models
.
IntegerField
(
primary_key
=
True
,
serialize
=
False
)),
...
...
@@ -48,6 +41,14 @@ class Migration(migrations.Migration):
],
),
migrations
.
CreateModel
(
name
=
'RemoteHistory'
,
fields
=
[
(
'id'
,
models
.
AutoField
(
auto_created
=
True
,
primary_key
=
True
,
serialize
=
False
,
verbose_name
=
'ID'
)),
(
'device_name'
,
models
.
CharField
(
max_length
=
255
)),
(
'ctrtime'
,
models
.
DateTimeField
(
default
=
django
.
utils
.
timezone
.
now
)),
],
),
migrations
.
CreateModel
(
name
=
'Video'
,
fields
=
[
(
'vid_name'
,
models
.
CharField
(
max_length
=
255
,
primary_key
=
True
,
serialize
=
False
)),
...
...
api/models.py
View file @
0dbcf4b
...
...
@@ -7,7 +7,8 @@ class Door(models.Model) :
door_id
=
models
.
CharField
(
max_length
=
255
,
primary_key
=
True
)
class
Device
(
models
.
Model
)
:
rfid_id
=
models
.
CharField
(
max_length
=
255
,
primary_key
=
True
)
device_id
=
models
.
AutoField
(
primary_key
=
True
)
rfid_id
=
models
.
CharField
(
max_length
=
255
)
created
=
models
.
DateTimeField
(
default
=
timezone
.
now
)
class
Video
(
models
.
Model
)
:
...
...
@@ -20,9 +21,9 @@ class Lock(models.Model) :
id
=
models
.
IntegerField
(
primary_key
=
True
)
state
=
models
.
BooleanField
(
default
=
True
)
class
History
(
models
.
Model
)
:
class
Remote
History
(
models
.
Model
)
:
device_name
=
models
.
CharField
(
max_length
=
255
)
c
trtime
=
models
.
DateTimeField
(
default
=
timezone
.
now
)
c
reated
=
models
.
DateTimeField
(
default
=
timezone
.
now
)
class
Record
(
models
.
Model
)
:
id
=
models
.
IntegerField
(
primary_key
=
True
)
...
...
api/serializers.py
View file @
0dbcf4b
from
api.models
import
Device
,
Video
,
Lock
,
History
,
Record
,
Door
,
AddDevice
from
api.models
import
Device
,
Video
,
Lock
,
Remote
History
,
Record
,
Door
,
AddDevice
from
rest_framework
import
serializers
class
DoorSerializer
(
serializers
.
ModelSerializer
)
:
...
...
@@ -16,9 +16,9 @@ class VideoSerializer(serializers.ModelSerializer) :
model
=
Video
fields
=
'__all__'
class
HistorySerializer
(
serializers
.
ModelSerializer
)
:
class
Remote
HistorySerializer
(
serializers
.
ModelSerializer
)
:
class
Meta
:
model
=
History
model
=
Remote
History
fields
=
'__all__'
class
RecordSerializer
(
serializers
.
ModelSerializer
)
:
...
...
api/views.py
View file @
0dbcf4b
...
...
@@ -7,8 +7,9 @@ from django.core.exceptions import FieldDoesNotExist, ObjectDoesNotExist
from
django.shortcuts
import
render
from
api.videorecord
import
record
from
api.models
import
Video
,
Device
,
History
,
Lock
,
Record
,
Door
,
AddDevice
from
api.serializers
import
VideoSerializer
,
DeviceSerializer
,
HistorySerializer
,
RecordSerializer
from
api.models
import
Video
,
Device
,
RemoteHistory
,
Lock
,
Record
,
Door
from
api.serializers
import
VideoSerializer
,
DeviceSerializer
,
RemoteHistorySerializer
,
RecordSerializer
,
LockSerializer
from
rest_framework
import
status
from
rest_framework.views
import
APIView
...
...
@@ -22,8 +23,143 @@ from src.settings import S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_STORAGE_BUCK
"""
import
time
from
datetime
import
datetime
,
timedelta
import
json
# Create your views here.
#로그인 및 토큰 반환
class
Login
(
APIView
)
:
def
get
(
self
,
request
,
format
=
None
)
:
# request query에 door_id 포함되어있음 : api/auth?door_id=12345
try
:
request_id
=
request
.
GET
.
get
(
'door_id'
,
None
)
if
request_id
==
None
:
raise
FieldDoesNotExist
queryset
=
Door
.
objects
.
filter
(
door_id
=
request_id
)
# door_id 유효성 검색
if
queryset
.
exists
()
:
# 유효할 때
res
=
{
'is_available'
:
True
,
'access_token'
:
'토큰'
# 토큰 도입 후 수정 필요
}
else
:
res
=
{
'is_available'
:
False
}
return
Response
(
res
,
status
=
status
.
HTTP_200_OK
)
except
FieldDoesNotExist
as
error
:
return
Response
({
'error'
:
"FieldDoesNotExist "
,
'date'
:
datetime
.
now
()
},
status
=
status
.
HTTP_400_BAD_REQUEST
)
#기기 관련 api
class
Devices
(
APIView
)
:
# 기기 목록 조회
def
get
(
self
,
request
,
format
=
None
)
:
queryset
=
Device
.
objects
.
all
()
serializer
=
DeviceSerializer
(
queryset
,
many
=
True
)
res
=
{
'deviceList'
:
serializer
.
data
}
return
Response
(
res
,
status
=
status
.
HTTP_200_OK
)
# 기기 추가 요청
def
put
(
self
,
request
,
format
=
None
)
:
try
:
print
(
request
.
body
)
data
=
json
.
loads
(
request
.
body
)
rfid_id
=
data
.
get
(
'rfid_id'
,
None
)
res
=
{
'rfid_id'
:
rfid_id
}
if
rfid_id
==
None
:
raise
FieldDoesNotExist
return
Response
(
res
,
status
=
status
.
HTTP_200_OK
)
except
FieldDoesNotExist
as
error
:
return
Response
({
'error'
:
"FieldDoesNotExist "
,
'date'
:
datetime
.
now
()
},
status
=
status
.
HTTP_400_BAD_REQUEST
)
# 기기 추가
def
post
(
self
,
request
,
format
=
None
)
:
# request body에 rfid_id 포함되어있음
try
:
print
(
request
.
body
)
data
=
json
.
loads
(
request
.
body
)
request_id
=
data
.
get
(
'rfid_id'
,
None
)
if
request_id
==
None
:
raise
FieldDoesNotExist
queryset
=
Device
.
objects
.
create
(
rfid_id
=
request_id
)
return
Response
({
'msg'
:
'success device add'
})
except
FieldDoesNotExist
as
error
:
return
Response
({
'error'
:
"FieldDoesNotExist "
,
'date'
:
datetime
.
now
()
},
status
=
status
.
HTTP_400_BAD_REQUEST
)
# 기기 삭제
def
delete
(
self
,
request
,
device_id
,
format
=
None
):
# request URI에 device_id(자동생성되는 기기 고유 번호 != rfid_id) 포함
try
:
request_id
=
device_id
if
request_id
==
None
:
raise
FieldDoesNotExist
queryset
=
Device
.
objects
.
get
(
device_id
=
request_id
)
queryset
.
delete
()
return
Response
({
'msg'
:
'success delete device'
})
except
FieldDoesNotExist
as
error
:
return
Response
({
'error'
:
"FieldDoesNotExist "
,
'date'
:
datetime
.
now
()
},
status
=
status
.
HTTP_400_BAD_REQUEST
)
# 원격 잠금 해제
class
Remote
(
APIView
):
# 원격 잠금 해제 기록 조회
def
get
(
self
,
request
,
format
=
None
)
:
#models.py의 class History 사용.
queryset
=
RemoteHistory
.
objects
.
all
()
serializer
=
RemoteHistorySerializer
(
queryset
,
many
=
True
)
res
=
{
"remoteHistoryList"
:
serializer
.
data
}
return
Response
(
res
,
status
=
status
.
HTTP_200_OK
)
# 원격 잠금 해제
def
post
(
self
,
request
,
format
=
None
)
:
try
:
print
(
request
.
body
)
data
=
json
.
loads
(
request
.
body
)
device_name
=
data
.
get
(
'device_name'
,
None
)
if
device_name
==
None
:
raise
FieldDoesNotExist
else
:
# 잠금 상태 변경
target
=
Lock
.
objects
.
get
(
id
=
1
)
serializer
=
LockSerializer
(
target
,
many
=
False
)
state
=
serializer
.
data
[
'state'
]
if
state
==
True
:
print
(
">> 원격 잠금해제 요청이 들어옴"
)
target
.
state
=
False
target
.
save
()
return
Response
({
'msg'
:
'success remote unlock'
},
status
=
status
.
HTTP_200_OK
)
except
FieldDoesNotExist
as
error
:
return
Response
({
'error'
:
"FieldDoesNotExist "
,
'date'
:
datetime
.
now
()
},
status
=
status
.
HTTP_400_BAD_REQUEST
)
# 비디오 목록 조회
class
VideoList
(
APIView
)
:
def
get
(
self
,
request
,
format
=
None
)
:
...
...
process/doorlock.py
View file @
0dbcf4b
#-*- coding:utf-8 -*-
#
-*- coding:utf-8 -*-
import
time
import
RPi.GPIO
as
GPIO
import
mfrc522
import
requests
from
multiprocessing
import
Queue
import
os
import
django
os
.
environ
.
setdefault
(
'DJANGO_SETTINGS_MODULE'
,
'src.settings'
)
django
.
setup
()
from
django.core
import
serializers
from
api.models
import
Lock
,
AddDevice
,
Device
from
api.serializers
import
LockSerializer
,
AddDeviceSerializer
,
DeviceSerializer
MFIAREReader
=
mfrc522
.
MFRC522
()
# RFID Reader
BASE_URL
=
"http://127.0.0.1:8000"
PIN
=
{
'Motor_MT_N'
:
17
,
'Motor_MT_P'
:
4
'Motor_MT_N'
:
17
,
'Motor_MT_P'
:
4
}
class
Motor
:
LEFT
=
0
RIGHT
=
1
...
...
@@ -34,9 +48,10 @@ class Motor:
self
.
pwmP
.
ChangeDutyCycle
(
0
)
self
.
pwmN
.
ChangeDutyCycle
(
0
)
def
RFIDProcess
(
signalQueue
):
while
True
:
################## 이곳을 지우고 코드를 작성해주세요 ################
"""
# RFID ID가 등록된 기기의 ID인 경우 success에 True를 넣습니다.
#
# RFID 태그가 된 경우 API에 요청을 보내 (GET /api/device) ID 목록을
...
...
@@ -50,48 +65,70 @@ def RFIDProcess(signalQueue):
# 그냥 기기 목록에 태그된 기기의 ID를 추가합니다.
#
# success가 True인 경우 모터가 회전합니다.
#
# 아래 코드는 테스트를 위한 코드입니다. 아래 코드까지 지우고 작성해주세요.
time
.
sleep
(
30
)
success
=
True
##############################################################
#
# 복잡한 것 같아 수도코드를 첨부합니다.
#
# success = False
# if RFID 태그가 됨:
# deviceId = 방금 태그된 RFID 장치의 ID
# devices = callApi(GET /api/device)
"""
success
=
False
try
:
(
readerStatus
,
tagType
)
=
MFIAREReader
.
MFRC522_Request
(
MFIAREReader
.
PICC_REQIDL
)
(
readerStatus
,
uid
)
=
MFIAREReader
.
MFRC522_Anticoll
()
# uid = [1, 2, 3, 4, 5]
if
readerStatus
==
MFIAREReader
.
MI_OK
:
# if RFID 태그가 됨:
deviceId
=
""
# 방금 태그된 RFID 장치의 ID.
for
i
in
uid
:
deviceId
+=
str
(
i
)
# deviceId = 12345
# devices = callApi(GET /api/device) # 기기 조회
response
=
requests
.
get
(
BASE_URL
+
"/api/device"
)
deviceList
=
[]
# 기기 목록
if
response
.
status_code
==
200
:
deviceList
=
(
response
.
json
()[
'deviceList'
])
# state = getFromIPC(원격 잠금해제 여부)
#
# if state == 원격 잠금해제:
# try:
# if devices.find(deviceId):
# raise 이미 등록된 RFID 장치
# else:
# callApi(POST /api/device, {rfid_id:deviceId})
# (가능하다면) 완료됐다는 소리 출력 (딩동댕 정도?)
# except:
# (가능하다면) 경고음 출력 (삑!)
# finally:
# setToIPC(원격 잠금해제 여부, 원격 잠금해제 아님)
# else: # 원격 잠금해제 상태가 아님 = 도어락 해제 프로세스
# try:
# if not devices.find(deviceId):
# raise 등록되지 않은 RFID 장치
# else:
# success = True
# except:
# (가능하다면) 경고음 출력 (삑!)
#
##############################################################
target
=
Lock
.
objects
.
get
(
id
=
1
)
# 장고 모델에서 잠금 상태 모델(Lock) 객체 가져옴
serializer
=
LockSerializer
(
target
,
many
=
False
)
# python 데이터타입으로 변환
state
=
serializer
.
data
[
'state'
]
# state에 저장(boolean)
findDevice
=
False
# 기기 등록 여부
for
i
in
deviceList
:
if
deviceId
in
i
[
"rfid"
]:
findDevice
=
True
if
state
==
False
:
# if state == 원격 잠금해제:
try
:
if
findDevice
:
# if devices.find(deviceId):
print
(
"이미 등록된 RFID 장치"
)
# raise
pass
else
:
# callApi(POST /api/device, {rfid_id:deviceId}) # 기기 추가
requests
.
post
(
BASE_URL
+
"/api/device"
,
data
=
{
"rfid_id"
:
deviceId
})
print
(
"딩동댕 ~ 완료하였습니다"
)
# 소리 출력
pass
except
:
print
(
"경고음 삑 -!"
)
pass
finally
:
# setToIPC(원격 잠금해제 여부, 원격 잠금해제 아님)
target
.
state
=
True
target
.
save
()
else
:
# 원격 잠금해제 상태가 아님 = 도어락 해제 프로세스
try
:
if
not
findDevice
:
# if not devices.find(deviceId)
print
(
"등록되지 않은 RFID 장치"
)
# raise
pass
else
:
success
=
True
except
:
print
(
"경고음 삑 -!"
)
# 소리 출력
pass
if
success
:
print
(
"등록된 RFID ID가 확인됨"
)
signalQueue
.
put
(
"RFID"
)
except
KeyboardInterrupt
:
pass
# GPIO.cleanup()
def
RemoteProcess
(
signalQueue
):
while
True
:
################## 이곳을 지우고 코드를 작성해주세요 ################
"""
# 원격 잠금해제 요청이 들어온 경우 success에 True를 넣습니다.
# 원격 잠금해제 요청은 IPC로 처리합니다.
# 지우님과 협업하여 작업해주세요.
...
...
@@ -101,15 +138,20 @@ def RemoteProcess(signalQueue):
# 원격 잠금해제 요청이 들어온 경우 API에서 write하도록 하면 되겠죠..?
#
# success가 True인 경우 모터가 회전합니다.
#
# 아래 코드는 테스트를 위한 코드입니다. 아래 코드까지 지우고 작성해주세요.
time
.
sleep
(
13
)
"""
success
=
False
target
=
Lock
.
objects
.
get
(
id
=
1
)
# 장고 모델에서 잠금 상태 모델(Lock) 객체 가져옴
serializer
=
LockSerializer
(
target
,
many
=
False
)
# python 데이터타입으로 변환
state
=
serializer
.
data
[
'state'
]
# state에 저장(boolean)
if
state
==
False
:
# 잠금 해제 요청이 왔을 경우
print
(
">> 원격 잠금해제 요청이 들어옴"
)
success
=
True
##############################################################
target
.
state
=
True
# 다시 잠금 상태로
target
.
save
()
# 바꾼 값으로 db에 저장
if
success
:
print
(
"원격 잠금해제 요청이 들어옴"
)
signalQueue
.
put
(
"Remote"
)
def
signalProcess
(
signalQueue
):
pid
=
os
.
fork
()
if
pid
==
0
:
...
...
@@ -117,6 +159,7 @@ def signalProcess(signalQueue):
else
:
RemoteProcess
(
signalQueue
)
def
doorProcess
(
doorQueue
):
motor
=
Motor
()
while
True
:
...
...
@@ -133,11 +176,12 @@ def doorProcess(doorQueue):
time
.
sleep
(
0.5
)
motor
.
stop
()
if
__name__
==
'__main__'
:
try
:
GPIO
.
setmode
(
GPIO
.
BCM
)
GPIO
.
setup
(
PIN
[
'Motor_MT_N'
],
GPIO
.
OUT
,
initial
=
GPIO
.
LOW
)
GPIO
.
setup
(
PIN
[
'Motor_MT_P'
],
GPIO
.
OUT
,
initial
=
GPIO
.
LOW
)
#
GPIO.setmode(GPIO.BCM)
#
GPIO.setup(PIN['Motor_MT_N'], GPIO.OUT, initial=GPIO.LOW)
#
GPIO.setup(PIN['Motor_MT_P'], GPIO.OUT, initial=GPIO.LOW)
signalQueue
=
Queue
()
pid
=
os
.
fork
()
...
...
@@ -148,7 +192,9 @@ if __name__ == '__main__':
while
True
:
signal
=
signalQueue
.
get
()
print
(
"{} 신호가 들어와 전달 준비"
.
format
(
signal
))
print
(
signal
)
if
signal
is
not
None
:
print
(
"signal is not None"
)
doorQueue
.
put
(
signal
)
else
:
doorProcess
(
doorQueue
)
...
...
@@ -157,4 +203,5 @@ if __name__ == '__main__':
except
Exception
as
e
:
print
(
e
)
finally
:
GPIO
.
cleanup
()
\ No newline at end of file
pass
# GPIO.cleanup()
...
...
src/urls.py
View file @
0dbcf4b
...
...
@@ -24,4 +24,8 @@ urlpatterns = [
path
(
'api/video/<str:vid_name>'
,
views
.
VideoDownload
.
as_view
()),
path
(
'auto/checkDate'
,
views
.
CheckDate
.
as_view
()),
path
(
'api/setting'
,
views
.
Recording
.
as_view
()),
path
(
'api/auth'
,
views
.
Login
.
as_view
()),
path
(
'api/device'
,
views
.
Devices
.
as_view
()),
path
(
'api/device/<str:device_id>'
,
views
.
Devices
.
as_view
()),
path
(
'api/remote'
,
views
.
Remote
.
as_view
()),
]
...
...
Please
register
or
login
to post a comment