Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

draft PR for supporting ircut get/set and genericizing service call #68

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 72 additions & 2 deletions pyhik/hikvision.py
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,76 @@ def get_device_info(self):
_LOGGING.error('There was a problem: %s', err)
return None

def call_service(self, isapi_path, method='GET', payload=None, xml_result=False, **kwargs):
"""Call any service"""
result = {}
url = '%s/ISAPI%s' % ( self.root_url, isapi_path)
if method != 'GET' and payload is None and kwargs:
xml = self.call_service(isapi_path, method='GET', xml_result=True)
ET.register_namespace("", self.namespace)
for k, v in kwargs.items():
elem = xml.find(self.element_query(k))
if elem is None:
_LOGGING.error("Couldn't find '%s' in the xml" % k)
_LOGGING.error('XML: %s', ET.tostring(xml))
else:
elem.text = v
payload = ET.tostring(xml)

try:
request_func = getattr(self.hik_request, method.lower())
response = request_func(url, data=payload, timeout=CONNECT_TIMEOUT)
if response.status_code == requests.codes.unauthorized:
_LOGGING.debug('Basic authentication failed. Using digest.')
self.hik_request.auth = HTTPDigestAuth(self.usr, self.pwd)
response = request_func(url, data=payload, timeout=CONNECT_TIMEOUT)

except (requests.exceptions.RequestException,
requests.exceptions.ConnectionError) as err:
_LOGGING.error('Unable to %s service %s error: %s', method, isapi_path, err)
return None

if response.status_code == requests.codes.unauthorized:
_LOGGING.error('Authentication failed')
return None

if response.status_code != requests.codes.ok:
# If we didn't receive 200, abort
_LOGGING.debug('Unable to %s services %s, code %s.', method, isapi_path, response.status_code)
return None

try:
tree = ET.fromstring(response.text)
# Try to fetch namespace from XML
nmsp = tree.tag.split('}')[0].strip('{')
self.namespace = nmsp if nmsp.startswith('http') else XML_NAMESPACE
_LOGGING.debug('Using Namespace: %s', self.namespace)

if xml_result:
result = tree
else:
for item in tree:
tag = item.tag.split('}')[1]
result[tag] = item.text

return result

except AttributeError as err:
_LOGGING.error('Entire response: %s', response.text)
_LOGGING.error('There was a problem: %s', err)
return None

def get_ircut(self, channel=1):
result = self.call_service('/Image/channels/%s/ircutFilter' % channel)
return result

def set_ircut(self, channel=1, filterType='auto',nightToDayLevel=6, nightToDayTime=20):
result = self.call_service('/Image/channels/%s/ircutFilter' % channel, method='PUT',
IrcutFilterType=filterType,
nightToDayFilterLevel=str(nightToDayLevel),
nightToDayFilterTime=str(nightToDayTime))
return result

def watchdog_handler(self):
"""Take care of threads if wachdog expires."""
_LOGGING.debug('%s Watchdog expired. Resetting connection.', self.name)
Expand Down Expand Up @@ -512,7 +582,7 @@ def alert_stream(self, reset_event, kill_event):
self.process_stream(tree)
self.update_stale()
except ET.ParseError as err:
_LOGGING.warning('XML parse error in stream.')
_LOGGING.warning('XML parse error in stream: %s',err)
parse_string = ""
else:
if start_event:
Expand Down Expand Up @@ -566,7 +636,7 @@ def process_stream(self, tree):
# Need to make sure this is actually a number
echid = int(echid.text)
break
except (ValueError, TypeError) as err:
except (ValueError, TypeError) as _err:
# Field must not be an integer or is blank
pass

Expand Down