RaspberryPi起動時にLINEでIPアドレスを通知する

# 概要
RaspberryPiを再起動する際、正常に起動し終わったかを判断するために通知機能が欲しいと思い実装。またホスト名での接続ができないケースもあるのでIPアドレスを通知するようにした。
※すでに参考サイトでほとんど説明されているが、Pythonプログラムで使用している「ipget」というモジュールのインストールについて説明がなかったので追記している。

※2022/1/17追記
RaspberryPi Zero Wでのやり方を追記
自動実行の起動順序を修正

※2022/8/22追記
サーバー用にグローバルIPアドレスの通知機能を追加
実行時に5秒待機してからメインルーチンを実行するよう修正

# 実行環境
MCU：Raspberry Pi 3B+
OS:Raspberry Pi OS 10.11

# 参考サイト
https://canmakewakuwaku.com/rasppi_ip_line/

# 手順
##ipgetをインストール

pip(pythonのパッケージ管理ソフト)をインストール

```terminal
sudo apt install python-pip python3-pip
```

pipを使ってipgetをインストール
※ipgetと合わせてrequestsもインストールしている。
　今回は使わないが、LINE通知プログラムではよく使われているらしい。

```terminal
sudo pip3 install ipget
sudo pip3 install requests
```

## LINEとの連携用トークンを取得
参考サイトを参照。
https://canmakewakuwaku.com/rasppi_speech_line/#toc7
一度しか表示されないので、画面にトークンが表示されたら消さずに残したまま次の手順に移る。

## LINE通知プログラムの作成

好きな場所にプログラムを作成する。
今回はホームディレクトリにlineというフォルダを作成してstartup.pyという名前で保存する。

```terminal
cd ~
mkdir line
cd line
nano startup.py
```

tokenの部分に取得しておいたトークンをコピペする。
下の方のメッセージはLINE通知で表示される文字列となる。

・2022/8/22修正
サーバー用にグローバルIPアドレスの通知機能を追加。
また、起動順序を調整しても通知されないケースがあるため、実行時に5秒待機してから通知するように変更すると安定した。

```python:startup.py
# -*- coding: utf-8 -*-
import requests
import ipget
import time
import subprocess

def line(message: str):
    url = "https://notify-api.line.me/api/notify"
    token = "****************************************"
    headers = {"Authorization": "Bearer " + token}

    params = {"message":  message}
    r = requests.post(url, headers=headers, params=params)
    print(r.text)

if __name__ == '__main__':
    time.sleep(5)

    ip_address = ipget.ipget()

    cmd = "curl inet-ip.info"
    global_ip_address = (subprocess.check_output(cmd.split())).decode(encoding='utf-8')
    global_ip_address = global_ip_address.rstrip("\n")

    message = f"\n"\
              f"RaspberryPiが起動しました。\n"\
              f"IP Address(無線): {ip_address.ipaddr('wlan0')}\n"\
              f"IP Address(有線): {ip_address.ipaddr('eth0')}\n"\
              f"グローバルIP: {global_ip_address}\n"
    line(message)
```

作成したプログラムを実行して動作確認する。
実行した直後にLINEが届いたら成功。

```terminal
python3 startup.py 
```

## RaspberryPi起動時にプログラムを実行するよう設定
とりあえずサクッと設定したいなら参考サイトを参照。
https://canmakewakuwaku.com/rasppi_ip_line/
今回はSSH接続が出来るようになったら通知をして欲しいので、その辺りを管理できるsystemdにサービスとして登録して管理する。
※ユーザー名を「pi」以外に設定している場合、7行目のリンクの「pi」の部分をユーザー名に変更する。

```terminal
sudo nano /etc/systemd/system/startup.service
```

```:startup.service
[Unit]
Description=Line Notify at StartUp
After=multi-user.target

[Service]
Type=oneshot
ExecStart=/usr/bin/python3 /home/pi/line/startup.py
TimeoutStopSec=5

[Install]
WantedBy = multi-user.target
```

上記の内容でAfterに設定したサービスよりも後に起動するよう設定される。
起動順序を確認したい場合は、下記のコマンドを入力すると前回起動時の情報（全てのサービスの起動順序と起動時間）がHTML形式で現在のフォルダに保存される。

```terminal
systemd-analyze plot > unitstart.html
```

作成したサービスを読み込んでスタートしてみる。
カッコのタイミングでLINEが届いたら問題なく動いているので、
自動起動を有効にして再起動してみる。
上手く届かなかった場合はstartをstatusに変更して実行し、エラーメッセージを確認する。

```terminal
sudo systemctl daemon-reload
sudo systemctl start startup.service 
(ここでLINEが届く)
sudo systemctl enable startup.service
sudo reboot
```

***

# 2022/1/17追記
RaspberryPi Zero Wでは有線LANが無いので、pythonファイルの有線LANの行を削除しないとエラーになる。

```python:startup.py
# -*- coding: utf-8 -*-
import requests
import ipget

def line(message: str):
    url = "https://notify-api.line.me/api/notify"
    token = "****************************************"
    headers = {"Authorization": "Bearer " + token}

    params = {"message":  message}
    r = requests.post(url, headers=headers, params=params)
    print(r.text)

if __name__ == '__main__':
    ip_address = ipget.ipget()
    message = f"\n"\
              f"RaspberryPiが起動しました。\n"\
              f"IP Address(無線): {ip_address.ipaddr('wlan0')}\n"
    line(message)
```