やりたいこと
カメラが人や車両を検知したらスマホに Push 通知。
録画データの ts から mp4 へのエンコードが完了したらスマホに Push 通知。
Zabbix からのメールに連動してスマホに Push 通知。
毎朝、その日の天気予報をスマホに Push 通知。
もうね、なんでもあり。
NanoPi NEO の CPU 温度が50度を超えたらPush通知。とかでもいい。
とにかく手軽に情報をスマホに集めたかった。
用意したもの
Raspberry Pi 4B だけ。スマホはお手元のものを…
使うのはNtfy(ノーティファイ)というセルフホスト型のサーバソフトウェア
ダウンロードとインストール
以下のリリースページからダウンロード。
これを書いている時点(2025/03/31)で V2.21.0 が最新。
そして、ラズパイに導入するので、ARM系のパッケージかつ64ビット版。
Docker版もあるっぽいけど、個人的には管理しやすい tar.gz を入手。
ダウンロードと解凍は以下の通り。
$ wget https://github.com/binwiederhier/ntfy/releases/download/v2.21.0/ntfy_2.21.0_linux_arm64.tar.gz
$ tar zxfv ntfy_2.21.0_linux_arm64.tar.gz
$ mv ntfy_2.21.0_linux_arm64 ntfy
$ cd ntfy
これだけでOK
サーバ設定
あとはチョチョイと設定すればすぐ動く。
設定ファイルは server 等ディレクトリ内の server.yml というファイルで行う。
$ cd server
$ vi server.yml
変更箇所は以下。
それぞれ、先頭の # を削除して、値を書いていく。
base-url: "http://yourdomain"
listen-http: ":80"
cache-file: "/var/lib/ntfy/cache.db"
auth-file: "/var/lib/ntfy/user.db"
attachment-cache-dir: "/var/cache/ntfy/attachments"
upstream-base-url: "https://ntfy.sh"
とりあえず、こんなもんで動くようにはなる。
「base-url: “http://yourdomain”」 ローカルで運用するだけならローカルIPで http://192.168.10.251 とかでも良い。
「listen-http: “:80″」は多分変えないとダメよね?Nginx か Apache が既に使っちゃってること多いと思うので。
「upstream-base-url: “https://ntfy.sh”」は iPhone に Push しなければ不要だけど、入れておいてもいいでしょう。
で、2つくらいファイル関連の設定も入れてあるけど、/var/lib/ntfy というディレクトリが存在しないので作っておく。
$ sudo mkdir /var/lib/ntfy
これで ./ntfy に戻って、下記のようにすると動き出す…
$ sudo ./ntfy -c ./server/server.yml
特にエラーは出ないはずだけど、エラーが出たら server.yml に間違いがないか確認。
無事に起動した場合は以下のように表示される。
2026/04/01 00:03:19 INFO Listening on :80[http], ntfy 2.21.0, log level is INFO (tag=startup)
2026/04/01 00:04:19 INFO Server stats (emails_received=0, emails_received_failure=0, emails_received_success=0, emails_sent=0, emails_sent_failure=0, emails_sent_success=0, messages_cached=0, messages_published=0, subscribers=0, tag=manager, topics_active=0, users=1, visitors=0)
起動出来たら、ブラウザで base-url に記載した URL にアクセスしてみる。
以下のような(色合いは端末によって変わる)UI が表示されればOK

通知のための設定:Topicの購読
左ペインの「+ トピックを購読する」をクリックして、新たに開かれたウィンドウ内にある「トピック名」に適当に名前を登録する。
「free_topic」とか「talk_to_oneself」とか、なんでもいい。
で、「購読する」をクリックすればOK

…なんか、Chrome は英語を日本語に自動で翻訳しちゃうので、新たに始まったTopic「talk_to_oneself」が「独り言を言う」に訳されちゃってるけど…まぁ、気にしない。

試しに通知を出してみる。
左ペインの「購読トピック」の「talk_to_oneself」(ブラウザ上の表示は「独り言を言う」)をクリックし、ブラウザ内左上に表示されている内容も「独り言を言う」になったら「通知を公開する」をクリック。
すると、新たなウィンドウが開かれるので、「タイトル」と「メッセージ」に適当に文章を書いて「送信」

で、ちゃんと通知が飛んだ。

PC上のブラウザで履歴が見れたので、基本的な動作はこれでOKということに。
では、次、目的の「スマホにPush通知」に移ろう。
スマホでは「ntfy」アプリを使う
iPhone でも Android でも、同じ名称のアプリがあるので、検索してインストール。

アプリを立ち上げたら、画面下にある「Settings」をタップして、その中の「Default server」を server.yml 内 base-url に設定したURLを書いておくと、あとが楽。
尚、舌では USERS に何かユーザーが入っちゃってるけど、通知の送受信に認証が必要になったら登録すればよいので、動作確認の段階では空欄のままでOK(ブラウザで通知送信確認した時も、特にユーザーの登録はしていないので問題ない)

で、お次は画面下にある「Notifications」へ移動。
購読したいトピックの登録をするので、画面右上の「+」をタップ。

「Topic name, e.g. phil_alerts」となっているところに、さっきブラウザで登録したトピックの「talk_to_onself」を入力。
「Use another server」は上の「Settings」の「Default server」に間違いなければそのままで良い。
入力が終わったら「Subscribe」

これで一通り設定完了。
さっきブラウザで通知を送ったけど、もう一度メッセージを変えて送ってみる。
また、今度はブラウザ下部にある「ここにメッセージを入力してください」に入力して試してみる…

数秒後…

うん、OKだね。
いろいろな通知方法
ここまではブラウザで試していたけど、これは目的の使い方じゃない。
ラズパイのGPIOにスイッチが繋がっててそれが押されたら、とか、何らかのアクションがあって、それに連動して通知を飛ばしたいわけなので、ブラウザでってのはまずない。
python で送信
じゃぁ、何が使われるかって言ったら、やっぱり python が多いのかな?と。
てことで、簡単なコードは以下の通り。
import requests
def send_ntfy(msg, title="アラート", priority="high"):
# トピックのURL
url = "http://yourdomain/talk_to_oneself"
headers = {
"Title": title.encode('utf-8'),
"Priority": priority,
"Tags": "warning,computer"
}
# メッセージ送信
response = requests.post(url, data=msg.encode('utf-8'), headers=headers)
if response.status_code == 200:
print("送信完了")
else:
print(f"なんかエラー出た: {response.status_code}")
# 実行
send_ntfy("こうすれば通知を送信できるはず", title="Pythonから")
curl で送信
これは超簡単。
$ curl -d "curlで送ってみる" http://yourdomain/talk_to_oneself
単純なのならこれで送れる。
けど、もう少し工夫すると以下のような感じかな。
$ curl -H "Title: curlから通知送信" -H "Priority: urgent" -H "Tags: warning,rotating_light" -d "curlならやろうと思えば1行でイケる!" http://yourdomain/talk_to_oneself
wget で送信
curl と同じくらいシンプルにイケる。
$ wget --post-data="wgetから送信" http://yourdomain/talk_to_oneself
同様に、ちょっと工夫すればもう少し情報増やせる。ちょっと長いけど…
$ wget --header="Title: curlから通知送信" --header="Priority: urgent" --header="Tags: warning,rotating_light" --post-data="wgetでも1行がちょっと長いけど、イケる!" -qO- http://yourdomain/talk_to_oneself
とりあえず、これだけできれば困らないかな。
この記事にコメントしてみる