pi-fieldとSORACOMを使ってキャベツを見守る(soracom編)

## はじめに

こんにちは、[株式会社Fusic](https://fusic.co.jp/)の@skymer156です。実は明日、社内の軽音ライブに出演するので、駆け足でこの記事を執筆しています。緊張でキーボードが震える...

こちらは、[SORACOM advent-calendar](https://qiita.com/advent-calendar/2023/soracom)の9日目の記事になります。
advent-calendarに投稿するのは初です！よろしくお願いします！

## 背景

ひょんなことから弊社では、キャベツ農場の画像が欲しいという声が上がりました。

しかし実地はオフィスから遠く離れているため、定期的に通うのは困難。。。

そこで、pi-fieldとSORACOMに白羽の矢が当たりました。

今回は、作成したシステムの概要と、未来の自分のためのTipsを書きます!(事情によりキャベツの写真は載せられない。。。すまぬ・・・)

## 使用したSORACOMのサービス

* SORACOM Napter
* SORACOM Beam
* SORACOM Harvest Data

## どんな構成？

システム構成は以下のようになっています。

　![soraco,.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442116/cd1c1143-f1fd-0cb8-3960-c03f0548ca9b.png)

電源の確保が難しい屋外での撮影を可能にするため、今回はメカトラックス様の[pi-field Lite](https://mechatrax.com/products/pi-field/)を使用させていただきました。この中に搭載されている、[4GPi](https://mechatrax.com/products/4gpi/)を使ってセルラー通信を行い、[slee-Pi 3](https://mechatrax.com/products/slee-pi/)を使って間欠動作(動作が必要なとき以外はスリープモードにして、消費電力を抑える方法)を実現しています。

SORACOM Beamを用いて、主題である撮影写真のS3へのアップロードを行っています。また、Harvest Dataを用いてバッテリー電圧の監視を行い、問題があった時の要因分析に使用します。今回はOTA(Over the Air)でのソフトウェアアップデートには対応しなかったため、ソフトウェア的に問題が発生した時のためSORACOM Napterにて筐体に接続する余地を残しています。

## 未来の自分のためのTips

* 4GPiの設定
* SORACOM Beamの設定
* ラズパイでWiFiも使用している時の注意
* Harvest

### 4GPiの設定

メカトラックスさんのセットアップ方法を確認しながら進めました。
pi-fieldは、4GPiの組み立てが完了した状態で納品されていたため、LTEで通信できるように設定を行っていきます。

基本的には[こちらの記事](https://mechatrax.com/blog/setup-4gpi/)を元に、NetworkManagerの設定を行なっていきます。基本的には記事を参照すれば設定は済むので、駆け足で進まない方は記事を参照されると良いかと思います。

メカトラックスさんの記事では、以下のようなコマンドが紹介されており、

`sudo nmcli con add type gsm ifname "*" con-name 「任意の接続名」 apn 「APN」 user 「ユーザー」 password 「パスワード」`

ここのAPN, ユーザー、パスワードを埋めていきます。埋める内容は[SORACOMの利用を始める STEP 3: デバイスを設定する (APN 設定 / ローミング設定)](https://users.soracom.io/ja-jp/guides/getting-started/setup/)に記載があります。ちなみに、APNとはAccess Point Nameの略だそうです。※[APNとは](https://k-tai.watch.impress.co.jp/docs/column/keyword/663582.html)

なお、接続名を任意のものにしなくても良い方は、以下のように設定しても良いそうです。

`sudo nmcli con add type gsm apn 「APN」 user 「ユーザー」 password 「パスワード」`

よって、SORACOMのAPNを記載すると、

`sudo nmcli con add type gsm apn soracom.io user sora password sora`

となります。ちなみに、nmcliはNetworkManager Command Line Interfaceの略です。

> nmcli は、ネットワーク接続の作成、表示、編集、削除、有効化、非アクティブ化、ネットワークデバイスのステータスの制御と表示に使用されます。 (Red Hat Customer Portal, nmcliを使用するIPネットワークの設定, より)

ifnameは接続のバインド先になるインターフェース、con-nameは接続名になります。[nmcli - redhat](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/networking_guide/sec-configuring_ip_networking_with_nmcli)

gsmはGlobal System for Mobile Communicationsの略です。ここのtypeには、例えばbluetoothやethernetなどが来ます。

4GPiの設定はこれだけ！簡潔で素晴らしい！設定が終わったら、その時点でSIMを差し込んで、pingを打ってみます。SIMを入れる向きは決まっているので要注意です！

![IMG_4440.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442116/dcc2c6d1-cb5f-6778-7c50-188569c9ad76.jpeg)

青枠に薄く記載がある方向に合わせます！

疎通確認は以下のコマンドを使用します。

`ping -c 4 pong.soracom.io`

### SORACOM Beamの設定

Beamの設定は本当にSORACOMのドキュメントに沿って進めるだけです！本当にそれだけ！[ドキュメント](https://users.soracom.io/ja-jp/docs/beam/aws-s3/)

しかしながら自分、2回もうまくいきませんでした。まぁ間違えた内容はタイポと値の間違いなのですが。。。ここから得た学びは、ドキュメントを熟読して設定するのが近道、ということです。

後から参照することのできない値のみどこかに記録しておいて、ARNやS3バケットの名前はAWSのコンソールを見てコピペするのが確実です。

また、ドキュメントにも書いてありますが、IAM Roleの作成の手順の途中でポリシーの作成を行なっているので、こちらもミスのなき様に。AWSに慣れている方であれば、先にポリシーを作ってからRoleを作ってもいいかと思います。(私はこの時コンソール触って一ヶ月も経ってなかったので、こんなことでも時間を取られました。)

SORACOM BeamはHarvestと同様に、SIMグループに対して設定します。私は今回S3へのファイルアップロードを行いましたが、これもSORACOMさんがサンプルコードを提供してくれているので、こちらをよしなに編集して使用しましょう。[file_upload_resource.py - ※スクリプトがDLされます。](https://users.soracom.io/ja-jp/docs/beam/aws-s3/files/file_upload_resource.py)

自分は今回、ファイルを保存するキーを明確に定義したかったので、引数の処理を消させていただいています。S3のキーは文字列内の`/`で区切られ、コンソール上ではさもフォルダのようにいい感じに整理してくれるので、有効活用させていただいてます。

```python
def upload(bucket_name, abs_filepath, key, content_type):

    s3_resource.Object(bucket_name, key).upload_file(abs_filepath,
                            ExtraArgs={'ContentType': content_type},
                            Config=config,
                            Callback=Progress(abs_filepath)
                            )
```

Harvestの設定に関しては今回省略しますが、[SORACOM Harvest Dataを有効化する](https://users.soracom.io/ja-jp/docs/harvest/enable-data/)を参考にすると素早くできると思います。

使用は本当に簡単で、エンドポイントにjsonを投げるだけです。今回は、slee-Piによって計測できる電圧値をsubprocessから取得して、requestsで送信しています。認証情報をデバイス側で持たなくていいのは、BeamもHarvestも素敵ですよね。

以下はサンプルコードになります。実際には、これを実行するシェルスクリプトを書き、デーモンの処理の一部としてこちらを実行しています。

```python
from subprocess import run, PIPE
import requests

def get_voltage() -> tuple[str, str]:
    cmd1 = ['sudo', 'sleepi3ctl', 'get', 'voltage', '1']
    cmd2 = ['sudo', 'sleepi3ctl', 'get', 'voltage', '2']
    cp_result1 = run(cmd1, stdout=PIPE, check=True, encoding='utf-8')
    cp_result2 = run(cmd2, stdout=PIPE, check=True, encoding='utf-8')
    return (cp_result1.stdout, cp_result2.stdout)

def build_message(voltage1: str, voltage2: str):
    cn1_vol = int(voltage1.strip())
    cn2_vol = int(voltage2.strip())
    return {'CN1_Voltage': cn1_vol, 'CN2_Voltage': cn2_vol}

def send_voltage_to_harvest() -> None:
    header = {'Content-Type': 'application/json'}
    payload = build_message(*get_voltage())

    # send to harvest
    response = requests.post('http://harvest.soracom.io', headers=header, json=payload)

    print('send to harvest: ', payload)

    # check response
    print(response.status_code)
    print(response.text)

def main():
    send_voltage_to_harvest()

if __name__ == "__main__":
    main()
```

### ラズパイで作業中にWiFiを使用するときの注意点

ラズパイでの作業中に、ソフトウェアのアップロードや、必要な追加ライブラリのインストールなどで大容量のDLが可能な回線が欲しくなる時があると思います。今回は使用しませんでしたが、opencvなどのライブラリを入れたりするならLTE回線ではなく、開発時にWiFiで作業をしたいところです。例に漏れず私もWiFiをraspi-configを使用して設定しました。

そうすると、LTEの回線が使用できなくなってしまいました。おそらく、ネットワークインターフェースを二個同時に使えないとか、優先度があるとかが原因なのだと思いますが、急にSORACOMの回線に依存する処理ができなくなるので注意です。(明確な原因を記載できてなくてすみません🙇教えていただけると嬉しいです。)

私は `/boot/config.txt` に設定を記載することで回避しました。参考はこちらです。[4 Ways to Disable Wi-Fi on Raspberry Through Terminal](https://linuxhint.com/disable-wifi-raspberry-pi-through-terminal/#4)

この記事の1番のように
`dtoverlay=disable-wifi`
を記載して、起動時にwifiを無効にしています。

### Harvest

これはTipsでもなんでもないですが、Harvestを使用すると何もしなくてもデータを可視化してくれます！これで今のデバイスのバッテリー状況が把握できるので、満足しています。みんなも使おうHarvest!!

![スクリーンショット 2023-12-07 22.49.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442116/5c7ffe23-ae19-e47d-f070-8a70cca4075f.png)

## 実際の写真

問題なく稼働していると、Beam->AWS経由で以下のような画像がSlackに送られてきます！大きく育つのが楽しみですね！
![2024_01_15_09_00_58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442116/f0124395-13fc-8008-ccc8-08db96638739.png)


## 終わり

間欠動作や使用した部品、使用した工具、撮影のスクリプトなどは、後編(未定)に記載予定です！開発のアドバイスをいただいた、[@Y_uuu](https://qiita.com/Y_uuu)さんには感謝です！読んでいただき、ありがとうございました！