Skip to content

Commit

Permalink
Handle Reolink token lease (#731)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidvng authored Aug 23, 2024
1 parent cf89f1f commit f0fecae
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 13 deletions.
3 changes: 2 additions & 1 deletion docs/agents/http_camera.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ using all of the available arguments::
{'agent-class': 'HTTPCameraAgent',
'instance-id': 'cameras',
'arguments': [['--mode', 'acq'],
['--config-file', 'cameras.yaml']]},
['--config-file', 'cameras.yaml'],
['--renew-token', 2700]]},

.. note::
The ``--config-file`` argument should be the config file path relative
Expand Down
51 changes: 39 additions & 12 deletions socs/agents/http_camera/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class HTTPCameraAgent:
txaio logger object, created by the OCSAgent
"""

def __init__(self, agent, config_file):
def __init__(self, agent, config_file, renew_token=2700):
self.agent = agent
self.is_streaming = False
self.log = self.agent.log
Expand All @@ -50,6 +50,8 @@ def __init__(self, agent, config_file):
with open(file_path, 'r') as f:
self.config = yaml.safe_load(f)

self.renew_token = renew_token

agg_params = {
'frame_length': 10 * 60 # [sec]
}
Expand Down Expand Up @@ -97,19 +99,41 @@ def acq(self, session, params=None):
self.log.info(f"Grabbing screenshot from {camera['location']}")

if camera['brand'] == 'reolink':
login_url = f"https://{camera['address']}/api.cgi?cmd=Login"
login_payload = [{"cmd": "Login",
"param": {"User":
{"Version": 0,
"userName": camera['user'],
"password": camera['password']}}}]
resp = requests.post(login_url, data=json.dumps(login_payload), verify=False)
rdata = resp.json()
token = rdata[0]['value']['Token']['name']
token = camera.get('token', None)
token_ts = camera.get('token_ts', 0)
# Token lease time is 1hr.
expired = (timestamp - token_ts) > self.renew_token
if token is None or expired:
login_url = f"https://{camera['address']}/api.cgi?cmd=Login"
login_payload = [{"cmd": "Login",
"param": {"User":
{"Version": 0,
"userName": camera['user'],
"password": camera['password']}}}]
try:
resp = requests.post(login_url, data=json.dumps(login_payload), verify=False)
except requests.exceptions.RequestException as e:
self.log.error(f'{e}')
self.log.info("Unable to get response from camera.")
connected = False
data[camera['location']]['last_attempt'] = time.time()
data[camera['location']]['connected'] = connected
continue
rdata = resp.json()
value = rdata[0].get('value', None)
if value is None:
self.log.info("Unable to get token. Max number of tokens used.")
connected = False
data[camera['location']]['last_attempt'] = time.time()
data[camera['location']]['connected'] = connected
continue
camera['token'] = value['Token']['name']
camera['token_ts'] = timestamp

payload = {'cmd': "Snap",
'channel': "0",
'rs': "flsYJfZgM6RTB_os",
'token': token}
'token': camera['token']}
url = f"https://{camera['address']}/cgi-bin/api.cgi"
elif camera['brand'] == 'acti':
payload = {'USER': camera['user'],
Expand Down Expand Up @@ -200,6 +224,8 @@ def add_agent_args(parser=None):
pgroup = parser.add_argument_group("Agent Options")
pgroup.add_argument("--config-file", type=str, help="Config file path relative to OCS_CONFIG_DIR")
pgroup.add_argument("--mode", choices=['acq', 'test'])
pgroup.add_argument("--renew-token", type=int, default=2700,
help="Renew API token after this amount of seconds. Used for Reolink cameras.")

return parser

Expand All @@ -220,7 +246,8 @@ def main(args=None):

agent, runner = ocs_agent.init_site_agent(args)
p = HTTPCameraAgent(agent,
config_file=args.config_file)
config_file=args.config_file,
renew_token=args.renew_token)

agent.register_process("acq",
p.acq,
Expand Down

0 comments on commit f0fecae

Please sign in to comment.