自己流ラズパイリモート開発設定ベストプラクティス 

# 初めに
### これは何？
今回、自分が昔から思っていたラズパイの面倒な部分、特にIoT開発時の手間を減らすために書いた記事です。自分の備忘録代わりに書きます。
### 対象ユーザ
想定している対象ユーザは自分のように、IoTデバイスを開発したくてラズパイ買った人（デバイスを自宅、あるいは社外に持ち出して開発するようなIoTデバイス開発全般に参考になるかもしれません）

### できるようになること
- ラズパイをリモートで接続、開発する手順が分かります
- リモート開発時に携行するデバイスが減ります


#### ラズパイは基本PCなので開発に必要なデバイスが多く、外で使用するのは面倒くさい
ラズパイ開発で必要なのは、

1.  **「ラズパイ本体」**
2.  **「バッテリー電源及びケーブル」**
3.  **「ディスプレイ及びケーブル」**
4.  **「wifi等の機器」**
5.  **「キーボード」**
6.  **「必要であればマウス」**

などですが、これはつまり**デバイス自体は小さくてもデスクトップPC開発と同等の環境が必要になる**ということです。
ラズパイを屋外設置し、現地でテストや状況によっては開発をするような使い方をしたかったので、屋外に持ち出す機器を最小にしつつ、かつ現地で開発をするために必要な構成を考えました。

作業後の構成では以下のようになります。

1.  **「ラズパイ本体（確認機種はラズパイ4、OSはRaspbian Buster）」**
2.  **「ノートPC(確認OSはWindows10)」（ディスプレイ、キーボード、マウスの代替、USBで電源も代替可能な時も）**
3.  **「スマートフォン(確認機種はPixel3a OSはAndroid)」（wifiの代替）**

# 自己流ラズパイリモート開発原則

1.  **ラズパイ構築後、即リモート設定する**
2.  **初期設定は「スマホで」ラズパイをいじる**
3.  **wifi 環境がある時はRDP/VNCなどでリモート接続**
4.  **ログなどはslackなど外部連携できるツールで通知すると便利**

トラブル編. **もしスマホ、wifi切替時にIPがうまく切り替わらなかった場合**

## 1. ラズパイ構築後、即リモート設定する
本記事は「ラズパイを構築した」ところから始めさせていただきます。
「ラズパイ構築」についてはネット上にもたくさんの記事がありますので、そちらをご参照ください。
今回重要なのは、構築した後です。ラズパイの開発環境を構築し、ラズパイでOSが立ち上がるところまでできたら、まずは急いで以下の設定を行ってしまいます。

1.ターミナル画面でRDP接続用の xrdp インストール
参考：[xrdpのインストールと接続](https://www.hiramine.com/physicalcomputing/raspberrypi3/xrdp_installconnect.html)

```
$ sudo apt-get update
$ sudo apt-get install xrdp
$ sudo apt install tightvncserver
```

2.ラズパイのターミナル画面で、slack通信用スクリプトで使用する slackweb , pustil インストール
参考：[Raspberry Piにリモートデスクトップで接続する](https://dbpro.xyz/3967)

```
$ sudo pip install slackweb
$ sudo pip install psutil
```

3.slack通信用の以下のプログラムをラズパイ上に配置
vi,nano などのエディターで画面を開き、以下のpythonのプログラムを貼り付ける
参考：[ラズパイのWi-FiアドレスをSlackに通知する](https://hokamura.net/programing/1731/)
参考：[ping疎通確認結果を機械的に判定する](https://qiita.com/hamemi/items/917eb822cf5bd12552cc)

```python:send_IPinfo.py
import slackweb
import psutil
import socket
import time
import subprocess

def is_ping(host):
	# linux only
    ping = subprocess.Popen(["ping", "-w", "3", "-c", "1", host], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    ping.communicate()
    return ping.returncode == 0

time.sleep(180)
hostname = socket.gethostname()
slackurl = "slackで取得したWebHook urlをここに記載"
##
for name, addrs in psutil.net_if_addrs().items():
    if name == "usb0" or name == "wlan0":
        print("connect succeed")
        flg = True
        for addr in addrs:
            if addr.family == socket.AF_INET:
                message = hostname + " " + name + " is " + addr.address
        slack = slackweb.Slack(url = slackurl)
        slack.notify(text="%s" % message)
        print(message)
```

4.自分の持つスマホをテザリングモードにしてケーブルで繋ぐ

iPhoneもAndroidもできます。以下を参考に、iOSはBlutoothで、Androidはケーブルで有線接続することで、ラズパイからテザリングでネットワーク接続することができるようになります。
参考：[iPhoneにBelutooth接続してテザリング](http://make.bcde.jp/raspberry-pi/iphone%E3%81%ABbelutooth%E6%8E%A5%E7%B6%9A%E3%81%97%E3%81%A6%E3%83%86%E3%82%B6%E3%83%AA%E3%83%B3%E3%82%B0/)
参考：[Raspberry PiとAndroidでUSBテザリング](https://dbpro.xyz/3967)

5.インターネット接続できるか確認し、できたらslackのAPIを登録する

今回は、slackのwebhookURL を取得し、pythonスクリプトで得た情報をslackに飛ばしますための設定をします。詳しくは以下を確認ください。
もし使用したくない場合は、スクリプトの以下28,29行目をコメントアウトするとslackを使用せずに動きますので、代わりにwebAPIやメール送信など外部連携できる方法に変えてみてください。

```
slack = slackweb.Slack(url = slackurl)
slack.notify(text="%s" % message)
```

参考：[SlackのWebhook URL取得手順](https://qiita.com/vmmhypervisor/items/18c99624a84df8b31008)

6.send_IPinfo.pyが動作するか確認し、確認できたらcronに登録する
参考：[Raspberry Piで cronを使って起動時にコマンドを自動実行したりｎ分間隔で繰り返し実行する方法](http://www.neko.ne.jp/~freewing/raspberry_pi/raspberry_pi_cron_crontab_autoexec_script/)

```
@reboot /usr/bin/python /home/pi/ipinfo_slack.py 
```

7.自分のPC、及びスマートフォンにリモートデスクトップアプリを入れ、slack及びコンソールに出るIPで接続できるか確認。


一旦、ここまでで、設定自体は終了です。手順の1-7までうまくできていれば、ラズパイには電源以外何も接続しないで開発ができる状態になります。

## 2. 初期設定は「スマホで」ラズパイをいじる

今回、「ラズパイのリモート開発」を軸としているため、リモート接続のためのネットワーク接続が必要になります。しかし、屋外でwifiなどのネットワークが必ずあるとも限らず、その為にもスマホのテザリングを活用するのがポイントです。

又、仮にノートPCがなくとも、スマホテザリングしてスマホにRDPのソフトを入れれば、簡単な設定はできますので、別のwifiネットワークを設定、などの用途で使用することもできます。

## 3. wifi 環境がある時はRDP/VNCなどでリモート接続

wifi などのネットワーク環境があれば、（スマホテザリングでも）リモートでラズパイ接続できます。
今回は手順として windowsでもGUI簡単に扱え、スマホ対応もしている RDP にしましたが、VNC など別のツールでも問題ないと思います。

## 4. ログなどはslackなど外部連携できるツールで通知すると便利

できるなら、開発しなければいけない時以外はラズパイに接続もしないで運用できるのが望ましいですね。今回はリモート接続することが前提となりますが、

- リモート接続したい
- リモート接続するにはラズパイのIPを知らないといけない
- ラズパイのIPはラズパイに接続してIPを調べないといけないのでリモート接続したい？？？

という矛盾が生まれてしまいます。本来はラズパイに接続せずにIPを知りたいので、「自分自身のIPを調べslackに通知するスクリプトを組み、それを cron で起動時に実行する」という仕組みにしています。

(※)注意点としては、起動した際にスマートフォンのテザリング、ないしwifiに接続できる状態にしておいてください。又、すぐpingするとnetwork疎通前にプログラムが起動してしまうので適当に3分間waitしており、すぐにはslackに通知は飛びません。


## トラブル編. もしスマホ、wifi切替時にIPがうまく切り替わらなかった場合

スマートフォンと、wifiを順次接続する、あるいはwifiからスマートフォンに接続するなどをしていると、本来ならIPも自動にそのネットワークに合わせてラズパイのIPも切り替わるのですが、IP がうまく切り替わらない時があります。その場合はxrdpサービスの再起動、ダメなら再インストールを試してみてください

サービスを再起動

```
sudo service xrdp restart
```

ダメなら xrdp を再インストール

``` 
sudo apt remove xrdp
sudo apt update
sudo apt install xrdp 
```

# 終わりに

上記の設定、あるいは考え方をすると、ラズパイがもっと楽にリモート開発できるのではないかと思います。