Raspberry Piに、Blynkサーバーを立てる（Widgetが使い放題）


**[Blynk](http://docs.blynk.cc/)**は、インターネット上にあるBlynk Serverを介して、デバイスと情報のやりとりをします（下の図）。スマホとIOTデバイス**だけ**で簡単にリモート操作ができるので大変すばらいい。
![architecture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194281/6b32a6b8-3cbd-c28a-7a1d-e8898afefedb.png)

# ローカルサーバーを持つ利点は?
今回、紹介するのは、そのBlynk serverをお家のRaspberry Piに立てることです。うん？サーバーなしですぐできるのが長所なのになぜだ？と思うかも知りません。

* 応答が速い (お家の無線LANだけでやりとりするので）
* BlynkのWidgetが使い放題（タダです)

下記の図のようにBlynk mobileアプリにジョイスティックやボタンなどのWidgetをつけるのにお金がかかります。（Energyというポイントが必要で、最初に1000pointsまで無料です）自分のサーバーなら、それを自由に設定できるので、開発の際に自由度がぐーんと増します。そして、お家のサーバーなので、ネットを介すよりタイムラグがすくなく、例えば、リモコンでミニカーを操作する場合、操作性が断然違います。

![IMG_3766.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194281/34098d79-d0d4-6093-dc21-e51b3e6a6e55.png)


## 今回使ったもの
* Raspberry Pi 3 Model B+


## 手順
1. Raspberry piにDockerをインストール
2. Blynk ServerカスタマイズしてImage作成
3. 自動起動設定と起動
4. Mobile AppのBlynkでユーザー作成


# 1. Raspberry piにDockerをインストール
下記の先人の知恵を借りました。

* [無線LAN設定](https://qiita.com/d0d0npa/items/0f2d6af2618618982723)
* [IPを固定](https://dev.classmethod.jp/articles/raspberrypi-remote-connect/)
* [RaspberryPiにDockerを構築する](https://qiita.com/d0d0npa/items/0f2d6af2618618982723)

ただ、素早くやってみたいだけの方はこちらのコードでどうぞ


```bash
// 現在の Raspberry pi内の環境
$ uname -a
Linux raspberrypi 4.14.98-v7+ #1200 SMP Tue Feb 12 20:27:48 GMT 2019 armv7l GNU/Linux

$ lsb_release -a
No LSB modules are available.
Distributor ID:	Raspbian
Description:	Raspbian GNU/Linux 9.8 (stretch)
Release:	9.8
Codename:	stretch
```

Raspberry Piに Docker インストール

```bash
# Install
$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh
$ sudo systemctl enable docker
$ docker --version
# Docker version 19.03.9, build 9d98839

# Raspbianの標準ユーザのpiにDockerの実行権限を付与します。
$ sudo usermod -aG docker pi
```

インストールと起動確認
インストールしたら、常にdockerが動くようになっています。

```bash
# 確認
$ systemctl status docker.service
● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2020-05-23 21:56:03 JST; 1 day 14h ago
   
$ ps aux | grep docker
root       416  0.1  6.5 967836 58464 ?        Ssl  May23   2:48 /usr/bin/dockerd -H fd:// -- ....
root       857  0.0  0.3 866456  3152 ?        Sl   May23   0:34 /usr/bin/docker-proxy -proto tcp -host-ip ....
root       870  0.0  0.3 867224  3396 ?        Sl   May23   0:00 /usr/bin/docker-proxy -proto tcp -host-ip ....
root       879  0.0  0.6 799176  5672 ?        Sl   May23   0:25 containerd-shim -namespace moby -workdir ....
pi       12761  0.0  0.0   4340   564 pts/0    S+   12:49   0:00 grep --color=auto docker
```

# 2. Blynk ServerカスタマイズしてImage作成

[blynkの公式Github repository](https://github.com/blynkkk/blynk-server)にdockerを使った起動方法がありますが、そこの説明のままに実行したら毎回データーが初期化されるなど不便なところがあります。そこで、そのイメージを少しカスタマイズしたものを用意したので、[このrepository](https://github.com/yusonkim/localblynkserver)からクローンして、Raspberry piで、実行してください。
大まかには、
**設定ファイル**を簡単に修正できるように、**ユーザーデータを保持**できるようにボリュームを指定しています。dockerに詳しくなくても中をのぞけば仕組みが簡単にわかると思います。

```bash:@RaspberryPi
# イメージビルドソースをクローン
# ビルドしたイメージの中でblynk
$ git clone https://github.com/yusonkim/localblynkserver.git
$ cd localblynkserver

# サーバー設定ファイルを開く(各自環境に合わせてeditorを使ってください)
$ vim server.properties
```

`initial.energy`は、新しいアカウントを作成した時に使えるWidget購入pointです。そのままでも十分ですが、ガンガン使うならもっと高くしても良いでしょう。
`admin.email`と`admin.pass`は、ウェブからの管理画面にアクセスする時に使うものです。この管理画面のURLは、`https://<Rasberry piのhostname>.local:9443/admin`で、お家のネットワーク内で、Macなど他のPCから接続できます。暗証番号等を新たに変更してください。

```:server.properties
...中略
#initial amount of energy
initial.energy=100000
...中略
admin.email=admin@blynk.cc
admin.pass=admin
```
そのあとは、Raspberry pi内でカスタムしたイメージを作成して、Rapberry piが再起動しても常に立ち上がるように設定するだけです。

```bash
# 設定ファイルを取り込んだカスタムBlynk Server Imageを作成
$ ./build.sh
```
# 3. 自動起動設定と起動
下記を参照しました。

* [Raspberry Piで自動起動する方法](https://qiita.com/karaage0703/items/ed18f318a1775b28eab4)

systemctlを使ってRaspberry Piが起動すると自動的にdocker runコマンドで起動するように設定しています。その時に、永続化するボリュームを指定してユーザーデーターがなくならないようにしています。実際には、下記のスクリプトを実行するだけでよいです。

```bash

# Blynk Serverが自動的に起動するように設定
$ ./deploy.sh

# 再起動
$ sudo reboot

# 再起動後確認
# プロセスはすぐ立ち上がりますが、サーバーが起動までには約1分ほどかかります。
$ docker ps

CONTAINER ID        IMAGE                       COMMAND             CREATED              STATUS              PORTS                                                      NAMES
646b4dbdd298        rasbian-blynk:customlocal   "entrypoint.sh"     About a minute ago   Up About a minute   0.0.0.0:8080->8080/tcp, 0.0.0.0:9443->9443/tcp, 8440/tcp   blynk
```

# 4. Mobile AppのBlynkでユーザー作成
アプリがなければ、AppStoreなどからダウンロードしてください。
もしログインしていれば、一度ログアウトして、新しくアカウントを作ります。
ローカルサーバーへの接続は、新しいアカウントを作る時に指定します。
Create New Account を選択して、EmailやPasswordを入力します。
そのあと、下にあるサーバー選択アイコンを選択します。
![IMG_3765.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194281/d369a06a-fbb6-6554-65d4-0af7b93f1094.png)
BlynkからCustomに設定を変更してから、住所にRaspberry piのIP、もしくは <hostname>.localをいれ、ポート番号を9443に指定します。
![IMG_3764.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194281/1a211ae7-2ec5-68fb-e898-bcd1fb472b3c.png)
プロジェクトを作って見ると、Energyが増えていることが確認できます。


# その他
## 管理画面から、token取得
IOTデバイスで動くプログラムを組むときは、PCだと思いますが、その時に、各プロジェクトごとにデバイスのtokenをいれなければなりません。結構長いので、モバイルのBlynkアプリからコピーするのは大変だと思いますが、先ほど出ていた管理画面に接続すれば、簡単に参照できます。

`https://<RaspberryPiのIP>:9443/admin`に接続します。

するとこんな画面が、でます。今回ssl証明書の設定をしてないので、怒られています。Advencedを押して、Proceed to ...を押して管理画面に入ることができます。sslの設定方法は[blynkの公式Github repository](https://github.com/blynkkk/blynk-server)にありますので、ソース上のserver.propertiesファイルも変更すれば、ご自身で設定できると思います。
![Screen Shot 2020-05-26 at 0.10.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194281/a7f9dec4-2f6d-6170-a1f9-8ee698d49d2b.png)
![Screen Shot 2020-05-26 at 0.10.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194281/8c37b3da-2c63-40e9-23ee-217d5a92940e.png)


設定したadmin情報でログインして見ると、
User欄からモバイルで登録したアカウントが確認できます。
![Screen Shot 2020-05-26 at 0.17.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194281/6ff77cdb-1d0d-21ef-b5eb-16e3cb761452.png)
そして、そのアカウントをクリックすれば、プロジェクトやデバイスなどの情報と、デバイスの情報欄にtokenが表示されていることがわかりますので、ここからコピーすれば良いでしょう。
![Screen Shot 2020-05-26 at 0.19.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194281/e4a6f0b1-ed2a-37c1-d0fc-2f69e5a35ca3.png)


## サーバー設置方法検討
Blynk社でローカルサーバー用のBlynk Server公開しているので、それを使えば簡単にローカルサーバーが立てられます。
が、今回は**Docker**を使ってサーバーを立てます。その理由は、

* どんな環境(ハードウェアに関係なし）でも失敗せずに立ち上げられます。
* パッケージやプログラム言語をインストールする必要がない
* 起動・停止・削除が簡単で、綺麗に行える

*Dockerを使うときは、ボリュームを適切にマウントして、ユーザーデーターを保持することに注意が必要です。*そうしなければ、サーバーを起動する度に初期化状態になります。簡単にできますので、心配は要りません。

**docker-compose**やkubernetes(k8s)を使うのもいいですが、今回は必要性をあまり感じませんでした。postgress dbを使って、データー（IOTデバイスからの生データー）を保存するとなるとdocker-composeやk8sもいいオプションですが、今回は、小さな容量で動くRaspberryPiなので、dbは必要ありません。ユーザーデーターもファイルで保存する方法でやっていますので、Blynk server単体で十分です。そして、サーバーの台数を増やしたりするAutoscalingも必要ありませんので、k8sもスキップしました。