Added some API's and Doc strings

OSD -> set and get
System -> get_performance, get_information
Recording -> get
This commit is contained in:
Alano Terblanche
2019-08-11 15:35:52 +02:00
parent 2722a80922
commit 5bc90f7c60

View File

@@ -13,6 +13,7 @@ class APIHandler:
""" """
The APIHandler class is the backend part of the API. The APIHandler class is the backend part of the API.
This handles communication directly with the camera. This handles communication directly with the camera.
Current camera's tested: RLC-411WS
All Code will try to follow the PEP 8 standard as described here: https://www.python.org/dev/peps/pep-0008/ All Code will try to follow the PEP 8 standard as described here: https://www.python.org/dev/peps/pep-0008/
@@ -30,7 +31,9 @@ class APIHandler:
self.username = username self.username = username
self.password = password self.password = password
###########
# Token # Token
###########
def login(self) -> bool: def login(self) -> bool:
""" """
@@ -100,9 +103,7 @@ class APIHandler:
else: else:
print("Something went wront\nStatus Code:", response.status_code) print("Something went wront\nStatus Code:", response.status_code)
return False return False
return False return False
except Exception as e: except Exception as e:
print("Setting Network Port Error\n", e) print("Setting Network Port Error\n", e)
raise raise
@@ -126,7 +127,7 @@ class APIHandler:
########### ###########
# GET # GET
########### ###########
def get_net_ports(self): def get_net_ports(self) -> json or None:
""" """
Get network ports Get network ports
:return: :return:
@@ -140,7 +141,10 @@ class APIHandler:
{"cmd": "GetP2p", "action": 0, "param": {}}] {"cmd": "GetP2p", "action": 0, "param": {}}]
param = {"token": self.token} param = {"token": self.token}
response = Request.post(self.url, data=body, params=param) response = Request.post(self.url, data=body, params=param)
return json.loads(response.text) if response.status_code == 200:
return json.loads(response.text)
print("Could not get network ports data. Status:", response.status_code)
return None
except Exception as e: except Exception as e:
print("Get Network Ports", e) print("Get Network Ports", e)
@@ -157,7 +161,9 @@ class APIHandler:
body = [{"cmd": "GetLocalLink", "action": 1, "param": {}}] body = [{"cmd": "GetLocalLink", "action": 1, "param": {}}]
param = {"cmd": "GetLocalLink", "token": self.token} param = {"cmd": "GetLocalLink", "token": self.token}
request = Request.post(self.url, data=body, params=param) request = Request.post(self.url, data=body, params=param)
return json.loads(request.text) if request.status_code == 200:
return json.loads(request.text)
print("Could not get ")
except Exception as e: except Exception as e:
print("Could not get Link Local", e) print("Could not get Link Local", e)
raise raise
@@ -186,6 +192,113 @@ class APIHandler:
print("Could not Scan wifi\n", e) print("Could not Scan wifi\n", e)
raise raise
###########
# Display
###########
###########
# GET
###########
def get_osd(self) -> json or None:
"""
Get OSD information.
Response data format is as follows:
[{"cmd" : "GetOsd","code" : 0, "initial" : {
"Osd" : {"bgcolor" : 0,"channel" : 0,"osdChannel" : {"enable" : 1,"name" : "Camera1","pos" : "Lower Right"},
"osdTime" : {"enable" : 1,"pos" : "Top Center"}
}},"range" : {"Osd" : {"bgcolor" : "boolean","channel" : 0,"osdChannel" : {"enable" : "boolean","name" : {"maxLen" : 31},
"pos" : ["Upper Left","Top Center","Upper Right","Lower Left","Bottom Center","Lower Right"]
},
"osdTime" : {"enable" : "boolean","pos" : ["Upper Left","Top Center","Upper Right","Lower Left","Bottom Center","Lower Right"]
}
}},"value" : {"Osd" : {"bgcolor" : 0,"channel" : 0,"osdChannel" : {"enable" : 0,"name" : "FarRight","pos" : "Lower Right"},
"osdTime" : {"enable" : 0,"pos" : "Top Center"}
}}}]
:return: json or None
"""
try:
param = {"cmd": "GetOsd", "token": self.token}
body = [{"cmd": "GetOsd", "action": 1, "param": {"channel": 0}}]
response = Request.post(self.url, data=body, params=param)
if response.status_code == 200:
return json.loads(response.text)
print("Could not retrieve OSD from camera successfully. Status:", response.status_code)
return None
except Exception as e:
print("Could not get OSD", e)
raise
def get_mask(self) -> json or None:
"""
Get the camera mask information
Response data format is as follows:
[{"cmd" : "GetMask","code" : 0,"initial" : {
"Mask" : {
"area" : [{"block" : {"height" : 0,"width" : 0,"x" : 0,"y" : 0},"screen" : {"height" : 0,"width" : 0}}],
"channel" : 0,
"enable" : 0
}
},"range" : {"Mask" : {"channel" : 0,"enable" : "boolean","maxAreas" : 4}},"value" : {
"Mask" : {
"area" : null,
"channel" : 0,
"enable" : 0}
}
}]
:return: json or None
"""
try:
param = {"cmd": "GetMask", "token": self.token}
body = [{"cmd": "GetMask", "action": 1, "param": {"channel": 0}}]
response = Request.post(self.url, data=body, params=param)
if response.status_code == 200:
return json.loads(response.text)
print("Could not get Mask from camera successfully. Status:", response.status_code)
return None
except Exception as e:
print("Could not get mask", e)
raise
###########
# SET
###########
def set_osd(self, bg_color: bool = 0, channel: int = 0, osd_channel_enabled: bool = 0, osd_channel_name: str = "",
osd_channel_pos: str = "Lower Right", osd_time_enabled: bool = 0,
osd_time_pos: str = "Lower Right") -> bool:
"""
Set OSD
:param bg_color: bool
:param channel: int channel id
:param osd_channel_enabled: bool
:param osd_channel_name: string channel name
:param osd_channel_pos: string channel position ["Upper Left","Top Center","Upper Right","Lower Left","Bottom Center","Lower Right"]
:param osd_time_enabled: bool
:param osd_time_pos: string time position ["Upper Left","Top Center","Upper Right","Lower Left","Bottom Center","Lower Right"]
:return:
"""
try:
param = {"cmd": "setOsd", "token": self.token}
body = [{"cmd": "SetOsd", "action": 1, "param":
{"Osd": {"bgcolor": bg_color, "channel": channel,
"osdChannel": {"enable": osd_channel_enabled, "name": osd_channel_name,
"pos": osd_channel_pos},
"osdTime": {"enable": osd_time_enabled, "pos": osd_time_pos}
}
}
}]
response = Request.post(self.url, data=body, params=param)
if response.status_code == 200:
r_data = json.loads(response.text)
if r_data["value"]["rspCode"] == "200":
return True
print("Could not set OSD. Camera responded with status:", r_data["value"])
return False
print("Could not set OSD. Status:", response.status_code)
return False
except Exception as e:
print("Could not set OSD", e)
raise
########### ###########
# SYSTEM # SYSTEM
########### ###########
@@ -208,17 +321,71 @@ class APIHandler:
print("Could not get General System settings\n", e) print("Could not get General System settings\n", e)
raise raise
def get_osd(self) -> json or None: def get_performance(self) -> json or None:
"""
Get a snapshot of the current performance of the camera.
Response data format is as follows:
[{"cmd" : "GetPerformance",
"code" : 0,
"value" : {
"Performance" : {
"codecRate" : 2154,
"cpuUsed" : 14,
"netThroughput" : 0
}
}
}]
:return: json or None
"""
try: try:
param = {"cmd": "GetOsd", "token": self.token} param = {"cmd": "GetPerformance", "token": self.token}
body = [{"cmd": "GetOsd", "action": 1, "param": {"channel": 0}}] body = [{"cmd": "GetPerformance", "action": 0, "param": {}}]
response = Request.post(self.url, data=body, params=param) response = Request.post(self.url, data=body, params=param)
if response.status_code == 200: if response.status_code == 200:
return json.loads(response.text) return json.loads(response.text)
print("Could not retrieve OSD from camera successfully. Status:", response.status_code) print("Cound not retrieve performance information from camera successfully. Status:", response.status_code)
return None return None
except Exception as e: except Exception as e:
print("Could not get OSD", e) print("Could not get performance", e)
raise
def get_information(self) -> json or None:
"""
Get the camera information
Response data format is as follows:
[{"cmd" : "GetDevInfo","code" : 0,"value" : {
"DevInfo" : {
"B485" : 0,
"IOInputNum" : 0,
"IOOutputNum" : 0,
"audioNum" : 0,
"buildDay" : "build 18081408",
"cfgVer" : "v2.0.0.0",
"channelNum" : 1,
"detail" : "IPC_3816M100000000100000",
"diskNum" : 1,
"firmVer" : "v2.0.0.1389_18081408",
"hardVer" : "IPC_3816M",
"model" : "RLC-411WS",
"name" : "Camera1_withpersonality",
"serial" : "00000000000000",
"type" : "IPC",
"wifi" : 1
}
}
}]
:return: json or None
"""
try:
param = {"cmd": "GetDevInfo", "token": self.token}
body = [{"cmd": "GetDevInfo", "action": 0, "param": {}}]
response = Request.post(self.url, data=body, params=param)
if response == 200:
return json.loads(response.text)
print("Could not retrieve camera information. Status:", response.status_code)
return None
except Exception as e:
print("Could not get device information", e)
raise raise
########## ##########
@@ -231,6 +398,17 @@ class APIHandler:
def get_online_user(self) -> json or None: def get_online_user(self) -> json or None:
""" """
Return a list of current logged-in users in json format Return a list of current logged-in users in json format
Response data format is as follows:
[{"cmd" : "GetOnline","code" : 0,"value" : {
"User" : [{
"canbeDisconn" : 0,
"ip" : "192.168.1.100",
"level" : "admin",
"sessionId" : 1000,
"userName" : "admin"
}]
}
}]
:return: json or None :return: json or None
""" """
try: try:
@@ -248,6 +426,29 @@ class APIHandler:
def get_users(self) -> json or None: def get_users(self) -> json or None:
""" """
Return a list of user accounts from the camera in json format Return a list of user accounts from the camera in json format
Response data format is as follows:
[{"cmd" : "GetUser","code" : 0,"initial" : {
"User" : {
"level" : "guest"
}},
"range" : {"User" : {
"level" : [ "guest", "admin" ],
"password" : {
"maxLen" : 31,
"minLen" : 6
},
"userName" : {
"maxLen" : 31,
"minLen" : 1
}}
},"value" : {
"User" : [
{
"level" : "admin",
"userName" : "admin"
}]
}
}]
:return: json or None :return: json or None
""" """
try: try:
@@ -364,7 +565,7 @@ class APIHandler:
def get_hdd_info(self) -> json or None: def get_hdd_info(self) -> json or None:
""" """
Gets all HDD and SD card information from Camera Gets all HDD and SD card information from Camera
Format is as follows: Response data format is as follows:
[{"cmd" : "GetHddInfo", [{"cmd" : "GetHddInfo",
"code" : 0, "code" : 0,
"value" : { "value" : {
@@ -413,3 +614,249 @@ class APIHandler:
except Exception as e: except Exception as e:
print("Could not format HDD/SD", e) print("Could not format HDD/SD", e)
raise raise
###########
# Recording
###########
###########
# SET
###########
###########
# GET
###########
def get_recording_encoding(self) -> json or None:
"""
Get the current camera encoding settings for "Clear" and "Fluent" profiles.
Response data format is as follows:
[{
"cmd" : "GetEnc",
"code" : 0,
"initial" : {
"Enc" : {
"audio" : 0,
"channel" : 0,
"mainStream" : {
"bitRate" : 4096,
"frameRate" : 15,
"profile" : "High",
"size" : "3072*1728"
},
"subStream" : {
"bitRate" : 160,
"frameRate" : 7,
"profile" : "High",
"size" : "640*360"
}
}
},
"range" : {
"Enc" : [
{
"audio" : "boolean",
"mainStream" : {
"bitRate" : [ 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192 ],
"default" : {
"bitRate" : 4096,
"frameRate" : 15
},
"frameRate" : [ 20, 18, 16, 15, 12, 10, 8, 6, 4, 2 ],
"profile" : [ "Base", "Main", "High" ],
"size" : "3072*1728"
},
"subStream" : {
"bitRate" : [ 64, 128, 160, 192, 256, 384, 512 ],
"default" : {
"bitRate" : 160,
"frameRate" : 7
},
"frameRate" : [ 15, 10, 7, 4 ],
"profile" : [ "Base", "Main", "High" ],
"size" : "640*360"
}
},
{
"audio" : "boolean",
"mainStream" : {
"bitRate" : [ 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192 ],
"default" : {
"bitRate" : 4096,
"frameRate" : 15
},
"frameRate" : [ 20, 18, 16, 15, 12, 10, 8, 6, 4, 2 ],
"profile" : [ "Base", "Main", "High" ],
"size" : "2592*1944"
},
"subStream" : {
"bitRate" : [ 64, 128, 160, 192, 256, 384, 512 ],
"default" : {
"bitRate" : 160,
"frameRate" : 7
},
"frameRate" : [ 15, 10, 7, 4 ],
"profile" : [ "Base", "Main", "High" ],
"size" : "640*360"
}
},
{
"audio" : "boolean",
"mainStream" : {
"bitRate" : [ 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192 ],
"default" : {
"bitRate" : 3072,
"frameRate" : 15
},
"frameRate" : [ 30, 22, 20, 18, 16, 15, 12, 10, 8, 6, 4, 2 ],
"profile" : [ "Base", "Main", "High" ],
"size" : "2560*1440"
},
"subStream" : {
"bitRate" : [ 64, 128, 160, 192, 256, 384, 512 ],
"default" : {
"bitRate" : 160,
"frameRate" : 7
},
"frameRate" : [ 15, 10, 7, 4 ],
"profile" : [ "Base", "Main", "High" ],
"size" : "640*360"
}
},
{
"audio" : "boolean",
"mainStream" : {
"bitRate" : [ 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192 ],
"default" : {
"bitRate" : 3072,
"frameRate" : 15
},
"frameRate" : [ 30, 22, 20, 18, 16, 15, 12, 10, 8, 6, 4, 2 ],
"profile" : [ "Base", "Main", "High" ],
"size" : "2048*1536"
},
"subStream" : {
"bitRate" : [ 64, 128, 160, 192, 256, 384, 512 ],
"default" : {
"bitRate" : 160,
"frameRate" : 7
},
"frameRate" : [ 15, 10, 7, 4 ],
"profile" : [ "Base", "Main", "High" ],
"size" : "640*360"
}
},
{
"audio" : "boolean",
"mainStream" : {
"bitRate" : [ 1024, 1536, 2048, 3072, 4096, 5120, 6144, 7168, 8192 ],
"default" : {
"bitRate" : 3072,
"frameRate" : 15
},
"frameRate" : [ 30, 22, 20, 18, 16, 15, 12, 10, 8, 6, 4, 2 ],
"profile" : [ "Base", "Main", "High" ],
"size" : "2304*1296"
},
"subStream" : {
"bitRate" : [ 64, 128, 160, 192, 256, 384, 512 ],
"default" : {
"bitRate" : 160,
"frameRate" : 7
},
"frameRate" : [ 15, 10, 7, 4 ],
"profile" : [ "Base", "Main", "High" ],
"size" : "640*360"
}
}
]
},
"value" : {
"Enc" : {
"audio" : 0,
"channel" : 0,
"mainStream" : {
"bitRate" : 2048,
"frameRate" : 20,
"profile" : "Main",
"size" : "3072*1728"
},
"subStream" : {
"bitRate" : 64,
"frameRate" : 4,
"profile" : "High",
"size" : "640*360"
}
}
}
}]
:return: json or None
"""
try:
param = {"cmd": "GetEnc", "token": self.token}
body = [{"cmd": "GetEnc", "action": 1, "param": {"channel": 0}}]
response = Request.post(self.url, data=body, params=param)
if response.status_code == 200:
return json.loads(response.text)
print("Could not retrieve recording encoding data. Status:", response.status_code)
return None
except Exception as e:
print("Could not get recording encoding", e)
raise
def get_recording_advanced(self) -> json or None:
"""
Get recording advanced setup data
Response data format is as follows:
[{
"cmd" : "GetRec",
"code" : 0,
"initial" : {
"Rec" : {
"channel" : 0,
"overwrite" : 1,
"postRec" : "15 Seconds",
"preRec" : 1,
"schedule" : {
"enable" : 1,
"table" : "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
}
}
},
"range" : {
"Rec" : {
"channel" : 0,
"overwrite" : "boolean",
"postRec" : [ "15 Seconds", "30 Seconds", "1 Minute" ],
"preRec" : "boolean",
"schedule" : {
"enable" : "boolean"
}
}
},
"value" : {
"Rec" : {
"channel" : 0,
"overwrite" : 1,
"postRec" : "15 Seconds",
"preRec" : 1,
"schedule" : {
"enable" : 1,
"table" : "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
}
}
}
}]
:return: json or None
"""
try:
param = {"cmd": "GetRec", "token": self.token}
body = [{"cmd": "GetRec", "action": 1, "param": {"channel": 0}}]
response = Request.post(self.url, data=body, params=param)
if response.status_code == 200:
return json.loads(response.text)
print("Could not retrieve advanced recording. Status:", response.status_code)
return None
except Exception as e:
print("Could not get advanced recoding", e)