-
Notifications
You must be signed in to change notification settings - Fork 6
/
app.py
140 lines (94 loc) · 3.8 KB
/
app.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
import json, requests
import time
import paho.mqtt.client as mqtt
from webexteam import sent_notification
# mqtt setting
MQTT_SERVER = ""
MQTT_PORT = 1883
MQTT_TOPIC = "/merakimv/#"
# Meraki api key
MERAKI_API_KEY = ""
# Camera network ID, get video link
NETWORK_ID = ""
# Array of cameras serial numbers
COLLECT_CAMERAS_SERIAL_NUMBERS = ["*"]
# Array of zone id, all is *. eg ["*"]
COLLECT_ZONE_IDS = [""]
# motion trigger setting
MOTION_ALERT_PEOPLE_COUNT_THRESHOLD = 1
MOTION_ALERT_ITERATE_COUNT = 4
MOTION_ALERT_TRIGGER_PEOPLE_COUNT = 1
MOTION_ALERT_PAUSE_TIME = 15
_MONITORING_TRIGGERED = False
_MONITORING_MESSAGE_COUNT = 0
_MONITORING_PEOPLE_TOTAL_COUNT = 0
def collect_zone_information(topic, payload):
## /merakimv/Q2GV-S7PZ-FGBK/123
parameters = topic.split("/")
serial_number = parameters[2]
zone_id = parameters[3]
index = len([i for i, x in enumerate(COLLECT_ZONE_IDS) if x == zone_id])
# if not wildcard or not in the zone_id list or equal to 0 (whole camera)
if COLLECT_ZONE_IDS[0] != "*":
if index == 0 or zone_id == "0":
return
# detect motion
global _MONITORING_TRIGGERED, _MONITORING_MESSAGE_COUNT, _MONITORING_PEOPLE_TOTAL_COUNT
# if motion monitoring triggered
if _MONITORING_TRIGGERED:
_MONITORING_MESSAGE_COUNT = _MONITORING_MESSAGE_COUNT + 1
_MONITORING_PEOPLE_TOTAL_COUNT = _MONITORING_PEOPLE_TOTAL_COUNT + payload
if _MONITORING_MESSAGE_COUNT > MOTION_ALERT_ITERATE_COUNT:
if _MONITORING_PEOPLE_TOTAL_COUNT >= MOTION_ALERT_TRIGGER_PEOPLE_COUNT:
# notification
notify(serial_number)
# pause
time.sleep(MOTION_ALERT_PAUSE_TIME)
# reset
_MONITORING_MESSAGE_COUNT = 0
_MONITORING_PEOPLE_TOTAL_COUNT = 0
_MONITORING_TRIGGERED = False
if payload >= MOTION_ALERT_PEOPLE_COUNT_THRESHOLD:
_MONITORING_TRIGGERED = True
print("payload : " + str(payload) +
", _MONITORING_TRIGGERED : " + str(_MONITORING_TRIGGERED) +
", _MONITORING_MESSAGE_COUNT : " + str(_MONITORING_MESSAGE_COUNT) +
", _MONITORING_PEOPLE_TOTAL_COUNT : " + str(_MONITORING_PEOPLE_TOTAL_COUNT))
def notify(serial_number):
# Get video link
url = "https://api.meraki.com/api/v0/networks/{1}/cameras/{0}/videoLink".format(serial_number, NETWORK_ID)
# current timestamp
ts = str(time.time()).split(".")[0] + "000"
querystring = {"timestamp": ts}
headers = {
'X-Cisco-Meraki-API-Key': MERAKI_API_KEY,
"Content-Type": "application/json"
}
resp = requests.request("GET", url, headers=headers, params=querystring)
if int(resp.status_code / 100) == 2:
msg = "An alert triggered. \n Video : ".format(resp.json().get("url"))
sent_notification(msg)
def on_connect(client, userdata, flags, rc):
print("Connected with result code " + str(rc))
client.subscribe(MQTT_TOPIC)
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
payload = json.loads(msg.payload.decode("utf-8"))
parameters = msg.topic.split("/")
serial_number = parameters[2]
# filter camera
if COLLECT_CAMERAS_SERIAL_NUMBERS[0] != "*" or len(
[i for i, x in enumerate(COLLECT_CAMERAS_SERIAL_NUMBERS) if x == serial_number]):
return
if msg.topic[-14:] != 'raw_detections':
collect_zone_information(msg.topic, payload)
if __name__ == "__main__":
# mqtt
try:
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect(MQTT_SERVER, MQTT_PORT, 60)
client.loop_forever()
except Exception as ex:
print("[MQTT]failed to connect or receive msg from mqtt, due to: \n {0}".format(ex))