diff --git a/README.md b/README.md index 6d88ba4..f91b5ee 100644 --- a/README.md +++ b/README.md @@ -32,36 +32,36 @@ This project intends to stick with [PEP8](https://www.python.org/dev/peps/pep-00 GET: - [X] Login - [X] Logout -- [ ] Display -> OSD -- [ ] Recording -> Encode (Clear and Fluent Stream) -- [ ] Recording -> Advance (Scheduling) +- [X] Display -> OSD +- [X] Recording -> Encode (Clear and Fluent Stream) +- [X] Recording -> Advance (Scheduling) - [X] Network -> General - [X] Network -> Advanced -- [ ] Network -> DDNS -- [ ] Network -> NTP -- [ ] Network -> E-mail -- [ ] Network -> FTP -- [ ] Network -> Push +- [X] Network -> DDNS +- [X] Network -> NTP +- [X] Network -> E-mail +- [X] Network -> FTP +- [X] Network -> Push - [X] Network -> WIFI -- [ ] Alarm -> Motion +- [X] Alarm -> Motion - [X] System -> General -- [ ] System -> DST -- [ ] System -> Information +- [X] System -> DST +- [X] System -> Information - [ ] System -> Maintenance -- [ ] System -> Performance +- [X] System -> Performance - [ ] System -> Reboot -- [ ] User -> Online User -- [ ] User -> Add User -- [ ] User -> Manage User -- [ ] Device -> HDD/SD Card +- [X] User -> Online User +- [X] User -> Add User +- [X] User -> Manage User +- [X] Device -> HDD/SD Card - [ ] Zoom - [ ] Focus -- [ ] Image (Brightness, Contrass, Saturation, Hue, Sharp, Mirror, Rotate) +- [ ] Image (Brightness, Contrast, Saturation, Hue, Sharp, Mirror, Rotate) - [ ] Advanced Image (Anti-flicker, Exposure, White Balance, DayNight, Backlight, LED light, 3D-NR) -- [ ] Image Data -> "Snap" Frame from Video Stream +- [X] Image Data -> "Snap" Frame from Video Stream SET: -- [ ] Display -> OSD +- [X] Display -> OSD - [ ] Recording -> Encode (Clear and Fluent Stream) - [ ] Recording -> Advance (Scheduling) - [X] Network -> General @@ -73,15 +73,15 @@ SET: - [ ] Network -> Push - [X] Network -> WIFI - [ ] Alarm -> Motion -- [X] System -> General +- [ ] System -> General - [ ] System -> DST - [X] System -> Reboot -- [ ] User -> Online User -- [ ] User -> Add User -- [ ] User -> Manage User -- [ ] Device -> HDD/SD Card +- [X] User -> Online User +- [X] User -> Add User +- [X] User -> Manage User +- [X] Device -> HDD/SD Card (Format) - [x] PTZ - [x] Zoom - [x] Focus -- [ ] Image (Brightness, Contrass, Saturation, Hue, Sharp, Mirror, Rotate) +- [ ] Image (Brightness, Contrast, Saturation, Hue, Sharp, Mirror, Rotate) - [ ] Advanced Image (Anti-flicker, Exposure, White Balance, DayNight, Backlight, LED light, 3D-NR) diff --git a/api/APIHandler.py b/api/APIHandler.py index 7fa04b7..a62846a 100644 --- a/api/APIHandler.py +++ b/api/APIHandler.py @@ -6,6 +6,7 @@ from .network import NetworkAPIMixin from .system import SystemAPIMixin from .user import UserAPIMixin from .ptz import PtzAPIMixin +from .alarm import AlarmAPIMixin from resthandle import Request @@ -16,7 +17,8 @@ class APIHandler(SystemAPIMixin, DisplayAPIMixin, RecordingAPIMixin, ZoomAPIMixin, - PtzAPIMixin): + PtzAPIMixin, + AlarmAPIMixin): """ The APIHandler class is the backend part of the API, the actual API calls are implemented in Mixins. diff --git a/api/__init__.py b/api/__init__.py index a7db0e9..06bd9be 100644 --- a/api/__init__.py +++ b/api/__init__.py @@ -1,4 +1,4 @@ from .APIHandler import APIHandler -__version__ = "0.0.1" +__version__ = "0.0.2" VERSION = __version__ diff --git a/api/alarm.py b/api/alarm.py new file mode 100644 index 0000000..2f48efb --- /dev/null +++ b/api/alarm.py @@ -0,0 +1,11 @@ +class AlarmAPIMixin: + """API calls for getting device alarm information.""" + + def get_alarm_motion(self) -> object: + """ + Gets the device alarm motion + See examples/response/GetAlarmMotion.json for example response data. + :return: response json + """ + body = [{"cmd": "GetAlarm", "action": 1, "param": {"Alarm": {"channel": 0, "type": "md"}}}] + return self._execute_command('GetAlarm', body) diff --git a/api/network.py b/api/network.py index 8e1ecc5..39af7b8 100644 --- a/api/network.py +++ b/api/network.py @@ -36,6 +36,7 @@ class NetworkAPIMixin: def get_net_ports(self) -> object: """ Get network ports + See examples/response/GetNetworkAdvanced.json for example response data. :return: response json """ body = [{"cmd": "GetNetPort", "action": 1, "param": {}}, @@ -50,3 +51,65 @@ class NetworkAPIMixin: def scan_wifi(self): body = [{"cmd": "ScanWifi", "action": 1, "param": {}}] return self._execute_command('ScanWifi', body) + + def get_network_general(self) -> object: + """ + Get the camera information + See examples/response/GetNetworkGeneral.json for example response data. + :return: response json + """ + body = [{"cmd": "GetLocalLink", "action": 0, "param": {}}] + return self._execute_command('GetLocalLink', body) + + def get_network_ddns(self) -> object: + """ + Get the camera DDNS network information + See examples/response/GetNetworkDDNS.json for example response data. + :return: response json + """ + body = [{"cmd": "GetDdns", "action": 0, "param": {}}] + return self._execute_command('GetDdns', body) + + def get_network_ntp(self) -> object: + """ + Get the camera NTP network information + See examples/response/GetNetworkNTP.json for example response data. + :return: response json + """ + body = [{"cmd": "GetNtp", "action": 0, "param": {}}] + return self._execute_command('GetNtp', body) + + def get_network_email(self) -> object: + """ + Get the camera email network information + See examples/response/GetNetworkEmail.json for example response data. + :return: response json + """ + body = [{"cmd": "GetEmail", "action": 0, "param": {}}] + return self._execute_command('GetEmail', body) + + def get_network_ftp(self) -> object: + """ + Get the camera FTP network information + See examples/response/GetNetworkFtp.json for example response data. + :return: response json + """ + body = [{"cmd": "GetFtp", "action": 0, "param": {}}] + return self._execute_command('GetFtp', body) + + def get_network_push(self) -> object: + """ + Get the camera push network information + See examples/response/GetNetworkPush.json for example response data. + :return: response json + """ + body = [{"cmd": "GetPush", "action": 0, "param": {}}] + return self._execute_command('GetPush', body) + + def get_network_status(self) -> object: + """ + Get the camera status network information + See examples/response/GetNetworkGeneral.json for example response data. + :return: response json + """ + return self.get_network_general() diff --git a/api/recording.py b/api/recording.py index c204708..ff8f5e7 100644 --- a/api/recording.py +++ b/api/recording.py @@ -1,12 +1,10 @@ -import io +import requests import random import string -from urllib import request - +from urllib import parse +from io import BytesIO from PIL import Image - from RtspClient import RtspClient -from resthandle import Request class RecordingAPIMixin: @@ -43,25 +41,26 @@ class RecordingAPIMixin: proxies={"host": "127.0.0.1", "port": 8000}) as rtsp_client: rtsp_client.preview() - def get_snap(self, timeout: int = 3) -> Image or None: + def get_snap(self, timeout: int = 3, proxies=None) -> Image or None: """ Gets a "snap" of the current camera video data and returns a Pillow Image or None :param timeout: Request timeout to camera in seconds + :param proxies: http/https proxies to pass to the request object. :return: Image or None """ - randomstr = ''.join(random.choices(string.ascii_uppercase + string.digits, k=10)) - snap = self.url + "?cmd=Snap&channel=0&rs=" \ - + randomstr \ - + "&user=" + self.username \ - + "&password=" + self.password + data = {} + data['cmd'] = 'Snap' + data['channel'] = 0 + data['rs'] = ''.join(random.choices(string.ascii_uppercase + string.digits, k=10)) + data['user'] = self.username + data['password'] = self.password + parms = parse.urlencode(data).encode("utf-8") + try: - req = request.Request(snap) - req.set_proxy(Request.proxies, 'http') - reader = request.urlopen(req, timeout) - if reader.status == 200: - b = bytearray(reader.read()) - return Image.open(io.BytesIO(b)) - print("Could not retrieve data from camera successfully. Status:", reader.status) + response = requests.get(self.url, proxies=proxies, params=parms, timeout=timeout) + if response.status_code == 200: + return Image.open(BytesIO(response.content)) + print("Could not retrieve data from camera successfully. Status:", response.stats_code) return None except Exception as e: diff --git a/api/system.py b/api/system.py index 244b849..0eadc6a 100644 --- a/api/system.py +++ b/api/system.py @@ -30,3 +30,12 @@ class SystemAPIMixin: """ body = [{"cmd": "Reboot", "action": 0, "param": {}}] return self._execute_command('Reboot', body) + + def get_dst(self) -> object: + """ + Get the camera DST information + See examples/response/GetDSTInfo.json for example response data. + :return: response json + """ + body = [{"cmd": "GetTime", "action": 0, "param": {}}] + return self._execute_command('GetTime', body) \ No newline at end of file diff --git a/examples/response/GetAlarmMotion.json b/examples/response/GetAlarmMotion.json new file mode 100644 index 0000000..56be0cc --- /dev/null +++ b/examples/response/GetAlarmMotion.json @@ -0,0 +1,150 @@ +[ + { + "cmd": "GetAlarm", + "code": 0, + "initial": { + "Alarm": { + "action": { "mail": 1, "push": 1, "recChannel": [0] }, + "channel": 0, + "enable": 1, + "schedule": { + "table": "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" + }, + "scope": { + "cols": 80, + "rows": 45, + "table": "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" + }, + "sens": [ + { + "beginHour": 0, + "beginMin": 0, + "endHour": 6, + "endMin": 0, + "sensitivity": 10 + }, + { + "beginHour": 6, + "beginMin": 0, + "endHour": 12, + "endMin": 0, + "sensitivity": 10 + }, + { + "beginHour": 12, + "beginMin": 0, + "endHour": 18, + "endMin": 0, + "sensitivity": 10 + }, + { + "beginHour": 18, + "beginMin": 0, + "endHour": 23, + "endMin": 59, + "sensitivity": 10 + } + ], + "type": "md" + } + }, + "range": { + "Alarm": { + "action": { "mail": "boolean", "push": "boolean", "recChannel": [0] }, + "channel": 0, + "enable": "boolean", + "schedule": { "table": { "maxLen": 168, "minLen": 168 } }, + "scope": { + "cols": { "max": 80, "min": 80 }, + "rows": { "max": 45, "min": 45 }, + "table": { "maxLen": 8159 } + }, + "sens": [ + { + "beginHour": { "max": 23, "min": 0 }, + "beginMin": { "max": 59, "min": 0 }, + "endHour": { "max": 23, "min": 0 }, + "endMin": { "max": 59, "min": 0 }, + "id": 0, + "sensitivity": { "max": 50, "min": 1 } + }, + { + "beginHour": { "max": 23, "min": 0 }, + "beginMin": { "max": 59, "min": 0 }, + "endHour": { "max": 23, "min": 0 }, + "endMin": { "max": 59, "min": 0 }, + "id": 1, + "sensitivity": { "max": 50, "min": 1 } + }, + { + "beginHour": { "max": 23, "min": 0 }, + "beginMin": { "max": 59, "min": 0 }, + "endHour": { "max": 23, "min": 0 }, + "endMin": { "max": 59, "min": 0 }, + "id": 2, + "sensitivity": { "max": 50, "min": 1 } + }, + { + "beginHour": { "max": 23, "min": 0 }, + "beginMin": { "max": 59, "min": 0 }, + "endHour": { "max": 23, "min": 0 }, + "endMin": { "max": 59, "min": 0 }, + "id": 3, + "sensitivity": { "max": 50, "min": 1 } + } + ], + "type": "md" + } + }, + "value": { + "Alarm": { + "action": { "mail": 1, "push": 1, "recChannel": [0] }, + "channel": 0, + "enable": 1, + "schedule": { + "table": "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" + }, + "scope": { + "cols": 80, + "rows": 45, + "table": "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" + }, + "sens": [ + { + "beginHour": 0, + "beginMin": 0, + "endHour": 6, + "endMin": 0, + "id": 0, + "sensitivity": 10 + }, + { + "beginHour": 6, + "beginMin": 0, + "endHour": 12, + "endMin": 0, + "id": 1, + "sensitivity": 10 + }, + { + "beginHour": 12, + "beginMin": 0, + "endHour": 18, + "endMin": 0, + "id": 2, + "sensitivity": 10 + }, + { + "beginHour": 18, + "beginMin": 0, + "endHour": 23, + "endMin": 59, + "id": 3, + "sensitivity": 10 + } + ], + "type": "md" + } + } + } +] diff --git a/examples/response/GetDSTInfo.json b/examples/response/GetDSTInfo.json new file mode 100644 index 0000000..5895d9e --- /dev/null +++ b/examples/response/GetDSTInfo.json @@ -0,0 +1,35 @@ +[ + { + "cmd": "GetTime", + "code": 0, + "value": { + "Dst": { + "enable": 1, + "endHour": 2, + "endMin": 0, + "endMon": 11, + "endSec": 0, + "endWeek": 1, + "endWeekday": 0, + "offset": 1, + "startHour": 2, + "startMin": 0, + "startMon": 3, + "startSec": 0, + "startWeek": 1, + "startWeekday": 0 + }, + "Time": { + "day": 27, + "hour": 18, + "hourFmt": 0, + "min": 50, + "mon": 10, + "sec": 46, + "timeFmt": "MM/DD/YYYY", + "timeZone": 21600, + "year": 2020 + } + } + } +] diff --git a/examples/response/GetNetworkAdvanced.json b/examples/response/GetNetworkAdvanced.json new file mode 100644 index 0000000..25c729e --- /dev/null +++ b/examples/response/GetNetworkAdvanced.json @@ -0,0 +1,42 @@ +[ + { + "cmd": "GetNetPort", + "code": 0, + "initial": { + "NetPort": { + "httpPort": 80, + "httpsPort": 443, + "mediaPort": 9000, + "onvifPort": 8000, + "rtmpPort": 1935, + "rtspPort": 554 + } + }, + "range": { + "NetPort": { + "httpPort": { "max": 65535, "min": 1 }, + "httpsPort": { "max": 65535, "min": 1 }, + "mediaPort": { "max": 65535, "min": 1 }, + "onvifPort": { "max": 65535, "min": 1 }, + "rtmpPort": { "max": 65535, "min": 1 }, + "rtspPort": { "max": 65535, "min": 1 } + } + }, + "value": { + "NetPort": { + "httpPort": 80, + "httpsPort": 443, + "mediaPort": 9000, + "onvifPort": 8000, + "rtmpPort": 1935, + "rtspPort": 554 + } + } + }, + { "cmd": "GetUpnp", "code": 0, "value": { "Upnp": { "enable": 0 } } }, + { + "cmd": "GetP2p", + "code": 0, + "value": { "P2p": { "enable": 0, "uid": "99999999999999" } } + } +] diff --git a/examples/response/GetNetworkDDNS.json b/examples/response/GetNetworkDDNS.json new file mode 100644 index 0000000..a79127a --- /dev/null +++ b/examples/response/GetNetworkDDNS.json @@ -0,0 +1,15 @@ +[ + { + "cmd": "GetDdns", + "code": 0, + "value": { + "Ddns": { + "domain": "", + "enable": 0, + "password": "", + "type": "no-ip", + "userName": "" + } + } + } +] diff --git a/examples/response/GetNetworkEmail.json b/examples/response/GetNetworkEmail.json new file mode 100644 index 0000000..9595a2a --- /dev/null +++ b/examples/response/GetNetworkEmail.json @@ -0,0 +1,25 @@ +[ + { + "cmd": "GetEmail", + "code": 0, + "value": { + "Email": { + "addr1": "", + "addr2": "", + "addr3": "", + "attachment": "picture", + "interval": "5 Minutes", + "nickName": "", + "password": "", + "schedule": { + "enable": 1, + "table": "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" + }, + "smtpPort": 465, + "smtpServer": "smtp.gmail.com", + "ssl": 1, + "userName": "" + } + } + } +] diff --git a/examples/response/GetNetworkFtp.json b/examples/response/GetNetworkFtp.json new file mode 100644 index 0000000..8ba4622 --- /dev/null +++ b/examples/response/GetNetworkFtp.json @@ -0,0 +1,24 @@ +[ + { + "cmd": "GetFtp", + "code": 0, + "value": { + "Ftp": { + "anonymous": 0, + "interval": 30, + "maxSize": 100, + "mode": 0, + "password": "", + "port": 21, + "remoteDir": "", + "schedule": { + "enable": 1, + "table": "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" + }, + "server": "", + "streamType": 0, + "userName": "" + } + } + } +] diff --git a/examples/response/GetNetworkGeneral.json b/examples/response/GetNetworkGeneral.json new file mode 100644 index 0000000..958bbdd --- /dev/null +++ b/examples/response/GetNetworkGeneral.json @@ -0,0 +1,19 @@ +[ + { + "cmd": "GetLocalLink", + "code": 0, + "value": { + "LocalLink": { + "activeLink": "LAN", + "dns": { "auto": 1, "dns1": "192.168.255.4", "dns2": "192.168.255.4" }, + "mac": "EC:71:DB:AA:59:CF", + "static": { + "gateway": "192.168.255.1", + "ip": "192.168.255.58", + "mask": "255.255.255.0" + }, + "type": "DHCP" + } + } + } +] diff --git a/examples/response/GetNetworkNTP.json b/examples/response/GetNetworkNTP.json new file mode 100644 index 0000000..7293fed --- /dev/null +++ b/examples/response/GetNetworkNTP.json @@ -0,0 +1,14 @@ +[ + { + "cmd": "GetNtp", + "code": 0, + "value": { + "Ntp": { + "enable": 1, + "interval": 1440, + "port": 123, + "server": "ntp.moos.xyz" + } + } + } +] diff --git a/examples/response/GetNetworkPush.json b/examples/response/GetNetworkPush.json new file mode 100644 index 0000000..399207f --- /dev/null +++ b/examples/response/GetNetworkPush.json @@ -0,0 +1,14 @@ +[ + { + "cmd": "GetPush", + "code": 0, + "value": { + "Push": { + "schedule": { + "enable": 1, + "table": "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" + } + } + } + } +] diff --git a/setup.py b/setup.py index 614ea1c..70c8068 100644 --- a/setup.py +++ b/setup.py @@ -65,6 +65,7 @@ setup(name=NAME, 'api.recording', 'api.system', 'api.user', - 'api.zoom' + 'api.zoom', + 'api.alarm' ] )