1
0
mirror of synced 2026-03-09 20:13:40 +00:00

Compare commits

50 Commits

Author SHA1 Message Date
Daniel Chesterton
1a4718db0c Add support for overriding device name and add optional additional entities 2021-12-31 00:00:37 +00:00
bump_version
cfcee7dd2d Version 1.0.13 [skip ci] 2021-12-30 23:05:26 +00:00
Daniel Chesterton
ad323ec8ef Fix Dockerfile to send correct STOPSIGNAL 2021-12-30 23:05:09 +00:00
bump_version
8b6ee051d4 Version 1.0.12 [skip ci] 2021-12-30 16:22:04 +00:00
Daniel Chesterton
fd2123535d Switch action for bump-version 2021-12-30 16:21:43 +00:00
Daniel Chesterton
477aa89606 Merge pull request #52 from dchesterton/dependabot/github_actions/docker/login-action-1.12.0
[ci skip]: Bump docker/login-action from 1.10.0 to 1.12.0
2021-12-24 02:31:08 +00:00
Daniel Chesterton
8e5f0620cc Merge pull request #50 from dchesterton/dependabot/github_actions/actions/checkout-2.4.0
[ci skip]: Bump actions/checkout from 2.3.5 to 2.4.0
2021-12-24 02:31:00 +00:00
Daniel Chesterton
cc5e374419 Add entity_category and fix bug with storage totals 2021-12-24 02:30:37 +00:00
dependabot[bot]
afaef732c5 [ci skip]: Bump docker/login-action from 1.10.0 to 1.12.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 1.10.0 to 1.12.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v1.10.0...v1.12.0)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-21 12:08:06 +00:00
dependabot[bot]
4cd3b1add8 [ci skip]: Bump actions/checkout from 2.3.5 to 2.4.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 2.3.5 to 2.4.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2.3.5...v2.4.0)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-03 12:06:23 +00:00
bump_version
766aa50499 Version 1.0.11 [skip ci] 2021-10-26 20:38:41 +00:00
Daniel Chesterton
594a42320f Fix issue with fetching serial number (closes #35) 2021-10-26 21:38:19 +01:00
Daniel Chesterton
2886e5c1ca Merge pull request #36 from dchesterton/dependabot/github_actions/docker/build-push-action-2.7.0
[ci skip]: Bump docker/build-push-action from 2.6.1 to 2.7.0
2021-10-26 21:25:18 +01:00
Daniel Chesterton
9ba2544237 Merge pull request #39 from dchesterton/dependabot/github_actions/docker/setup-buildx-action-1.6.0
[ci skip]: Bump docker/setup-buildx-action from 1.5.1 to 1.6.0
2021-10-26 21:25:03 +01:00
bump_version
0ccdc6fe11 Version 1.0.10 [skip ci] 2021-10-26 20:13:44 +00:00
Daniel Chesterton
ed38b86eb6 Change bump-version 2021-10-26 21:13:17 +01:00
Daniel Chesterton
9d3d44f36b Merge pull request #46 from dchesterton/dependabot/pip/paho-mqtt-1.6.1
Bump paho-mqtt from 1.5.1 to 1.6.1
2021-10-26 21:09:59 +01:00
dependabot[bot]
8cb2cc2327 Bump paho-mqtt from 1.5.1 to 1.6.1
Bumps [paho-mqtt](https://github.com/eclipse/paho.mqtt.python) from 1.5.1 to 1.6.1.
- [Release notes](https://github.com/eclipse/paho.mqtt.python/releases)
- [Changelog](https://github.com/eclipse/paho.mqtt.python/blob/master/ChangeLog.txt)
- [Commits](https://github.com/eclipse/paho.mqtt.python/compare/v1.5.1...v1.6.1)

---
updated-dependencies:
- dependency-name: paho-mqtt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-26 20:07:01 +00:00
Daniel Chesterton
4d4961e842 Merge pull request #45 from dchesterton/dependabot/github_actions/actions/checkout-2.3.5
[ci skip]: Bump actions/checkout from 2.3.4 to 2.3.5
2021-10-26 21:06:39 +01:00
Daniel Chesterton
cbb1995deb Merge pull request #42 from dchesterton/dependabot/pip/amcrest-1.9.3
Bump amcrest from 1.8.0 to 1.9.3
2021-10-26 21:06:20 +01:00
dependabot[bot]
781becf0d0 [ci skip]: Bump actions/checkout from 2.3.4 to 2.3.5
Bumps [actions/checkout](https://github.com/actions/checkout) from 2.3.4 to 2.3.5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2.3.4...v2.3.5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-18 12:06:55 +00:00
dependabot[bot]
8a1b1945ff Bump amcrest from 1.8.0 to 1.9.3
Bumps [amcrest](https://github.com/tchellomello/python-amcrest) from 1.8.0 to 1.9.3.
- [Release notes](https://github.com/tchellomello/python-amcrest/releases)
- [Commits](https://github.com/tchellomello/python-amcrest/compare/1.8.0...1.9.3)

---
updated-dependencies:
- dependency-name: amcrest
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-20 12:03:25 +00:00
dependabot[bot]
65623b45a2 [ci skip]: Bump docker/setup-buildx-action from 1.5.1 to 1.6.0
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 1.5.1 to 1.6.0.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v1.5.1...v1.6.0)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-06 12:05:58 +00:00
dependabot[bot]
4af6eac710 [ci skip]: Bump docker/build-push-action from 2.6.1 to 2.7.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 2.6.1 to 2.7.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v2.6.1...v2.7.0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-20 12:06:38 +00:00
bump_version
7bbe3cbcf4 Version 1.0.9 [skip ci] 2021-08-07 20:26:29 +00:00
Daniel Chesterton
8e96fc5408 Add ping functionality to stop app hanging 2021-08-07 21:26:07 +01:00
bump_version
0f8858cef4 Version 1.0.8 [skip ci] 2021-08-03 17:10:40 +00:00
Daniel Chesterton
e43cda557a Merge pull request #31 from dchesterton/dependabot/pip/amcrest-1.8.0
Bump amcrest from 1.7.2 to 1.8.0
2021-08-03 18:10:19 +01:00
dependabot[bot]
7dff1b3bf4 Bump amcrest from 1.7.2 to 1.8.0
Bumps [amcrest](https://github.com/tchellomello/python-amcrest) from 1.7.2 to 1.8.0.
- [Release notes](https://github.com/tchellomello/python-amcrest/releases)
- [Commits](https://github.com/tchellomello/python-amcrest/compare/1.7.2...1.8.0)

---
updated-dependencies:
- dependency-name: amcrest
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-02 12:03:54 +00:00
bump_version
28f2761899 Version 1.0.7 [skip ci] 2021-07-27 17:01:21 +00:00
Daniel Chesterton
17854bda0f Merge pull request #29 from bennycooly/feature/mqtt-tls
Add TLS support
2021-07-27 18:01:02 +01:00
Ben Fu
88323631ea Update README with TLS vars 2021-07-26 10:40:26 -05:00
Ben Fu
2a56eee4f5 Add TLS support 2021-07-26 09:51:18 -05:00
bump_version
caacaea81f Version 1.0.6 [skip ci] 2021-07-18 20:23:21 +00:00
Daniel Chesterton
d7e52c0843 Add STORAGE_POLL_INTERVAL environment variable 2021-07-18 21:23:01 +01:00
Daniel Chesterton
dc6b6c0149 Merge pull request #21 from dchesterton/dependabot/github_actions/docker/login-action-1.10.0
[ci skip]: Bump docker/login-action from 1.9.0 to 1.10.0
2021-07-18 21:12:33 +01:00
Daniel Chesterton
2687358810 Merge pull request #25 from dchesterton/dependabot/github_actions/docker/build-push-action-2.6.1
[ci skip]: Bump docker/build-push-action from 2.5.0 to 2.6.1
2021-07-18 21:12:26 +01:00
Daniel Chesterton
1a076c7660 Merge pull request #27 from dchesterton/dependabot/github_actions/docker/setup-buildx-action-1.5.1
[ci skip]: Bump docker/setup-buildx-action from 1.3.0 to 1.5.1
2021-07-18 21:12:18 +01:00
dependabot[bot]
3ee2a7bf64 [ci skip]: Bump docker/setup-buildx-action from 1.3.0 to 1.5.1
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 1.3.0 to 1.5.1.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v1.3.0...v1.5.1)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-12 12:06:09 +00:00
dependabot[bot]
441905c91f [ci skip]: Bump docker/build-push-action from 2.5.0 to 2.6.1
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 2.5.0 to 2.6.1.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v2.5.0...v2.6.1)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-02 12:06:12 +00:00
dependabot[bot]
a5a9383ad4 [ci skip]: Bump docker/login-action from 1.9.0 to 1.10.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 1.9.0 to 1.10.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v1.9.0...v1.10.0)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-23 12:05:14 +00:00
bump_version
61cda99e5f Version 1.0.5 [skip ci] 2021-05-28 21:52:33 +00:00
Daniel Chesterton
1b85a28e01 Fix workflow 2021-05-28 22:52:10 +01:00
bump_version
b6e6dc1eca Version 1.0.4 [skip ci] 2021-05-28 21:38:00 +00:00
Daniel Chesterton
2a683fefc8 Fix workflow 2021-05-28 22:37:36 +01:00
bump_version
a94b964f9f Version 1.0.3 [skip ci] 2021-05-28 10:45:07 +00:00
Daniel Chesterton
afb215850c Fix workflow 2021-05-28 11:44:43 +01:00
bump_version
c99b918e84 Version 1.0.2 [skip ci] 2021-05-28 10:20:20 +00:00
Daniel Chesterton
df45393453 Add config topic 2021-05-28 11:19:55 +01:00
bump_version
f5b655dbf1 Version 1.0.1 [skip ci] 2021-05-27 22:26:15 +00:00
6 changed files with 192 additions and 44 deletions

View File

@@ -12,27 +12,33 @@ jobs:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2.3.4 uses: actions/checkout@v2.4.0
- name: Bump version - name: Bump version
uses: remorses/bump-version@js uses: remorses/bump-version@js
id: version id: version
with: with:
version_file: ./VERSION version_file: ./VERSION
github_token: ${{ secrets.GITHUB_TOKEN }}
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout code
uses: actions/checkout@v2.4.0
with:
ref: main
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v1.2.0 uses: docker/setup-qemu-action@v1.2.0
with:
platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1.3.0 uses: docker/setup-buildx-action@v1.6.0
- name: Login to DockerHub - name: Login to DockerHub
uses: docker/login-action@v1.9.0 uses: docker/login-action@v1.12.0
with: with:
username: ${{ secrets.DOCKER_USERNAME }} username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }} password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push - name: Build and push
uses: docker/build-push-action@v2.5.0 uses: docker/build-push-action@v2.7.0
with: with:
context: .
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: | tags: |

View File

@@ -5,11 +5,13 @@ RUN mkdir /install
WORKDIR /install WORKDIR /install
COPY requirements.txt / COPY requirements.txt /
RUN pip install --prefix=/install -r /requirements.txt RUN pip install --no-warn-script-location --prefix=/install -r /requirements.txt
FROM base FROM base
STOPSIGNAL SIGINT
COPY --from=builder /install /usr/local COPY --from=builder /install /usr/local
COPY src /app COPY src /app
COPY VERSION /app
WORKDIR /app WORKDIR /app
CMD [ "python", "-u", "/app/amcrest2mqtt.py" ] CMD [ "python", "-u", "/app/amcrest2mqtt.py" ]

View File

@@ -14,8 +14,14 @@ It supports the following environment variables:
- `MQTT_HOST` (optional, default = 'localhost') - `MQTT_HOST` (optional, default = 'localhost')
- `MQTT_QOS` (optional, default = 0) - `MQTT_QOS` (optional, default = 0)
- `MQTT_PORT` (optional, default = 1883) - `MQTT_PORT` (optional, default = 1883)
- `MQTT_TLS_ENABLED` (required if using TLS) - set to `true` to enable
- `MQTT_TLS_CA_CERT` (required if using TLS) - path to the ca certs
- `MQTT_TLS_CERT` (required if using TLS) - path to the private cert
- `MQTT_TLS_KEY` (required if using TLS) - path to the private key
- `HOME_ASSISTANT` (optional, default = false) - `HOME_ASSISTANT` (optional, default = false)
- `HOME_ASSISTANT_PREFIX` (optional, default = 'homeassistant') - `HOME_ASSISTANT_PREFIX` (optional, default = 'homeassistant')
- `STORAGE_POLL_INTERVAL` (optional, default = 3600) - how often to fetch storage data (in seconds)
- `DEVICE_NAME` (optional) - override the default device name used in the Amcrest app
It exposes events to the following topics: It exposes events to the following topics:
@@ -23,6 +29,7 @@ It exposes events to the following topics:
- `amcrest2mqtt/[SERIAL_NUMBER]/doorbell` - doorbell status (if AD110 or AD410) - `amcrest2mqtt/[SERIAL_NUMBER]/doorbell` - doorbell status (if AD110 or AD410)
- `amcrest2mqtt/[SERIAL_NUMBER]/human` - human detection (if AD410) - `amcrest2mqtt/[SERIAL_NUMBER]/human` - human detection (if AD410)
- `amcrest2mqtt/[SERIAL_NUMBER]/motion` - motion events (if supported) - `amcrest2mqtt/[SERIAL_NUMBER]/motion` - motion events (if supported)
- `amcrest2mqtt/[SERIAL_NUMBER]/config` - device configuration information
## Device Support ## Device Support
@@ -57,7 +64,7 @@ services:
### Multiple Devices ### Multiple Devices
The app will not support multiple devices. You can run multiple instances of the app if you need to expose events for multiple devies. The app will not support multiple devices. You can run multiple instances of the app if you need to expose events for multiple devices.
### Non-Docker Environments ### Non-Docker Environments

View File

@@ -1 +1 @@
1.0.0 1.0.13

View File

@@ -1,3 +1,3 @@
amcrest==1.7.2 amcrest==1.9.3
paho-mqtt==1.5.1 paho-mqtt==1.6.1
python-slugify==5.0.2 python-slugify==5.0.2

View File

@@ -7,8 +7,8 @@ import sys
from json import dumps from json import dumps
import signal import signal
from threading import Timer from threading import Timer
import ssl
storage_sensors_interval = 60 # 1 hour
is_exiting = False is_exiting = False
mqtt_client = None mqtt_client = None
@@ -18,15 +18,34 @@ amcrest_port = int(os.getenv("AMCREST_PORT") or 80)
amcrest_username = os.getenv("AMCREST_USERNAME") or "admin" amcrest_username = os.getenv("AMCREST_USERNAME") or "admin"
amcrest_password = os.getenv("AMCREST_PASSWORD") amcrest_password = os.getenv("AMCREST_PASSWORD")
storage_poll_interval = int(os.getenv("STORAGE_POLL_INTERVAL") or 3600)
device_name = os.getenv("DEVICE_NAME")
mqtt_host = os.getenv("MQTT_HOST") or "localhost" mqtt_host = os.getenv("MQTT_HOST") or "localhost"
mqtt_qos = int(os.getenv("MQTT_QOS") or 0) mqtt_qos = int(os.getenv("MQTT_QOS") or 0)
mqtt_port = int(os.getenv("MQTT_PORT") or 1883) mqtt_port = int(os.getenv("MQTT_PORT") or 1883)
mqtt_username = os.getenv("MQTT_USERNAME") mqtt_username = os.getenv("MQTT_USERNAME")
mqtt_password = os.getenv("MQTT_PASSWORD") # can be None mqtt_password = os.getenv("MQTT_PASSWORD") # can be None
mqtt_tls_enabled = os.getenv("MQTT_TLS_ENABLED") == "true"
mqtt_tls_ca_cert = os.getenv("MQTT_TLS_CA_CERT")
mqtt_tls_cert = os.getenv("MQTT_TLS_CERT")
mqtt_tls_key = os.getenv("MQTT_TLS_KEY")
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"
def read_file(file_name):
with open(file_name, 'r') as file:
data = file.read().replace('\n', '')
return data
def read_version():
if os.path.isfile("./VERSION"):
return read_file("./VERSION")
return read_file("../VERSION")
# 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")
@@ -56,6 +75,8 @@ def on_mqtt_disconnect(client, userdata, rc):
def exit_gracefully(rc, skip_mqtt=False): def exit_gracefully(rc, skip_mqtt=False):
global topics, mqtt_client global topics, mqtt_client
log("Exiting app...")
if mqtt_client is not None and mqtt_client.is_connected() and skip_mqtt == False: if mqtt_client is not None and mqtt_client.is_connected() and skip_mqtt == False:
mqtt_publish(topics["status"], "offline", exit_on_error=False) mqtt_publish(topics["status"], "offline", exit_on_error=False)
mqtt_client.loop_stop(force=True) mqtt_client.loop_stop(force=True)
@@ -66,19 +87,31 @@ def exit_gracefully(rc, skip_mqtt=False):
os._exit(rc) os._exit(rc)
def refresh_storage_sensors(): def refresh_storage_sensors():
global camera, topics, storage_sensors_interval global camera, topics, storage_poll_interval
Timer(storage_sensors_interval, refresh_storage_sensors).start() Timer(storage_poll_interval, refresh_storage_sensors).start()
log("Fetching storage sensors...") log("Fetching storage sensors...")
try: try:
storage = camera.storage_all storage = camera.storage_all
mqtt_publish(topics["storage_used_percent"], str(storage["used_percent"])) mqtt_publish(topics["storage_used_percent"], str(storage["used_percent"]))
mqtt_publish(topics["storage_used"], str(storage["used"][0])) mqtt_publish(topics["storage_used"], to_gb(storage["used"]))
mqtt_publish(topics["storage_total"], str(storage["total"][0])) mqtt_publish(topics["storage_total"], to_gb(storage["total"]))
except AmcrestError as error: except AmcrestError as error:
log(f"Error fetching storage information {error}", level="WARNING") log(f"Error fetching storage information {error}", level="WARNING")
def to_gb(total):
return str(round(float(total[0]) / 1024 / 1024 / 1024, 2))
def ping_camera():
Timer(30, ping_camera).start()
response = os.system(f"ping -c1 -W100 {amcrest_host} >/dev/null 2>&1")
if response != 0:
log("Ping unsuccessful", level="ERROR")
exit_gracefully(1)
def signal_handler(sig, frame): def signal_handler(sig, frame):
# exit immediately upon receiving a second SIGINT # exit immediately upon receiving a second SIGINT
global is_exiting global is_exiting
@@ -102,6 +135,10 @@ if mqtt_username is None:
log("Please set the MQTT_USERNAME environment variable", level="ERROR") log("Please set the MQTT_USERNAME environment variable", level="ERROR")
sys.exit(1) sys.exit(1)
version = read_version()
log(f"App Version: {version}")
# Handle interruptions # Handle interruptions
signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGINT, signal_handler)
@@ -113,14 +150,25 @@ camera = AmcrestCamera(
# Fetch camera details # Fetch camera details
log("Fetching camera details...") log("Fetching camera details...")
device_type = camera.device_type.replace("type=", "").strip() try:
is_ad110 = device_type == "AD110" device_type = camera.device_type.replace("type=", "").strip()
is_ad410 = device_type == "AD410" is_ad110 = device_type == "AD110"
is_doorbell = is_ad110 or is_ad410 is_ad410 = device_type == "AD410"
serial_number = camera.serial_number.strip() is_doorbell = is_ad110 or is_ad410
sw_version = camera.software_information[0].replace("version=", "").strip() serial_number = camera.serial_number
device_name = camera.machine_name.replace("name=", "").strip()
device_slug = slugify(device_name, separator="_") if not isinstance(serial_number, str):
log(f"Error fetching serial number", level="ERROR")
exit_gracefully(1)
sw_version = camera.software_information[0].replace("version=", "").strip()
if not device_name:
device_name = camera.machine_name.replace("name=", "").strip()
device_slug = slugify(device_name, separator="_")
except AmcrestError as error:
log(f"Error fetching camera details", level="ERROR")
exit_gracefully(1)
log(f"Device type: {device_type}") log(f"Device type: {device_type}")
log(f"Serial number: {serial_number}") log(f"Serial number: {serial_number}")
@@ -129,6 +177,7 @@ log(f"Device name: {device_name}")
# MQTT topics # MQTT topics
topics = { topics = {
"config": f"amcrest2mqtt/{serial_number}/config",
"status": f"amcrest2mqtt/{serial_number}/status", "status": f"amcrest2mqtt/{serial_number}/status",
"event": f"amcrest2mqtt/{serial_number}/event", "event": f"amcrest2mqtt/{serial_number}/event",
"motion": f"amcrest2mqtt/{serial_number}/motion", "motion": f"amcrest2mqtt/{serial_number}/motion",
@@ -144,6 +193,9 @@ topics = {
"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",
"storage_total": f"{home_assistant_prefix}/sensor/amcrest2mqtt-{serial_number}/{device_slug}_storage_total/config", "storage_total": f"{home_assistant_prefix}/sensor/amcrest2mqtt-{serial_number}/{device_slug}_storage_total/config",
"version": f"{home_assistant_prefix}/sensor/amcrest2mqtt-{serial_number}/{device_slug}_version/config",
"host": f"{home_assistant_prefix}/sensor/amcrest2mqtt-{serial_number}/{device_slug}_host/config",
"serial_number": f"{home_assistant_prefix}/sensor/amcrest2mqtt-{serial_number}/{device_slug}_serial_number/config",
}, },
} }
@@ -152,8 +204,27 @@ mqtt_client = mqtt.Client(
client_id=f"amcrest2mqtt_{serial_number}", clean_session=False client_id=f"amcrest2mqtt_{serial_number}", clean_session=False
) )
mqtt_client.on_disconnect = on_mqtt_disconnect mqtt_client.on_disconnect = on_mqtt_disconnect
mqtt_client.username_pw_set(mqtt_username, password=mqtt_password)
mqtt_client.will_set(topics["status"], payload="offline", qos=mqtt_qos, retain=True) mqtt_client.will_set(topics["status"], payload="offline", qos=mqtt_qos, retain=True)
if mqtt_tls_enabled:
log(f"Setting up MQTT for TLS")
if mqtt_tls_ca_cert is None:
log("Missing var: MQTT_TLS_CA_CERT", level="ERROR")
sys.exit(1)
if mqtt_tls_cert is None:
log("Missing var: MQTT_TLS_CERT", level="ERROR")
sys.exit(1)
if mqtt_tls_cert is None:
log("Missing var: MQTT_TLS_KEY", level="ERROR")
sys.exit(1)
mqtt_client.tls_set(
ca_certs=mqtt_tls_ca_cert,
certfile=mqtt_tls_cert,
keyfile=mqtt_tls_key,
cert_reqs=ssl.CERT_REQUIRED,
tls_version=ssl.PROTOCOL_TLS,
)
else:
mqtt_client.username_pw_set(mqtt_username, password=mqtt_password)
try: try:
mqtt_client.connect(mqtt_host, port=mqtt_port) mqtt_client.connect(mqtt_host, port=mqtt_port)
@@ -187,6 +258,7 @@ if home_assistant:
"state_topic": topics["doorbell"], "state_topic": topics["doorbell"],
"payload_on": "on", "payload_on": "on",
"payload_off": "off", "payload_off": "off",
"icon": "mdi:doorbell",
"name": f"{device_name} Doorbell", "name": f"{device_name} Doorbell",
"unique_id": f"{serial_number}.doorbell", "unique_id": f"{serial_number}.doorbell",
}, },
@@ -223,52 +295,113 @@ if home_assistant:
) )
mqtt_publish( mqtt_publish(
topics["home_assistant"]["storage_used_percent"], topics["home_assistant"]["version"],
base_config base_config
| { | {
"state_topic": topics["storage_used_percent"], "state_topic": topics["config"],
"unit_of_measurement": "%", "value_template": "{{ value_json.sw_version }}",
"icon": "mdi:micro-sd", "icon": "mdi:package-up",
"name": f"{device_name} Storage Used %", "name": f"{device_name} Version",
"unique_id": f"{serial_number}.storage_used_percent", "unique_id": f"{serial_number}.version",
"entity_category": "diagnostic",
"enabled_by_default": False
}, },
json=True, json=True,
) )
mqtt_publish( mqtt_publish(
topics["home_assistant"]["storage_used"], topics["home_assistant"]["serial_number"],
base_config base_config
| { | {
"state_topic": topics["storage_used"], "state_topic": topics["config"],
"unit_of_measurement": "GB", "value_template": "{{ value_json.serial_number }}",
"icon": "mdi:micro-sd", "icon": "mdi:alphabetical-variant",
"name": f"{device_name} Storage Used", "name": f"{device_name} Serial Number",
"unique_id": f"{serial_number}.storage_used", "unique_id": f"{serial_number}.serial_number",
"entity_category": "diagnostic",
"enabled_by_default": False
}, },
json=True, json=True,
) )
mqtt_publish( mqtt_publish(
topics["home_assistant"]["storage_total"], topics["home_assistant"]["host"],
base_config base_config
| { | {
"state_topic": topics["storage_total"], "state_topic": topics["config"],
"unit_of_measurement": "GB", "value_template": "{{ value_json.host }}",
"icon": "mdi:micro-sd", "icon": "mdi:ip-network",
"name": f"{device_name} Storage Total", "name": f"{device_name} Host",
"unique_id": f"{serial_number}.storage_total", "unique_id": f"{serial_number}.host",
"entity_category": "diagnostic",
"enabled_by_default": False
}, },
json=True, json=True,
) )
if storage_poll_interval > 0:
mqtt_publish(
topics["home_assistant"]["storage_used_percent"],
base_config
| {
"state_topic": topics["storage_used_percent"],
"unit_of_measurement": "%",
"icon": "mdi:micro-sd",
"name": f"{device_name} Storage Used %",
"unique_id": f"{serial_number}.storage_used_percent",
"entity_category": "diagnostic",
},
json=True,
)
mqtt_publish(
topics["home_assistant"]["storage_used"],
base_config
| {
"state_topic": topics["storage_used"],
"unit_of_measurement": "GB",
"icon": "mdi:micro-sd",
"name": f"{device_name} Storage Used",
"unique_id": f"{serial_number}.storage_used",
"entity_category": "diagnostic",
},
json=True,
)
mqtt_publish(
topics["home_assistant"]["storage_total"],
base_config
| {
"state_topic": topics["storage_total"],
"unit_of_measurement": "GB",
"icon": "mdi:micro-sd",
"name": f"{device_name} Storage Total",
"unique_id": f"{serial_number}.storage_total",
"entity_category": "diagnostic",
},
json=True,
)
# Main loop # Main loop
mqtt_publish(topics["status"], "online") mqtt_publish(topics["status"], "online")
refresh_storage_sensors() mqtt_publish(topics["config"], {
"version": version,
"device_type": device_type,
"device_name": device_name,
"sw_version": sw_version,
"serial_number": serial_number,
"host": amcrest_host,
}, json=True)
if storage_poll_interval > 0:
refresh_storage_sensors()
ping_camera()
log("Listening for events...") 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, timeout_cmd=(10.00, 3600)):
if (is_ad110 and code == "ProfileAlarmTransmit") or (code == "VideoMotion" and not is_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)