forked from spfuu/2N-Intercom
-
Notifications
You must be signed in to change notification settings - Fork 0
/
commands.py
1292 lines (1078 loc) · 48.6 KB
/
commands.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
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
import json
import logging
import os
import requests
from urllib.parse import urljoin
from requests.auth import HTTPBasicAuth, HTTPDigestAuth
ns = {
'event2n': 'http://www.2n.cz/2013/event',
'wsnt': 'http://docs.oasis-open.org/wsn/b-2'
}
log = logging.getLogger(__name__)
class CommandService(object):
def __init__(self, ip_cam):
self.ip_cam = ip_cam
self.auth = None
if self.ip_cam.auth_type == 1:
self.auth = HTTPBasicAuth(self.ip_cam.user, self.ip_cam.password)
if self.ip_cam.auth_type == 2:
self.auth = HTTPDigestAuth(self.ip_cam.user, self.ip_cam.password)
schema = 'http'
if self.ip_cam.ssl:
schema = 'https'
self.base_url = "{schema}://{ip}".format(schema=schema, ip=self.ip_cam.ip_address)
def system_info(self):
"""
The /api/system/info function provides basic information on the device: type, serial
number, firmware version, etc. The function is available in all device types regardless
of the set access rights.
:return: The reply is in the application/json format.
Example:
GET /api/system/info
{
"success" : true,
"result" : {
"variant" : "2N Helios IP Vario",
"serialNumber" : "08-1860-0035",
"hwVersion" : "535v1",
"swVersion" : "2.10.0.19.2",
"buildType" : "beta",
"deviceName" : "2N Helios IP Vario"
}
}
variant: Model name (version)
SerialNumber: Serial number
hwVersion: Hardware version
swVersion: Firmware version
buildType: Firmware build type (alpha, beta, or empty value for official versions)
deviceName: Device name set in the configuration interface on the Services / Web Server tab
"""
response = requests.get(urljoin(self.base_url, "/api/system/info"), auth=self.auth, verify=False)
response.raise_for_status()
return response.text
def system_status(self):
"""
The /api/system/status function returns the current intercom status.
The function is part of the System service and the user must be assigned the System
Control privilege for authentication if required. The function is available with the
Enhanced Integration licence key only.
:return: The reply is in the application/json format and includes the current device status.
Example:
GET /api/system/status
{
"success" : true,
"result" : {
"systemTime" : 1418225091,
"upTime" : 190524
}
}
systemTime: Device real time in seconds since 00:00 1.1.1970 (unix time)
upTime: Device operation time since the last restart in seconds
"""
response = requests.get(urljoin(self.base_url, "/api/system/status"), auth=self.auth, verify=False)
response.raise_for_status()
return response.text
def system_restart(self):
"""
The /api/system/restart restarts the intercom.
The function is part of the System service and the user must be assigned the System
Control privilege for authentication if required. The function is available with the
Enhanced Integration licence key only .
:return: The reply is in the application/json format and includes no parameters.
Example:
GET /api/system/restart
{
"success" : true
}
"""
response = requests.get(urljoin(self.base_url, "/api/system/restart"), auth=self.auth, verify=False)
response.raise_for_status()
return response.text
def firmware_upload(self, filename):
"""
The /api/firmware function helps you upload a new firmware version to the device.
When the upload is complete, use /api/firmware/apply to confirm restart and FW change.
The function is part of the System service and the user must be assigned the System
Control privilege for authentication if required . The function is available with the
Enhanced Integration licence key only.
:type filename: firmware file to upload
:return: The reply is in the application/json format.
Example:
PUT /api/firmware
{
"success" : true,
"result" : {
"version" : "2.10.0.19.2",
"downgrade" : false
}
}
version: Firmware version to be uploaded
downgrade: Flag set if the FW to be uploaded is older than the current one
If the FW file to be uploaded is corrupted or not intended for your device, the intercom
returns error code 12 – invalid parameter value.
"""
response = requests.put(urljoin(self.base_url, "/api/firmware"), auth=self.auth, verify=False,
files={'blob-fw': (
os.path.basename(filename), open(filename, 'rb'), 'application/octet-stream')})
response.raise_for_status()
return response.text
def firmware_apply(self):
"""
The /api/firmware/apply function is used for earlier firmware upload ( PUT
/api/firmware ) confirmation and subsequent device restart.
The function is part of the System service and the user must be assigned the System
Control privilege for authentication if required. The function is available with the
Enhanced Integration licence key only.
:return: The reply is in the application/json format and includes no parameters.
Example:
GET /api/firmware/apply
{
"success" : true
}
"""
response = requests.get(urljoin(self.base_url, "/api/firmware/apply"), auth=self.auth, verify=False)
response.raise_for_status()
return response.text
def config_get(self, filename=None):
"""
The /api/config function helps you to download the device configuration.
The function is part of the System service and the user must be assigned the System
Control privilege for authentication if required . The function is available with the
Enhanced Integration licence key only.
:type filename: path to a file where the config is stored.
text
:return: The reply is in the application/json format and includes no parameters.
Example:
GET /api/firmware/apply
{
"success" : true
}
"""
if filename is not None:
save_dir = os.path.dirname(filename)
if not os.access(save_dir, os.W_OK):
raise IOError("No write permissions to {dir}.".format(dir=save_dir))
response = requests.get(urljoin(self.base_url, "/api/config"), auth=self.auth, verify=False, stream=True)
response.raise_for_status()
if response.headers['Content-Type'] == 'application/json':
return response.text
with open(filename, 'wb') as f:
for chunk in response.iter_content(chunk_size=1024):
if chunk: # filter out keep-alive new chunks
f.write(chunk)
return json.dumps({'success': True})
raise ValueError("Parameter filename cannot be empty or None")
def config_upload(self, filename):
"""
The /api/config function helps you to upload the device configuration.
The function is part of the System service and the user must be assigned the System
Control privilege for authentication if required . The function is available with the
Enhanced Integration licence key only.
:type filename: config file to upload (xml)
:return: The reply is in the application/json format and includes no other parameters.
Example:
PUT /api/config
{
"success" : true
}
"""
response = requests.put(urljoin(self.base_url, "/api/config"), auth=self.auth, verify=False,
files={'blob-cfg': (
os.path.basename(filename), open(filename, 'rb'), 'application/octet-stream')})
response.raise_for_status()
return response.text
def factory_reset(self):
"""
The /api/config/factoryreset function resets the factory default values for all the
intercom parameters. This function is equivalent to the function of the same name in
the System / Maintenance / Default setting section of the configuration web interface .
The function is part of the System service and the user must be assigned the System
Control privilege for authentication if required. The function is available with the
Enhanced Integration licence key only.
:return: The reply is in the application/json format and includes no parameters.
Example:
GET /api/config/factoryreset
{
"success" : true
}
"""
response = requests.get(urljoin(self.base_url, "/api/config/factoryreset"), auth=self.auth, verify=False)
response.raise_for_status()
return response.text
def switch_caps(self):
"""
The /api/switch/caps function returns the current switch settings and control
options. Define the switch in the optional switch parameter. If the switch parameter
is not included, settings of all the switches are returned.
The function is part of the Switch service and the user must be assigned the Switch
Monitoring privilege for authentication if required . The function is available with the Enhanced Integration
licence key only.
:return: The reply is in the application/json format and includes a switch list ( switches )
including current settings. If the switch parameter is used, the switches field includes
just one item.
Example:
GET /api/switch/caps
{
"success" : true,
"result" : {
"switches" : [
{
"switch" : 1,
"enabled" : true,
"mode" : "monostable",
"switchOnDuration" : 5,
"type" : "normal"
},
{
"switch" : 2,
"enabled" : true,
"mode" : "monostable",
"switchOnDuration" : 5,
"type" : "normal"
},
{
"switch" : 3,
"enabled" : false
},
{
"switch" : 4,
"enabled" : false
}]
}
}
switch: Switch Id (1 to 4)
enabled: Switch control enabled in the configuration web interface
mode: Selected switch mode ( monostable , bistable )
switchOnDuration: Switch activation time in seconds (for monostable mode only)
type: Switch type ( normal , security )
"""
response = requests.get(urljoin(self.base_url, "/api/switch/caps"), auth=self.auth, verify=False)
response.raise_for_status()
return response.text
def switch_status(self, switch=None):
"""
The /api/switch/status function returns the current switch statuses.
The function is part of the Switch service and the user must be assigned the Switch
Monitoring privilege for authentication if required. The function is available with the
Enhanced Integration licence key only.
:type switch: Optional switch parameter. If the switch parameter is not included,
states of all the switches are returned.
:return: The reply is in the application/json format and includes a switch list (switches)
including current statuses ( active) . If the switch parameter is used, the switches field
includes just one item.
Example:
POST /api/switch/status
{
"success" : true,
"result" : {
"switches" : [
{
"switch" : 1,
"active" : false
},
{
"switch" : 2,
"active" : false
},
{
"switch" : 3,
"active" : false
},
{
"switch" : 4,
"active" : false
}]
}
}
"""
data = None
if switch is not None and switch > 0:
data = {'switch': switch}
response = requests.post(urljoin(self.base_url, "/api/switch/status"), auth=self.auth, verify=False, data=data)
response.raise_for_status()
return response.text
def switch_control(self, switch, action, response=None):
"""
The /api/switch/ctrl function controls the switch statuses. The function has two
mandatory parameters: switch , which determines the switch to be controlled, and
action , defining the action to be executed over the switch (activation, deactivation,
state change).
The function is part of the Switch service and the user must be assigned the Switch
Control privilege for authentication if required . The function is available with the
Enhanced Integration licence key only.
:param switch: Mandatory switch identifier (typically, 1 to 4). Use also/api/switch/caps
to know the exact count of switches .
:param action: Mandatory action defining parameter ( on – activate switch, off – deactivate switch,
trigger – change switch state).
:param response: Optional parameter modifying the intercom response to include the text
defined here instead of the JSON message.
:return: The reply is in the application/json format and includes no parameters.
Example:
POST /api/switch/ctrl
{
"success" : true
}
"""
if response:
data = {
'switch': switch,
'action': action,
'response': response
}
else:
data = {
'switch': switch,
'action': action
}
response = requests.post(urljoin(self.base_url, "/api/switch/ctrl"), auth=self.auth, verify=False, data=data)
response.raise_for_status()
return response.text
def io_caps(self, port=None):
"""
The /api/io/caps function returns a list of available hardware inputs and outputs
(ports) of the device. Define the input/output in the optional port parameter. If the
port parameter is not included, settings of all the inputs and outputs are returned .
The function is part of the I/O service and the user must be assigned the I/O
Monitoring privilege for authentication if required . The function is available with the
Enhanced Integration licence key only.
:param port: Optional input/output identifier
:return: The reply is in the application/json format and includes a port list (ports) including
current settings. If the port parameter is used, the ports field includes just one item.
Example:
POST /api/io/caps
{
"success" : true,
"result" : {
"ports" : [
{
"port" : "relay1",
"type" : "output"
},
{
"port" : "relay2",
"type" : "output"
}]
}
}
port: Input/output identifier
type: Type ( input – for digital inputs, output – for digital outputs)
"""
data = None
if port:
data = {
'port': port
}
response = requests.post(urljoin(self.base_url, "/api/io/caps"), auth=self.auth, verify=False, data=data)
response.raise_for_status()
return response.text
def io_status(self, port=None):
"""
The /api/io/status function returns the current statuses of logic inputs and outputs
(ports) of the device. Define the input/output in the optional port parameter. If the
port parameter is not included, statuses of all the inputs and outputs are returned.
The function is part of the I/O service and the user must be assigned the I/O
Monitoring privilege for authentication if required . The function is available with the
:param port: Optional input/output identifier. Use also /api/io/caps to get
identifiers of the available inputs and outputs.
:return: The reply is in the application/json format and includes a port list (ports) including
current settings ( state ). If the port parameter is used, the ports field includes just
one item.
Example:
POST /api/io/status
{
"success" : true,
"result" : {
"ports" : [
{
"port" : "relay1",
"state" : 0
},
{
"port" : "relay2",
"state" : 0
}]
}
}
"""
data = None
if port:
data = {
'port': port
}
response = requests.post(urljoin(self.base_url, "/api/io/status"), auth=self.auth, verify=False, data=data)
response.raise_for_status()
return response.text
def io_control(self, port, action, response=None):
"""
The /api/io/ctrl function controls the statuses of the device logic outputs. The
function has two mandatory parameters: port, which determines the output to be
controlled, and action, defining the action to be executed over the output (activation,
deactivation).
The function is part of the I/O service and the user must be assigned the I/O
Control privilege for authentication if required . The function is available with the
Enhanced Integration licence key only.
:param port: Mandatory I/O identifier. Use also /api/io/caps to get the identifiers of
the available inputs and outputs.
:param action: Mandatory action defining parameter (on – activate output, log. 1, off –
deactivate output, log. 0)
:param response: Optional parameter modifying the intercom response to include the text
defined here instead of the JSON message.
:return: The reply is in the application/json format and includes no parameters.
Example:
POST /api/io/ctrl
{
"success" : true
}
"""
if response:
data = {
'port': port,
'action': action,
'response': response
}
else:
data = {
'port': port,
'action': action
}
response = requests.post(urljoin(self.base_url, "/api/io/ctrl"), auth=self.auth, verify=False, data=data)
response.raise_for_status()
return response.text
def phone_status(self, account=None):
"""
The /api/phone/status functions helps you get the current statuses of the device
SIP accounts.
The function is part of the Phone/Call service and the user must be assigned the
Phone/Call Monitoring privilege for authentication if required . The function is
available with the Enhanced Integration licence key only.
:param account: Optional SIP account identifier (1 or 2). If the parameter is not included,
the function returns statuses of all the SIP accounts.
:return: The reply is in the application/json format and includes a list of device SIP accounts
( accounts ) including current statuses. I f the account parameter is used, the
accounts field includes just one item .
Example:
POST /api/phone/status
{
"success" : true,
"result" : {
"accounts" : [
{
"account" : 1,
"sipNumber" : "5046",
"registered" : true,
"registerTime" : 1418034578
},
{
"account" : 2,
"sipNumber" : "",
"registered" : false
}]
}
}
account: Unique SIP account identifier (1 or 2)
sipNumber: SIP account telephone number
registered: Account registration with the SIP Registrar
registerTime: Last successful registration time in seconds since 00:00 1.1.1970 (unix time)
"""
data = None
if account:
data = {
'account': account
}
response = requests.post(urljoin(self.base_url, "/api/phone/status"), auth=self.auth, verify=False, data=data)
response.raise_for_status()
return response.text
def call_status(self, session=None):
"""
The /api/call/status function helps you get the current states of active telephone
calls. The function returns a list of active calls including parameters.
The function is part of the Phone/Call service and the user must be assigned the
Phone/Call Monitoring privilege for authentication if required . The function is
available with the Enhanced Integration licence key only.
:param session: Optional call identifier. If the parameter is not included, the function
returns statuses of all the active calls.
:return: The reply is in the application/json format and includes a list of active calls (
sessions) including their current states. If the session parameter is used, the
sessions field includes just one item. If there is no active call, the sessions field is
empty.
Example:
POST /api/call/status
{
"success" : true,
"result" : {
"sessions" : [
{
"session" : 1,
"direction" : "outgoing",
"state" : "ringing"
}]
}
session: Call identifier
direction: Call direction ( incoming , outgoing )
state: Call state ( connecting , ringing , connected )
"""
data = None
if session:
data = {
'session': session
}
response = requests.post(urljoin(self.base_url, "/api/call/status"), auth=self.auth, verify=False, data=data)
response.raise_for_status()
return response.text
def call_dial(self, number):
"""
The /api/call/dial function initiates a new outgoing call to a selected phone number
or sip uri. After some test with a Fritzbox, it seems you have to call '**your_number/1'
to call internal phones. '/2' seems to be necessary if you want to call number over sip account 2.
The function is part of the Phone/Call service and the user must be assigned the
Phone/Call Control privilege for authentication if required . The function is available
with the Enhanced Integration licence key only.
:param number: Mandatory parameter specifying the destination phone number or sip uri
:return: The reply is in the application/json format and includes information on the outgoing
call created.
Example:
GET /api/call/dial
{
"success" : true,
"result" : {
"session" : 2
}
}
session: Call identifier, used, for example, for call monitoring with
/api/call/status or call termination with /api/call/hangup
"""
data = {
'number': number
}
response = requests.post(urljoin(self.base_url, "/api/call/dial"), auth=self.auth, verify=False, data=data)
response.raise_for_status()
return response.text
def call_answer(self, session):
"""
The /api/call/answer function helps you answer an active incoming call (in the
ringing state).
The function is part of the Phone/Call service and the user must be assigned the
Phone/Call Control privilege for authentication if required . The function is available
with the Enhanced Integration licence key only.
:param session: Active incoming call identifier
:return: The reply is in the application/json format and includes no parameters.
Example:
POST /api/call/answer
{
"success" : true
}
"""
data = {
'session': session
}
response = requests.post(urljoin(self.base_url, "/api/call/answer"), auth=self.auth, verify=False, data=data)
response.raise_for_status()
return response.text
def call_hangup(self, session, reason=None):
"""
The /api/call/hangup helps you hang up an active incoming or outgoing call.
The function is part of the Phone/Call service and the user must be assigned the
Phone/Call Control privilege for authentication if required . The function is available
with the Enhanced Integration licence key only.
:param session: Active call identifier
:param reason: End call reason:
normal - normal call end (default value) reason
rejected - call rejection signalling
busy - station busy signalling
:return: The reply is in the application/json format and includes no parameters.
Example:
POST /api/call/hangup
{
"success" : true
}
"""
if reason:
data = {
'session': session,
'reason': reason
}
else:
data = {
'session': session
}
response = requests.post(urljoin(self.base_url, "/api/call/hangup"), auth=self.auth, verify=False, data=data)
response.raise_for_status()
return response.text
def camera_caps(self):
"""
The /api/camera/caps function returns a list of available video sources and
resolution options for JPEG snapshots to be downloaded via the
/api/camera/snapshot function.
The function is part of the Camera service and the user must be assigned the Camera
Monitoring privilege for authentication if required.
:return: The reply is in the application/json format and includes a list of supported
resolutions of JPEG snapshots ( jpegResolution ) and a list of available video sources (
sources ), which can be used in the /api/camera/snapshot parameters.
Example:
POST /api/camera/caps
{
"success" : true,
"result" : {
"jpegResolution" : [
{
"width" : 160,
"height" : 120
},
{
"width" : 176,
"height" : 144
},
{
"width" : 320,
"height" : 240
},
{
"width" : 352,
"height" : 272
},
{
"width" : 352,
"height" : 288
},
{
"width" : 640,
"height" : 480
}],
"sources" : [
{
"source" : "internal"
},
{
"source" : "external"
}]
}
}
width, height: Snapshot resolution in pixels
source: Video source identifier
"""
response = requests.post(urljoin(self.base_url, "/api/camera/caps"), auth=self.auth, verify=False)
response.raise_for_status()
return response.text
def camera_snapshot(self, width, height, filename, source=None, time=None):
"""
The /api/camera/snapshot function helps you download images from an internal or
external IP camera connected to the intercom. Specify the video source, resolution and
other parameters.
The function is part of the Camera service and the user must be assigned the Camera
Monitoring privilege for authentication if required.
:type time: Optional parameter defining the snapshot time in the intercom memory where time <= 0 … count of
seconds to the past, time > 0 … count of seconds from 1.1.1970 (Unix Time). The time values must be within the
intercom memory range: <-30, 0> seconds.
:type filename: File path where the snapshot is stored to.
:param width: Mandatory parameter specifying the horizontal resolution of the JPEG image in pixels
:param height: Mandatory parameter specifying the vertical resolution of the JPEG image in pixels.
The snapshot height and width must comply with one of the supported options (see api/camera/caps ).
:param source: Optional parameter defining the video source ( internal – internal camera,
external – external IP camera). If the parameter is not included, the default video source included in
the Hardware / Camera / Common settings section of the configuration web interface is selected.
:return: The reply is in the application/json format and includes no parameters.
This code differs from the orignal code by 2N. 'fp' parameter is not supported here and the picture is saved to
a file.
Example:
POST /api/camera/snapshot
{
"success": true
}
"""
data = {
'width': width,
'height': height
}
if source:
data['source'] = source
if time:
data['time'] = time
if filename is not None:
save_dir = os.path.dirname(filename)
if not os.access(save_dir, os.W_OK):
raise IOError("No write permissions to {dir}.".format(dir=save_dir))
response = requests.post(urljoin(self.base_url, "/api/camera/snapshot"), auth=self.auth, verify=False,
stream=True, data=data)
response.raise_for_status()
if response.headers['Content-Type'] == 'application/json':
return response.text
with open(filename, 'wb') as f:
for chunk in response.iter_content(chunk_size=1024):
if chunk: # filter out keep-alive new chunks
f.write(chunk)
return json.dumps({'success': True})
def display_caps(self):
"""
The /api/display/caps function returns a list of device displays including their
properties. Use the function for display detection and resolution.
The function is part of the Display service and the user must be assigned the Display
Control privilege for authentication if required . The function is available with the
Enhanced Integration licence key only.
:return: The reply is in the application/json format and includes a list of available displays (displays).
Example:
POST /api/display/caps
{
"success" : true,
"result" : {
"displays" : [
{
"display" : "internal",
"resolution" : {
"width" : 320,
"height" : 240
}
}]
}
}
display: Display identifier
resolution: Display resolution in pixels
"""
response = requests.post(urljoin(self.base_url, "/api/display/caps"), auth=self.auth, verify=False)
response.raise_for_status()
return response.text
def display_upload_image(self, display, gif_filename):
"""
The /api/display/image function helps you upload content to be displayed.
Note: The function is available only if the standard display function is disabled in the Hardware / Display
section of the configuration web interface.
The function is part of the Display service and the user must be assigned the Display
Control privilege for authentication if required . The function is available with the
Enhanced Integration licence key only.
:param display: Mandatory display identifier ( internal )
:param gif_filename: Mandatory parameter file path to a GIF image with display resolution
:return: The reply is in the application/json format and includes no parameters.
Example:
PUT /api/display/image
{
"success" : true
}
"""
data = {
'display': display
}
response = requests.put(urljoin(self.base_url, "/api/display/image"), auth=self.auth, verify=False, data=data,
files={'blob-image': (os.path.basename(gif_filename), open(gif_filename, 'rb'),
'application/octet-stream')})
response.raise_for_status()
return response.text
def display_delete_image(self, display):
"""
The /api/display/image function helps you delete content from the display.
Note: The function is available only if the standard display function is disabled in the Hardware / Display
section of the configuration web interface.
The function is part of the Display service and the user must be assigned the Display
Control privilege for authentication if required . The function is available with the
Enhanced Integration licence key only.
:param display: Mandatory display identifier ( internal )
:return: The reply is in the application/json format and includes no parameters.
Example:
DELETE /api/display/image
{
"success" : true
}
"""
data = {
'display': display
}
response = requests.delete(urljoin(self.base_url, "/api/display/image"), auth=self.auth, verify=False,
data=data)
response.raise_for_status()
return response.text
def log_caps(self):
"""
The /api/log/caps function returns a list of supported event types that are recorded
in the device. This list is a subset of the full event type list below:
The function is part of the Logging service and requires no special user privileges.
:return: The reply is in the application/json format.
Example:
GET /api/log/caps
{
"success" : true,
"result" : {
"events" : [
"KeyPressed",
"KeyReleased",
"InputChanged",
"OutputChanged",
"CardEntered",
"CallStateChanged",
"AudioLoopTest",
"CodeEntered",
"DeviceState",
"RegistrationStateChanged"
]
}
}
events: Array of strings including a list of supported event types
"""
response = requests.post(urljoin(self.base_url, "/api/log/caps"), auth=self.auth, verify=False)
response.raise_for_status()
return response.text
def log_subscribe(self, include=None, filter=None, duration=None):
"""
The /api/log/subscribe function helps you create a subscription channel and returns
a unique identifier to be used for subsequent dialling of the /api/log/pull or
/api/log/unsubscribe function.
Each subscription channel contains an event queue of its own. All the new events that
match the channel filter ( filter parameter) are added to the channel queue and read
using the /api/log/pull function.
At the same time, the device keeps the event history queue (last 500 events) in its
internal memory. The event history queue is empty by default.
Use the include parameter to specify whether the channel queue shall be empty after
restart (storing of events occurring after the channel is opened), or be filled with all or
some events from the event history records.
Use the duration parameter to define the channel duration if it is not accessed via
/api/log/pull . The channel will be closed automatically when the defined timeout
passes as if the /api/log/unsubscribe function were used.
The function is part of the Logging service and requires some user privileges for
authentication. Unprivileged user events shall not be included in the channel queue.
Event type / Required user privileges:
----
DeviceState None
AudioLoopTest None
MotionDetected None