This repository has been archived by the owner on Jan 20, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
service.py
217 lines (171 loc) · 8.88 KB
/
service.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
import xbmc
import xbmcvfs
import xbmcaddon
import time
from threading import Thread
from os import path
from resources.lib import foscam
from resources.lib import common
from resources.lib import gui
__addon__ = xbmcaddon.Addon()
__id__ = __addon__.getAddonInfo('id')
g_reset = False
class Main:
def __init__(self):
common.log("Service is starting...")
self.path = xbmc.translatePath('special://profile/addon_data/%s' %__id__ )
#Checks if directory exists for file storage, if not it creates it
if not xbmcvfs.exists(self.path):
try:
xbmcvfs.mkdir(self.path)
except:
pass
self._reset = False
self.monitor = MyMonitor(action=self.restart)
self.start()
def restart(self):
common.log_verbose("A setting change has been detected!")
self._reset = True
common.log_normal("Applying changed settings in 10 seconds")
self.monitor.waitForAbort(10)
self._reset = False
self.start()
def start(self):
#Collects camera configurations and confirm you can connect to at least 1
atLeastOneCamera, cameras = common.getSettings()
common.log_verbose("Number of Cameras to start: " + str(len(cameras)))
#cameras =
# camera_number[0], host[1], port[2], username[3], password[4], preview_enabled[5]
# motion_enabled[6], motion_sensitivity[7], motion_trigger_interval[8],
# sound_enabled[9], sound_sensitivity[10], sound_trigger_interval[11],
# check_interval[12], duration[13], location[14], scaling[15], trigger_interval[16], set_motion_settings[17]
if atLeastOneCamera:
for camera in cameras:
preview_enabled = camera[5]
if preview_enabled:
atLeastOneCameraPreviewEnabled = True
break
else:
camera_number = camera[0]
common.log_verbose("Preview disabled for Camera " + camera_number)
if atLeastOneCameraPreviewEnabled:
for camera in cameras:
camera_number = camera[0]
preview_enabled = camera[5]
set_motion_settings = camera[17]
common.log_verbose(camera)
if set_motion_settings:
self.configureAlarmSettings(camera)
else:
self.resetCameraAlarmSettings(camera)
if preview_enabled:
t = Thread(target=self.checkAlarm, args=(camera, self.path))
t.start()
common.log_verbose("Thread Started: Camera " + camera_number)
common.log_normal("Cameras started")
#Loop required to detect settings changes
while not self.monitor.abortRequested():
self.monitor.waitForAbort(10)
#Camera Thread
def checkAlarm(self, camera_settings, path):
camera_number = camera_settings[0]
motion_enabled = camera_settings[6]
sound_enabled = camera_settings[9]
duration = camera_settings[13]
check_interval = camera_settings[12]
trigger_interval = camera_settings[16]
windowOpen = False
#Send request to camera and receive response
with foscam.Camera (camera_settings) as camera:
snapshot_url = camera.snapshot_url
preview = gui.CamWindow(camera_settings, path, snapshot_url)
while not self.monitor.abortRequested() and not self._reset:
alarmActive = False
alarmState = camera.get_device_state()
#Parses result for alarm state
if alarmState:
for alarm, enabled in (('motionDetect', motion_enabled), ('sound', sound_enabled)):
if enabled:
param = "{0}Alarm".format(alarm)
#common.log_verbose("{0:s} = {1:d}".format(param, alarmState[param]))
if alarmState[param] == 2:
alarmActive = True
common.log_verbose("Alarm detected on Camera " + camera_number)
break
if alarmActive:
durationTime = time.time() + duration #Resets the time to close
if not windowOpen:
common.log_normal("Opening preview window for camera " + camera_number)
windowOpen = True
preview.start()
else:
if windowOpen: #Alarm not active but window still open
common.log_verbose("Camera {0} window closing in {1} seconds.".format(camera_number, 1 - (time.time() - durationTime)))
if durationTime < time.time():
windowOpen = False
preview.stop()
common.log_verbose("Camera {0} window closed. No alarm detected while window was still open.".format(camera_number))
#Wait for next loop logic
if alarmActive:
sleep = int(trigger_interval - 1)
else:
sleep = int(check_interval)
common.log_verbose("Camera {0} will sleep for {1} seconds".format(camera_number, sleep))
self.monitor.waitForAbort(sleep)
#--
#Configure Motion Settings
def configureAlarmSettings(self, camera_settings):
with foscam.Camera(camera_settings) as camera:
# Applies new settings to camera
camera_number = camera_settings[0]
motion_enabled = camera_settings[6]
sound_enabled = camera_settings[9]
command = camera.set_motion_detect_config()
common.log_verbose(command)
if motion_enabled:
command['isEnable'] = 1
command['sensitivity'] = common.get_setting('motion_sensitivity' + camera_number)
command['triggerInterval'] = common.get_setting('motion_trigger_interval' + camera_number)
self.send_command(command)
common.log_verbose(command)
command = camera.set_sound_detect_config()
common.log_verbose(command)
if sound_enabled:
command['isEnable'] = 1
command['sensitivity'] = common.get_setting('sound_sensitivity' + camera_number)
command['triggerInterval'] = common.get_setting('sound_trigger_interval' + camera_number)
#for iday in range(7):
# command['schedule{0:d}'.format(iday)] = 2**48 - 1
self.send_command(command)
common.log_verbose(command)
def resetCameraAlarmSettings(self, camera_settings):
with foscam.Camera(camera_settings) as camera:
# Sets setting.xml settings based on camera settings
camera_number = camera_settings[0]
motion_enabled = camera_settings[6]
sound_enabled = camera_settings[9]
common.log_verbose('Resetting Camera Motion Config to settings.xml')
response = camera.get_motion_detect_config()
common.log_verbose(response)
common.set_setting('motion_sensitivity' + camera_number, str(response['sensitivity']))
common.set_setting('motion_trigger_interval' + camera_number, str(response['triggerInterval']))
common.log_verbose('Resetting Camera Sound Config to settings.xml')
response = camera.get_sound_detect_config()
common.log_verbose(response)
common.set_setting('sound_sensitivity' + camera_number, str(response['sensitivity']))
common.set_setting('sound_trigger_interval' + camera_number, str(response['triggerInterval']))
def send_command(self, command):
response = command.send()
if not response:
msg = u"{0}: {1}".format(common.get_string(32104), response.message)
common.notify(msg)
#--
class MyMonitor(xbmc.Monitor):
def __init__(self, action):
xbmc.Monitor.__init__(self)
self.action = action
def onSettingsChanged(self):
self.action()
# Service Start
if __name__ == '__main__':
Main()