You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
amcrest2mqtt/app.py

138 lines
5.5 KiB
Python

# This software is licensed under the MIT License, which allows you to use,
# copy, modify, merge, publish, distribute, and sell copies of the software,
# with the requirement to include the original copyright notice and this
# permission notice in all copies or substantial portions of the software.
#
# The software is provided 'as is', without any warranty.
import asyncio
import argparse
from amcrest_mqtt import AmcrestMqtt
import logging
import os
import sys
import time
from util import *
import yaml
# Let's go!
version = read_version()
# Cmd-line args
argparser = argparse.ArgumentParser()
argparser.add_argument(
'-c',
'--config',
required=False,
help='Directory holding config.yaml or full path to config file',
)
args = argparser.parse_args()
# Setup config from yaml file or env
configpath = args.config or '/config'
try:
if not configpath.endswith('.yaml'):
if not configpath.endswith('/'):
configpath += '/'
configfile = configpath + 'config.yaml'
with open(configfile) as file:
config = yaml.safe_load(file)
config['config_path'] = configpath
config['config_from'] = 'file'
except:
config = {
'mqtt': {
'host': os.getenv('MQTT_HOST') or 'localhost',
'qos': int(os.getenv('MQTT_QOS') or 0),
'port': int(os.getenv('MQTT_PORT') or 1883),
'username': os.getenv('MQTT_USERNAME'),
'password': os.getenv('MQTT_PASSWORD'), # can be None
'tls_enabled': os.getenv('MQTT_TLS_ENABLED') == 'true',
'tls_ca_cert': os.getenv('MQTT_TLS_CA_CERT'),
'tls_cert': os.getenv('MQTT_TLS_CERT'),
'tls_key': os.getenv('MQTT_TLS_KEY'),
'prefix': os.getenv('MQTT_PREFIX') or 'amcrest2mqtt',
'homeassistant': os.getenv('MQTT_HOMEASSISTANT') == True,
'discovery_prefix': os.getenv('MQTT_DISCOVERY_PREFIX') or 'homeassistant',
},
'amcrest': {
'hosts': os.getenv("AMCREST_HOSTS"),
'names': os.getenv("AMCREST_NAMES"),
'port': int(os.getenv("AMCREST_PORT") or 80),
'username': os.getenv("AMCREST_USERNAME") or "admin",
'password': os.getenv("AMCREST_PASSWORD"),
'storage_update_interval': int(os.getenv("STORAGE_UPDATE_INTERVAL") or 900),
'snapshot_update_interval': int(os.getenv("SNAPSHOT_UPDATE_INTERVAL") or 300),
'webrtc': {
'host': os.getenv("AMCREST_WEBRTC_HOST"),
'port': int(os.getenv("AMCREST_WEBRTC_PORT") or 1984),
'link': os.getenv("AMCREST_WEBRTC_LINK") or 'stream.html',
'sources': os.getenv("AMCREST_WEBRTC_SOURCES"),
},
},
'debug': True if os.getenv('DEBUG') else False,
'hide_ts': True if os.getenv('HIDE_TS') else False,
'timezone': os.getenv('TZ'),
'config_from': 'env',
}
config['version'] = version
config['configpath'] = os.path.dirname(configpath)
# defaults
if 'username' not in config['mqtt']: config['mqtt']['username'] = ''
if 'password' not in config['mqtt']: config['mqtt']['password'] = ''
if 'qos' not in config['mqtt']: config['mqtt']['qos'] = 0
if 'timezone' not in config: config['timezone'] = 'UTC'
if 'debug' not in config: config['debug'] = os.getenv('DEBUG') or False
if 'hide_ts' not in config: config['hide_ts'] = os.getenv('HIDE_TS') or False
# init logging, based on config settings
logging.basicConfig(
format = '%(asctime)s.%(msecs)03d [%(levelname)s] %(name)s: %(message)s' if config['hide_ts'] == False else '[%(levelname)s] %(name)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
level=logging.INFO if config['debug'] == False else logging.DEBUG
)
logger = logging.getLogger(__name__)
logger.info(f'Starting: amcrest2mqtt v{version}')
logger.info(f'Config loaded from {config["config_from"]}')
# Check for required config properties
if config['amcrest']['hosts'] is None:
logger.error('Missing env var: AMCREST_HOSTS or amcrest.hosts in config')
exit(1)
config['amcrest']['host_count'] = len(config['amcrest']['hosts'])
if config['amcrest']['names'] is None:
logger.error('Missing env var: AMCREST_NAMES or amcrest.names in config')
exit(1)
config['amcrest']['name_count'] = len(config['amcrest']['names'])
if config['amcrest']['host_count'] != config['amcrest']['name_count']:
logger.error('The AMCREST_HOSTS and AMCREST_NAMES must have the same number of space-delimited hosts/names')
exit(1)
logger.info(f'Found {config["amcrest"]["host_count"]} host(s) defined to monitor')
if 'webrtc' in config['amcrest']:
webrtc = config['amcrest']['webrtc']
if 'host' not in webrtc:
logger.error('Missing HOST in webrtc config')
exit(1)
if 'sources' not in webrtc:
logger.error('Missing SOURCES in webrtc config')
exit(1)
config['amcrest']['webrtc_sources_count'] = len(config['amcrest']['webrtc']['sources'])
if config['amcrest']['host_count'] != config['amcrest']['webrtc_sources_count']:
logger.error('The AMCREST_HOSTS and AMCREST_WEBRTC_SOURCES must have the same number of space-delimited hosts/names')
exit(1)
if 'port' not in webrtc: webrtc['port'] = 1984
if 'link' not in webrtc: webrtc['link'] = 'stream.html'
if config['amcrest']['password'] is None:
logger.error('Please set the AMCREST_PASSWORD environment variable')
exit(1)
logger.debug("DEBUG logging is ON")
# Go!
with AmcrestMqtt(config) as mqtt:
asyncio.run(mqtt.main_loop())