mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-02 17:25:22 +03:00
Merge branch 'release-0.11.0' of https://github.com/blakeblackshear/frigate into reorder-hide-cameras
This commit is contained in:
commit
56e4b0ee4b
2
.github/workflows/pull_request.yml
vendored
2
.github/workflows/pull_request.yml
vendored
@ -56,5 +56,7 @@ jobs:
|
|||||||
uses: docker/setup-buildx-action@v1
|
uses: docker/setup-buildx-action@v1
|
||||||
- name: Build
|
- name: Build
|
||||||
run: make
|
run: make
|
||||||
|
- name: Run mypy
|
||||||
|
run: docker run --rm --entrypoint=python3 frigate:latest -u -m mypy --config-file frigate/mypy.ini frigate
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: docker run --rm --entrypoint=python3 frigate:latest -u -m unittest
|
run: docker run --rm --entrypoint=python3 frigate:latest -u -m unittest
|
||||||
14
Makefile
14
Makefile
@ -14,16 +14,8 @@ frigate: version
|
|||||||
frigate_push: version
|
frigate_push: version
|
||||||
docker buildx build --push --platform linux/arm64/v8,linux/amd64 --tag blakeblackshear/frigate:0.11.0-$(COMMIT_HASH) --file docker/Dockerfile .
|
docker buildx build --push --platform linux/arm64/v8,linux/amd64 --tag blakeblackshear/frigate:0.11.0-$(COMMIT_HASH) --file docker/Dockerfile .
|
||||||
|
|
||||||
run_tests:
|
run_tests: frigate
|
||||||
# PLATFORM: linux/arm64/v8 linux/amd64 or linux/arm/v7
|
docker run --rm --entrypoint=python3 frigate:latest -u -m unittest
|
||||||
# ARCH: aarch64 amd64 or armv7
|
docker run --rm --entrypoint=python3 frigate:latest -u -m mypy --config-file frigate/mypy.ini frigate
|
||||||
@cat docker/Dockerfile.base docker/Dockerfile.$(ARCH) > docker/Dockerfile.test
|
|
||||||
@sed -i "s/FROM frigate-web as web/#/g" docker/Dockerfile.test
|
|
||||||
@sed -i "s/COPY --from=web \/opt\/frigate\/build web\//#/g" docker/Dockerfile.test
|
|
||||||
@sed -i "s/FROM frigate-base/#/g" docker/Dockerfile.test
|
|
||||||
@echo "" >> docker/Dockerfile.test
|
|
||||||
@echo "RUN python3 -m unittest" >> docker/Dockerfile.test
|
|
||||||
@docker buildx build --platform=$(PLATFORM) --tag frigate-base --build-arg NGINX_VERSION=1.0.2 --build-arg FFMPEG_VERSION=1.0.0 --build-arg ARCH=$(ARCH) --build-arg WHEELS_VERSION=1.0.3 --file docker/Dockerfile.test .
|
|
||||||
@rm docker/Dockerfile.test
|
|
||||||
|
|
||||||
.PHONY: run_tests
|
.PHONY: run_tests
|
||||||
|
|||||||
@ -12,9 +12,9 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: docker/Dockerfile.dev
|
dockerfile: docker/Dockerfile.dev
|
||||||
devices:
|
#devices:
|
||||||
- /dev/bus/usb:/dev/bus/usb
|
# - /dev/bus/usb:/dev/bus/usb
|
||||||
- /dev/dri:/dev/dri # for intel hwaccel, needs to be updated for your hardware
|
# - /dev/dri:/dev/dri # for intel hwaccel, needs to be updated for your hardware
|
||||||
volumes:
|
volumes:
|
||||||
- /etc/localtime:/etc/localtime:ro
|
- /etc/localtime:/etc/localtime:ro
|
||||||
- .:/lab/frigate:cached
|
- .:/lab/frigate:cached
|
||||||
|
|||||||
@ -110,6 +110,7 @@ environment_vars:
|
|||||||
EXAMPLE_VAR: value
|
EXAMPLE_VAR: value
|
||||||
|
|
||||||
# Optional: birdseye configuration
|
# Optional: birdseye configuration
|
||||||
|
# NOTE: Can (enabled, mode) be overridden at the camera level
|
||||||
birdseye:
|
birdseye:
|
||||||
# Optional: Enable birdseye view (default: shown below)
|
# Optional: Enable birdseye view (default: shown below)
|
||||||
enabled: True
|
enabled: True
|
||||||
|
|||||||
@ -324,6 +324,13 @@ class BirdseyeConfig(FrigateBaseModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class BirdseyeCameraConfig(FrigateBaseModel):
|
||||||
|
enabled: bool = Field(default=True, title="Enable birdseye view for camera.")
|
||||||
|
mode: BirdseyeModeEnum = Field(
|
||||||
|
default=BirdseyeModeEnum.objects, title="Tracking mode for camera."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
FFMPEG_GLOBAL_ARGS_DEFAULT = ["-hide_banner", "-loglevel", "warning"]
|
FFMPEG_GLOBAL_ARGS_DEFAULT = ["-hide_banner", "-loglevel", "warning"]
|
||||||
FFMPEG_INPUT_ARGS_DEFAULT = [
|
FFMPEG_INPUT_ARGS_DEFAULT = [
|
||||||
"-avoid_negative_ts",
|
"-avoid_negative_ts",
|
||||||
@ -547,6 +554,9 @@ class CameraConfig(FrigateBaseModel):
|
|||||||
ui: CameraUiConfig = Field(
|
ui: CameraUiConfig = Field(
|
||||||
default_factory=CameraUiConfig, title="Camera UI Modifications."
|
default_factory=CameraUiConfig, title="Camera UI Modifications."
|
||||||
)
|
)
|
||||||
|
birdseye: BirdseyeCameraConfig = Field(
|
||||||
|
default_factory=BirdseyeCameraConfig, title="Birdseye camera configuration."
|
||||||
|
)
|
||||||
timestamp_style: TimestampStyleConfig = Field(
|
timestamp_style: TimestampStyleConfig = Field(
|
||||||
default_factory=TimestampStyleConfig, title="Timestamp style configuration."
|
default_factory=TimestampStyleConfig, title="Timestamp style configuration."
|
||||||
)
|
)
|
||||||
@ -783,6 +793,7 @@ class FrigateConfig(FrigateBaseModel):
|
|||||||
# Global config to propegate down to camera level
|
# Global config to propegate down to camera level
|
||||||
global_config = config.dict(
|
global_config = config.dict(
|
||||||
include={
|
include={
|
||||||
|
"birdseye": ...,
|
||||||
"record": ...,
|
"record": ...,
|
||||||
"snapshots": ...,
|
"snapshots": ...,
|
||||||
"live": ...,
|
"live": ...,
|
||||||
|
|||||||
@ -4,13 +4,14 @@ import threading
|
|||||||
import os
|
import os
|
||||||
import signal
|
import signal
|
||||||
import queue
|
import queue
|
||||||
import multiprocessing as mp
|
from multiprocessing.queues import Queue
|
||||||
from logging import handlers
|
from logging import handlers
|
||||||
from setproctitle import setproctitle
|
from setproctitle import setproctitle
|
||||||
|
from typing import Deque
|
||||||
from collections import deque
|
from collections import deque
|
||||||
|
|
||||||
|
|
||||||
def listener_configurer():
|
def listener_configurer() -> None:
|
||||||
root = logging.getLogger()
|
root = logging.getLogger()
|
||||||
console_handler = logging.StreamHandler()
|
console_handler = logging.StreamHandler()
|
||||||
formatter = logging.Formatter(
|
formatter = logging.Formatter(
|
||||||
@ -21,14 +22,14 @@ def listener_configurer():
|
|||||||
root.setLevel(logging.INFO)
|
root.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
def root_configurer(queue):
|
def root_configurer(queue: Queue) -> None:
|
||||||
h = handlers.QueueHandler(queue)
|
h = handlers.QueueHandler(queue)
|
||||||
root = logging.getLogger()
|
root = logging.getLogger()
|
||||||
root.addHandler(h)
|
root.addHandler(h)
|
||||||
root.setLevel(logging.INFO)
|
root.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
def log_process(log_queue):
|
def log_process(log_queue: Queue) -> None:
|
||||||
threading.current_thread().name = f"logger"
|
threading.current_thread().name = f"logger"
|
||||||
setproctitle("frigate.logger")
|
setproctitle("frigate.logger")
|
||||||
listener_configurer()
|
listener_configurer()
|
||||||
@ -43,34 +44,32 @@ def log_process(log_queue):
|
|||||||
|
|
||||||
# based on https://codereview.stackexchange.com/a/17959
|
# based on https://codereview.stackexchange.com/a/17959
|
||||||
class LogPipe(threading.Thread):
|
class LogPipe(threading.Thread):
|
||||||
def __init__(self, log_name, level):
|
def __init__(self, log_name: str):
|
||||||
"""Setup the object with a logger and a loglevel
|
"""Setup the object with a logger and start the thread"""
|
||||||
and start the thread
|
|
||||||
"""
|
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
self.daemon = False
|
self.daemon = False
|
||||||
self.logger = logging.getLogger(log_name)
|
self.logger = logging.getLogger(log_name)
|
||||||
self.level = level
|
self.level = logging.ERROR
|
||||||
self.deque = deque(maxlen=100)
|
self.deque: Deque[str] = deque(maxlen=100)
|
||||||
self.fdRead, self.fdWrite = os.pipe()
|
self.fdRead, self.fdWrite = os.pipe()
|
||||||
self.pipeReader = os.fdopen(self.fdRead)
|
self.pipeReader = os.fdopen(self.fdRead)
|
||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
def fileno(self):
|
def fileno(self) -> int:
|
||||||
"""Return the write file descriptor of the pipe"""
|
"""Return the write file descriptor of the pipe"""
|
||||||
return self.fdWrite
|
return self.fdWrite
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> None:
|
||||||
"""Run the thread, logging everything."""
|
"""Run the thread, logging everything."""
|
||||||
for line in iter(self.pipeReader.readline, ""):
|
for line in iter(self.pipeReader.readline, ""):
|
||||||
self.deque.append(line.strip("\n"))
|
self.deque.append(line.strip("\n"))
|
||||||
|
|
||||||
self.pipeReader.close()
|
self.pipeReader.close()
|
||||||
|
|
||||||
def dump(self):
|
def dump(self) -> None:
|
||||||
while len(self.deque) > 0:
|
while len(self.deque) > 0:
|
||||||
self.logger.log(self.level, self.deque.popleft())
|
self.logger.log(self.level, self.deque.popleft())
|
||||||
|
|
||||||
def close(self):
|
def close(self) -> None:
|
||||||
"""Close the write end of the pipe."""
|
"""Close the write end of the pipe."""
|
||||||
os.close(self.fdWrite)
|
os.close(self.fdWrite)
|
||||||
|
|||||||
40
frigate/mypy.ini
Normal file
40
frigate/mypy.ini
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
[mypy]
|
||||||
|
python_version = 3.9
|
||||||
|
show_error_codes = true
|
||||||
|
follow_imports = silent
|
||||||
|
ignore_missing_imports = true
|
||||||
|
strict_equality = true
|
||||||
|
warn_incomplete_stub = true
|
||||||
|
warn_redundant_casts = true
|
||||||
|
warn_unused_configs = true
|
||||||
|
warn_unused_ignores = true
|
||||||
|
enable_error_code = ignore-without-code
|
||||||
|
check_untyped_defs = true
|
||||||
|
disallow_incomplete_defs = true
|
||||||
|
disallow_subclassing_any = true
|
||||||
|
disallow_untyped_calls = true
|
||||||
|
disallow_untyped_decorators = true
|
||||||
|
disallow_untyped_defs = true
|
||||||
|
no_implicit_optional = true
|
||||||
|
warn_return_any = true
|
||||||
|
warn_unreachable = true
|
||||||
|
no_implicit_reexport = true
|
||||||
|
|
||||||
|
[mypy-frigate.*]
|
||||||
|
ignore_errors = true
|
||||||
|
|
||||||
|
[mypy-frigate.const]
|
||||||
|
ignore_errors = false
|
||||||
|
|
||||||
|
[mypy-frigate.log]
|
||||||
|
ignore_errors = false
|
||||||
|
|
||||||
|
[mypy-frigate.version]
|
||||||
|
ignore_errors = false
|
||||||
|
|
||||||
|
[mypy-frigate.watchdog]
|
||||||
|
ignore_errors = false
|
||||||
|
disallow_untyped_calls = false
|
||||||
|
|
||||||
|
[mypy-frigate.zeroconf]
|
||||||
|
ignore_errors = false
|
||||||
@ -190,14 +190,14 @@ class BirdsEyeFrameManager:
|
|||||||
channel_dims,
|
channel_dims,
|
||||||
)
|
)
|
||||||
|
|
||||||
def camera_active(self, object_box_count, motion_box_count):
|
def camera_active(self, mode, object_box_count, motion_box_count):
|
||||||
if self.mode == BirdseyeModeEnum.continuous:
|
if mode == BirdseyeModeEnum.continuous:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if self.mode == BirdseyeModeEnum.motion and motion_box_count > 0:
|
if mode == BirdseyeModeEnum.motion and motion_box_count > 0:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if self.mode == BirdseyeModeEnum.objects and object_box_count > 0:
|
if mode == BirdseyeModeEnum.objects and object_box_count > 0:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def update_frame(self):
|
def update_frame(self):
|
||||||
@ -311,10 +311,14 @@ class BirdsEyeFrameManager:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def update(self, camera, object_count, motion_count, frame_time, frame) -> bool:
|
def update(self, camera, object_count, motion_count, frame_time, frame) -> bool:
|
||||||
|
# don't process if birdseye is disabled for this camera
|
||||||
|
camera_config = self.config.cameras[camera].birdseye
|
||||||
|
if not camera_config.enabled:
|
||||||
|
return False
|
||||||
|
|
||||||
# update the last active frame for the camera
|
# update the last active frame for the camera
|
||||||
self.cameras[camera]["current_frame"] = frame_time
|
self.cameras[camera]["current_frame"] = frame_time
|
||||||
if self.camera_active(object_count, motion_count):
|
if self.camera_active(camera_config.mode, object_count, motion_count):
|
||||||
self.cameras[camera]["last_active_frame"] = frame_time
|
self.cameras[camera]["last_active_frame"] = frame_time
|
||||||
|
|
||||||
now = datetime.datetime.now().timestamp()
|
now = datetime.datetime.now().timestamp()
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import unittest
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
from pydantic import ValidationError
|
from pydantic import ValidationError
|
||||||
from frigate.config import (
|
from frigate.config import (
|
||||||
|
BirdseyeModeEnum,
|
||||||
FrigateConfig,
|
FrigateConfig,
|
||||||
DetectorTypeEnum,
|
DetectorTypeEnum,
|
||||||
)
|
)
|
||||||
@ -80,6 +81,62 @@ class TestConfig(unittest.TestCase):
|
|||||||
runtime_config = frigate_config.runtime_config
|
runtime_config = frigate_config.runtime_config
|
||||||
assert "dog" in runtime_config.cameras["back"].objects.track
|
assert "dog" in runtime_config.cameras["back"].objects.track
|
||||||
|
|
||||||
|
def test_override_birdseye(self):
|
||||||
|
config = {
|
||||||
|
"mqtt": {"host": "mqtt"},
|
||||||
|
"birdseye": { "enabled": True, "mode": "continuous" },
|
||||||
|
"cameras": {
|
||||||
|
"back": {
|
||||||
|
"ffmpeg": {
|
||||||
|
"inputs": [
|
||||||
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"detect": {
|
||||||
|
"height": 1080,
|
||||||
|
"width": 1920,
|
||||||
|
"fps": 5,
|
||||||
|
},
|
||||||
|
"birdseye": {
|
||||||
|
"enabled": False,
|
||||||
|
"mode": "motion"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
frigate_config = FrigateConfig(**config)
|
||||||
|
assert config == frigate_config.dict(exclude_unset=True)
|
||||||
|
|
||||||
|
runtime_config = frigate_config.runtime_config
|
||||||
|
assert not runtime_config.cameras["back"].birdseye.enabled
|
||||||
|
assert runtime_config.cameras["back"].birdseye.mode is BirdseyeModeEnum.motion
|
||||||
|
|
||||||
|
def test_inherit_birdseye(self):
|
||||||
|
config = {
|
||||||
|
"mqtt": {"host": "mqtt"},
|
||||||
|
"birdseye": { "enabled": True, "mode": "continuous" },
|
||||||
|
"cameras": {
|
||||||
|
"back": {
|
||||||
|
"ffmpeg": {
|
||||||
|
"inputs": [
|
||||||
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"detect": {
|
||||||
|
"height": 1080,
|
||||||
|
"width": 1920,
|
||||||
|
"fps": 5,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
frigate_config = FrigateConfig(**config)
|
||||||
|
assert config == frigate_config.dict(exclude_unset=True)
|
||||||
|
|
||||||
|
runtime_config = frigate_config.runtime_config
|
||||||
|
assert runtime_config.cameras["back"].birdseye.enabled
|
||||||
|
assert runtime_config.cameras["back"].birdseye.mode is BirdseyeModeEnum.continuous
|
||||||
|
|
||||||
def test_override_tracked_objects(self):
|
def test_override_tracked_objects(self):
|
||||||
config = {
|
config = {
|
||||||
"mqtt": {"host": "mqtt"},
|
"mqtt": {"host": "mqtt"},
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import collections
|
|
||||||
import copy
|
import copy
|
||||||
import datetime
|
import datetime
|
||||||
import hashlib
|
import hashlib
|
||||||
@ -11,6 +10,7 @@ import threading
|
|||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
|
from collections.abc import Mapping
|
||||||
from multiprocessing import shared_memory
|
from multiprocessing import shared_memory
|
||||||
from typing import AnyStr
|
from typing import AnyStr
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ def deep_merge(dct1: dict, dct2: dict, override=False, merge_lists=False) -> dic
|
|||||||
for k, v2 in dct2.items():
|
for k, v2 in dct2.items():
|
||||||
if k in merged:
|
if k in merged:
|
||||||
v1 = merged[k]
|
v1 = merged[k]
|
||||||
if isinstance(v1, dict) and isinstance(v2, collections.Mapping):
|
if isinstance(v1, dict) and isinstance(v2, Mapping):
|
||||||
merged[k] = deep_merge(v1, v2, override)
|
merged[k] = deep_merge(v1, v2, override)
|
||||||
elif isinstance(v1, list) and isinstance(v2, list):
|
elif isinstance(v1, list) and isinstance(v2, list):
|
||||||
if merge_lists:
|
if merge_lists:
|
||||||
|
|||||||
@ -203,7 +203,7 @@ class CameraWatchdog(threading.Thread):
|
|||||||
self.config = config
|
self.config = config
|
||||||
self.capture_thread = None
|
self.capture_thread = None
|
||||||
self.ffmpeg_detect_process = None
|
self.ffmpeg_detect_process = None
|
||||||
self.logpipe = LogPipe(f"ffmpeg.{self.camera_name}.detect", logging.ERROR)
|
self.logpipe = LogPipe(f"ffmpeg.{self.camera_name}.detect")
|
||||||
self.ffmpeg_other_processes = []
|
self.ffmpeg_other_processes = []
|
||||||
self.camera_fps = camera_fps
|
self.camera_fps = camera_fps
|
||||||
self.ffmpeg_pid = ffmpeg_pid
|
self.ffmpeg_pid = ffmpeg_pid
|
||||||
@ -219,8 +219,7 @@ class CameraWatchdog(threading.Thread):
|
|||||||
if "detect" in c["roles"]:
|
if "detect" in c["roles"]:
|
||||||
continue
|
continue
|
||||||
logpipe = LogPipe(
|
logpipe = LogPipe(
|
||||||
f"ffmpeg.{self.camera_name}.{'_'.join(sorted(c['roles']))}",
|
f"ffmpeg.{self.camera_name}.{'_'.join(sorted(c['roles']))}"
|
||||||
logging.ERROR,
|
|
||||||
)
|
)
|
||||||
self.ffmpeg_other_processes.append(
|
self.ffmpeg_other_processes.append(
|
||||||
{
|
{
|
||||||
|
|||||||
@ -5,21 +5,22 @@ import time
|
|||||||
import os
|
import os
|
||||||
import signal
|
import signal
|
||||||
|
|
||||||
from frigate.util import (
|
from frigate.edgetpu import EdgeTPUProcess
|
||||||
restart_frigate,
|
from frigate.util import restart_frigate
|
||||||
)
|
from multiprocessing.synchronize import Event
|
||||||
|
from typing import Dict
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class FrigateWatchdog(threading.Thread):
|
class FrigateWatchdog(threading.Thread):
|
||||||
def __init__(self, detectors, stop_event):
|
def __init__(self, detectors: Dict[str, EdgeTPUProcess], stop_event: Event):
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
self.name = "frigate_watchdog"
|
self.name = "frigate_watchdog"
|
||||||
self.detectors = detectors
|
self.detectors = detectors
|
||||||
self.stop_event = stop_event
|
self.stop_event = stop_event
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> None:
|
||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
while not self.stop_event.wait(10):
|
while not self.stop_event.wait(10):
|
||||||
now = datetime.datetime.now().timestamp()
|
now = datetime.datetime.now().timestamp()
|
||||||
@ -32,7 +33,10 @@ class FrigateWatchdog(threading.Thread):
|
|||||||
"Detection appears to be stuck. Restarting detection process..."
|
"Detection appears to be stuck. Restarting detection process..."
|
||||||
)
|
)
|
||||||
detector.start_or_restart()
|
detector.start_or_restart()
|
||||||
elif not detector.detect_process.is_alive():
|
elif (
|
||||||
|
detector.detect_process is not None
|
||||||
|
and not detector.detect_process.is_alive()
|
||||||
|
):
|
||||||
logger.info("Detection appears to have stopped. Exiting frigate...")
|
logger.info("Detection appears to have stopped. Exiting frigate...")
|
||||||
restart_frigate()
|
restart_frigate()
|
||||||
|
|
||||||
|
|||||||
@ -14,38 +14,41 @@ logger = logging.getLogger(__name__)
|
|||||||
ZEROCONF_TYPE = "_frigate._tcp.local."
|
ZEROCONF_TYPE = "_frigate._tcp.local."
|
||||||
|
|
||||||
# Taken from: http://stackoverflow.com/a/11735897
|
# Taken from: http://stackoverflow.com/a/11735897
|
||||||
def get_local_ip() -> str:
|
def get_local_ip() -> bytes:
|
||||||
"""Try to determine the local IP address of the machine."""
|
"""Try to determine the local IP address of the machine."""
|
||||||
|
host_ip_str = ""
|
||||||
try:
|
try:
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
|
||||||
# Use Google Public DNS server to determine own IP
|
# Use Google Public DNS server to determine own IP
|
||||||
sock.connect(("8.8.8.8", 80))
|
sock.connect(("8.8.8.8", 80))
|
||||||
|
|
||||||
return sock.getsockname()[0] # type: ignore
|
host_ip_str = sock.getsockname()[0]
|
||||||
except OSError:
|
except OSError:
|
||||||
try:
|
try:
|
||||||
return socket.gethostbyname(socket.gethostname())
|
host_ip_str = socket.gethostbyname(socket.gethostname())
|
||||||
except socket.gaierror:
|
except socket.gaierror:
|
||||||
return "127.0.0.1"
|
host_ip_str = "127.0.0.1"
|
||||||
finally:
|
finally:
|
||||||
sock.close()
|
sock.close()
|
||||||
|
|
||||||
|
try:
|
||||||
|
host_ip_pton = socket.inet_pton(socket.AF_INET, host_ip_str)
|
||||||
|
except OSError:
|
||||||
|
host_ip_pton = socket.inet_pton(socket.AF_INET6, host_ip_str)
|
||||||
|
|
||||||
def broadcast_zeroconf(frigate_id):
|
return host_ip_pton
|
||||||
|
|
||||||
|
|
||||||
|
def broadcast_zeroconf(frigate_id: str) -> Zeroconf:
|
||||||
zeroconf = Zeroconf(interfaces=InterfaceChoice.Default, ip_version=IPVersion.V4Only)
|
zeroconf = Zeroconf(interfaces=InterfaceChoice.Default, ip_version=IPVersion.V4Only)
|
||||||
|
|
||||||
host_ip = get_local_ip()
|
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(
|
info = ServiceInfo(
|
||||||
ZEROCONF_TYPE,
|
ZEROCONF_TYPE,
|
||||||
name=f"{frigate_id}.{ZEROCONF_TYPE}",
|
name=f"{frigate_id}.{ZEROCONF_TYPE}",
|
||||||
addresses=[host_ip_pton],
|
addresses=[host_ip],
|
||||||
port=5000,
|
port=5000,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@ click == 8.1.*
|
|||||||
Flask == 2.1.*
|
Flask == 2.1.*
|
||||||
imutils == 0.5.*
|
imutils == 0.5.*
|
||||||
matplotlib == 3.5.*
|
matplotlib == 3.5.*
|
||||||
|
mypy == 0.942
|
||||||
numpy == 1.22.*
|
numpy == 1.22.*
|
||||||
opencv-python-headless == 4.5.5.*
|
opencv-python-headless == 4.5.5.*
|
||||||
paho-mqtt == 1.6.*
|
paho-mqtt == 1.6.*
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user