SORACOM-SIMで IoT送信してみたい - 3) 別サーバ(GAS)に送信する

## 送信先のサーバはどこで指定しているか？

ATコマンド群のサンプルを使ってきたので、無事 SORACOMサーバに届いていました。

### 送信先サーバの指定はどれ？

発行した ATコマンド群のどこかに、送信先サーバURLの指定があるハズです。
```
AT+SHCONF="URL","http://uni.soracom.io"　　　<--- ★
AT+SHCONF="BODYLEN",1024
AT+SHCONF="HEADERLEN",350
AT+SHCONN
AT+SHSTATE?
AT+SHCHEAD
AT+SHAHEAD="User-Agent","CAT-M/NB-IoT GNSS Unit w/ SIM7080G"
AT+SHAHEAD="Connection","close"
AT+SHAHEAD="Accept","*/*"
AT+SHAHEAD="Content-Type","text/plain"
　： 略
```
ここに送ることで Harvest Data にデータが届いた訳です。


### 接続先サーバを変更しちゃえ
```
AT+SHCONF="URL","http://io.myserver.com"　　　<--- ★
AT+SHCONF="BODYLEN",1024
AT+SHCONF="HEADERLEN",350
AT+SHCONN
　： 略
```
これで送信先が変わるハズ。
いや、ちょっと待て。これはダメだ。

### ATコマンドの接続先を変更するデメリット
ATコマンド発行するのは、各デバイス。
ATコマンド発行するプログラムを改修するには リモートメンテナンス？ それはかなり手間。(嫌だ)

## SORACOMさんの ベストプラクティス

### Unified Endpoint (Public beta)
[Unified Endpoint (Public beta)](https://users.soracom.io/ja-jp/docs/unified-endpoint/)
を見ると、以下のような記載があります。

> Unified Endpoint は、デバイスから送信されたデータを、Beam / Funnel / Funk / Harvest Data に転送するための エントリポイント を提供するサービスです。
![xx](https://users.soracom.io/ja-jp/docs/unified-endpoint/unified-endpoint-01.png)

送信先 [エントリポイント一覧](https://users.soracom.io/ja-jp/docs/unified-endpoint/entry-points/)　を読むと、

HTTPの場合
\- uni.soracom.io:80　　　　<--- ★
\- uni.soracom.io:8888
\- unified.soracom.io:80
\- unified.soracom.io:8888

つまり ココに送っておけば、SORACOMユーザーコンソールの設定で、データ送信先を一元管理して 随時変更ができるのですね。(ありがたや)

## SORACOM Beam って？

上の **Unified Endpoint** の図を見ると **Beam** から **我がのサーバ** に転送してくれるようです。

[SORACOM Beam](https://users.soracom.io/ja-jp/docs/beam/)　を見ると、以下のような記載があります。

> SORACOM Beam は、IoT デバイスから送信されたデータに対して、プロトコル変換や TLS 暗号化などの処理を加えて任意の接続先に転送できるサービスです。
>
> 本来デバイスで行う上記の処理を、Beam に肩代わりさせることで、デバイスの消費電力や通信量の削減が期待できます。また、転送先を SORACOM ユーザーコンソールで変更できるため、デバイスの設定を変更することなくデータの転送先を変更できます。
> ![aaa](https://users.soracom.io/ja-jp/docs/beam/fig_beam_01.png)
> 
これだ！ (喜)

HTTPSの実装も、ここ(Beam)でやてくれるのか！ 
デバイス側で HTTPS実装するのって CPU/メモリリソースを食うので厳しいし、3G/LTEでHTTPSパケット発行する通信料も増えるので、どうしようヤバいな と考えていたので。

### Beamの設定

では、Beamの設定ってどんな感じでしょう。
![SORACOM_BeamHTTP設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153211/011b9fbe-cabd-788f-e910-cb57278d10d0.png)

この転送先に、我がのサーバURLを指定すればいい訳ですね。
今回は GoogleAppsScript (略して GAS) に送ります。

|項目|設定値|
|:-|:-|
|エントリポイント| |
|　パス|\/GAS01|
|転送先|   |
|　ホスト名|script.google.com|
|　パス|/macros/s/AKfycbwyET_(略)_jLK8vLZypV/exec|

ここで設定した通り、
　**Unified Endpoint** の **/GAS01** というパスに接続すると、
　転送先に指定した **ホスト名** の **'/macros/s/～略～/exec'** に転送するよ
という設定です。

## モデムからの送信先指定

この SORACOM Beam に設定した GASへ転送するには、デバイス側の ATコマンドの変更は必要でしょうか。
上に記載したように、接続先サーバは変更不要です。
では、GASに送るデータ(POST QUERY)を定義すればイイはずです。

~~~
AT+SHCONF="URL","http://uni.soracom.io"
AT+SHCONF="BODYLEN",1024
AT+SHCONF="HEADERLEN",350
AT+SHCONN
AT+SHSTATE?
AT+SHCHEAD
AT+SHAHEAD="User-Agent","CAT-M/NB-IoT GNSS Unit w/ SIM7080G"
AT+SHAHEAD="Connection","close"
AT+SHAHEAD="Accept","*/*"
AT+SHAHEAD="Content-Type","application/x-www-form-urlencoded"　　<-- POST QUERY を送るという MIME-type
AT+SHBOD=31,10000　　　　　　　　　　　<--- POST QUERY をBODYに指定
> vID=KZ015&vTemp1=207&vTemp2=193 　　<--- 我がのGASに送信するデータ
AT+SHREQ="/GAS01",3　　　　　　　　　　<--- 重要なのはココ (*1)
AT+SHDISC
~~~
*1 : SORACOM Beam の設定画面で 「**ココに** 送ったものを 転送先に転送する」のパス名に定義した値ですから、今回は "**/GAS01**" を指定。
　　あ、ちなみに **,3** とは **POSTで送れ** の意味。(GETで送るなら **,1** )

## 実行結果

では、SORACOM基地局に繋いで、GAS接続用の ATコマンドを打つと・・・
正しくGASにデータが届いていました。[成功]
![GAS_Spreadsheet.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153211/dc6a18a0-5834-02de-f08a-944bb2f81fa3.png)

### ATコマンドの実行結果
~~~
　： 略
AT+SHBOD=31,10000
> vID=KZ015&vTemp1=207&vTemp2=193
OK
AT+SHREQ="/GAS01",3

OK
+SHREQ: "POST",207,3947　　　<--- *2

AT+SHDISC

OK
~~~
ATコマンド発行時のログを見ると、
*2 : POST成功(HTTPステータス 207)、HTTP-Response 3947 byte 返されています。

念のため HTTP-Response 3947 byte 読んでみましょうか。
~~~
　： 略
AT+SHBOD=31,10000
> vID=KZ015&vTemp1=207&vTemp2=193
OK
AT+SHREQ="/GAS01",3
OK
+SHREQ: "POST",207,3947
AT+SHREAD=0,3947　　　<--- HTTP-Response 3947byteを読みます のATコマンド
OK
+SHREAD: 3947
　： なんだかんだ　　　<--- HTTP-Responseのメッセージ

AT+SHDISC

OK
~~~
この **なんだかんだ** の部分ですが、私の環境では Unified Endpointに届いたデータを SORACOM Beamと SORACOM HarvestData の２か所に転送するように環境設定していますので、**それぞれの実行結果が json形式で返ってくる** ようです。
~~~
{"result":"ng",
	"detail":{
		"SoracomBeam":{
			"statusCode":405,　　　<--- ★ エラー(405)
			"contentType":"text/html; charset=utf-8",
			"body":"<!DOCTYPE html><html lang=\"ja\">...略...</html>",
			"headers":{
				　: 略
				"transfer-encoding":"chunked"
			}
		},
		"SoracomHarvest":{
			"statusCode":201
		}
	}
}
~~~
あれ？ **SORACOM Beam の実行結果が 405** ですね。GASにデータは届いているのに。(謎)
詳しいことは追及できません。(失礼)
<br>
<br>

以上で、本記事 [SORACOM-SIMで IoT送信してみたい - 3) 別サーバ(GAS)に送信する](#) の記事は終了です。

---
次のページ：

[執筆予定]
　[MicroPythonから IoT送信してみる](#)
 　※ちょっと先かも... (冷汗)