Add support for human detection on AD410 and add versioning

pull/21/head
Daniel Chesterton 4 years ago
parent 0407bca341
commit 2e3e3afc4d

@ -11,6 +11,12 @@ jobs:
if: "!contains(github.event.head_commit.message, '[ci skip]')" if: "!contains(github.event.head_commit.message, '[ci skip]')"
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
steps: steps:
- name: Bump version
uses: remorses/bump-version@js
id: version
with:
version_file: ./VERSION
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2.3.4 uses: actions/checkout@v2.3.4
- name: Set up QEMU - name: Set up QEMU
@ -27,4 +33,7 @@ jobs:
with: with:
push: true push: true
platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x
tags: dchesterton/amcrest2mqtt:latest tags: |
dchesterton/amcrest2mqtt:latest
dchesterton/amcrest2mqtt:${{ steps.version.outputs.version }}
labels: "version=${{ steps.version.outputs.version }}"

@ -17,9 +17,12 @@ It supports the following environment variables:
- `HOME_ASSISTANT` (optional, default = false) - `HOME_ASSISTANT` (optional, default = false)
- `HOME_ASSISTANT_PREFIX` (optional, default = 'homeassistant') - `HOME_ASSISTANT_PREFIX` (optional, default = 'homeassistant')
It exposes events to the `amcrest2mqtt/[SERIAL_NUMBER]/event` MQTT topic. If the device is an AD110 or AD410 doorbell it will expose It exposes events to the following topics:
the doorbell status to `amcrest2mqtt/[SERIAL_NUMBER]/doorbell`. If the device supports motion events it will expose motion events
to `amcrest2mqtt/[SERIAL_NUMBER]/motion`. - `amcrest2mqtt/[SERIAL_NUMBER]/event` - all events
- `amcrest2mqtt/[SERIAL_NUMBER]/doorbell` - doorbell status (if AD110 or AD410)
- `amcrest2mqtt/[SERIAL_NUMBER]/human` - human detection (if AD410)
- `amcrest2mqtt/[SERIAL_NUMBER]/motion` - motion events (if supported)
## Device Support ## Device Support

@ -0,0 +1 @@
1.0.0

@ -27,19 +27,6 @@ mqtt_password = os.getenv("MQTT_PASSWORD") # can be None
home_assistant = os.getenv("HOME_ASSISTANT") == "true" home_assistant = os.getenv("HOME_ASSISTANT") == "true"
home_assistant_prefix = os.getenv("HOME_ASSISTANT_PREFIX") or "homeassistant" home_assistant_prefix = os.getenv("HOME_ASSISTANT_PREFIX") or "homeassistant"
# Exit if any of the required vars are not provided
if amcrest_host is None:
log("Please set the AMCREST_HOST environment variable", level="ERROR")
sys.exit(1)
if amcrest_password is None:
log("Please set the AMCREST_PASSWORD environment variable", level="ERROR")
sys.exit(1)
if mqtt_username is None:
log("Please set the MQTT_USERNAME environment variable", level="ERROR")
sys.exit(1)
# Helper functions and callbacks # Helper functions and callbacks
def log(msg, level="INFO"): def log(msg, level="INFO"):
ts = datetime.now(timezone.utc).strftime("%d/%m/%Y %H:%M:%S") ts = datetime.now(timezone.utc).strftime("%d/%m/%Y %H:%M:%S")
@ -102,6 +89,20 @@ def signal_handler(sig, frame):
is_exiting = True is_exiting = True
exit_gracefully(0) exit_gracefully(0)
# Exit if any of the required vars are not provided
if amcrest_host is None:
log("Please set the AMCREST_HOST environment variable", level="ERROR")
sys.exit(1)
if amcrest_password is None:
log("Please set the AMCREST_PASSWORD environment variable", level="ERROR")
sys.exit(1)
if mqtt_username is None:
log("Please set the MQTT_USERNAME environment variable", level="ERROR")
sys.exit(1)
# Handle interruptions
signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGINT, signal_handler)
# Connect to camera # Connect to camera
@ -109,10 +110,13 @@ camera = AmcrestCamera(
amcrest_host, amcrest_port, amcrest_username, amcrest_password amcrest_host, amcrest_port, amcrest_username, amcrest_password
).camera ).camera
# Fetch camera details
log("Fetching camera details...") log("Fetching camera details...")
device_type = camera.device_type.replace("type=", "").strip() device_type = camera.device_type.replace("type=", "").strip()
is_doorbell = device_type in ["AD110", "AD410"] is_ad110 = device_type == "AD110"
is_ad410 = device_type == "AD410"
is_doorbell = is_ad110 or is_ad410
serial_number = camera.serial_number.strip() serial_number = camera.serial_number.strip()
sw_version = camera.software_information[0].replace("version=", "").strip() sw_version = camera.software_information[0].replace("version=", "").strip()
device_name = camera.machine_name.replace("name=", "").strip() device_name = camera.machine_name.replace("name=", "").strip()
@ -129,11 +133,13 @@ topics = {
"event": f"amcrest2mqtt/{serial_number}/event", "event": f"amcrest2mqtt/{serial_number}/event",
"motion": f"amcrest2mqtt/{serial_number}/motion", "motion": f"amcrest2mqtt/{serial_number}/motion",
"doorbell": f"amcrest2mqtt/{serial_number}/doorbell", "doorbell": f"amcrest2mqtt/{serial_number}/doorbell",
"human": f"amcrest2mqtt/{serial_number}/human",
"storage_used": f"amcrest2mqtt/{serial_number}/storage/used", "storage_used": f"amcrest2mqtt/{serial_number}/storage/used",
"storage_used_percent": f"amcrest2mqtt/{serial_number}/storage/used_percent", "storage_used_percent": f"amcrest2mqtt/{serial_number}/storage/used_percent",
"storage_total": f"amcrest2mqtt/{serial_number}/storage/total", "storage_total": f"amcrest2mqtt/{serial_number}/storage/total",
"home_assistant": { "home_assistant": {
"doorbell": f"{home_assistant_prefix}/binary_sensor/amcrest2mqtt-{serial_number}/{device_slug}_doorbell/config", "doorbell": f"{home_assistant_prefix}/binary_sensor/amcrest2mqtt-{serial_number}/{device_slug}_doorbell/config",
"human": f"{home_assistant_prefix}/binary_sensor/amcrest2mqtt-{serial_number}/{device_slug}_human/config",
"motion": f"{home_assistant_prefix}/binary_sensor/amcrest2mqtt-{serial_number}/{device_slug}_motion/config", "motion": f"{home_assistant_prefix}/binary_sensor/amcrest2mqtt-{serial_number}/{device_slug}_motion/config",
"storage_used": f"{home_assistant_prefix}/sensor/amcrest2mqtt-{serial_number}/{device_slug}_storage_used/config", "storage_used": f"{home_assistant_prefix}/sensor/amcrest2mqtt-{serial_number}/{device_slug}_storage_used/config",
"storage_used_percent": f"{home_assistant_prefix}/sensor/amcrest2mqtt-{serial_number}/{device_slug}_storage_used_percent/config", "storage_used_percent": f"{home_assistant_prefix}/sensor/amcrest2mqtt-{serial_number}/{device_slug}_storage_used_percent/config",
@ -187,6 +193,21 @@ if home_assistant:
json=True, json=True,
) )
if is_ad410:
mqtt_publish(
topics["home_assistant"]["human"],
base_config
| {
"state_topic": topics["human"],
"payload_on": "on",
"payload_off": "off",
"device_class": "motion",
"name": f"{device_name} Human",
"unique_id": f"{serial_number}.human",
},
json=True,
)
mqtt_publish( mqtt_publish(
topics["home_assistant"]["motion"], topics["home_assistant"]["motion"],
base_config base_config
@ -248,9 +269,12 @@ log("Listening for events...")
try: try:
for code, payload in camera.event_actions("All", retries=5): for code, payload in camera.event_actions("All", retries=5):
if (device_type == "AD110" and code == "ProfileAlarmTransmit") or (code == "VideoMotion" and device_type != "AD110"): if (is_ad110 and code == "ProfileAlarmTransmit") or (code == "VideoMotion" and not is_ad110):
motion_payload = "on" if payload["action"] == "Start" else "off" motion_payload = "on" if payload["action"] == "Start" else "off"
mqtt_publish(topics["motion"], motion_payload) mqtt_publish(topics["motion"], motion_payload)
elif code == "CrossRegionDetection" and payload["data"]["ObjectType"] == "Human":
human_payload = "on" if payload["action"] == "Start" else "off"
mqtt_publish(topics["human"], human_payload)
elif code == "_DoTalkAction_": elif code == "_DoTalkAction_":
doorbell_payload = "on" if payload["data"]["Action"] == "Invite" else "off" doorbell_payload = "on" if payload["data"]["Action"] == "Invite" else "off"
mqtt_publish(topics["doorbell"], doorbell_payload) mqtt_publish(topics["doorbell"], doorbell_payload)

Loading…
Cancel
Save