状態管理

IoTシステムの基本的な機能である状態管理を担っているのが、externalとinternalの2つのサービスです。ここら辺のシステムは昨年度のものをそのまま引き継いでいます。

IoTシステムにおける状態管理について簡単に説明すると、システム上の状態と現実のハードウェアの状態を一致させるということです。例えば最近よくあるようなスマホから電気をON/OFFできるようなライトがあった時に、サーバー上ではライトの現在の状態(ライトがついているのか消えているのか)を保持しており、スマホからライトを消すという指示がくるとサーバー上の状態を更新するとともに、現実のライトもOFFにします。もし状態管理がうまくいっていないと、システム上だとライトが消えているのに現実のライトは点いているというような事態に陥ってしまうのでとても重要な部分です。

また、この状態管理によってシステムの状態とハードウェアの状態が一致していることが保証されていると、ソフトウェアではより抽象的にハードウェアを扱うことが可能になります。

さて、今回のシステムではexternalがポイントとストップレールの状態をKVS(Key Value Store)で保持しています。このexternalの状態が変化するとその変化がinternalを介してサーボを制御するESP32に伝わることで現実世界のポイントが動きます。たとえば、sakurajosui_b1というストップレールをONにすると、

  1. ストップレールをONにするボタンが押される
  2. クライアントからexternalのAPIを叩く
  3. externalで状態(ON/OFF)を更新して、操作するポイントの名前と状態をinternalへ伝える
  4. externalから渡された状態に基づいて、そのポイントを管理するESP32に対してサーボの角度を指定するAPIを叩く
  5. ESP32で指定された角度にサーボが動き、ストップレールが動く

というような流れになっておりそれぞれで抽象化されているので、上から下へ流れるにつれてレイヤが下がっていくイメージです。

実装的な面で言うと、externalとinternalはそれぞれgolangで実装され、gRPCを用いて話すようになっており、フロントエンド側からはJSON形式のhttpでリクエストを受けつけるようになっています。ここら辺もconnectとかを使ってprotobufを使うように統一できると良さそうですね。

また、internalのサーバーはESP32と同じネットワーク上に存在しており、ESP32に固定IPを割り振ってそのIPアドレスをinternal側で管理することで実装しています。最近のIoTシステムだと、ESP32から直接クラウド上のサーバーにアクセスして状態の変更を監視するみたいなパターンが多いので少し特殊かもしれません...?

MongooseOSとmDashを使ってクラウドにするぞー!という計画はあったのですが、接続できる台数の制限があったり、1からこの部分のコードを書き直していると他の部分が追いつかないなどがあったので断念しました...。もし次回があればそこらへんも挑戦してみたいです。