sakura ioのLTEモジュールからAlibaba Cloudへデータを転送してみる

# はじめに
Sakura IOのLETモジュールとArduinoシールドを知人が貸してくれた。こういうものが手元にあるとどこかに繋げたくなる。「[sakura.ioとAlibaba Cloud が繋がった! enebular のおかげ！](https://qiita.com/eterao/items/9de429278288e3ca21b3)」で@eteraoさんがAlibaba CloudのIoT Gatewayに接続しているので、私は**Function compute**に直結してみよう。**Function compute**とは乱暴に言えばFaaS、AWSでいうところのLambdaだ。任意のAlibaba Cloudのサービスにデータを転送できるが、とりあえず今日はsakura ioから飛んできた生データをログに書き込むところまで。


## 構成
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/10d41316-996a-9126-de79-0c70d3355989.png)

## ブツ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/a38b69eb-9116-29a1-1c1e-5537ec4d6699.png)


ドキュメント読む限りSoftBankのBand1(2Ghz)またはBand8(900Mhz)のLTE Cat1(Cat M1ではない)をつかむらしい。現段階ではBandやPLMN、Cell IDなどモバイルの生情報を生で見れるATコマンドやAPIは見つけられず。。。

https://sakura.io/product/
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/d7ac2cc1-c6bd-6bb1-556a-96ea88c39975.png)



# Alibaba Cloudの準備
まずはfunction computeのログを保存するlog serviceを準備する。

## log serviceの構成
log service のコンソールへ遷移
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/b8a352f4-029e-6670-7a25-64eb8cf49b02.png)

logs erviceのプロジェクトを作成
ここではプロジェクト名は"makotakatest"、リージョンは東京を選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/56d58b3b-b0e4-7911-3ca8-2820438cf900.png)

作られたプロジェクト名のリンクへ遷移
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/18ff7d9d-fc53-e7d0-0a56-be71a72b093f.png)

logstoreを作成。 ここではlogstore名は"logstoretest"、ほかは全てデフォルト値。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/0c611b12-20e3-df1b-2d9a-23140cb98f53.png)

これでlogを保存する場所が確保できました


## function computeの構成
Function Computeのコンソールへ遷移します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/d0960136-211f-c285-49e0-a68198cf10ff.png)

サービスを作成します。ここではサービス名sakura。詳細設定をオンに。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/8789d8ed-3ee2-a5a4-b479-afcadff3ba4c.png)

ログ設定のログプロジェクト、logstoreに先ほど作成した”makotakatest”,"testlogstore"を選択します。このままではこのfunction compute インスタンスはlogstoreにアクセスする権限がないので権限を付与するために「新しいロールを作成」を選択して「承認」へ。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/57caf79a-3843-bd50-8658-8f4c3576dcbc.png)

Role nameをわかりやすい"sakura-role"に変更して「権限付与に同意」
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/170fde3c-01f7-f17d-e091-6414f8c17ddf.png)

権限が付与されたことを確認して「OK」
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/87f09489-928d-8fb6-ba30-dff3bfe9a547.png)


「関数」を追加
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/2da20a46-08e4-46ac-e66f-92f47ec5bf29.png)

「空の関数」を選択。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/22a93ff2-9c55-67b1-b613-8a4ecef4bc28.png)

トリガーの設定で、トリガータイプを"HTTP"、トリガー名をここでは"sakura"、承認を"anonymous"、メソッドにPOSTを入力
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/4308aa42-3dd8-cd99-e749-7d48d13d9232.png)

サービス名で"sakura"を選択、関数名をここではgetValueと入力。ランタイムはここではPython2.7を選択。インライン編集を選択してソースコード編集。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/799a5d53-a7fd-abce-04a8-9793fb9f2169.png)

sakura ioのwebhookには”Secret”という設定項目があり、これをキーにPOSTされたテキストのSHA1のハッシュを取り、その値を"X-Sakura-Signature"というHTTPヘッダーで送信する。Alibaba Cloud側では受け取ったPOSTのbodyに同じSecret値のハッシュを計算してこの"X-Sakura-Signature"の値と比較することで正しいデータか評価可能。
コード中では`X-Sakura-Signature`の値は`environ['HTTP_X_SAKURA_SIGNATURE']`で参照可能。ほかのheaderも、HTTP_に続けてすべて大文字に変換し、"-"(ハイフン)を"_"(アンダースコア)に変換したheader名をキーにすれば値を取得可能。
ここでのsecretは"**aliyun123**"。**sakura IOで設定するので控えておく。**

```python
# -*- coding: utf-8 -*-

import logging
import json
import hmac
import hashlib

def handler(environ, start_response):
    logger = logging.getLogger() 
#以下でPOSTされたbodyの内容をテキストで取得
    try:
      request_body_size = int(environ.get('CONTENT_LENGTH', 0))
    except (ValueError):
      request_body_size = 0
    request_body = environ['wsgi.input'].read(request_body_size)
#ハッシュ値チェック
    secret = "aliyun123"
    signature = hmac.new(secret.encode("utf-8"), request_body.encode("utf-8"), hashlib.sha1).hexdigest()
#ハッシュ値が正しいときの処理
    if(environ['HTTP_X_SAKURA_SIGNATURE'] == signature):
      logger.info('signature check is OK: ' + environ['HTTP_X_SAKURA_SIGNATURE'])
      bd = json.loads(request_body)
      logger.info(bd['payload']['channels'][0]['value'])
#ハッシュ値が正しくないときの処理
    else:
      logger.info("signature check is NG: " + environ['HTTP_X_SAKURA_SIGNATURE'])

    status = '200 OK'
    response_headers = [('Content-type', 'text/plain')]
    start_response(status, response_headers)
    return "api gateway"
```

アクセス権限の承認へ進み
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/92a6bee1-3361-3d99-dd55-23d41b0bc02b.png)

権限付与に同意
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/e5690750-c53a-e318-7e89-389c12faaa4a.png)

内容を確認して同意
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/655e1eba-5b99-ac26-2c61-3a574dbb6635.png)

まだログが有効化されていないので、ログを有効化
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/e41794fd-780d-416d-0326-cd27e92ce162.png)

「OK」を押下
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/b20cda2f-a037-0342-d0e9-1295adfa34bb.png)

これで関数が作成された。**URLの値がsakura IO側で設定するWebhookのエンドポイントになるので控えておく**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/05c4013c-72f4-98c1-df4e-3609bca68690.png)

これでAlibaba Cloud側の準備は終わりだ。Sakura IO側でSecret(ここではaliyun123)とエンドポイントのURLの値が必要になるので控えておく。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/fd5466ca-dc17-dc54-785b-396630197091.png)


# sakura ioの準備
## 環境準備
下記に大変わかりやすくまとまっている。
https://sakura.io/docs/pages/guide/startup-guide/arduino.html

この手順に従って以下までを実施

- コントロールパネルへのログイン
- プロジェクト作成
- 通信モジュール登録

## 新しい連携サービスの作成
ここではoutgoing webhookを利用するので新規に連携サービスを作成する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/9f548c73-c678-4cf4-c79b-d6bf92c8b2b4.png)

Outgoing webhookを選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/fd1ac979-0cf8-2415-aff1-538c980ffefa.png)

ここでは名前にAlibaba Cloud、Payloadに先ほどAlibaba Cloud側で作成したエンドポイントのURL、Secretに先ほどAlibaba Cloudで設定した同じ値(ここではaliyun123)を入力し、作成を押下。これでsakura io側も準備ができた。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/8dd0a12d-a6f9-e60c-1ad7-83d5c9f731e1.png)

# デバイスの準備

## デバイスの組み立て
以下を参考に「通信モジュールとArduinoシールドの組み立て」を実施。今日はセンサーは接続しません。
https://sakura.io/docs/pages/guide/startup-guide/arduino.html#id7

## 開発環境の準備
以下を参考に
https://sakura.io/docs/pages/guide/startup-guide/arduino.html#id9

- Arduino IDEのインストール
- Arduinoの接続
- SakuraIOライブラリの入手

まで実施

## 手入力送信用プログラムの書き込み
手入力によるデータ送信確認のため、予め用意されているスケッチをArduinoに書む。 [ファイル]＞[スケッチ例]＞[SakuraIO]から Shell を呼び出し、マイコンに書き込む。

これでシリアルコンソールからデータを送信できるようになった。以下はchannel 0でintegerの123を送信する、という意味

```
enqueue 0 i 123
send
```

#テスト
とりあえず送ってみる
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/d7e2e96c-0058-81a8-52ef-6d732cb75497.png)


地味だけどAlibaba Cloudのfunction computeで"123"という値が受信できたことをログで確認できた。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132165/8c46bb31-f888-8093-e5d7-b173a8a79e67.png)

#最後に
これは私の趣味の世界です。所属する団体の考え方は全く反映していません。