Skip to content

Commit

Permalink
Add session token refresh logic, add home defence switch, add incorre…
Browse files Browse the repository at this point in the history
…ct account details error codes
  • Loading branch information
RenierM26 committed Apr 3, 2021
1 parent ff1b5f3 commit f9e56ed
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 21 deletions.
57 changes: 39 additions & 18 deletions pyezviz/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import pandas
from pyezviz import EzvizCamera, EzvizClient
from pyezviz.constants import DefenseModeType


def main():
Expand Down Expand Up @@ -35,7 +36,14 @@ def main():
type=str,
default="status",
help="Device action to perform",
choices=["device", "status", "switch", "connection", "switch-all"],
choices=["device", "status", "switch", "connection"],
)

parser_home_defence_mode = subparsers.add_parser(
"home_defence_mode", help="Set home defence mode"
)
parser_home_defence_mode.add_argument(
"--mode", required=False, help="Choose mode", choices=["HOME_MODE", "AWAY_MODE"]
)

parser_camera = subparsers.add_parser("camera", help="Camera actions")
Expand Down Expand Up @@ -130,50 +138,56 @@ def main():
print(json.dumps(client.get_device(), indent=2))
except BaseException as exp:
print(exp)
return 1
finally:
client.close_session()

if args.device_action == "status":
elif args.device_action == "status":
try:
client.login()
# print(json.dumps(client.load_cameras(), indent=2))
print(
pandas.DataFrame(client.load_cameras()).to_string(
columns=[
"serial",
"name", # version upgrade_available
"name",
# version,
# upgrade_available,
"status",
"device_category",
"device_sub_category",
"sleep",
"privacy",
"audio",
"ir_led",
"state_led", # follow_move alarm_notify alarm_schedules_enabled alarm_sound_mod encrypted
"state_led",
# follow_move,
# alarm_notify,
# alarm_schedules_enabled,
# alarm_sound_mod,
# encrypted,
"local_ip",
"local_rtsp_port",
"detection_sensibility",
"battery_level",
"alarm_schedules_enabled",
"alarm_notify",
"Motion_Trigger", # last_alarm_time last_alarm_pic
"Motion_Trigger",
# last_alarm_time,
# last_alarm_pic
]
)
)
except BaseException as exp:
print(exp)
return 1
finally:
client.close_session()

if args.device_action == "switch":
elif args.device_action == "switch":
try:
client.login()
print(json.dumps(client.get_switch(), indent=2))
except BaseException as exp:
print(exp)
return 1
finally:
client.close_session()

Expand All @@ -183,17 +197,27 @@ def main():
print(json.dumps(client.get_connection(), indent=2))
except BaseException as exp:
print(exp)
return 1
finally:
client.close_session()

elif args.device_action == "switch-all":
else:
print("Action not implemented: %s", args.device_action)

elif args.action == "home_defence_mode":

if args.mode:
try:
client.login()
print(json.dumps(client.switch_devices(args.enable), indent=2))
print(
json.dumps(
client.api_set_defence_mode(
getattr(DefenseModeType, args.mode).value
),
indent=2,
)
)
except BaseException as exp:
print(exp)
return 1
finally:
client.close_session()

Expand All @@ -206,14 +230,14 @@ def main():
logging.debug("Camera loaded")
except BaseException as exp:
print(exp)
return 1
finally:
client.close_session()

if args.camera_action == "move":
try:
camera.move(args.direction, args.speed)
except BaseException as exp:
print(exp)
return 1
finally:
client.close_session()

Expand All @@ -223,7 +247,6 @@ def main():

except BaseException as exp:
print(exp)
return 1
finally:
client.close_session()

Expand All @@ -244,7 +267,6 @@ def main():
camera.switch_follow_move(args.enable)
except BaseException as exp:
print(exp)
return 1
finally:
client.close_session()

Expand All @@ -260,7 +282,6 @@ def main():
camera.change_defence_schedule(args.schedule)
except BaseException as exp:
print(exp)
return 1
finally:
client.close_session()
else:
Expand Down
51 changes: 48 additions & 3 deletions pyezviz/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
API_ENDPOINT_PAGELIST = "/v3/userdevices/v1/devices/pagelist"
API_ENDPOINT_DEVICES = "/v3/devices/"
API_ENDPOINT_LOGIN = "/v3/users/login/v5"
API_ENDPOINT_REFRESH_SESSION_ID = "/v3/apigateway/login"
API_ENDPOINT_SWITCH_STATUS = "/switchStatus"
API_ENDPOINT_PTZCONTROL = "/ptzControl"
API_ENDPOINT_ALARM_SOUND = "/alarm/sound"
Expand Down Expand Up @@ -45,6 +46,7 @@ def __init__(
self.password = password
self._session = None
self._sessionid = None
self._rfsessionid = None
self._timeout = timeout
self.api_uri = url

Expand All @@ -54,7 +56,6 @@ def _login(self):
# Region code to url.
if len(self.api_uri.split(".")) == 1:
self.api_uri = "apii" + self.api_uri + ".ezvizlife.com"
print(f"Region code depreciated, please use full url: {self.api_uri}")

# Ezviz API sends md5 of password
temp = hashlib.md5()
Expand All @@ -63,7 +64,7 @@ def _login(self):
payload = {
"account": self.account,
"password": md5pass,
"featureCode": "d9edb711e6563e99d366d1a84602f51f",
"featureCode": "f57ac347d68dcf8baf907a906f59c01f",
}

try:
Expand Down Expand Up @@ -95,9 +96,20 @@ def _login(self):
self.api_uri = json_result["loginArea"]["apiDomain"]
print("Region incorrect!")
print(f"Your region url: {self.api_uri}")
self._session = None
return self.login()

if json_result["meta"]["code"] == 1013:
raise PyEzvizError("Incorrect Username.")

if json_result["meta"]["code"] == 1014:
raise PyEzvizError("Incorrect Password.")

if json_result["meta"]["code"] == 1015:
raise PyEzvizError("The user is locked.")

self._sessionid = str(json_result["loginSession"]["sessionId"])
self._rfsessionid = str(json_result["loginSession"]["rfSessionId"])
if not self._sessionid:
raise PyEzvizError(
f"Login error: Please check your username/password: {req.text}"
Expand Down Expand Up @@ -478,8 +490,41 @@ def login(self):
"""Set http session."""
if self._session is None:
self._session = requests.session()
return self._login()

if self._sessionid and self._rfsessionid:
try:
req = self._session.put(
"https://" + self.api_uri + API_ENDPOINT_REFRESH_SESSION_ID,
data={
"refreshSessionId": self._rfsessionid,
"featureCode": "f57ac347d68dcf8baf907a906f59c01f",
},
headers={"sessionId": self._sessionid},
timeout=self._timeout,
)
req.raise_for_status()

except requests.HTTPError as err:
raise requests.HTTPError(err)

return self._login()
try:
json_result = req.json()

except ValueError as err:
raise PyEzvizError(
"Impossible to decode response: "
+ str(err)
+ "\nResponse was: "
+ str(req.text)
) from err

self._sessionid = str(json_result["sessionInfo"]["sessionId"])
self._rfsessionid = str(json_result["sessionInfo"]["refreshSessionId"])
if not self._sessionid:
raise PyEzvizError(f"Relogin required: {req.text}")

return True

def data_report(self, serial, enable=1, max_retries=0):
"""Enable alarm notifications."""
Expand Down

0 comments on commit f9e56ed

Please sign in to comment.