diff --git a/.gitignore b/.gitignore index fc4d283..5c52a42 100755 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ lib/ lib64/ parts/ sdist/ +share/ var/ wheels/ *.egg-info/ diff --git a/zoneminder/monitor.py b/zoneminder/monitor.py index c40e2ce..5743ae7 100755 --- a/zoneminder/monitor.py +++ b/zoneminder/monitor.py @@ -131,6 +131,23 @@ def is_recording(self) -> Optional[bool]: return False return int(status) == STATE_ALARM + @property + def is_available(self) -> bool: + """Indicate if this Monitor is currently available.""" + status_response = self._client.get_state( + 'api/monitors/daemonStatus/id:{}/daemon:zmc.json'.format( + self._monitor_id + ) + ) + + if not status_response: + _LOGGER.warning('Could not get availability for monitor {}'.format( + self._monitor_id + )) + return False + + return status_response.get('status', False) + def get_events(self, time_period, include_archived=False) -> Optional[int]: """Get the number of events that have occurred on this Monitor. diff --git a/zoneminder/zm.py b/zoneminder/zm.py index 222c460..aebcfc5 100755 --- a/zoneminder/zm.py +++ b/zoneminder/zm.py @@ -72,27 +72,31 @@ def change_state(self, api_url, post_data) -> dict: def _zm_request(self, method, api_url, data=None, timeout=DEFAULT_TIMEOUT) -> dict: """Perform a request to the ZoneMinder API.""" - # Since the API uses sessions that expire, sometimes we need to re-auth - # if the call fails. - for _ in range(ZoneMinder.LOGIN_RETRIES): - req = requests.request( - method, urljoin(self._server_url, api_url), data=data, - cookies=self._cookies, timeout=timeout, - verify=self._verify_ssl) - - if not req.ok: - self.login() - else: - break - - else: - _LOGGER.error("Unable to get API response from ZoneMinder") - try: - return req.json() - except ValueError: - _LOGGER.exception('JSON decode exception caught while attempting ' - 'to decode "%s"', req.text) + # Since the API uses sessions that expire, sometimes we need to + # re-auth if the call fails. + for _ in range(ZoneMinder.LOGIN_RETRIES): + req = requests.request( + method, urljoin(self._server_url, api_url), data=data, + cookies=self._cookies, timeout=timeout, + verify=self._verify_ssl) + + if not req.ok: + self.login() + else: + break + + else: + _LOGGER.error('Unable to get API response from ZoneMinder') + + try: + return req.json() + except ValueError: + _LOGGER.exception('JSON decode exception caught while' + 'attempting to decode "%s"', req.text) + return {} + except requests.exceptions.ConnectionError: + _LOGGER.exception('Unable to connect to ZoneMinder') return {} def get_monitors(self) -> List[Monitor]: @@ -163,6 +167,18 @@ def get_url_with_auth(self, url) -> str: return url + '&pass={:s}'.format(self._password) + @property + def is_available(self) -> bool: + """Indicate if this ZoneMinder service is currently available.""" + status_response = self.get_state( + 'api/host/daemonCheck.json' + ) + + if not status_response: + return False + + return status_response.get('result') == 1 + @staticmethod def _build_zms_url(server_host, zms_path) -> str: """Build the ZMS url to the current ZMS instance."""