IoTモジュールの安定度の考察

IoTモジュールは連続可動を前提にしているケースが多く、それなりの安定度が求められる。ただ何らかの欠陥があり以下のような問題を起こす事がある。

* ハングアップ（完全停止）
* 再起動
* センサーデータ読み取りミス
* 故障

再起動は問題ないケースもあるが、ハングアップするのは非常にこまる。この原因は次のような物が考えられる。

* 電池切れ
* プログラムの問題
* ハードの問題
* メモリリーク
* ファイルシステムが壊れる
* カウンターのオーバーフロー
* メモリ不足
* ネットワークが不安定
* なんらかの攻撃により
* などなど

ハングアップしても電源再投入で復帰するケースと完全に壊れて復帰できないケースがあります。

ハングアップの回避策は以下のような事が考えられる。

* がんばってデバッグする
* システムの二重化
* 定期的にリブートする
* 異常時にはリブートする
* リモート電プチを用意する

組み込み系のSOCではWatchdog Timerとよばれる機能があるものも多い。
![WDT.png](https://qiita-image-store.s3.amazonaws.com/0/104066/ad460c64-fe35-2e62-1948-a39110ea449e.png)

これはタイマーをセットして、そのタイマーがオーバーフローするよりも前にClearをおこなうとシステムはそのまま動作するが、ClearされないとタイマーのオーバーフローでResetするというような仕組みである。システムが複雑になるとClearを呼ぶタイミングが難しくなるかもしれない。

Watchdogリスタートを繰り返してそれ自体がDOS攻撃のようなことにならないようにする必要もあるかもしれない。

再現性が低いハングアップや、外部要因でのハングアップはWatchdogで対応するのが良い気がします。

機器が不調になってWatchdogでリスタートしている場合、その間隔にも注意が必要です。状態が悪化してより頻度が多くなった場合は交換を行うべきでしょう。

メモリが少なくなったときにリブートする方法もある。Bare Metalなシステムではstackとheapのポインターががある程度の近さになったら再起動するなどが良いかもしれない。

![heapstack.png](https://qiita-image-store.s3.amazonaws.com/0/104066/aa4c62ee-039e-4f7d-b502-9e9a2105365e.png)

メモリが少なくなるのはなんらかのメモリリークで本来はそれを直すべきかもしれない。

最初からリブート前提で作るのはあまり良くないが、再現性の低い問題がある場合などは、リブートでもしかたないかもしれない。

本体は動いていてもセンサーがおかしくなることもある。この場合、本体をリセットしてもセンサーの電源が入ったままなので、復旧しない可能性もある。

リセットピンがあるセンサーであればSOCのGPIOと接続してエラーがあった場合や、定期的にリセットする事もできる。

IoTではパフォーマンスよりも、リソースの消費が少なくなるようにプログラミングすべきで、出来る限りバッファなどは固定で持ちmallocしないようにするのが良いのかもしれない。lwipの実装はそうなってるようだ。

# ネット接続

インターネットの接続は中継経路の問題やサーバー自体の問題で失敗する事も考慮に入れる必要がある。

1分おきにデータをとっても毎回サーバーにアクセスするのは無駄なので、まとめて送ったほうがいいかもしれない。

問題はいろいろある

* 全く接続できない
* 通信が極端に遅い
* サーバ証明書が失効している
* tcpのコネクトは出来るが返答がない
* サーバを入れ替えてcloseのシーケンスが変わった
* などなど

通信できないのはインターネットの性格上仕方がないが、それによるハングアップなどが無いようにしなければならない。

Windows 10のパソコンが起動時にARPメッセージを大量に送信して、それにつられてモジュールがハングアップするケースがあった。ローカルのネットワークの構成をシンプルにする事も大切である。

VLANを利用して、ネットワークを隔離するのも有効かもしれない。

# ファイルシステム

Linuxのようなシステムを使う場合、予期せぬ電源断で再起動するとファイルシステムが壊れて、起動できなくなる場合がある。Linuxのようなシステムを使う場合は、RWなファイルシステムは避けるべきかもしれない。

特殊なファイルシステムで予期せぬ電源断にも対応できるものもあるようだ。

# https

httpsではサーバの証明書の確認を端末が持っているCAのリストによりおこなう。サーバー証明書は定期的に更新が必要で、端末が持っているCAのリストで確認できない証明書をサーバーに貼ると通信できなくなる。あたり前田のクラッカーだがよくある。

将来の証明書の事など分からないのでCAのリストを更新できるような仕組みを作り込むのが良いのかもしれないが、ちょっと大変かも。

# 時間

httpsでサーバにアクセスする場合には証明書の有効期間を確認するためにある程度正確な時間が必要になる。IoTであればntpサーバに問い合わせて定期的に時間を合わせるのが良い。RTCを持つ必要はほとんどないと思われる。

証明書は一年くらいで貼りかえられるので、そのタイミングで問題が起きないことも注意したほうがいい。

起動時に一度だけSNTPで時間を合わせ、そのままの場合ホストの時計はそれほど性格ではないのでずれます。たとえば一日10秒のずれがある場合は、一年で3650秒のずれでほ1時間です。10年でも10時間であまり考える必要はなさそうです。

停電などで再起動したときにネットワークの準備ができてなくてSNTPが使えないケースもあるかもしれないので、SNTPが成功するまでは次の処理を行わないようにするのが良いのかもしれません。

# センサー

センサーはまれに動作不安定になり不良なデータになることがある。明らかに不正なデータはデバイス側で送信しない方法もあるが、受け取ったサーバ側で処理する方法もある。どちらが良いかはケースバイケースだと思う。

サーバを一般サービスのThinkSpeakなどで利用する場合は、簡単にデータを確認できるようにするため、値に極端な変化があった場合はエラーとして前の値を使い、エラーフィールドにビットを立てるのが、良い気がする。値がふらつくセンサーの場合はエラーとする閾値を大きく取らなければいけないし、また温度や気圧に比べて湿度は急激な変化が起こり得るので、これも閾値を大きくする必要があった。サンプリング間隔による値の調整も必要である。

ThinkSpeakはMATLABを使えば[エラー値を取り除く](https://qiita.com/yamori813/items/9d897719cc7754597d31)こともできます。

![スクリーンショット 2019-12-22 12.52.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/ff80b142-463c-095c-53bf-b1db64746381.png)

WATCHDOGなどで再起動した場合は、CPUはリセットされるがセンサーは前の状態のままである。GPIOからのRESET PINのコントロールなどでリセットできるようにするのも一つの方法である。

センサーによってはエラーではないが振れ幅が大きい値を返すものもある。この場合サンプリング間隔や集計方法を調整する必要がある。

# テスト

私はThingSpeakに最短update時間の15秒おきにデータを登録してInternet of Testをおこなっている。

![スクリーンショット（2018-12-18 21.15.15）.png](https://qiita-image-store.s3.amazonaws.com/0/104066/ad6f20e1-19ed-d7b1-86e5-a82dfd4f5251.png)

いろいろテストしていたらThingSpeakのfreeの上限値の一日あたり8,219を越えてしまい、動作が不安定になりました。

![スクリーンショット（2018-12-20 8.36.36）.png](https://qiita-image-store.s3.amazonaws.com/0/104066/b27d71af-6cd3-3861-7e35-4b35b69b4b90.png)

レスポンスも無くセッションがクローズされていて、ちょっといけてないです。時々登録て出来ているのは複数台のサーバで上限値の処理の同期が出来ていない可能性があるのかもしれません。

テストで20秒置きにデータを登録したとして一日4320です。実際は1時間置きに登録したとして、年間8760です。年間の確認に2日くらいかかる計算になります。

2019/12/15に蟹さんのmrubyでThingSpeakにデータを送っていたモジュールがハングアップしました。どうもThingSpeakでサーバメンテナンスがあったのにひきづられたような気がします。WatchDogを入れてなかったので、入れてば再起動できたかもしれません。ただ原因が確定できないので、再現もできないし、このようなケースのテストは非常に困難です。

# デバッグ

以下のようなデバッグ方法が考えられる。

* シリアルコンソールをモニターする
* LEDにステータスを出す
* arpに反応するか確認
* pingに反応するるか確認
* ネットワーク経路でtcpdumpで確認
* JTAGでデバッグする

ある程度の決まった時間や、決まった回数で落ちているのは、デバッグしやすいが、不確定な時間や回数で落ちるのはたちが悪い。

再現性の低いものや、再現しなくなたりするとデバッグできないこともある。すべての問題を解決できるわけではない。

連続番号のシリアルや機器の状態をサーバに送るようにしておくのもデバッグには役に立ちます。

2019/12に不調になった蟹さんが2020/4に元に戻った。原因は自宅内機器でSNMPなどの対応などを行ったことが影響した模様だ。通常の自宅内で利用しているサブネットと別のサブネットを直接NATから切り、ほとんどパケットが流れない状態にしたところ問題が起きなくなった。原因追及に時間がかかったのは、まさかEthernet Switchが流れてくるパケットにつられて落ちるなどありえないだろうと考えてしまったことと、気温の影響ではないかと考えすぎたことが原因です。反省として決めつけないで、正常に動いてた状態にできるだけ戻して、原因追及することが大切と思います。

# トラブルシュート

ハードウエアは必ず壊れるので、壊れた時になにか問題かがわかるようにするのも大切。

完全に原因追及が出来ない場合も起こりうる。場合によってはワークアラウンドを行うことも有効だ。

# データの保存

IoTのでデバイス側でデータを保持するのはサーバに上げるまででよいはずだが、なんからの理由である程度の過去データを保持する場合は、どのようにするのがいいだろうか。Flashは書き込み回数に上限があり、一時的にはメモリに保持して、1日に一度程度でFlashに書き込みとかであればFlashの寿命も問題にならない。書き込みか可能回数が多い工業用の製品やEEPROMなどの利用を検討するのも良いかもしれない。

# データの完全性

インターネットなのでアクセスの欠落は起きうると考えるべきだ。完璧な完全を求めるならばIoTではないアプローチになるのではないだろうか。

問題が起きたときに検知して対応できる仕組みも大切だ。

とは言え、不安定では一般には受け入れられないと考えられ、不確実であっても人間が理解しうるように、どのように落としどころを作るかが課題なのかもしれない。

# 故障

ハードウエアは故障することもある。一番多いのはコンデンサーの経年劣化と思われる。振動が多いところなどは半田にクラックが入り接触不良なども考えられる。最近は豪雨被害も多く、浸水による故障などもあるかもしれない。昨今の複雑な機器だと原因が特定できないこともある。

真夏の日は極寒の日に比べると30度ちかく高いこともある。これはハードウエアに相当なストレスになり、ちゃんとした放熱対策が必要になる。