enebular と WHILL Model CR で シェアリングサービスをプロトタイプしてみた。

WHILLのソフトウェアエンジニアの河原です。

この記事は
[enebular Advent Calendar 2019](https://qiita.com/advent-calendar/2019/enebular)の13日目と、
[WHILL Advent Calendar 2019](https://adventar.org/calendars/4220)の13日目
の記事です。
が、投稿がだいぶ遅れてしまいました。申し訳ありません。

[enebular](https://www.enebular.com/) と [WHILL Model CR](https://whill.jp/model-cr) で シェアリングサービスをプロトタイプしてみた。という内容です。

## 動機
去年、中国の深センに遊びに行った時に、街中にシェアリングサイクルが何台もあり、アプリでQRコードを読み取ってアンロックして使えるというのがありました。

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">mobike(シェアサイクル)の解錠<br>スマホでスキャンしたら自転車の鍵が開く<a href="https://twitter.com/hashtag/%E6%B2%B3%E5%8E%9F%E6%B7%B1%E3%82%BB%E3%83%B3%E6%97%85?src=hash&amp;ref_src=twsrc%5Etfw">#河原深セン旅</a> <a href="https://t.co/kQrgSrHB8W">pic.twitter.com/kQrgSrHB8W</a></p>&mdash; Keisuke KAWAHARA (@ktansai) <a href="https://twitter.com/ktansai/status/973419029850333184?ref_src=twsrc%5Etfw">March 13, 2018</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

滞在中、自由に移動できるという点でとても便利なサービスだなと思い、重宝していました。
日本でもdocomoのシェアサイクルが東京では利用可能で、たまに個人的に使っています。

WHILLでも、こういったシェアリングサービスがあれば便利だなと思っていたので、今回あまり時間をかけず、プロトタイプしてみました。

**※注意: 今回作っているのはWHILLでのビジネスや開発に関係なく、趣味的にハッカソン感覚で作ってみたという感じです。**



## 作ったもの

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">enebular と WHILL Model CR で シェアリングサービスをプロトタイプしてみた。<a href="https://t.co/klQwXW4Gd5">https://t.co/klQwXW4Gd5</a><br>(注意:音あり) <a href="https://t.co/AzKELRAdR4">pic.twitter.com/AzKELRAdR4</a></p>&mdash; Keisuke KAWAHARA (@ktansai) <a href="https://twitter.com/ktansai/status/1206593471303208960?ref_src=twsrc%5Etfw">December 16, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

利用イメージ的には、スマホでログインして、レンタルを開始というボタンを押したら、一定時間利用可能になるというイメージです。

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">クラウドでロックされている時は電源を入れようとしても、強制的にOFFにされて、QRコードをスキャンするように促されます。 <a href="https://t.co/DjHK1a27dY">pic.twitter.com/DjHK1a27dY</a></p>&mdash; Keisuke KAWAHARA (@ktansai) <a href="https://twitter.com/ktansai/status/1206594532659220480?ref_src=twsrc%5Etfw">December 16, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ちなみに、QRコードをスキャンせずに電源を入れようとすると電源が切れ、QRコードをスキャンするように指示されます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38001/16f1cbea-fde4-282c-eac7-6cf39a126f25.png)

仕組み的には、enebular がスマホからのリクエストでFirebaseのRealtime DBを操作します。
Macで動いているPythonのスクリプトが定期的にFirebaseにアクセスして、クラウド上でロックされているかをwatchしています。
Realtime DBの値によって、電源をOFFにするべきか、ONにするべきかというのを判断しています。


MacBookはWHILLの下のかごの中に入れています。
<img width="400"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38001/671e3e60-c855-a07b-e5fc-6bfaed17636e.jpeg">

MacBookとWHILLはこういう感じでつながっています。
<img width="400"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38001/e6b3183d-ee6a-f2e7-7763-c7672f51a08f.jpeg">

ケーブルに関してはこちらの記事を御覧ください。
[WHILL Model CRのRS232Cケーブルは怖くないよ！](https://note.com/katsushun89/n/n3784991a6143)



## 使ったもの
### WHILL Model CR
https://whill.jp/model-cr

WHILLでは現在、Model Cという市販のモデルを販売していますが、この Model CR はそのModel CにSDKが提供されているモデルになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38001/900d94f7-3f90-c65f-d788-ac8b77104cc0.png)

[制御のための通信のプロトコル](https://github.com/WHILL/whill_control_system_protocol_specification)は公開されているので、自作でSDKなどを用意していただいても良いのですが、

現在 WHILL公式からは以下のSDKが公開されています。
- ROS用パッケージ https://github.com/WHILL/ros_whill
- Arduino SDK https://github.com/WHILL/whill-sdk-arduino
- Python SDK https://github.com/WHILL/pywhill
- C++ SDK https://github.com/WHILL/libwhill

RaspberryPiや、Arduinoからでも簡単にWHILLを制御することが可能です。


### enebular 
https://www.enebular.com

enebularは株式会社ウフルが開発しているNode-REDで簡単にビジュアル的にプログラムを開発/デプロイすることができるサービスです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38001/9336bebf-0d81-79d0-c68e-27868b921d32.png)

以前に知り合いに付いていって、LTイベントに参加したのですが、そのときはアカウントを作って少しだけ触っただけでした。
APIサーバーを作ったり、webサーバーを作ったり、IoT系のプロトタイピングにぴったりなイメージがあります。
このWHILLのプロトタイピングをするのに丁度いいかなと思い、使ってみました。


## WHILL側の開発
WHILLの社員であるのにも関わらず、Model CRとそのSDKを触るのは実は初めてでした。なので、間違っている部分もあるかもしれません。
今回は公開されているPythonのSDK(https://github.com/WHILL/pywhill )を使いました。

git clone してみると、このようにexampleがいくつかありました。
このまま実行しようとすると、importのパスでエラーが起き、上の階層に移動させて、import文に正しくパスを指定してあげると問題なく動くようになりました。

```
.
├── LICENSE
├── README.md
├── main.py ← ここに作ったら動く
├── example
│   ├── cr_example1_joy.py
│   ├── cr_example2_data.py
│   ├── cr_example3_callback.py
│   ├── cr_example4_blink_power.py
│   ├── cr_example5_hold_joy.py
│   └── cr_example6_copy_speed_profile.py
└── script
    ├── whill.py
    ├── whill_data.py
    └── whill_packet.py
```

ちなみにOSサポートの欄には Macはunder migrationと書いてあったのですが、問題なく使うことができました。

細かく書いていると長くなりそうなので、重要ポイントだけ掲載します。

まずWHILLをイニシャライズします。USBポートをつないで、データを取得するようにします。

```main.py
from script.whill import ComWHILL

whill = ComWHILL(port='/dev/tty.usbserial-FT1ZQR8V')
request_speed_mode = 0
whill.start_data_stream(1000, 0, request_speed_mode)
```

そして、Firebase上のロック状態を監視しています。
Firebase上でロックされていたら、SDKでWHILLの電源を監視して、ONの場合は電源を切って、音声を再生します。
Firebase上でアンロックされた場合は、WHILLの電源をONにして、クラウド上でロックされるまで待機します。


```main.py

while True:
    time.sleep(1)
    is_refreshed = whill.refresh()
    
    if(firebase_db.get()) : 
        # firebaseから取得して、WHILLがクラウドでlockされていたら、電源状態をチェックする。
        if whill.latest_received_data_set == 0:
            whill.start_data_stream(1000, 1, request_speed_mode)
        else:
            if(whill.power_status == 1): 
                whill.send_power_off()  # 電源がONになっていたらOFFにする
                print("power on")
                print("send power off")
                whill.power_status = 0
                sayLockMessage() # しゃべる
            else : 
                print("power off")

    else :
        # firebase上でlockが解除されていたら、電源をONにして喋る。
        print("ロック解除") 
        whill.send_power_on()
        sayUnLockMessage()
        while firebase_db.get() == False : # クラウドでロックされるまでスリープする。
            time.sleep(1)
```

喋る部分に関してはsayコマンドをpythonのsubprocessから呼ぶという処理にしました。

```python

def sayLockMessage() :
    command = "say ウィルはロックされています。利用開始するにはキューアールコードをスキャンしてください"
    subprocess.run(command,shell=True)
```

ちなみにFirebase上のDBはこういう感じで、シンプルにロック状態をBoolで管理しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38001/8f01cb7d-2c3c-7977-0af4-59c6e829dc40.png)



## enebular側の開発
今回、作成したflowはこんな感じです。
![スクリーンショット 2019-12-15 1.10.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38001/1b753e54-eb60-d040-168c-85e04b2dee6d.png)

上の /rental にブラウザでアクセスすると、templateで設定されているhtmlがレスポンスとして帰ってきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38001/acbfbfbf-9aff-9233-bdb5-63a694565279.png)

ここの上のボタンを押すと、/rental_start に対してリクエストを発行し、ロックするを押すと、/lock というリクエストを発行します。これらは両方、テンプレートで用意されたJsonをRealtime DBにsetしに行きます。

Firebaseの連携するノードや、Twitter、メールなどのノードも用意されていて驚きました。組み合わせるだけで、本当にノンコーディングでおもしろいサービスが作れそうですね。

例えば、ログイン機能とかユーザー名とレンタル時間を指定したら、「○○さん、レンタルを開始しました。使用期限は△△:△△です」のような音声を再生する機能とか、ログインしていないユーザーがアクセスしたら、「他のユーザーが使用中で、何時に帰ってくる予定です。」とかいうのをスマホ上に表示できるようにしたら、面白いました。

enebularで何か動くものを作るのははじめてだったのですが、拍子抜けするほど、簡単にサービスの連携や開発やデプロイができ、感動しました。

今度から、趣味の電子工作とかでもenebularを使ってサクッとサーバーサイドの処理をプロトしてみようかなと思います。

## まとめ
enebular でサーバーサイドの処理をゴリゴリ書かずに、簡単にプロトタイプができました。
WHILLには、組み込みが専門のエンジニアもいるので、気軽にこうやって使えるenebularを紹介してみようと思います。

## 宣伝
最後に、宣伝になってしまうのですが、
WHILL Model CRはこういったサービスを作ったり、自動運転などの開発がしやすいモデルになっています。
人が乗れる乗り物で、SDKで手軽に制御できるものはそんなに無いと思います。
ぜひ、興味があればサイトの方を御覧ください。
https://whill.jp/model-cr

また、WHILL,inc. では、今回紹介したような、WHILLを活用した新しいサービスの企画&開発や、自動運転モデルの開発等に関連して、
サーバーやWeb系(フロントエンド/バックエンド)のエンジニアの仲間を探しています。

例: 
- [モビリティを活用した新サービスを立ち上げるエンジニア募集!](https://www.wantedly.com/projects/357830 )
- [パーソナルモビリティ連携の自社サービス立ち上げサーバーサイドエンジニア募集](https://www.wantedly.com/projects/245054 )

上記以外にも様々な採用枠があります。
[Wantedly](https://www.wantedly.com/companies/whill ) 

もし、何か興味があるということがありましたら、や Twitter [@ktansai](https://twitter.com/ktansai) まで DMやリプライなどご連絡いただければ、質問回答orご紹介します。