Skip to content

Commit

Permalink
Merge pull request #21 from tchellomello/amcrest_simplified_response
Browse files Browse the repository at this point in the history
[WIP] - Extended Amcrest functions to support sensors implemented for Home Assistant
  • Loading branch information
dougsland committed Jan 3, 2017
2 parents 17f2947 + bcda8a8 commit 88f838c
Show file tree
Hide file tree
Showing 9 changed files with 170 additions and 11 deletions.
8 changes: 8 additions & 0 deletions src/amcrest/event.py
Expand Up @@ -137,6 +137,14 @@ def event_channels_happened(self, eventcode):
)
return ret.content.decode('utf-8')

@property
def is_motion_detected(self):
event = self.event_channels_happened('VideoMotion')
if 'channels' not in event:
return False
else:
return True

@property
def event_management(self):
ret = self.command(
Expand Down
22 changes: 13 additions & 9 deletions src/amcrest/http.py
Expand Up @@ -12,23 +12,28 @@
# vim:sw=4:ts=4:et
import requests

from distutils.util import strtobool

from .audio import Audio
from .system import System
from .network import Network
from .motion_detection import MotionDetection
from .snapshot import Snapshot
from .user_management import UserManagement
from .event import Event
from .record import Record
from .video import Video
from .log import Log
from .motion_detection import MotionDetection
from .nas import Nas
from .network import Network
from .ptz import Ptz
from .record import Record
from .snapshot import Snapshot
from .special import Special
from .storage import Storage
from .system import System
from .user_management import UserManagement
from .utils import Utils
from .video import Video


class Http(System, Network, MotionDetection, Snapshot,
UserManagement, Event, Audio, Record, Video,
Log, Ptz, Special):
Log, Ptz, Special, Storage, Utils, Nas):

def __init__(self, host, port, user,
password, verbose=True, protocol='http'):
Expand Down Expand Up @@ -62,5 +67,4 @@ def command(self, cmd, timeout_cmd=3):
resp.raise_for_status()
except:
raise

return resp
10 changes: 10 additions & 0 deletions src/amcrest/motion_detection.py
Expand Up @@ -23,6 +23,16 @@ def __get_config(self, config_name):
def motion_detection(self):
return self.__get_config("MotionDetect")

def is_motion_detector_on(self):
ret = self.motion_detection
status = [s for s in ret.split() if '.Enable=' in s][0].split('=')[-1]
return self.str2bool(status)

def is_record_on_motion_detection(self):
ret = self.motion_detection
status = [s for s in ret.split() if '.RecordEnable=' in s][0].split('=')[-1]
return self.str2bool(status)

@motion_detection.setter
def motion_detection(self, opt):
if opt.lower() == "true" or opt.lower() == "false":
Expand Down
23 changes: 23 additions & 0 deletions src/amcrest/nas.py
@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# vim:sw=4:ts=4:et


class Nas:

@property
def nas_information(self):
ret = self.command(
'configManager.cgi?action=getConfig&name=NAS'
)
return ret.content.decode('utf-8')

5 changes: 5 additions & 0 deletions src/amcrest/ptz.py
Expand Up @@ -34,6 +34,11 @@ def ptz_presets_list(self, channel=0):
)
return ret.content.decode('utf-8')

@property
def ptz_presets_count(self, channel=0):
ret = self.ptz_presets_list()
return ret.count("Name=")

def ptz_status(self, channel=0):
ret = self.command(
'ptz.cgi?action=getStatus&channel={0}'.format(channel)
Expand Down
18 changes: 18 additions & 0 deletions src/amcrest/record.py
Expand Up @@ -34,3 +34,21 @@ def media_global_config(self):
'configManager.cgi?action=getConfig&name=MediaGlobal'
)
return ret.content.decode('utf-8')

@property
def record_mode(self):
status_code = { 0 : 'Automatic',
1 : 'Manual',
2 : 'Stop',
None: 'Unknown'}

ret = self.command(
'configManager.cgi?action=getConfig&name=RecordMode'
)

try:
status = int([s for s in ret.content.decode('utf-8').split() if 'Mode=' in s][0].split('=')[-1])
except:
status = None

return status_code[status]
45 changes: 45 additions & 0 deletions src/amcrest/storage.py
@@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# vim:sw=4:ts=4:et


class Storage:

@property
def storage_device_info(self):
ret = self.command(
'storageDevice.cgi?action=getDeviceAllInfo'
)
return ret.content.decode('utf-8')

@property
def storage_device_names(self):
ret = self.command(
'storageDevice.cgi?action=factory.getCollect'
)
return ret.content.decode('utf-8')

@property
def storage_used(self, dev='/dev/mmc0', unit='GB'):
ret = self.storage_device_info
# TODO
# Use regex to enhance the filter
status = [s for s in ret.split() if '.UsedBytes=' in s][0]
return self.to_unit(status.split('=')[-1], unit)

@property
def storage_total(self, dev='/dev/mmc0', unit='GB'):
ret = self.storage_device_info
# TODO
# Use regex to enhance the filter
status = [s for s in ret.split() if '.TotalBytes=' in s][0]
return self.to_unit(status.split('=')[-1], unit)
5 changes: 3 additions & 2 deletions src/amcrest/system.py
Expand Up @@ -64,7 +64,8 @@ def software_information(self):
ret = self.command(
'magicBox.cgi?action=getSoftwareVersion'
)
return ret.content.decode('utf-8')
version, build_date = ret.content.decode('utf-8').split()
return (version, build_date)

@property
def hardware_version(self):
Expand All @@ -85,7 +86,7 @@ def serial_number(self):
ret = self.command(
'magicBox.cgi?action=getSerialNo'
)
return ret.content.decode('utf-8')
return ret.content.decode('utf-8').split('=')[-1]

@property
def machine_name(self):
Expand Down
45 changes: 45 additions & 0 deletions src/amcrest/utils.py
@@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# vim:sw=4:ts=4:et

from distutils.util import strtobool

PRECISION = 2

class Utils:


def str2bool(self, value):
"""
Args:
value - text to be converted to boolean
True values: y, yes, true, t, on, 1
False values: n, no, false, off, 0
"""
return bool(strtobool(value))

def to_unit(self, value, unit='B'):
"""Convert bytes to give unit."""
BYTE_SIZES = ['B', 'KB', 'MB', 'GB', 'TB']

if not isinstance(value, (int, float)):
value = float(value)

if unit in BYTE_SIZES:
result = value / 1024**BYTE_SIZES.index(unit)
return (float('{:.{prec}f}'.format(result, prec=PRECISION)), unit)


def percent(self, part, whole):
"""Convert data to percent"""
result = 100 * float(part)/float(whole)
return float('{:.{prec}f}'.format(result, prec=PRECISION))

0 comments on commit 88f838c

Please sign in to comment.