-
Notifications
You must be signed in to change notification settings - Fork 5
/
main.py
110 lines (89 loc) · 3.3 KB
/
main.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
from decouple import config
import pyaarlo
import asyncio
import logging
import signal
from camera import Camera
from base import Base
# Read config from ENV
ARLO_USER = config('ARLO_USER')
ARLO_PASS = config('ARLO_PASS')
IMAP_HOST = config('IMAP_HOST')
IMAP_USER = config('IMAP_USER')
IMAP_PASS = config('IMAP_PASS')
IMAP_GRAB_ALL = config('IMAP_GRAB_ALL', default=False, cast=bool)
IMAP_DELETE_AFTER = config('IMAP_DELETE_AFTER', default=False, cast=bool)
MQTT_BROKER = config('MQTT_BROKER', default=None)
FFMPEG_OUT = config('FFMPEG_OUT')
DEFAULT_RESOLUTION = config('DEFAULT_RESOLUTION', default=(1280, 768))
MOTION_TIMEOUT = config('MOTION_TIMEOUT', default=60, cast=int)
STATUS_INTERVAL = config('STATUS_INTERVAL', default=120, cast=int)
LAST_IMAGE_IDLE = config('LAST_IMAGE_IDLE', default=False, cast=bool)
WATCH_REFRESH_TIME = config('WATCH_REFRESH_TIME', default=2, cast=int)
DEBUG = config('DEBUG', default=False, cast=bool)
PYAARLO_BACKEND = config('PYAARLO_BACKEND', default=None)
PYAARLO_REFRESH_DEVICES = config('PYAARLO_REFRESH_DEVICES', default=0, cast=int)
PYAARLO_STREAM_TIMEOUT = config('PYAARLO_STREAM_TIMEOUT', default=0, cast=int)
PYAARLO_STORAGE_DIR = config('PYAARLO_STORAGE_DIR', default=None)
PYAARLO_ECDH_CURVE = config('PYAARLO_ECDH_CURVE', default=None)
# Initialize logging
logging.basicConfig(
level=logging.DEBUG if DEBUG else logging.INFO,
format='%(asctime)s [%(levelname)s] %(name)s: %(message)s'
)
shutdown_event = asyncio.Event()
async def main():
# login to arlo with 2FA
arlo_args = {
'username': ARLO_USER,
'password': ARLO_PASS,
'tfa_source': 'imap',
'tfa_type': 'email',
'tfa_host': IMAP_HOST,
'tfa_username': IMAP_USER,
'tfa_password': IMAP_PASS,
'tfa_grab_all': IMAP_GRAB_ALL,
'tfa_delete_after': IMAP_DELETE_AFTER
}
if PYAARLO_REFRESH_DEVICES:
arlo_args['refresh_devices_every'] = PYAARLO_REFRESH_DEVICES
if PYAARLO_STREAM_TIMEOUT:
arlo_args['stream_timeout'] = PYAARLO_STREAM_TIMEOUT
if PYAARLO_BACKEND:
arlo_args['backend'] = PYAARLO_BACKEND
if PYAARLO_STORAGE_DIR:
arlo_args['storage_dir'] = PYAARLO_STORAGE_DIR
if PYAARLO_ECDH_CURVE:
arlo_args['ecdh_curve'] = PYAARLO_ECDH_CURVE
arlo = pyaarlo.PyArlo(**arlo_args)
# Initialize bases
bases = [Base(b, STATUS_INTERVAL) for b in arlo.base_stations]
# Initialize cameras
cameras = [Camera(
c, FFMPEG_OUT, MOTION_TIMEOUT, STATUS_INTERVAL, LAST_IMAGE_IDLE,
DEFAULT_RESOLUTION, WATCH_REFRESH_TIME
) for c in arlo.cameras]
# Start both
[asyncio.create_task(d.run()) for d in cameras + bases]
# Initialize mqtt service
if MQTT_BROKER:
import mqtt
asyncio.create_task(mqtt.mqtt_client(cameras, bases))
# Graceful shutdown
def request_shutdown(signal, frame):
logging.info('Shutdown requested...')
shutdown_event.set()
# Register callbacks for shutdown
signal.signal(signal.SIGTERM, request_shutdown)
signal.signal(signal.SIGINT, request_shutdown)
# Wait for shutdown
await shutdown_event.wait()
logging.info('Shutting down...')
for c in cameras:
c.shutdown(signal)
arlo.stop(logout=True)
# Run main
try:
asyncio.run(main())
except RuntimeError:
logging.info("Closed.")