Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ntfy] Improve example/tutorial about Frigate event notifications #639

Merged
merged 8 commits into from
Apr 27, 2023
6 changes: 5 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ in progress
- [ux] Rename subcommand ``mqttwarn make-samplefuncs`` to ``mqttwarn make-udf``,
and adjust naming.
- [ntfy] Add dedicated service plugin ``ntfy``
- [ntfy] Use RFC 2047 for encoding HTTP header values
- [ntfy] Use RFC 2047 for encoding HTTP header values. Thanks, @binwiederhier.
- [ntfy] Add more fields: icon, cache, firebase, unifiedpush
- [ntfy] Also interpolate outbound ntfy option fields
- [ntfy] [Frigate] Improve example/tutorial about Frigate event notifications
- [ntfy] [Frigate] Synchronize JSON event and snapshot image receive order
- [ntfy] [Frigate] Tests: Verify notification was properly received by ntfy


2023-04-11 0.33.0
Expand Down
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
159 changes: 130 additions & 29 deletions examples/frigate/README.rst
Original file line number Diff line number Diff line change
@@ -1,60 +1,90 @@
.. _processing-frigate-events:

##############################################
Frigate » Forward events and snapshots to Ntfy
Frigate » Forward events and snapshots to ntfy
##############################################


*****
About
*****

The specific scenario is to setup a notification pipeline which looks like::
This tutorial presents a notification pipeline, which implements forwarding
Frigate events to ntfy notifications, using mqttwarn. It looks like this::

Frigate -> Mosquitto -> mqttwarn -> Apprise -> Ntfy
Frigate -> Mosquitto -> mqttwarn -> ntfy

Components
==========

`Frigate`_ (`Frigate on GitHub`_) is a network video recorder (NVR) with
realtime local object detection for IP cameras. It uses MQTT to publish
`events in JSON format`_ and `camera pictures in JPEG format`_.

`Apprise`_ is a polyglot notification library that allows you to send
notifications to almost all of the most popular notification services
available today. It has an adapter for `Ntfy`_.
`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
`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.


*******
Details
*******
********
Synopsis
********

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'

2. Enjoy the outcome.

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

We are investigating how to `Send message body or attachment to Apprise/Ntfy`_,
and if it is feasible to make mqttwarn process JPEG content, see `Non-UTF-8
encoding causes error`_.


*****
Usage
*****


Configuration
=============

Please inspect the `frigate.ini`_ mqttwarn configuration file and adjust it to
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
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 @@ -73,17 +103,88 @@ Publish a few example events individually::
Publish an example image::

wget -O goat.png https://user-images.githubusercontent.com/453543/231550862-5a64ac7c-bdfa-4509-86b8-b1a770899647.png
convert goat.png goat.jpg
mosquitto_pub -f goat.jpg -t 'frigate/cam-testdrive/goat/snapshot'
open /tmp/mqttwarn-frigate-cam-testdrive-goat.jpg
mosquitto_pub -f goat.png -t 'frigate/cam-testdrive/goat/snapshot'
open /tmp/mqttwarn-frigate-cam-testdrive-goat.png


*******
Details
*******

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
the test cases either as part of the complete test suite, or by running them from this
directory::

pytest --no-cov -k frigate
pytest --no-cov test_frigate.py


************
Attributions
************

Acknowledgements
================
- `Sev`_ for coming up with the idea of using mqttwarn to connect Frigate with ntfy
- `Blake Blackshear`_ for `Frigate`_
- `Philipp C. Heckel`_ for `ntfy`_

Content
=======
The copyright of data, particular images, and pictograms, are held by their
respective owners, unless otherwise noted.

Example snapshot image
----------------------

- **Description**: A picture of a `Changthangi`_ goat
- **Date**: April 7, 2023
- **Source**: Own work via Unsplash
- **Author**: `Jaromír Kalina`_
- **License**: `Unsplash License`_
- **URL**: https://unsplash.com/photos/spdQ1dVuIHw


.. _Apprise: https://github.com/caronc/apprise
.. _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
.. _Non-UTF-8 encoding causes error: https://github.com/jpmens/mqttwarn/issues/634
.. _Ntfy: https://ntfy.sh/
.. _Ntfy on GitHub: https://github.com/binwiederhier/ntfy
.. _Send message body or attachment to Apprise/Ntfy: https://github.com/jpmens/mqttwarn/issues/632
.. _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
.. _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
.. _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
6 changes: 4 additions & 2 deletions examples/frigate/assets/frigate-event-full.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,11 @@
"stationary": false,
"motionless_count": 1,
"position_changes": 2,
"current_zones": [],
"current_zones": [
"barn"
],
"entered_zones": [
"zone1"
"lawn"
],
"has_clip": true,
"has_snapshot": true
Expand Down
6 changes: 4 additions & 2 deletions examples/frigate/assets/frigate-event-update-good.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@
"false_positive": false,
"start_time": 1680791459.255384,
"end_time": null,
"current_zones": [],
"current_zones": [
"barn"
],
"entered_zones": [
"zone1"
"lawn"
],
"has_clip": true,
"has_snapshot": true
Expand Down
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
Loading