From f78b2c48a7e6a1f570327f28974ae345e97d0971 Mon Sep 17 00:00:00 2001 From: Blake Blackshear Date: Thu, 3 Dec 2020 08:00:23 -0600 Subject: [PATCH] add zeroconf discovery --- docker/Dockerfile.base | 1 + frigate/app.py | 2 ++ frigate/zeroconf.py | 58 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 frigate/zeroconf.py diff --git a/docker/Dockerfile.base b/docker/Dockerfile.base index 4b43c46a1..372f45953 100644 --- a/docker/Dockerfile.base +++ b/docker/Dockerfile.base @@ -30,6 +30,7 @@ RUN apt-get -qq update \ RUN pip3 install \ peewee \ + zeroconf \ voluptuous COPY nginx/nginx.conf /etc/nginx/nginx.conf diff --git a/frigate/app.py b/frigate/app.py index a773b9067..a73823d61 100644 --- a/frigate/app.py +++ b/frigate/app.py @@ -20,6 +20,7 @@ from frigate.object_processing import TrackedObjectProcessor from frigate.record import RecordingMaintainer from frigate.video import capture_camera, track_camera from frigate.watchdog import FrigateWatchdog +from frigate.zeroconf import broadcast_zeroconf logger = logging.getLogger(__name__) @@ -152,6 +153,7 @@ class FrigateApp(): self.start_event_cleanup() self.start_recording_maintainer() self.start_watchdog() + self.zeroconf = broadcast_zeroconf(self.config.mqtt.client_id) self.flask_app.run(host='127.0.0.1', port=5001, debug=False) self.stop() diff --git a/frigate/zeroconf.py b/frigate/zeroconf.py new file mode 100644 index 000000000..4e8f0f5f0 --- /dev/null +++ b/frigate/zeroconf.py @@ -0,0 +1,58 @@ +import logging +import socket + +from zeroconf import ( + ServiceInfo, + NonUniqueNameException, + InterfaceChoice, + IPVersion, + Zeroconf, +) + +logger = logging.getLogger(__name__) + +ZEROCONF_TYPE = "_frigate._tcp.local." + +# Taken from: http://stackoverflow.com/a/11735897 +def get_local_ip() -> str: + """Try to determine the local IP address of the machine.""" + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + + # Use Google Public DNS server to determine own IP + sock.connect(("8.8.8.8", 80)) + + return sock.getsockname()[0] # type: ignore + except OSError: + try: + return socket.gethostbyname(socket.gethostname()) + except socket.gaierror: + return "127.0.0.1" + finally: + sock.close() + +def broadcast_zeroconf(frigate_id): + zeroconf = Zeroconf(interfaces=InterfaceChoice.Default, ip_version=IPVersion.V4Only) + + host_ip = get_local_ip() + + try: + host_ip_pton = socket.inet_pton(socket.AF_INET, host_ip) + except OSError: + host_ip_pton = socket.inet_pton(socket.AF_INET6, host_ip) + + info = ServiceInfo( + ZEROCONF_TYPE, + name=f"{frigate_id}.{ZEROCONF_TYPE}", + addresses=[host_ip_pton], + port=5000, + ) + + logger.info("Starting Zeroconf broadcast") + try: + zeroconf.register_service(info) + except NonUniqueNameException: + logger.error( + "Frigate instance with identical name present in the local network" + ) + return zeroconf \ No newline at end of file