本アーキテクチャを適用する際に押さえておきたいポイントと注意点です。
外出しする「設定情報」の見つけ方
「設定情報」は個体ごとに異なった設定を行う値です。たとえば 2 台目のデバイスにプログラムを書き込む際に変更する値や情報は、すべて設定情報と考えて良いでしょう。実装上では #define
や const
等の定義や定数が外出しの候補となります。
メタデータサービスに保存する設定情報のフォーマット
ここで紹介した設定情報のフォーマットは JSON でしたが、本アーキテクチャの目的は設定情報を読み込み反映させる手段の一つであるため、必ずしも JSON である必要はありません。
フォーマットはデバイス側での処理のしやすさと、性能とのバランスで決定します。たとえば、Raspberry Pi のようなハードウェアであれば JSON や XML のような構造化テキストも処理可能ですが、メモリが小さいマイコンでの JSON の取扱いはメモリを圧迫します。バイナリは省メモリで扱える反面、クラウド側 (メタデータサービス) での取扱いに適していないので、CSV や固定長テキストといったフォーマットが検討できるでしょう。
構造化されていないフォーマットにおいては、文法や構造のチェックを実装する手間も存在します。これらの要素を加味したうえでフォーマットを決めていきます。
ユーザーデータの利用
SORACOM Air のメタデータサービスには「ユーザーデータ」という領域があります。メタデータはタグとして IoT SIM ごとに異なる値を設定できますが、ユーザーデータは SIM グループ ごとに設定可能ですので、共通する設定情報を保存しておくといった活用方法があります。
詳細は「デバイスで IoT SIM の情報を利用する (メタデータサービス)」の メタデータサービスを利用してユーザーデータにアクセスする をご覧ください。
設定情報の取得と反映タイミング
これまで、設定情報の取得と反映はデバイスの起動時として解説してきましたが、実装によってはデバイスの稼働中においても可能です。タイミングをまとめると 2 つとなります。
- デバイス起動時
- デバイス稼働中の割り込み時
デバイス起動時における設定情報の取得と反映は、本アーキテクチャにおいての基本実装で、もっとも簡単なものとなります。これに加えて、デバイス稼働中の「割り込み」を利用した設定情報の取得と反映をする方法があります。これには 2 つの方法があります。
- スイッチやボタン等の信号による割り込み
- 時間による割り込み
信号による割り込みは、たとえば「設定取得ボタン」といった形です。基本的に有人運用向けですが、必要なタイミングで反映ができることから、運用としてもわかりやすい方法となります。時間による割り込みは定時実行とも言われ、「1 日に 1 回、設定情報を取得し反映させる」というものです。無人で運用する際に有用ですが、間隔によっては反映までに時間がかかるという面もあります。
また、割り込み発生時の実装方法も 2 通り存在します。
- デバイスの電源 OFF/ON、もしくは再起動を行い、次回の起動時で設定情報の取得と反映をする
- 再起動せずに設定情報を取得し、デバイス稼働中でも反映ができるようにする
デバイスの電源 OFF/ON や再起動は実装が容易です。特に電源の OFF/ON は複雑な作業が無い事から、手間なく運用できる方法です。一般的には内部メモリが消失することから、保存が必要であれば外部記憶が必要となります。本アーキテクチャは、設定情報を保存しておく仕組みがデバイス上に無くとも個別適用が可能であることがメリットの 1 つであるため、たとえばデータ収集・蓄積サービス SORACOM Harvest Files といったクラウドストレージの利用を組み合わせることで、本アーキテクチャを活かす事が可能です。
一点注意したいのは、いつ電源が OFF になっても電源 ON で復旧できる実装が不可欠です。またソフトウェアリセットによる再起動は、マイコンがリセットできてもセンサーや周辺機器のリセットは別に行う必要があるため、マイコンとセンサーや周辺機器との状態が不一致になり動作に支障をきたす場合もあります。全体的なリセットを行う実装や、電源の OFF/ON を行う運用を行う事、もしくはもう一つの考え方「デバイス稼働中における設定情報の反映」を検討します。
デバイス稼働中における設定情報の反映はデバイスとクラウド間の「双方向通信」とも言われます。利点は内部メモリやセンサー、周辺機器のリセットといった課題を解消できます。 双方向通信を実現するデザインパターンは デバイス-クラウドの双方向通信 デザインパターンと実装 として、別途公開していますのでご覧ください。
適用結果のフィードバック先
本アーキテクチャは設定情報を取得して適用する部分にフォーカスを当てて解説していますが、適用の結果を知る方法があるとトラブルシュートに役立ちます。
結果の保存先にもメタデータサービスは利用可能です。
あらかじめメタデータサービスの設定で「読み取り専用」を OFF にした上で metadata.soracom.io/v1/subscriber/update_tags
に HTTP POST することで、タグと値を書き込むことができます。
以下の例は config_version
を 4
としてメタデータサービスに書き込んでいます。
$ curl -s -X POST -H "Content-Type: application/json" \
-d "{\"config_version\":\"4\"}" \
metadata.soracom.io/v1/subscriber/update_tags
書き込んだ後のタグの状態は以下のようになります。値はキーが存在していれば値は上書き、存在していなければキーと共に新規作成されます。
$ curl -s metadata.soracom.io/v1/subscriber.tags | jq .
{
"name": "RPi4/MS2131i",
"config": "{\"inverval\": 5000, \"sensors\": {\"led\": 1, \"temp\": 0, \"humi\": 0, \"gps\": 1}}",
"config_version": "4"
}
タグの値は文字形式のみ使用可能です。たとえば {"config_version": 10}
と値を数値形式にした場合は失敗しますのでご注意ください。
本アーキテクチャ適用時の注意点
設定情報の取得失敗に備えましょう
電波状況などの要因から設定情報の取得を失敗する可能性があるため、その場合の挙動を考慮しておく必要があります。例としては再起動をしつづける、あらかじめデバイス内に設定情報した標準値で起動するといった実装が考えられます。
設定情報を保存しているシステムへのアクセスは分散を検討しましょう
設定情報を保存しているシステム (メタデータサービス) へ短時間でのアクセスが集中すると、システム保護のために Too many requests
といった措置がされる場合があります。これは SORACOM のみならずクラウドサービス全般に言えることで、たとえば「毎時 0 分に実行」といった実装は大量のデバイスになった場合に本問題に遭遇する可能性が高まります。また、取得失敗後の再取得タイミングも同じにしてしまうと同様の問題が続くため、ランダムで数秒ずらすといった分散アクセスを検討してください。
この分散に関する実装は exponential backoff(外部サイト AWS 様の解説) も参考になります。
#define
や #ifdef
等によるコンパイル前の設定には利用できません
特にマイコン向けの開発で用いられる C/C++では、プログラム本体ではなくコンパイル前の定義命令 (プリプロセッサ) を利用して設定情報を書き込む手法が用いられます。本アーキテクチャは稼働中において動的に適用する仕組みとなっているため、プリプロセッサの挙動を本アーキテクチャで制御することはできません。