Skip to content

Commit

Permalink
[ntfy] Improve and clean up Frigate notification tutorial
Browse files Browse the repository at this point in the history
- Pull text message templates from Python code into configuration file
- Remove unused code
- Type hints
- Code formatting
- Add Docker Compose configuration for Mosquitto and ntfy services
- Update documentation
  • Loading branch information
amotl committed Apr 26, 2023
1 parent 01d94c0 commit 9a0134a
Show file tree
Hide file tree
Showing 7 changed files with 216 additions and 120 deletions.
9 changes: 9 additions & 0 deletions examples/frigate/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Software component versions.
MOSQUITTO_VERSION=2.0.15
NTFY_VERSION=latest

# Broker configuration (Mosquitto).
PORT_MOSQUITTO=1883

# Notification service configuration (ntfy).
PORT_NTFY=5555
77 changes: 52 additions & 25 deletions examples/frigate/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,16 @@ The specific scenario is to setup a notification pipeline which looks like::
realtime local object detection for IP cameras. It uses MQTT to publish
`events in JSON format`_ and `camera pictures in JPEG format`_.

`ntfy`_ (`ntfy on GitHub`_) is a simple HTTP-based pub-sub notification
`Eclipse Mosquitto`_ (`Mosquitto on GitHub`_) is an open source message broker
that implements the MQTT protocol versions 5.0, 3.1.1 and 3.1. Mosquitto is
lightweight and is suitable for use on all devices from low power single board
computers to full servers.

`mqttwarn`_ (`mqttwarn on GitHub`_) is a highly configurable MQTT message router,
where the routing targets are notification plugins, written in Python. mqttwarn
has a corresponding notification plugin adapter for ntfy.

`ntfy`_ (`ntfy on GitHub`_) is a simple HTTP-based `pub-sub`_ notification
service, allowing you to send notifications to your phone or desktop from
any computer, entirely without signup, cost or setup.

Expand All @@ -26,16 +35,14 @@ any computer, entirely without signup, cost or setup.
Synopsis
********

1. Subscribe to ntfy topic by visiting http://localhost:5555/frigate-test.

2. Publish Frigate sample events.
1. Publish Frigate sample events.

.. code-block:: bash
cat assets/frigate-event-new-good.json | jq -c | mosquitto_pub -t 'frigate/events' -l
mosquitto_pub -f goat.png -t 'frigate/cam-testdrive/goat/snapshot'
3. Enjoy the outcome.
2. Enjoy the outcome.

.. figure:: https://user-images.githubusercontent.com/453543/233172276-6a59cefa-6461-48bc-80f2-c355b6acc496.png

Expand All @@ -54,27 +61,26 @@ your needs before running mqttwarn on it. If you also want to inspect the
corresponding user-defined functions, you are most welcome. They are stored
within `frigate.py`_.

Prerequisites
=============

Acquire sources and go to the right directory::

git clone https://github.com/jpmens/mqttwarn
cd mqttwarn/examples/frigate


In a box
========

Start the Mosquitto MQTT broker::

docker run --name=mosquitto --rm -it --publish=1883:1883 \
eclipse-mosquitto:2.0.15 mosquitto -c /mosquitto-no-auth.conf
Start the Mosquitto MQTT broker and the ntfy service::

Start the ntfy API service::
docker compose up

docker run --name=ntfy --rm -it --publish=5555:80 binwiederhier/ntfy \
serve \
--base-url="http://localhost:5555" \
--cache-file="/tmp/ntfy-cache.db" \
--attachment-cache-dir="/tmp/ntfy-attachments" \
--attachment-expiry-duration="168h"
Subscribe to ntfy topic by visiting http://localhost:5555/frigate-testdrive.

Run mqttwarn::

cd examples/frigate/
MQTTWARNINI=frigate.ini mqttwarn

Run the example publisher program::
Expand All @@ -97,13 +103,30 @@ Publish an example image::
open /tmp/mqttwarn-frigate-cam-testdrive-goat.png


***********
Development
***********
*******
Details
*******

We are investigating how to `Receiving and processing MQTT messages from Frigate NVR`_,
and if it is feasible to make mqttwarn process JPEG content, see `Non-UTF-8
encoding causes error`_.
The implementation is based on mqttwarn core, its `ntfy service plugin`_, the
mqttwarn configuration file ``frigate.ini``, as well as the user-defined function
file ``frigate.py``. You can inspect them below.

.. admonition:: Inspect configuration file ``frigate.ini``
:class: tip dropdown

.. literalinclude:: frigate.ini
:language: ini

.. admonition:: Inspect user-defined function file ``frigate.py``
:class: tip dropdown

.. literalinclude:: frigate.py
:language: python


*****
Tests
*****

The `test_frigate.py`_ file covers different code paths by running a few Frigate event
message samples through the machinery, and inspecting their outcomes. You can invoke
Expand Down Expand Up @@ -143,17 +166,21 @@ Example snapshot image
.. _Blake Blackshear: https://github.com/blakeblackshear
.. _camera pictures in JPEG format: https://docs.frigate.video/integrations/mqtt/#frigatecamera_nameobject_namesnapshot
.. _Changthangi: https://en.wikipedia.org/wiki/Changthangi
.. _Eclipse Mosquitto: https://mosquitto.org/
.. _events in JSON format: https://docs.frigate.video/integrations/mqtt/#frigateevents
.. _Frigate: https://frigate.video/
.. _Frigate on GitHub: https://github.com/blakeblackshear/frigate
.. _frigate.ini: https://github.com/jpmens/mqttwarn/blob/main/examples/frigate/frigate.ini
.. _frigate.py: https://github.com/jpmens/mqttwarn/blob/main/examples/frigate/frigate.py
.. _Jaromír Kalina: https://unsplash.com/@jkalinaofficial
.. _Non-UTF-8 encoding causes error: https://github.com/jpmens/mqttwarn/issues/634
.. _Mosquitto on GitHub: https://github.com/eclipse/mosquitto
.. _mqttwarn: https://mqttwarn.readthedocs.io/
.. _mqttwarn on GitHub: https://github.com/jpmens/mqttwarn
.. _ntfy: https://ntfy.sh/
.. _ntfy on GitHub: https://github.com/binwiederhier/ntfy
.. _ntfy service plugin: https://mqttwarn.readthedocs.io/en/latest/notifier-catalog.html#ntfy
.. _Philipp C. Heckel: https://github.com/binwiederhier
.. _Receiving and processing MQTT messages from Frigate NVR: https://github.com/jpmens/mqttwarn/issues/632
.. _pub-sub: https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern
.. _Sev: https://github.com/sevmonster
.. _test_frigate.py: https://github.com/jpmens/mqttwarn/blob/main/examples/frigate/test_frigate.py
.. _Unsplash License: https://unsplash.com/license
61 changes: 61 additions & 0 deletions examples/frigate/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
version: "3.8"

services:

# ---------
# Mosquitto
# ---------
# https://hub.docker.com/_/eclipse-mosquitto
mosquitto:
image: eclipse-mosquitto:${MOSQUITTO_VERSION}
container_name: mosquitto
command: ["mosquitto", "-c", "/mosquitto-no-auth.conf"]
ports:
- "${PORT_MOSQUITTO}:${PORT_MOSQUITTO}"

# Define health check for Mosquitto.
healthcheck:
test: [ "CMD", "mosquitto_sub", "-v", "-t", "foobar", "-E" ]
start_period: 1s
interval: 3s
timeout: 10s
retries: 60

# ----
# ntfy
# ----
# https://docs.ntfy.sh/install/#docker
# https://hub.docker.com/r/binwiederhier/ntfy
ntfy:
image: binwiederhier/ntfy:${NTFY_VERSION}
container_name: ntfy
command: >
serve
--base-url="http://localhost:5555"
--attachment-cache-dir="/tmp/ntfy-attachments"
--attachment-expiry-duration="168h"
environment:
# optional: set desired timezone
- TZ=UTC
ports:
- "${PORT_NTFY}:80"
healthcheck:
test: ["CMD-SHELL", "wget -q --tries=1 http://localhost:5555/v1/health -O - | grep -Eo '\"healthy\"\\s*:\\s*true' || exit 1"]
interval: 60s
timeout: 10s
retries: 3
start_period: 40s

# -------
# Bundler
# -------
# Wait for all defined services to be fully available by probing their health
# status, even when using `docker compose up --detach`.
# https://marcopeg.com/2019/docker-compose-healthcheck/
start-dependencies:
image: dadarek/wait-for-dependencies
depends_on:
mosquitto:
condition: service_healthy
ntfy:
condition: service_healthy
11 changes: 7 additions & 4 deletions examples/frigate/frigate.ini
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Frigate » Forward events and snapshots to Ntfy, using mqttwarn.
# https://mqttwarn.readthedocs.io/en/latest/examples/frigate/README.html

[defaults]
functions = frigate.py
launch = ntfy, store-image
Expand All @@ -14,20 +17,20 @@ status_publish = True
# Docs: https://docs.frigate.video/integrations/mqtt/#frigateevents

[config:ntfy]
targets = {
targets = {
'test': {
'url': 'http://username:password@localhost:5555/frigate-testdrive',
'attachment': '/tmp/mqttwarn-frigate-{camera}-{label}.png',
'click': 'https://httpbin.org/anything?camera={event.camera}&label={event.label}&zone={event.entered_zones[0]}',
}
}

[frigate/events]
filter = frigate_events_filter()
alldata = frigate_events()
targets = ntfy:test
title = {title}
format = {format}
click = {click}
title = {event.label} entered {event.entered_zones_str} at {event.time}
format = {event.label} was in {event.current_zones_str} before

# Limit the alert based on camera/zone.
frigate_skip_rules = {
Expand Down
Loading

0 comments on commit 9a0134a

Please sign in to comment.