Added notification system

This commit is contained in:
Ashish D'Souza 2023-05-20 11:44:46 -04:00
parent b0534c481f
commit d29d9e16f0
7 changed files with 157 additions and 2 deletions

View File

@ -15,7 +15,7 @@ services:
timeout: 30s
environment:
FRIGATE_MQTT_USERNAME: frigate
FRIGATE_MQTT_PASSWORD: ${FRIGATE_MQTT_PASSWORD}
FRIGATE_MQTT_PASSWORD: ${MQTT_PASSWORD}
FRIGATE_GARAGE_RTSP_USERNAME: motion
FRIGATE_GARAGE_RTSP_PASSWORD: ${FRIGATE_GARAGE_RTSP_PASSWORD}
FRIGATE_FRONT_DOOR_RTSP_USERNAME: motion
@ -46,6 +46,23 @@ services:
# - frigate
ports:
- 127.0.0.1:5000:5000
notify:
container_name: frigate-notify
image: frigate-notify:latest
restart: unless-stopped
environment:
MQTT_USERNAME: frigate
MQTT_PASSWORD: ${MQTT_PASSWORD}
REQUESTS_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt
volumes:
- type: bind
source: /data/certs/homelab_ca.crt
target: /usr/local/share/ca-certificates/homelab_ca.crt
read_only: true
- type: bind
source: /etc/localtime
target: /etc/localtime
read_only: true
# mqtt:
# container_name: mqtt
# image: eclipse-mosquitto:latest

View File

@ -55,6 +55,29 @@
dest: /data/frigate-config/config.yaml
mode: preserve
- name: Create temporary Docker build directory
ansible.builtin.tempfile:
state: directory
register: docker_build_dir
- name: Copy Docker build directory
ansible.builtin.copy:
src: notify/
dest: '{{docker_build_dir.path}}'
mode: preserve
- name: Build frigate-notify Docker image
ansible.builtin.docker_image:
build:
path: '{{docker_build_dir.path}}'
name: frigate-notify
tag: latest
source: build
force_source: true
state: present
- name: Remove temporary Docker build directory
ansible.builtin.file:
path: '{{docker_build_dir.path}}'
state: absent
- name: Read homelab config
ansible.builtin.slurp:
src: '{{ansible_user_dir}}/.homelab.json'

11
notify/Dockerfile Normal file
View File

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

2
notify/requirements.txt Normal file
View File

@ -0,0 +1,2 @@
requests==2.30.0
paho-mqtt==1.6.1

37
notify/src/mqtt.py Normal file
View File

@ -0,0 +1,37 @@
import os
import json
from time import sleep
import paho.mqtt.client as mqtt
from ntfy import send_rate_limited_notification
def on_connect(client, userdata, flags, rc):
print(f'Connected with return code {rc}')
client.subscribe('frigate/events')
def on_message(client, userdata, message):
payload = json.loads(message.payload.decode())
if payload['type'] == 'new' and payload['after']['label'] == 'person':
event_id = payload['after']['id']
camera = payload['after']['camera']
object_label = payload['after']['label']
score = payload['after']['top_score']
send_rate_limited_notification(event_id, camera, object_label, score)
def subscribe():
client = mqtt.Client('frigate_notifications')
client.username_pw_set(os.environ['MQTT_USERNAME'], password=os.environ['MQTT_PASSWORD'])
client.on_connect = on_connect
client.on_message = on_message
client.connect(host='192.168.0.6', port=1883)
client.loop_forever()
if __name__ == '__main__':
subscribe()

59
notify/src/ntfy.py Normal file
View File

@ -0,0 +1,59 @@
import json
import requests
from datetime import datetime, timedelta
last_notification_time = None
def send_rate_limited_notification(event_id, camera, object_label, score, quiet_period=1):
global last_notification_time
now = datetime.now()
if last_notification_time is None or now - last_notification_time >= timedelta(minutes=quiet_period):
last_notification_time = now
send_notification(event_id, camera, object_label, score, priority=3)
def send_notification(event_id, camera, object_label, score, priority=3):
camera_location = ' '.join(word.capitalize() for word in camera.split('_'))
response = requests.post('https://ntfy.homelab.net', json={
'topic': 'frigate_notifications',
'title': 'Frigate',
'message': f'{object_label.capitalize()} at {camera_location} ({score:.0%})',
'priority': priority,
'click': f'https://frigate.homelab.net/cameras/{camera}',
'icon': 'https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/frigate.png',
'attach': f'https://frigate.homelab.net/api/events/{event_id}/thumbnail.jpg?format=android',
'actions': [
{
'action': 'http',
'label': 'Disable (30m)',
'url': 'https://www.google.com/',
'method': 'GET',
'clear': True
}
]
})
response2 = requests.post('https://ntfy.homelab.net', json={
'topic': 'frigate_notifications_dad',
'title': 'Frigate',
'message': f'{object_label.capitalize()} at {camera_location} ({score:.0%})',
'priority': priority,
'click': f'https://frigate.homelab.net/cameras/{camera}',
'icon': 'https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/frigate.png',
'attach': f'https://frigate.homelab.net/api/events/{event_id}/thumbnail.jpg?format=android',
'actions': [
{
'action': 'http',
'label': 'DBL (30m)',
'url': 'https://www.google.com/',
'method': 'GET',
'clear': True
}
]
})
return response.status_code == 200 and response2.status_code == 200

View File

@ -35,7 +35,7 @@
- name: Docker Compose up Frigate
environment:
FRIGATE_MQTT_PASSWORD: '{{frigate_config.mqtt.password}}'
MQTT_PASSWORD: '{{frigate_config.mqtt.password}}'
FRIGATE_GARAGE_RTSP_PASSWORD: '{{frigate_config.rtsp.garage.password}}'
FRIGATE_FRONT_DOOR_RTSP_PASSWORD: '{{frigate_config.rtsp.front_door.password}}'
FRIGATE_BACK_DOOR_RTSP_PASSWORD: '{{frigate_config.rtsp.back_door.password}}'
@ -49,3 +49,9 @@
ansible.builtin.file:
path: '{{docker_compose_dir.path}}'
state: absent
- name: Update CA certificates
community.docker.docker_container_exec:
container: frigate-notify
command: update-ca-certificates
user: root