A Python 2.7/3.x module for Amcrest Cameras using the SDK HTTP API.

Overview

Python Amcrest

https://travis-ci.org/tchellomello/python-amcrest.svg?branch=master

A Python 2.7/3.x module for Amcrest Cameras using the SDK HTTP API. Amcrest and Dahua devices share similar firmwares. Dahua Cameras and NVRs also work with this module.

Documentation: http://python-amcrest.readthedocs.io/

Installation

PyPI

/etc/profile.d/amcrest-cli-autocomplete.sh ">
$ pip install amcrest --upgrade
$ eval "$(register-python-argcomplete amcrest-cli)"

# To enable amcrest-cli autocomplete in the system:
$ echo 'eval "$(register-python-argcomplete amcrest-cli)"' >  /etc/profile.d/amcrest-cli-autocomplete.sh

RPM

$ git clone [email protected]:tchellomello/python-amcrest.git
$ ./autogen.sh
$ make rpm
$ dnf/yum install amcrest-cli-NVR.rpm pythonX-amcrest-NVR.rpm

Usage

#Capture audio camera.audio_stream_capture(httptype="singlepart", channel=1, path_file="/home/user/Desktop/audio.aac") CTRL-C to stop the continuous audio flow or use a timer #Move camera down camera.ptz_control_command(action="start", code="Down", arg1=0, arg2=0, arg3=0) #Record realtime stream into a file camera.realtime_stream(path_file="/home/user/Desktop/myvideo") CTRL-C to stop the continuous video flow or use a timer ">
from amcrest import AmcrestCamera
camera = AmcrestCamera('192.168.0.1', 80, 'admin', 'password').camera

#Check software information
camera.software_information
'version=2.420.AC00.15.R\r\nBuildDate=2016-09-08'

#Capture snapshot
camera.snapshot(0, "/home/user/Desktop/snapshot00.jpeg")
<requests.packages.urllib3.response.HTTPResponse object at 0x7f84945083c8>

#Capture audio
camera.audio_stream_capture(httptype="singlepart", channel=1, path_file="/home/user/Desktop/audio.aac")
CTRL-C to stop the continuous audio flow or use a timer

#Move camera down
camera.ptz_control_command(action="start", code="Down", arg1=0, arg2=0, arg3=0)

#Record realtime stream into a file
camera.realtime_stream(path_file="/home/user/Desktop/myvideo")
CTRL-C to stop the continuous video flow or use a timer

Command Line

$ man amcrest-cli
or
$ amcrest-cli --help

# Saving credentials to file.
$ vim ~/.config/amcrest.conf
[patio]
hostname: 192.168.0.20
username: admin
password: 123456
port: 80

[living_room]
hostname: 192.168.0.21
username: admin
password: secret
port: 80

$ amcrest-cli --camera living_room --version-http-api
version=1.40

Text User Interface (TUI)

Configure amcrest.conf and trigger amcrest-tui, make sure the user triggering amcrest-tui have access to framebuffer device or use sudo.

NOTE: Execute it from console logins, like /dev/ttyX (Non X Window). Pseudo-terminals like xterm, ssh, screen and others WONT WORK.

$ vim ~/.config/amcrest.conf
[patio]
hostname: 192.168.0.20
username: admin
password: 123456
port: 80

[living_room]
hostname: 192.168.0.21
username: admin
password: secret
port: 80

$ amcrest-tui

Supportability Matrix

Cameras

Model Tested Status Results/Issues
IPM-721 Yes working  
IPM-HX1 Yes working  
IP2M-841 Yes working  
IP2M-842 Yes working  
IP3M-941 Yes working  
IP3M-943 Yes working  
IP3M-956 Yes working  
IP3M-956E Yes working  
IP3M-HX2 Yes working  
IP4M-1026B Yes working  
IP4M-1051B Yes working  
IP5M-1176EB Yes working  
IP8M-2496EB Yes working  
IP8M-T2499EW-28M Yes working  

Network Video Recorders (NVR)

Model Tested Status Results/Issues
XVR DAHUA 5104S Yes working  

If you have different model, feel fee to contribute and report your results.

Help

If you need any help, please join our community on the Gitter channels available at Gitter.

Comments
  • AttributeError: module 'socket' has no attribute 'TCP_KEEPIDLE'

    AttributeError: module 'socket' has no attribute 'TCP_KEEPIDLE'

    Getting the following error when I try to run anything, even just getting cam info:

    AttributeError: module 'socket' has no attribute 'TCP_KEEPIDLE'

    Process finished with exit code 1

    opened by rtmg2007 20
  • Introducing Unittest

    Introducing Unittest

    Integration with:

    • Tox

    • Coveralls

    • Unittest framework

    • Fixed some lint issues

    • Removed fbida from requirements since it is not a Python package. This should be only present on a SPEC file

    invalid 
    opened by tchellomello 16
  • snapshot() does not work for some cameras (HASS: Amcrest Cameras fail after update to 0.59.1)

    snapshot() does not work for some cameras (HASS: Amcrest Cameras fail after update to 0.59.1)

    **Description of problem:**After upgrade to 0.59.1 only 1 of my Amcrest cameras output appear in both of my Amcrest cameras displays on the Dashboard.

    I upgrade my RPI 3 running on Raspbian Stretch Desktop to HA version 0.60.0. Still having the same trouble with my Amcrest Cameras. I did see this in the Info tab if this helps!! Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProtocolError('Connection aborted.', RemoteDisconnected('Remote end closed connection without response',))': /cgi-bin/snapshot.cgi?channel=0 2:18 PM components/camera/amcrest.py (WARNING)

    bug help wanted priority 
    opened by akerrichardt 10
  • sending audio

    sending audio

    first off, this is awesome i figured i was going to end up having to put something like this together myself but it's already done!

    on that note; has anyone had any luck sending audio to their cam? this utility appears to send the audio to the cam just fine. However it always sounds completely messed up when outputting through the cam. Initially i started with just curl with the same result until i stumbled upon this.

    im assuming it's some type of audio encoding issue. I have tried sending in most of the available formats with different bit/sample rates with no luck.

    so far this encoding gets me the closest but it's still FAR from correct

    G.711A as content type ffmpeg -i 4353.mp3 -c:a pcm_alaw -ac 1 -ar 16000 -sample_fmt s16 output.wav

    help wanted question 
    opened by josh-- 10
  • Add event_stream() which returns stream of camera events

    Add event_stream() which returns stream of camera events

    Description

    Currently, determining if motion or other events occur requires polling via event_channels_happened() (or one of the other methods or properties that use it.) This can delay response to events, and can even miss events if the event duration is shorter than the polling period.

    This adds a new method -- event_stream() -- which will return events as they happen. It is a generator and will normally not return, so it should be run in a separate thread or process.

    Example use case

    import re
    import threading
    from amcrest import AmcrestCamera, CommError
    
    _START_STOP = re.compile(r"Code=([^;]+);action=(Start|Stop)", flags=re.S)
    
    def process_events(camera, event_codes):
        event_codes = ",".join(event_codes)
        while True:
            try:
                for event_info in camera.event_stream(event_codes, retries=5):
                    print("Event info:", repr(event_info))
                    for code, action in _START_STOP.findall(event_info):
                        print("--->", code, action)
            except CommError as error:
                print("Error while processing events:", repr(error))
    
    camera = AmcrestCamera(...).camera
    thread = threading.Thread(target=process_events, args=(camera, ["VideoMotion"]))
    thread.daemon = True
    thread.start()
    

    To do

    • [x] Make sure comm errors and camera power cycling are handled properly.
    • [x] Get feedback from other users with other camera models and/or firmware versions.
    • [x] Prototype usage in Home Assistant's amcrest integration.
    • [x] Determine if anything can be done about urllib3 warning:
    WARNING:urllib3.connectionpool:Failed to parse headers (url=http://<host>:<port>/cgi-bin/eventManager.cgi?action=attach&codes=%5BVideoMotion%5D): [StartBoundaryNotFoundDefect(), MultipartInvariantViolationDefect()], unparsed data: ''
    Traceback (most recent call last):
      File "/home/phil/test/amcrest/venv/lib/python3.7/site-packages/urllib3/connectionpool.py", line 441, in _make_request
        assert_header_parsing(httplib_response.msg)
      File "/home/phil/test/amcrest/venv/lib/python3.7/site-packages/urllib3/util/response.py", line 71, in assert_header_parsing
        raise HeaderParsingError(defects=defects, unparsed_data=unparsed_data)
    urllib3.exceptions.HeaderParsingError: [StartBoundaryNotFoundDefect(), MultipartInvariantViolationDefect()], unparsed data: ''
    

    Thanks to @NickWaterton and his groundwork in PR #140!

    opened by pnbruckner 9
  • Add functionality to use additional channels

    Add functionality to use additional channels

    Add additional methods to be able to use specified channels, allowing this to be used with NVRs. Currently, the @property's read from channel 0, change these methods to call into the new functions for the channel it used previously, so these should not change behavior.

    Behavioral changes include:

    • Event.event_channels_happened returns a list of channels where the event has occurred, rather than the request output. This simplifies the is_x_detected methods.
    • The Event.is_x_detected methods return a list of channels where the event occurred, rathen than a bool of if the event occurred or not.
    • Video.video_in_option returns a list of all option configurations for all channels, rather than just returning the first option. All of the properties (eg video_enabled and day_night_color) are unchanged, as they check channel 0.
    • Some of the System properties (eg serial_number) are split with pretty() to give just the value rather than the full message payload.
    opened by flacjacket 6
  • FIX for #75 and #149

    FIX for #75 and #149

    Potential fix for #75 and #149

    I do not have access to the hardware at this time (due to corona virus). So I cannot test this.

    The user using play_wav will now need to know the encoding type for their .wav file.

    The most critical part of this PR is the new optional argument 'encoding'

    It is up to someone who has access to a camera to test out all the encodings and report back to this community their results.

    According to a comment in the same file:

    Supported audio encode type according with documentation: PCM ADPCM G.711A G.711.Mu G.726 G.729 MPEG2 AMR AAC

    G.711A will be the default one as that was the encoding type that was hard coded before.

    Take care, and happy testing!

    opened by AlexKohanim 6
  • Reuse command sessions

    Reuse command sessions

    In command method, don't create a new requests session every time. Rather, keep a session for each value of retries. Also don't try to update default values for retries and timeout for each command because that wasn't thread safe.

    opened by pnbruckner 6
  • Release 1.8.0?

    Release 1.8.0?

    It'd be great to have a new release now that some of the NVR channel related functionality is in. Looking at the commits since 1.7.2, I think this is the set of key changes:

    Breaking changes

    • Python 2 no longer supported, Python 3.6 is the minimum required version
    • PTZ commands (e.g. zoom_in, move_left) require boolean value for start parameter, rather than "start" and "stop" strings for the action parameter

    New features

    • Smart motion detection events added as is_human_detected and is_vehicle_detected properties.
    • Added methods to query separate channels to allow using multiple cameras on NVRs.
    • Type annotations added to allow for type checking.

    I'd say no particular rush to get this out, just curious what sort of things would be needed to get to the point of cutting a release. A couple of the current open PRs seem like they are also close to ready if they can get some minor fixes from authors, so those would probably be good to get in if possible.

    opened by flacjacket 5
  • **Feature Request** Smart Motion Detection

    **Feature Request** Smart Motion Detection

    I recently upgraded a camera to the IPC-HDW5442TM-AS. This has some new events and I was hoping to use the Smart Motion Detection (can detect humans and vehicles). Playing with the API calls I found that the getConfig name is SmartMotionDetect

    The following command:

    http://<IP>/cgi-bin/configManager.cgi?action=getConfig&name=SmartMotionDetect
    

    Returns:

    table.SmartMotionDetect[0].Enable=true
    table.SmartMotionDetect[0].ObjectTypes.Human=true
    table.SmartMotionDetect[0].ObjectTypes.Vehicle=false
    table.SmartMotionDetect[0].Sensitivity=Middle
    

    This shows that the smart detection is enabled, and for humans but not vehicles - and the sensitivity is set to medium (3 options, low/medium/high).

    Using this I expect that the event subscription would be either SmartMotionDetect or SmartVideoMotion based on what is already in this repo. I am a novice, and wasn't sure how to test this. I tried, but was unsuccessful getting a correct response with the existing motion detection (I'm sure I'm doing something wrong though).

    When I tried to test some of the commands in the interpreter I expect I am doing it wrong. I am getting generator objects so I expect it is doing something but I am sending the wrong commands or not telling it how to output... as said earlier, I'm a novice 😄 .

    >>> import amcrest
    >>> camera = amcrest.AmcrestCamera('<IP>',80,'<admin>','<password>').camera
    >>> camera.software_information
    ('version=2.800.0000000.20.R', 'build:2020-09-03\r\n')
    >>> camera.event_stream('All')
    <generator object Event.event_stream at 0x7f307bfe0900>
    >>> camera.event_stream('VideoMotion')
    <generator object Event.event_stream at 0x7f307bfe0820>
    >>> camera.event_actions('All')
    <generator object Event.event_actions at 0x7f307bfe0900>
    

    If this is as simple as adding a new event name, fantastic - but if it needs testing, I would be happy to do it, but might need a little hand holding to start. If I could be told how to test the VideoMotion and get a response correctly, I'm sure I could work from there to get the SmartVideoMotion or SmartMotionDetect whatever they call it figured out.

    Thanks! DeadEnd

    opened by DeadEnded 5
  • Older Firmware Cameras Not Supportive of URL that is Encoded (EventManager)

    Older Firmware Cameras Not Supportive of URL that is Encoded (EventManager)

    On a Dahua 2015 firmware, no upgrade possible (last firmware)

    This URL gets a bad response (400) http://192.168.1.41:80/cgi-bin/eventManager.cgi?action=attach&codes=%5BAll%5D

    This URL works http://192.168.1.41:80/cgi-bin/eventManager.cgi?action=attach&codes=[All]

    A quick fix was detailed here (with Python Amcrest 1.7.0) in HA Reported bug https://github.com/home-assistant/core/issues/33875#issuecomment-615548520

    Which seems to be working for me.

    wontfix 
    opened by jamesarbrown 5
  • Events to trigger HTTP Post to external URL

    Events to trigger HTTP Post to external URL

    I'm still reading through some of the documentation with this camera and the API. I'm hoping that I can set a configuration option that will cause the camera to automatically HTTP Post event data to a server I have running in the cloud. I'm hoping to do this without having to have a listener running actively monitoring those events myself.

    .e.g something like setConfig onMotionDetected POST to https://someexternalsite.com

    I'm not seeing anything like this, but the documentation regarding setting config options is a little tough to grok.

    Regards

    opened by trankin 0
  • Support enabling and disabling the mechanical chime

    Support enabling and disabling the mechanical chime

    One of the biggest reasons I'm dropping my Nest doorbell is because of the lack of API control. The Amcrest AD110 has the required control for me to bring things local, but it's missing one thing: the ability to silence the indoor chime. I have young children and a baby on the way, and we want that doorbell chime SILENCED during nap time.

    It seems it is possible to disable (and likely reenable) the chime using the web api.

    http://<ip address of ad110>/cgi-bin/configManager.cgi?action=setConfig&ExternalDoorBell.Enable=false
    http://<ip address of ad110>/cgi-bin/configManager.cgi?action=setConfig&ExternalDoorBell.Enable=true
    

    You can get the current status like so:

    http://<ip address of ad110>/cgi-bin/configManager.cgi?action=getConfig&name=ExternalDoorBell
    

    Is this something the module can support so it may trickle up the stream and eventually into Home Assistant?

    opened by mririgoyen 1
  • event_actions() causes AttributeError

    event_actions() causes AttributeError

    I am connecting to an Amcrest AD410 Doorbell and utilizing the event_actions() method and after about 100s, I receive the Error: AttributeError: 'NoneType' object has no attribute 'read'.

    More specifically, I am calling: camera.event_actions("All", retries=5, timeout_cmd=(10.00, 3600)) and with DEBUG log level, I get the follow:

    2022-04-30 00:42:29,922 - urllib3.connectionpool [DEBUG] Starting new HTTP connection (1): 192.168.10.20:80
    2022-04-30 00:42:29,970 - urllib3.connectionpool [DEBUG] http://192.168.10.20:80 "GET /cgi-bin/eventManager.cgi?action=attach&codes=%5BAll%5D HTTP/1.1" 401 0
    2022-04-30 00:44:12,784 - urllib3.connectionpool [DEBUG] http://192.168.10.20:80 "GET /cgi-bin/eventManager.cgi?action=attach&codes=%5BAll%5D HTTP/1.1" 200 None
    2022-04-30 00:44:12,785 - amcrest.http [DEBUG] <Doorbell-D66A> Query 9 worked. Exit code: <200>
    2022-04-30 00:44:12,786 - amcrest.event [DEBUG] <Doorbell-D66A> event info: '\r\nCode=VideoMotionInfo;action=State;index=0'
      File "/usr/local/lib/python3.10/site-packages/amcrest/event.py", line 361, in event_actions
        for event_info in self.event_stream(
      File "/usr/local/lib/python3.10/site-packages/amcrest/event.py", line 312, in event_stream
        for line in _event_lines(ret.iter_content(decode_unicode=True)):
      File "/usr/local/lib/python3.10/site-packages/amcrest/event.py", line 39, in _event_lines
        for char in ret:
      File "/usr/local/lib/python3.10/site-packages/requests/utils.py", line 549, in stream_decode_response_unicode
        for chunk in iterator:
      File "/usr/local/lib/python3.10/site-packages/requests/models.py", line 760, in generate
        for chunk in self.raw.stream(chunk_size, decode_content=True):
      File "/usr/local/lib/python3.10/site-packages/urllib3/response.py", line 575, in stream
        for line in self.read_chunked(amt, decode_content=decode_content):
      File "/usr/local/lib/python3.10/site-packages/urllib3/response.py", line 770, in read_chunked
        chunk = self._handle_chunk(amt)
      File "/usr/local/lib/python3.10/site-packages/urllib3/response.py", line 714, in _handle_chunk
        value = self._fp._safe_read(amt)
      File "/usr/local/lib/python3.10/http/client.py", line 630, in _safe_read
        data = self.fp.read(amt)
    AttributeError: 'NoneType' object has no attribute 'read'
    

    What's also odd that I first get a 401 response before eventually getting a 200. Not sure if this is affecting things tho as I see the same behavior with other calls (ie camera.storage_all) and they return fine.

    Environment:

    • OS: Debian GNU/Linux 10 (buster)
    • Python: 3.10
      • amcrest: 1.9.7
    opened by maxirus 0
  • Add github action to automate creating PyPI packages

    Add github action to automate creating PyPI packages

    Add a new github action that will build and upload PyPI packages when new releases are cut. This works by running but not uploading the package when a tag is created, then, when the Github release is published, the build is run and the package is pushed to PyPI.

    To work, this will also require a PyPI API token. I am able to generate a token, but do not have access to add it as a Github Actions secret to this repo.

    opened by flacjacket 0
Releases(1.9.7)
Owner
Marcelo Moreira de Mello
Marcelo Moreira de Mello
This repo provides the source code for "Cross-Domain Adaptive Teacher for Object Detection".

Cross-Domain Adaptive Teacher for Object Detection This is the PyTorch implementation of our paper: Cross-Domain Adaptive Teacher for Object Detection

Meta Research 91 Dec 12, 2022
A python bot that stops muck chains

muck-chains-stopper-bot a bot that stops muck chains this is the source code of u/DaniDevChainBreaker (the main r/DaniDev muck chains breaker) guys th

24 Jan 04, 2023
Telegram Link Wayback Bot. This bot archives a web page thrown at itself with wayback Machine (Archive.org).

Telegram Link Wayback Bot. This bot archives a web page thrown at itself with wayback Machine (Archive.org).

Hüzünlü Artemis [HuzunluArtemis] 11 Feb 18, 2022
Invites link generator for telegram(made for channel referral links)

InviteLinkGen Invites link generator for telegram(for channel referral links) made for @HelakuruEsana channel Spotify Giveaway

Jaindu Charindith 7 Feb 01, 2022
A Telegram Bin Checker Bot made with python for check Bin valid or Invalid. 💳

Bin Checker Bot A Telegram Bin Checker Bot made with python for check Bin valid or Invalid. 📌 Deploy On Heroku 🏷 Environment Variables API_ID - Your

Chamindu Denuwan 20 Dec 10, 2022
ToqueIO Nuke tools - A collection of tools designed to assist in enhancing your workflows within nuke

ToqueIO Nuke tools - A collection of tools designed to assist in enhancing your workflows within nuke

4 Feb 19, 2022
Pogodasbot - Telegram bot sending channel weather info

Pogodasbot - Telegram bot sending channel weather info

Qayrat Sultan 1 Dec 15, 2022
A simple Discord bot that can fetch definitions and post them in chat.

A simple Discord bot that can fetch definitions and post them in chat. If you are connected to a voice channel, the bot will also read out the definition to you.

Tycho Bellers 4 Sep 29, 2022
Play Video & Music on Telegram Group Video Chat

Video Stream is an Advanced Telegram Bot that's allow you to play Video & Music on Telegram Group Video Chat 🧪 Get SESSION_NAME from below: Pyrogram

Sehath Perera 1 Jan 17, 2022
SOLSEA-NFT-EXPLORE - Using Streamlit to build a simple UI on top of the Solana API

SOLSEA NFT Explorer Using Streamlit to build a simple UI on top of the Solana AP

Devin Capriola 3 Mar 19, 2022
Tracks twitter spaces and sends it to a discord webhook.

Tracks twitter spaces and sends it to a discord webhook. Uses the twitter api to find twitter spaces and then the m3u8 url for the space is found using selenium and will have it posted using a discor

Sam Phung 20 Dec 17, 2022
A discord bot with a leveling system (similar to mee6).

Discord.py A discord bot with a leveling system (like mee6) Pre-requisites Knowing how to get create an app/bot via discord's developer portal. Websit

26 Dec 11, 2022
A telegram bot to forward messages automatically when they arrived.

Telegram Message Forwarder Bot A telegram bot, which can forward messages from channel, group or chat to another channel, group or chat automatically.

Adnan Ahmad 181 Jan 07, 2023
An elegant mirai-api-http v2 Python SDK.

Ariadne 一个适用于 mirai-api-http v2 的 Python SDK。 本项目适用于 mirai-api-http 2.0 以上版本。 目前仍处于开发阶段,内部接口可能会有较大的变化。 安装 poetry add graia-ariadne 或 pip install graia

Graia Project 259 Jan 02, 2023
Python interface to the World Bank Indicators and Climate APIs

wbpy A Python interface to the World Bank Indicators and Climate APIs. Readthedocs Github source World Bank API docs The Indicators API lets you acces

Matt Duck 47 Oct 31, 2022
Бот Telegram для Школы в Капотне (ЦО № 1858)

co1858 Telegram Bot Активно разрабатывался в 2015-2016 году как учебный проект, с целью научиться создавать ботов для Telegram. Бот автоматически парс

Ilya Pavlov 4 Aug 30, 2022
A multi-tenant multi-client scalable product categorising demo stack

Better Categories 4All: A multi-tenant multi-client product categorising stack The steps to reproduce training and inference are in the end of this fi

7 Feb 15, 2022
A Discord Bot coded using Python. Open to collaboration

DisPy-Bot A Discord Bot coded using Python. Open to collaboration La syntax pour intégrer le bot (imaginons la fonction lol_reponse dans le fichier au

BiMathAx 2 Mar 03, 2022
Local community telegram bot

Бот на районе Телеграм-бот для поиска адресов и заведений в вашем районе города или в небольшом городке. Требует недели прогулок по району д

Ilya Zverev 32 Jan 19, 2022
A maintained fork of Danny's discord.py

Nextcord A modern, easy-to-use, feature-rich, and async-ready API wrapper for Discord written in Python. Fork notice This is a fork of discord.py, whi

977 Jan 05, 2023