-
Notifications
You must be signed in to change notification settings - Fork 0
/
alexa-flask-serve.py
219 lines (160 loc) · 5.2 KB
/
alexa-flask-serve.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
import sys
import os
import dropbox
import picamera
import subprocess
from gpiozero import MotionSensor
from time import sleep
import datetime
from twilio.rest import Client
from flask import Flask
from flask_ask import Ask, statement, convert_errors
import logging
import threading
ACCOUNT_SID = os.environ['TWILIOSID']
AUTH_TOKEN = os.environ['TWILIOTOKEN']
KEY = os.environ['DBKEY']
SECRET = os.environ['DBSECRET']
TOKEN = os.environ['DBTOKEN']
toNum = os.environ['TONUM']
fromNum = os.environ['FROMNUM']
client = Client(ACCOUNT_SID, AUTH_TOKEN)
app = Flask(__name__)
ask = Ask(app, '/')
logging.getLogger("flask_ask").setLevel(logging.DEBUG)
SYSTEM_STATUS = False
outdir = "/home/neil/raspi-home-monitor/output/"
PHOTOFLAG = False
VIDEOFLAG = True
TESTFLAG = False
vidLength = 10 #seconds
if len(sys.argv) > 1: #then there are command line arguments
if '-v' in sys.argv:
PHOTOFLAG = False
VIDEOFLAG = True
if len(sys.argv) > 2:
vidLength = int(sys.argv[2]) #If video, then there is the optional length argument
if '-t' in sys.argv:
PHOTOFLAG = False
TESTFLAG = True
#Functions --------------------------------------------
def getValidFilename(baseName, ext):
currentNum = 0
with open("num.txt",'r') as nf:
try:
currentNum = int(nf.read())
except:
currentNum = 0
nextNum = currentNum+1
with open("num.txt",'w') as nf:
nf.write(str(nextNum))
validName = baseName + '-' + str(nextNum) + ext
return validName
#CAPTURING
def capture():
print("Capturing...")
baseName = "vid"
ext = ".h264" #TODO figure out the video extension
filename = getValidFilename(baseName,ext)
with picamera.PiCamera() as camera:
camera.resolution = (1296, 972)
camera.start_recording(outdir + filename)
camera.wait_recording(vidLength)
camera.stop_recording()
return filename
def convert(filename):
print("Converting...")
base = filename.split('.')[0]
convName = base + ".mp4"
subprocess.call(["MP4Box", "-add", "output/" + filename, "output/" + convName])
return convName
#DROPBOX UTILITIES
#Uploads a file to the dropbox client
def upload(dbclient, filename):
with open("output/" + filename, 'rb') as f:
data = f.read()
writepath = "/"
writepath += filename
response = dbclient.files_upload(data,writepath,mode=dropbox.files.WriteMode.add)
print("uploaded:", response)
#TWILIO
def send(txtbody):
client.messages.create(
to=toNum,
from_=fromNum,
body=txtbody
)
#MAIN STUFFS
def monitorWorker(pir):
global SYSTEM_STATUS
while True:
if SYSTEM_STATUS:
if pir.motion_detected:
theTime = datetime.datetime.now().time()
message = "Motion detected! " + str(theTime)
print(message)
try:
filename = capture()
except:
print("Failed to capture")
try:
convName = convert(filename)
except:
print("Failed to convert")
continue
local = False
try:
dbclient = dropbox.Dropbox(TOKEN)
except:
print("Client didn't connect!!! Recording Locally")
local = True
if not local:
print("Client Connected")
print("Uploading to Dropbox")
try:
upload(dbclient, convName)
except:
print("Failed upload")
try:
send(message)
except:
print("Error sending message")
print("\n-------------\n")
sleep(10) #sleep for 30 seconds to avoid repeated alarms
@ask.intent('SetStatus', mapping={'status': 'status'})
def gpio_status(status):
global SYSTEM_STATUS
if status is 'on':
if (SYSTEM_STATUS == True):
return statement('Monitor is already on')
else:
SYSTEM_STATUS = True
return statement('Turning System {}'.format(status))
if status is 'off':
if (SYSTEM_STATUS == False):
return statement('Monitor is already off')
else:
SYSTEM_STATUS = True
return statement('Turning System {}'.format(status))
@ask.intent('Activate')
def activate():
global SYSTEM_STATUS
if (SYSTEM_STATUS == True):
return statement('Monitor is already on')
else:
SYSTEM_STATUS = True
return statement('Turning System on')
@ask.intent('Deactivate')
def deactivate():
global SYSTEM_STATUS
if (SYSTEM_STATUS == False):
return statement('Monitor is already off')
else:
SYSTEM_STATUS = False
return statement('Turning System off')
if __name__ == '__main__':
pir = MotionSensor(4)
workerThread = threading.Thread(target=monitorWorker, args=(pir,))
workerThread.start() #SYSTEM STATUS IS FALSE STILL - NOT MONITORING
port = 5000 #the custom port you want
app.run(host='0.0.0.0', port=port)