This repository has been archived by the owner on Jul 17, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient.py
382 lines (320 loc) · 10.3 KB
/
client.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
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
"""
Computer Systems and Networks
University of Applied Sciences Utrecht
TICT-V1CSN-15 Project
"""
import datetime
import socket
import time
import sys
import uuid
import pygame
import RPi.GPIO as GPIO
from _thread import *
HOST = '' # Enter IP address of device where server.py is running
PORT = 5555
UUID = uuid.uuid4().hex
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# var GPIO
run = True
connected_to_server = False
registered = False
debug = True
last_ping = 0
alarm_tripped = False
alarm_enabled = False
alarm_interval_seconds = 5
alarm_running = True
system_on = False
alarm_trigger_time = 0
alarm_on = False
trigger_delay = 5
server_disable_alarm = False
pygame.mixer.init()
pygame.mixer.music.load("shootingstars.mp3")
# LCD var declarations
LCD_RS = 7
LCD_E = 8
LCD_D4 = 25
LCD_D5 = 24
LCD_D6 = 23
LCD_D7 = 18
LCD_WIDTH = 16
LCD_CHR = True
LCD_CMD = False
LCD_LINE_1 = 0x80
LCD_LINE_2 = 0xC0
LCD_E_PULSE = 0.0005
LCD_E_DELAY = 0.0005
LCD_text_1 = " Alarm is off "
LCD_text_2 = " Not connected_to_server "
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM) # Use BCM GPIO numbers
GPIO.setup(LCD_E, GPIO.OUT) # E
GPIO.setup(LCD_RS, GPIO.OUT) # RS
GPIO.setup(LCD_D4, GPIO.OUT) # DB4
GPIO.setup(LCD_D5, GPIO.OUT) # DB5
GPIO.setup(LCD_D6, GPIO.OUT) # DB6
GPIO.setup(LCD_D7, GPIO.OUT) # DB7
GPIO.setup(6, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(11, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(26, GPIO.OUT)
GPIO.setup(19, GPIO.OUT)
GPIO.setup(13, GPIO.OUT)
def lcd_init():
""" Initialise display """
lcd_byte(0x33, LCD_CMD) # 110011 Initialise
lcd_byte(0x32, LCD_CMD) # 110010 Initialise
lcd_byte(0x06, LCD_CMD) # 000110 Cursor move direction
lcd_byte(0x0C, LCD_CMD) # 001100 Display On,Cursor Off, Blink Off
lcd_byte(0x28, LCD_CMD) # 101000 Data length, number of lines, font size
lcd_byte(0x01, LCD_CMD) # 000001 Clear display
time.sleep(LCD_E_DELAY)
def lcd_byte(bits, mode):
""" Send byte to data pins """
GPIO.output(LCD_RS, mode) # RS
# High bits
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits & 0x10 == 0x10:
GPIO.output(LCD_D4, True)
if bits & 0x20 == 0x20:
GPIO.output(LCD_D5, True)
if bits & 0x40 == 0x40:
GPIO.output(LCD_D6, True)
if bits & 0x80 == 0x80:
GPIO.output(LCD_D7, True)
# Toggle 'Enable' pin
lcd_toggle_enable()
# Low bits
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits & 0x01 == 0x01:
GPIO.output(LCD_D4, True)
if bits & 0x02 == 0x02:
GPIO.output(LCD_D5, True)
if bits & 0x04 == 0x04:
GPIO.output(LCD_D6, True)
if bits & 0x08 == 0x08:
GPIO.output(LCD_D7, True)
# Toggle 'Enable' pin
lcd_toggle_enable()
def lcd_toggle_enable():
""" Toggle enable """
time.sleep(LCD_E_DELAY)
GPIO.output(LCD_E, True)
time.sleep(LCD_E_PULSE)
GPIO.output(LCD_E, False)
time.sleep(LCD_E_DELAY)
def lcd_string(message, line):
""" Writes message to LCD on specified line """
message = message.ljust(LCD_WIDTH, " ")
lcd_byte(line, LCD_CMD)
for i in range(LCD_WIDTH):
lcd_byte(ord(message[i]), LCD_CHR)
def led_on(pin):
""" Turns pin to 1 """
GPIO.output(pin, GPIO.HIGH)
def led_off(pin):
""" Turns pin to 0 """
GPIO.output(pin, GPIO.LOW)
def button(x):
""" returns whether button is pressed or not """
y = GPIO.input(x)
if not y:
return True
def alarm_system_on():
""" Turn alarm system on, update hardware, software and server accordingly """
global system_on
global LCD_text_1
led_on(26)
system_on = True
socket_write("", "ALRM_ON")
LCD_text_1 = ' System is on'
time.sleep(0.2)
def alarm_system_off():
""" Turn alarm system off, update hardware, software and server accordingly """
global system_on
global LCD_text_1
led_off(26)
led_off(19)
led_off(13)
system_on = False
socket_write("", "ALRM_OFF")
LCD_text_1 = ' System is off'
time.sleep(0.5)
pygame.mixer.music.stop()
def led_flicker(x):
""" Turns pin x on and off until told otherwise """
while True:
led_on(x)
time.sleep(0.2)
led_off(x)
time.sleep(0.2)
if not system_on:
led_off(x)
break
def alarm_trigger():
""" Triggers alarm, waits trigger_delay time before updating hardware, software and server """
global server_disable_alarm
alarm_tripped = True
led_on(13)
while system_on:
if button(6):
break
if server_disable_alarm:
server_disable_alarm = False
break
global alarm_tripped
if (time.time() - alarm_trigger_time >= trigger_delay) and (alarm_trigger_time != 0):
pygame.mixer.music.play()
socket_write("", "ALRM_TRIP")
time.sleep(0.5)
led_off(13)
start_new_thread(led_flicker(19), ())
break
def alarm_trigger_off():
""" Turns the alarm off """
global server_disable_alarm
global alarm_tripped
led_off(19)
server_disable_alarm = True
alarm_tripped = False
led_off(19)
time.sleep(0.5)
pygame.mixer.music.stop()
def gpio_mainloop():
""" Contains general GPIO logic for LED, LCD and buttons """
global alarm_running
global system_on
global alarm_trigger_time
global LCD_text_1
global LCD_text_2
GPIO.output(26, 0)
GPIO.output(19, 0)
GPIO.output(13, 0)
while True:
if button(6) and system_on == False:
alarm_system_on()
if button(6) and system_on:
alarm_system_off()
if button(11) and system_on == True:
alarm_trigger_time = time.time()
start_new_thread (alarm_trigger, ())
print (system_on)
if button(5) and system_on == True:
alarm_trigger_time = time.time()
alarm_trigger()
lcd_string(LCD_text_1, LCD_LINE_1)
lcd_string(LCD_text_2, LCD_LINE_2)
def get_time():
""" Returns current time in format %d-%m-%Y %X """
return datetime.datetime.now().strftime('%d-%m-%Y %X')
def has_timeout():
""" Check if the client is no longer connected if it has not received socket data for more than 5.5 seconds """
while True:
time.sleep(10)
if time.time() - last_ping >= 5.5 and last_ping != 0:
if debug: print("There is no longer a connection to the server, exiting system")
global LCD_text_2
LCD_text_2 = ' Not Connected'
led_on(13)
alarm_trigger()
stop_client()
sys.exit()
def parse_socket_data(data: str):
""" Handles socket data accordingly """
global registered
global last_ping
global server_disable_alarm
if data == "REG_COMPLETE":
registered = True
elif data == "ALRM_CHNG":
if alarm_tripped:
alarm_trigger_off()
else:
alarm_trigger()
elif data == "ALRM_STATUS":
pass
elif data == "ALRM_TRIP":
alarm_trigger()
elif data == "ALRM_STOP":
alarm_trigger_off()
elif data == "ALRM_ON":
alarm_system_on()
elif data == "ALRM_OFF":
server_disable_alarm = True
alarm_system_off()
elif data == "CHNG_INTERVAL":
pass
elif data == "IS_ALIVE":
socket_write("ACK", "IS_ALIVE")
last_ping = time.time()
global LCD_text_2
LCD_text_2= ' Connected'
elif data == "UUID_REQ":
socket_write(str(UUID), "UUID")
elif data == "STATUS_UPD":
socket_write("{'online': " + str(alarm_tripped) + "}", "STATUS_UPDM")
def socket_write(data: str, data_header: str):
"""
Writes a concatenation of the client UUID, data header and data to
the connection socket of this program instance
"""
global LCD_text_2
message = str(UUID) + "," + data_header + "," + data
if debug: print("{} - Client send: {}".format(get_time(), message))
try:
client_socket.send(message.encode('ascii'))
except ConnectionResetError or ConnectionAbortedError:
if debug: print("{} - Connection has been terminated by the server.".format(get_time()))
LCD_text_2 = ' Not Connected'
stop_client()
sys.exit()
client_socket.send(message.encode('ascii'))
def stop_client():
""" Cleans up GPIO when exiting """
lcd_byte(0x01, LCD_CMD)
lcd_string(" Goodbye!", LCD_LINE_1)
GPIO.output(26, 0)
GPIO.output(19, 0)
GPIO.output(13, 0)
def socket_read():
"""
Listens to the connection socket of this program instance
and passes that data to the parse_socket_data() function
"""
try:
data = client_socket.recv(4096)
except ConnectionResetError or ConnectionAbortedError or KeyboardInterrupt:
if debug: print("{} - Connection has been terminated by the server.".format(get_time()))
stop_client()
sys.exit()
data = data.decode('utf-8').strip().split(',')
if data[0] == '':
alarm_trigger()
if debug: print("{} - Client received: {}".format(get_time(), data))
if (data[0] == UUID) or (data[0] == "BROADCAST"):
return parse_socket_data(data[1])
if __name__ == '__main__':
try:
try:
client_socket.connect((HOST, PORT))
connected_to_server = True
except socket.error as e:
if debug: print("{} - Socket error {}".format(get_time(), e))
sys.exit()
finally:
if debug: print("{} - Successfully connect to IP:{}, PORT:{}".format(get_time(), HOST, PORT))
lcd_init()
start_new_thread(gpio_mainloop, ())
start_new_thread(has_timeout, ())
while True:
socket_read()
finally:
stop_client()