Added webcontrol API

This commit is contained in:
Ashish D'Souza 2023-05-21 19:33:10 -04:00
parent a13f099e14
commit ce6b363d4e
11 changed files with 154 additions and 15 deletions

View File

@ -1,5 +1,5 @@
mqtt: mqtt:
host: 192.168.0.6 host: mqtt
user: '{FRIGATE_MQTT_USERNAME}' user: '{FRIGATE_MQTT_USERNAME}'
password: '{FRIGATE_MQTT_PASSWORD}' password: '{FRIGATE_MQTT_PASSWORD}'

View File

@ -45,7 +45,9 @@ services:
# networks: # networks:
# - frigate # - frigate
ports: ports:
- 127.0.0.1:5000:5000 - 127.0.0.1:10000:5000
extra_hosts:
- mqtt:192.168.0.6
notify: notify:
container_name: frigate-notify container_name: frigate-notify
image: frigate-notify:latest image: frigate-notify:latest
@ -63,6 +65,32 @@ services:
source: /etc/localtime source: /etc/localtime
target: /etc/localtime target: /etc/localtime
read_only: true read_only: true
extra_hosts:
- mqtt:192.168.0.6
webcontrol:
container_name: frigate-webcontrol
image: frigate-webcontrol:latest
labels:
autoheal: 'true'
restart: unless-stopped
healthcheck:
test: curl -s -f http://localhost -o /dev/null
interval: 60s
retries: 1
start_period: 30s
timeout: 30s
environment:
MQTT_USERNAME: frigate
MQTT_PASSWORD: ${MQTT_PASSWORD}
volumes:
- type: bind
source: /etc/localtime
target: /etc/localtime
read_only: true
ports:
- 127.0.0.1:10001:80
extra_hosts:
- mqtt:192.168.0.6
# mqtt: # mqtt:
# container_name: mqtt # container_name: mqtt
# image: eclipse-mosquitto:latest # image: eclipse-mosquitto:latest

View File

@ -6,9 +6,13 @@ server {
ssl_certificate_key "/certs/homelab.net/homelab.net.key"; ssl_certificate_key "/certs/homelab.net/homelab.net.key";
location / { location / {
proxy_pass "http://localhost:5000/"; proxy_pass "http://localhost:10000/";
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade"; proxy_set_header Connection "upgrade";
} }
location /webcontrol/ {
proxy_pass "http://localhost:10001/";
}
} }

View File

@ -55,7 +55,7 @@
dest: /data/frigate-config/config.yaml dest: /data/frigate-config/config.yaml
mode: preserve mode: preserve
- name: Create temporary Docker build directory - name: Create temporary Docker build directory for frigate-notify
ansible.builtin.tempfile: ansible.builtin.tempfile:
state: directory state: directory
register: docker_build_dir register: docker_build_dir
@ -73,7 +73,30 @@
source: build source: build
force_source: true force_source: true
state: present state: present
- name: Remove temporary Docker build directory - name: Remove temporary Docker build directory for frigate-notify
ansible.builtin.file:
path: '{{docker_build_dir.path}}'
state: absent
- name: Create temporary Docker build directory for frigate-webcontrol
ansible.builtin.tempfile:
state: directory
register: docker_build_dir
- name: Copy Docker build directory
ansible.builtin.copy:
src: webcontrol/
dest: '{{docker_build_dir.path}}'
mode: preserve
- name: Build frigate-webcontrol Docker image
ansible.builtin.docker_image:
build:
path: '{{docker_build_dir.path}}'
name: frigate-webcontrol
tag: latest
source: build
force_source: true
state: present
- name: Remove temporary Docker build directory for frigate-webcontrol
ansible.builtin.file: ansible.builtin.file:
path: '{{docker_build_dir.path}}' path: '{{docker_build_dir.path}}'
state: absent state: absent
@ -126,7 +149,8 @@
- '{{item.reverse_proxy}}' - '{{item.reverse_proxy}}'
- '{{item.reverse_proxy_port}}' - '{{item.reverse_proxy_port}}'
with_items: with_items:
- {service: frigate, port: 5000, domain: null, reverse_proxy: nginx_barad-dur, reverse_proxy_port: 443} - {service: frigate, port: 10000, domain: null, reverse_proxy: nginx_barad-dur, reverse_proxy_port: 443}
- {service: frigate, port: 10001, domain: null, reverse_proxy: nginx_barad-dur, reverse_proxy_port: 443}
- name: Insert into Postgres table service_data - name: Insert into Postgres table service_data
community.postgresql.postgresql_query: community.postgresql.postgresql_query:
login_host: '{{homelab_config.database.host}}' login_host: '{{homelab_config.database.host}}'

View File

@ -6,6 +6,6 @@ ENTRYPOINT ["python3", "mqtt.py"]
RUN pip3 install --upgrade pip RUN pip3 install --upgrade pip
COPY requirements.txt . COPY requirements.txt .
RUN pip install -r requirements.txt RUN pip3 install -r requirements.txt
COPY src . COPY src .

View File

@ -24,12 +24,12 @@ def on_message(client, userdata, message):
def subscribe(): def subscribe():
client = mqtt.Client('frigate_notifications') client = mqtt.Client()
client.username_pw_set(os.environ['MQTT_USERNAME'], password=os.environ['MQTT_PASSWORD']) client.username_pw_set(os.environ['MQTT_USERNAME'], password=os.environ['MQTT_PASSWORD'])
client.on_connect = on_connect client.on_connect = on_connect
client.on_message = on_message client.on_message = on_message
client.connect(host='192.168.0.6', port=1883) client.connect(host='mqtt', port=1883)
client.loop_forever() client.loop_forever()

View File

@ -1,7 +1,7 @@
import json import json
import requests
from datetime import datetime, timedelta from datetime import datetime, timedelta
import requests
last_notification_time = {} last_notification_time = {}
@ -30,8 +30,15 @@ def send_notification(event_id, camera, object_label, score, priority=3):
{ {
'action': 'http', 'action': 'http',
'label': 'Disable (30m)', 'label': 'Disable (30m)',
'url': 'https://www.google.com/', 'url': f'https://frigate.homelab.net/webcontrol/camera/{camera}/detect',
'method': 'GET', 'method': 'POST',
'headers': {
'Content-Type': 'application/json'
},
'body': json.dumps({
'value': False,
'duration': 30
}),
'clear': True 'clear': True
} }
] ]
@ -49,9 +56,15 @@ def send_notification(event_id, camera, object_label, score, priority=3):
{ {
'action': 'http', 'action': 'http',
'label': 'DBL (30m)', 'label': 'DBL (30m)',
'url': 'https://www.google.com/', 'url': f'https://frigate.homelab.net/webcontrol/camera/{camera}/detect',
'method': 'GET', 'method': 'POST',
'clear': True 'headers': {
'Content-Type': 'application/json'
},
'body': json.dumps({
'value': False,
'duration': 30
})
} }
] ]
}) })

11
webcontrol/Dockerfile Normal file
View File

@ -0,0 +1,11 @@
FROM python:3.11
WORKDIR /code
ENTRYPOINT ["python3", "server.py"]
RUN pip3 install --upgrade pip
COPY requirements.txt .
RUN pip3 install -r requirements.txt
COPY src .

View File

@ -0,0 +1,2 @@
flask==2.3.2
paho-mqtt==1.6.1

View File

@ -0,0 +1,37 @@
import os
from time import sleep
from threading import Thread
from flask import Blueprint, request, jsonify
import paho.mqtt.publish as mqtt_publish
blueprint = Blueprint('detection', __name__)
def set_camera_detection(camera: str, value: bool, delay: int = 0) -> None:
sleep(delay)
mqtt_publish.single(f'frigate/{camera}/detect/set', 'ON' if value else 'OFF', hostname='mqtt', port=1883, auth={'username': os.environ['MQTT_USERNAME'], 'password': os.environ['MQTT_PASSWORD']})
@blueprint.route('/camera/<string:camera>/detect', methods=['POST'])
def camera_detect_POST(camera):
if not request.json:
return jsonify({
'status': 'failure',
'description': 'Request body needs to be in JSON format'
}), 400
value = request.json.get('value', True)
set_camera_detection(camera, value)
duration = request.json.get('duration', 0)
if duration > 0:
# Start sleeping thread to revert value after duration
thread = Thread(target=set_camera_detection, args=(camera, not value, duration * 60))
thread.start()
return jsonify({
'status': 'success'
}), 200

20
webcontrol/src/server.py Normal file
View File

@ -0,0 +1,20 @@
from flask import Flask, jsonify
import detection
app = Flask(__name__)
app.register_blueprint(detection.blueprint)
@app.route('/', methods=['GET'])
def home_GET():
return jsonify({
'status': 'success',
'name': 'webcontrol',
'description': 'This is a custom webcontrol API for Frigate that allows minimal control over the NVR system through an HTTP API'
}), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80, debug=False)