-
Notifications
You must be signed in to change notification settings - Fork 0
/
detect_presence.py
121 lines (94 loc) · 3.25 KB
/
detect_presence.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
import numpy as np
from grideye_comm import device
import time
#import gpio
class PresenceDetector(object):
"""
Presence is detected if any pixel is greater than threshold from its baseline value
"""
def __init__(self, true_cutoff=0.4, debounce_limit=2, consecutive_trues=50):
self.collect_baseline()
self.debounce_limit = debounce_limit
self.debounce_timer = time.time()
self.last_value = False
self.consecutive_trues = consecutive_trues
self.num_trues = 0
self.cutoff = true_cutoff
def collect_avg(self,secs):
avg = device.read_packet()
samples = 1
start = time.time()
while (time.time()-start)<secs:
avg = np.add(avg,device.read_packet())
samples = samples + 1
return np.divide(avg,samples)
def collect_baseline(self,secs=5):
raw_input("Point sensor at room, make sure it's stable, and that nobody is in the room.")
self.empty_baseline = self.collect_avg(secs)
print("Empty baseline calculated: \n%s"%str(self.empty_baseline))
raw_input("Point sensor at room, make sure it's stable, and that somebody is in the room.")
self.occupied_baseline = self.collect_avg(secs*2)
print("Occupied baseline calculated: \n%s"%str(self.occupied_baseline))
self.threshold = np.abs(np.subtract(self.occupied_baseline,self.empty_baseline))
print("Threshold calculated: \n%s"%str(self.threshold))
def is_present(self, pkt=None):
"""
Reads a packet, and subtracts it from the baseline.
Then checks to see if any pixels are higher than threshold.
"""
if not pkt:
pkt = device.read_packet()
diff_from_empty = np.abs(np.subtract(pkt,self.empty_baseline))
any_gt_threshold = diff_from_empty>self.threshold
#print("Recording: \n%s\nDifference from empty baseline: \n%s\nAny greater than threshold: \n%s"%(str(pkt),str(diff_from_empty),str(any_gt_threshold)))
triggered_pixels = np.count_nonzero(any_gt_threshold)
return float(triggered_pixels)/float(any_gt_threshold.size)>self.cutoff
def debounce_present(self, pkt=None):
"""
If was false, true is immediatly accepted and sets timer
If was true, true resets timer. False is accepted if timer is passed, else ignored.
"""
raw_presence = self.is_present(pkt)
if raw_presence:
self.num_trues = self.num_trues+1
if self.num_trues<self.consecutive_trues:
raw_presence = False
else:
self.num_trues = 0
if self.last_value:
#If was true,
if raw_presence:
#true resets timer if it gets trues_in_a_row trues in a row
self.num_trues = self.num_trues + 1
self.debounce_timer = time.time()
self.last_value = True
return True
else:
#False is accepted if timer is passed, else ignored.
if (time.time()-self.debounce_timer)>self.debounce_limit:
self.last_value = False
return False
else:
self.last_value = True
return True
else:
#If was false
if raw_presence:
self.debounce_timer = time.time()
self.last_value = True
return True
else:
self.last_value = False
return False
if __name__ == "__main__":
detector = PresenceDetector()
prev = False
pin = 25
#gpio.write(pin,prev)
while True:
present = detector.debounce_present()
print("Presence detected!" if present else "Nobody in view.")
if present is not prev:
prev = present
#gpio.write(pin,present)
device.shutdown()