Skip to content

Commit f2ce669

Browse files
committedOct 5, 2020
Fixed PublishImages, and alerts
1 parent 7a7bb35 commit f2ce669

File tree

4 files changed

+51
-45
lines changed

4 files changed

+51
-45
lines changed
 

‎.vscode/launch.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
"version": "0.2.0",
66
"configurations": [
77
{
8-
"name": "Python: Current File (Integrated Terminal)",
8+
"name": "Python: CameraEvents",
99
"type": "python",
1010
"request": "launch",
11-
"program": "${file}",
11+
"program": "${workspaceFolder}/CameraEvents.py",
1212
"console": "integratedTerminal"
1313
},
1414
{

‎CameraEvents.py

+45-39
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class DahuaDevice():
8181

8282

8383

84-
def __init__(self, name, device_cfg, client, basetopic, homebridge):
84+
def __init__(self, name, device_cfg, client, basetopic, homebridge, publishImages):
8585
if device_cfg["channels"]:
8686
self.channels = device_cfg["channels"]
8787
else:
@@ -104,6 +104,7 @@ def __init__(self, name, device_cfg, client, basetopic, homebridge):
104104
self.basetopic = basetopic
105105
self.homebridge = homebridge
106106
self.snapshotoffset = device_cfg.get("snapshotoffset")
107+
self.publishImages = publishImages
107108

108109
#generate the event url
109110
self.url = self.EVENT_TEMPLATE.format(
@@ -171,7 +172,7 @@ def channelIsMine(self,channelname="",channelid=-1):
171172
return -1
172173

173174

174-
def SnapshotImage(self, channel, channelName, message,nopublish=False):
175+
def SnapshotImage(self, channel, channelName, message,publishImages=False):
175176
"""Takes a snap shot image for the specified channel
176177
channel (index number starts at 1)
177178
channelName if known for messaging
@@ -199,28 +200,29 @@ def SnapshotImage(self, channel, channelName, message,nopublish=False):
199200
#construct image payload
200201
#{{ \"message\": \"Motion Detected: {0}\", \"imagebase64\": \"{1}\" }}"
201202
imagepayload = (base64.encodebytes(image)).decode("utf-8")
202-
msgpayload = json.dumps({"message":message,"imagebase64":imagepayload})
203+
if publishImages:
204+
msgpayload = json.dumps({"message":message,"imagebase64":imagepayload})
205+
else:
206+
msgpayload = json.dumps({"message":message,"imagurl":imageurl})
203207
#msgpayload = "{{ \"message\": \"{0}\", \"imagebase64\": \"{1}\" }}".format(message,imgpayload)
204208

205-
if not nopublish:
206-
self.client.publish(self.basetopic +"/{0}/Image".format(channelName),msgpayload)
209+
self.client.publish(self.basetopic +"/{0}/Image".format(channelName),msgpayload)
210+
207211
except Exception as ex:
208212
_LOGGER.error("Error sending image: " + str(ex))
209213
try:
210214

211215
with open("default.png", 'rb') as thefile:
212216
imagepayload = thefile.read().encode("base64")
213217
msgpayload = json.dumps({"message":"ERR:" + message, "imagebase64": imagepayload})
214-
if not nopublish:
215-
self.client.publish(self.basetopic +"/{0}/Image".format(channelName),msgpayload)
216218
except:
217219
pass
218220

219221

220222
return image
221223

222224

223-
def SearchImages(self,channel,starttime, endtime, events,nopublish=True, message='',delay=0):
225+
def SearchImages(self,channel,starttime, endtime, events,publishImages=False, message='',delay=0):
224226
"""Searches for images for the channel
225227
channel is a numerical channel index (starts at 1)
226228
starttime is the start search time
@@ -364,13 +366,12 @@ def SearchImages(self,channel,starttime, endtime, events,nopublish=True, message
364366

365367
if image is not None:
366368
imagepayload = (base64.encodebytes(image)).decode("utf-8")
367-
msgpayload = json.dumps({"message":message,"imagebase64":imagepayload})
369+
if publishImages:
370+
msgpayload = json.dumps({"message":message,"imagebase64":imagepayload})
371+
else:
372+
msgpayload = json.dumps({"message":message,"imageurl":loadurl})
368373
#msgpayload = "{{ \"message\": \"{0}\", \"imagebase64\": \"{1}\" }}".format(message,imgpayload)
369374

370-
if not nopublish:
371-
_LOGGER.debug("SearchImages: Publishing " + filepath)
372-
self.client.publish(self.basetopic +"/{0}/Image".format(channelName),msgpayload)
373-
374375
#imageio.mimsave('movie.gif',images, duration=1.5)
375376
#try:
376377
# slack = Slacker(self.token)
@@ -407,7 +408,7 @@ def SearchImages(self,channel,starttime, endtime, events,nopublish=True, message
407408
return ""
408409
#def SearchImages(self,channel,starttime, endtime, events,nopublish=True, message='',delay=0):
409410

410-
def SearchClips(self,channel,starttime, endtime, events,nopublish=True, message='',delay=0):
411+
def SearchClips(self,channel,starttime, endtime, events,publishImages=False, message='',delay=0):
411412
"""Searches for clips for the channel
412413
channel is a numerical channel index (starts at 1)
413414
starttime is the start search time
@@ -537,7 +538,7 @@ def SearchClips(self,channel,starttime, endtime, events,nopublish=True, message=
537538
loadurl = MEDIA_LOADFILE.format(host=self.host,protocol=self.protocol,port=self.port,file=filepath)
538539
_LOGGER.debug("SearchClips: LoadUrl: " + loadurl)
539540
#result = s.get(loadurl,auth=auth,cookies=cookies,stream=True)
540-
if not nopublish:
541+
if not publishImages:
541542
_LOGGER.debug("SearchClips: Publishing " + filepath)
542543
self.client.publish(self.basetopic +"/{0}/Clip".format(channelName),loadurl)
543544
#result = s.get(loadurl,auth=auth,cookies=cookies)
@@ -550,7 +551,7 @@ def SearchClips(self,channel,starttime, endtime, events,nopublish=True, message=
550551
loadurl = MEDIA_LOADFILE.format(host=self.host,protocol=self.protocol,port=self.port,file=filepath)
551552
_LOGGER.debug("SearchImages: LoadUrl: " + loadurl)
552553
#result = s.get(loadurl,auth=auth,cookies=cookies,stream=True)
553-
if not nopublish:
554+
if not publishImages:
554555
_LOGGER.debug("SearchClips: Publishing " + filepath)
555556
self.client.publish(self.basetopic +"/{0}/Clip".format(channelName),loadurl)
556557
#result = s.get(loadurl,auth=auth,cookies=cookies)
@@ -658,19 +659,19 @@ def OnReceive(self, data):
658659
if self.alerts:
659660
#possible new process:
660661
#http://192.168.10.66/cgi-bin/snapManager.cgi?action=attachFileProc&Flags[0]=Event&Events=[VideoMotion%2CVideoLoss]
661-
process = threading.Thread(target=self.SnapshotImage,args=(index+self.snapshotoffset,Alarm["channel"],"Motion Detected: {0}".format(Alarm["channel"])))
662+
process = threading.Thread(target=self.SnapshotImage,args=(index+self.snapshotoffset,Alarm["channel"],"Motion Detected: {0}".format(Alarm["channel"]),self.publishImages))
662663
process.daemon = True # Daemonize thread
663664
process.start()
664665
else: #if Alarm["action"] == "Start":
665666
eventStart = False
666667
self.client.publish(self.basetopic +"/" + Alarm["Code"] + "/" + Alarm["channel"] ,"ON")
667668
self.client.publish(self.basetopic +"/" + Alarm["channel"] + "/event" ,"OFF")
668-
_LOGGER.info("ReceiveData: calling search Clips")
669-
starttime = datetime.datetime.now() - datetime.timedelta(minutes=1)
670-
endtime = datetime.datetime.now()
671-
process2 = threading.Thread(target=self.SearchClips,args=(index+self.snapshotoffset,starttime,endtime,'',False,'Search Clips VideoMotion',30))
672-
process2.daemon = True # Daemonize thread
673-
process2.start()
669+
#_LOGGER.info("ReceiveData: calling search Clips")
670+
#starttime = datetime.datetime.now() - datetime.timedelta(minutes=1)
671+
#endtime = datetime.datetime.now()
672+
#process2 = threading.Thread(target=self.SearchClips,args=(index+self.snapshotoffset,starttime,endtime,'',False,'Search Clips VideoMotion',30,self.publishImages))
673+
#process2.daemon = True # Daemonize thread
674+
#process2.start()
674675
elif Alarm["Code"] == "AlarmLocal":
675676
_LOGGER.info("Alarm Local received: "+ Alarm["name"] + " Index: " + str(index) + " Code: " + Alarm["Code"])
676677
# Start action reveived, turn alarm on.
@@ -706,18 +707,18 @@ def OnReceive(self, data):
706707
if self.alerts:
707708
#possible new process:
708709
#http://192.168.10.66/cgi-bin/snapManager.cgi?action=attachFileProc&Flags[0]=Event&Events=[VideoMotion%2CVideoLoss]
709-
process = threading.Thread(target=self.SnapshotImage,args=(index+self.snapshotoffset,Alarm["channel"],"IVS: {0}: {1}".format(Alarm["channel"],regionText)))
710+
process = threading.Thread(target=self.SnapshotImage,args=(index+self.snapshotoffset,Alarm["channel"],"IVS: {0}: {1}".format(Alarm["channel"],regionText,self.publishImages)))
710711
process.daemon = True # Daemonize thread
711712
process.start()
712713
else: #if Alarm["action"] == "Start":
713714
eventStart = False
714715
self.client.publish(self.basetopic +"/" + Alarm["channel"] + "/event" ,"OFF")
715-
_LOGGER.info("ReceiveData: calling search Clips")
716-
starttime = datetime.datetime.now() - datetime.timedelta(minutes=1)
717-
endtime = datetime.datetime.now()
718-
process2 = threading.Thread(target=self.SearchClips,args=(index+self.snapshotoffset,starttime,endtime,'',False,'Search Clips IVS',30))
719-
process2.daemon = True # Daemonize thread
720-
process2.start()
716+
#_LOGGER.info("ReceiveData: calling search Clips")
717+
#starttime = datetime.datetime.now() - datetime.timedelta(minutes=1)
718+
#endtime = datetime.datetime.now()
719+
#process2 = threading.Thread(target=self.SearchClips,args=(index+self.snapshotoffset,starttime,endtime,'',False,'Search Clips IVS',30,self.publishImages))
720+
#process2.daemon = True # Daemonize thread
721+
#process2.start()
721722

722723
else: #if Alarm["Code"] == "VideoMotion": - unknown event
723724
_LOGGER.info("dahua_event_received: "+ Alarm["name"] + " Index: " + Alarm["channel"] + " Code: " + Alarm["Code"])
@@ -813,7 +814,9 @@ def __init__(self, mqtt, cameras):
813814

814815
for device_cfg in cameras:
815816

816-
device = DahuaDevice(device_cfg.get("name"), device_cfg, self.client,self.basetopic, self.homebridge)
817+
device = DahuaDevice(device_cfg.get("name"), device_cfg, self.client,self.basetopic, self.homebridge, mqtt["mqttimages"])
818+
819+
_LOGGER.info("Device %s created on Url %s. Alert Status: %s" % (device.Name, device.host, device.alerts))
817820

818821
self.Devices.append(device)
819822

@@ -911,9 +914,12 @@ def mqtt_on_connect(self, client, userdata, flags, rc):
911914
#else:
912915
# state = "OFF"
913916

914-
#for device in self.Devices:
915-
# device.alerts = state
916-
# self.client.publish(self.basetopic +"/" + device.Name + "/alerts/state",state,qos=0,retain=True)
917+
for device in self.Devices:
918+
if device.alerts:
919+
state = "ON"
920+
else:
921+
state = "OFF"
922+
self.client.publish(self.basetopic +"/" + device.Name + "/alerts/state",state,qos=0,retain=True)
917923
self.client.subscribe(self.basetopic +"/+/picture")
918924
self.client.subscribe(self.basetopic +"/+/alerts")
919925

@@ -943,7 +949,7 @@ def mqtt_on_picture_message(self,client, userdata, msg):
943949
datestring = (msg.payload).decode()
944950
d = datetime.datetime.strptime(datestring, "%Y-%m-%dT%H:%M:%S")
945951
#def SearchImages(self,channel,starttime, endtime, events):
946-
device.SearchImages(channel+device.snapshotoffset,d,d + datetime.timedelta(minutes=2),'',nopublish=False,message="Snap Shot Image" )
952+
device.SearchImages(channel+device.snapshotoffset,d,d + datetime.timedelta(minutes=2),'',publishImages=device.publishImages,message="Snap Shot Image" )
947953
except Exception as searchI:
948954
_LOGGER.warn("Error searching images: " + str(searchI))
949955
d = None
@@ -1002,14 +1008,14 @@ def mqtt_on_cross_message(self,client, userdata, msg):
10021008
#temp = cp.get(camera_key,"host")
10031009
camera["host"] = cp.get(camera_key,'host')
10041010
camera["protocol"] = cp.get(camera_key,'protocol')
1005-
camera["isNVR"] = cp.get(camera_key,'isNVR')
1011+
camera["isNVR"] = cp.getboolean(camera_key,'isNVR',fallback=False)
10061012
camera["name"] = cp.get(camera_key,'name')
10071013
camera["port"] = cp.getint(camera_key,'port')
10081014
camera["user"] = cp.get(camera_key,'user')
10091015
camera["pass"] = cp.get(camera_key,'pass')
10101016
camera["auth"] = cp.get(camera_key,'auth')
10111017
camera["events"] = cp.get(camera_key,'events')
1012-
camera["alerts"] = cp.get(camera_key,"alerts",fallback=True)
1018+
camera["alerts"] = cp.getboolean(camera_key,"alerts",fallback=True)
10131019
channels = {}
10141020
if cp.has_option(camera_key,'channels'):
10151021
try:
@@ -1043,8 +1049,8 @@ def mqtt_on_cross_message(self,client, userdata, msg):
10431049
mqtt["basetopic"] = cp.get("MQTT Broker","BaseTopic")
10441050
mqtt["user"] = cp.get("MQTT Broker","user",fallback=None)
10451051
mqtt["password"] = cp.get("MQTT Broker","password",fallback=None)
1046-
mqtt["homebridge"] = cp.get("MQTT Broker","HomebridgeEvents",fallback=False)
1047-
mqtt["mqttimages"] = cp.get("MQTT Broker","PostImagesToMQTT",fallback=True)
1052+
mqtt["homebridge"] = cp.getboolean("MQTT Broker","HomebridgeEvents",fallback=False)
1053+
mqtt["mqttimages"] = cp.getboolean("MQTT Broker","PostImagesToMQTT",fallback=True)
10481054
dahua_event = DahuaEventThread(mqtt,cameras)
10491055

10501056
dahua_event.start()

‎Tests/test_devices.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def create_device():
3333

3434
basetopic = "CameraEvents"
3535

36-
device = CameraEvents.DahuaDevice("Camera", device_cfg, client,basetopic,False)
36+
device = CameraEvents.DahuaDevice("Camera", device_cfg, client,basetopic,homebridge=False,publishImages=True)
3737
return device
3838

3939
def read_config():
@@ -63,7 +63,7 @@ def test_dahua_take_snapshot():
6363
device.host = 'cam-nvr.andc.nz'
6464
device.user = 'IOS'
6565
device.password = 'Dragon25'
66-
image = device.SnapshotImage(1,"Garage","message",nopublish=True)
66+
image = device.SnapshotImage(1,"Garage","message",publishImages=False)
6767
assert image is not None
6868
if len(image) > 600:
6969
sized = True
@@ -76,7 +76,7 @@ def test_dahua_search_images():
7676
device.password = 'Dragon25'
7777
starttime = datetime.datetime.now() - datetime.timedelta(minutes=520)
7878
endtime = datetime.datetime.now()
79-
result = device.SearchImages(1, starttime,endtime,"",nopublish=True,message='')
79+
result = device.SearchImages(1, starttime,endtime,"",publishImages=False,message='')
8080
assert result is not None
8181
#if len(image) > 600:
8282
# sized = True

‎config-master.ini

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ HomebridgeEvents=True
1515
;Messge to CameraEvents/motion with message of camera name
1616
;End of event is CameraEvents/motion/reset
1717

18-
;Post an image to mqtt (True or default)
18+
;Post an image to mqtt (True is default)
1919
;With False the snapshot url is posted
2020
PostImagesToMQTT=False
2121

0 commit comments

Comments
 (0)