ottijp blog

おかんウォッチャ(見守りIoT)

  • 2022-12-17

これはInfocom Advent Calendar 2022 17日目の記事です.

TWELITE, ESP8266, AWS Lambdaを使って,おかんの見守りシステム「おかんウォッチャ」を作りました. 時間がなかったので,とりあえずブレッドボードに組んで,サーバにデータを飛ばすところまでです. ユニバーサル基盤実装とサーバロジック作成は後日やります.

システム構成

structure system

ドア開閉センサのセンサデータをサーバにアップロードし,異常事態発生時(1日以上ドアの開閉が無いとか)に家族に通知します. よく聞くアレ(電気ポットの使用をトリガに生存確認する仕組み)の模倣です.

要件

独居おかんの家に設置するため,以下のような要件を定義しました.

  • ゲートウェイはいつでも電源抜き差しOK
  • ゲートウェイは既設のWi-Fi経由でデータをアップロードする
  • エンドデバイス(ドア開閉センサ)は1年以上バッテリ交換不要

コンポーネント構成

structure component

上図はコンポーネントの構造と,コンポーネントの間のプロトコルの図です.それぞれ以下に説明していきます.

ハードウェア

エンドデバイス

TWELITE PALを使います.TWELITE PALは,電子回路素人(私)にはハードルの高い電源回路が仕上がっているので,とっても重宝しています!おすすめ.

今回は以下3つがセットになった商品をそのまま使います.

cf. Amazon | 【Amazon.co.jp 限定】モノワイヤレス TWELITE BLUE PAL & OPEN-CLOSE SENSE PALセット | 産業・研究開発用品 | 産業・研究開発用品 通販

enddevice

電池はCR2032を使うので,これも忘れずに.磁石は100均とかのでOKですが,設置場所への固定方法を考慮して形状や大きさを決めるとよいです.

ゲートウェイ

TWELITE DIPAE-ESP-WROOM-02を使います. AE-ESP-WROOM-02はESP8266EXを搭載したWi-Fiモジュールです.

とりあえずブレッドボードへの仮実装ですが,こんな感じです. (左側はUART-USB変換なので,ゲートウェイとしての実質的な構成は右側だけ.)

breadboard

後日,電源とかインジケータとか含めて回路設計してユニバーサル基盤に実装します.

ソフトウェア

TWELITE DIP

TWELITE DIPにはもともとApp_Tweliteというファームウェアが書き込まれていますが, ESP-WROOM-02に渡すオリジナルのフレームを作るために,App_Wingsをベースに改変したファームウェアを作り書き込みました. 開発にはMWSDKというモノワイヤレス社純正のSDKを使います.

App_Wingsに対しては,ざっくり次のような変更を行っています.

  • データ受信時のコールバック関数cbToCoNet_vRxEvent()でApp_Wingsデフォルトの処理に加えて,カスタム処理を実装
  • 開閉センサPALの場合のみ,受信パケットをパースしてESP-WROOM-02に渡すオリジナルフレームを構築
  • UART1にオリジナルフレームを出力

App_Wingsとのソースコードの差分はこちらを参照してください.

cf. App_WingへOkan_Watcher用の改変を入れる · ottijp/okan-watcher@6e4b957

なお,ESP-WROOM-02に送るオリジナルフレームは,次のようなフォーマットを設計しました.STX,ETX以外はバイナリデータを16進文字列にシリアライズしたものです. (例えば[STX]81000000081B0001[ETX]

structure frame

また,TWELITE PALと通信するために,TWELITE PAL, TWELITE DIPそれぞれにUART接続し,チャネル,アプリケーションID,暗号化キーが同じになるように設定しました.

ESP-WROOM-02

Arduinoで開発します.ソースコードはこちらです.

cf. add: ESP8266プログラム · ottijp/okan-watcher@d4c1eb5

やっていることは単純で,TWELITE DIPから受信したフレームをパースし,JSONを構築してサーバにHTTPSでPOSTしています.

構築されるJSONは次のようになります.

{
  "type": "magnet",
  "src_address": "81XXXXXX",
  "battery": 2075,
  "pole": 0,
  "changed": true
}

サーバサイド

AWSのSAM (Serverless Application Model)を使って,Lambdaファンクションを作りました. SAMは,直接CloudFormationのコードを書いたり,ロールやポリシを考えたりしなくても,簡単にサーバレスのリソースを作成・更新でき,ビジネスロジックの開発に集中できる便利なフレームワークです.

ソースコードはこちらです.

cf. add: サーバ側プログラム · ottijp/okan-watcher@91c6c04

template.yamlにAWS::Serverless::Apiのリソースを定義し,HTTPヘッダのx-api-keyで認証を行うようにしているのがポイントです. ESP-WROOM-02のプログラムで,この認証用のx-api-keyをセットしています.

template.yaml(抜粋)
Resources:
  OkanWatcherApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      Auth:
        ApiKeyRequired: true
        UsagePlan:
          CreateUsagePlan: PER_API
          UsagePlanName: GatewayAuthorization

動作のチェック

TWELITE PALに磁石を近づけることで,TWELITE DIP,ESP-WROOM-02を経由してAWS Lambdaにデータが送信されました.

lambdaログ(一部マスク)
$ sam logs --stack-name okan-watcher --tail
2022/12/16/[$LATEST]edaed414aefe428888c3416a3d511568 2022-12-16T14:53:21.621000 START RequestId: d8fbf8dc-4a08-41a5-885e-fbeb9b841281 Version: $LATEST
2022/12/16/[$LATEST]edaed414aefe428888c3416a3d511568 2022-12-16T14:53:21.622000 2022-12-16T14:53:21.622Z        d8fbf8dc-4a08-41a5-885e-fbeb9b841281    INFO    {"resource":"/sensordata","path":"/sensordata","httpMethod":"POST","headers":{"Accept-Encoding":"identity;q=1,chunked;q=0.1,*;q=0","Host":"xxxxxxxxxxxxxxxxxxxxxxx","User-Agent":"ESP8266HTTPClient","X-Amzn-Trace-Id":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","x-api-key":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","X-Forwarded-For":"xxxxxxxxxxxxxx","X-Forwarded-Port":"443","X-Forwarded-Proto":"https"},"multiValueHeaders":{"Accept-Encoding":["identity;q=1,chunked;q=0.1,*;q=0"],"Host":["xxxxxxxxxxxxxxxxxxxxxxx"],"User-Agent":["ESP8266HTTPClient"],"X-Amzn-Trace-Id":["xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"],"x-api-key":["xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"],"X-Forwarded-For":["xxxxxxxxxxxxxx"],"X-Forwarded-Port":["443"],"X-Forwarded-Proto":["https"]},"queryStringParameters":null,"multiValueQueryStringParameters":null,"pathParameters":null,"stageVariables":null,"requestContext":{"resourceId":"xxxxxx","resourcePath":"/sensordata","httpMethod":"POST","extendedRequestId":"xxxxxxxxxxxxxxxx","requestTime":"16/Dec/2022:14:53:21 +0000","path":"/sensordata","accountId":"xxxxxxxxxxxx","protocol":"HTTP/1.1","stage":"Prod","domainPrefix":"xxxxxxxxxxxx","requestTimeEpoch":1671202401319,"requestId":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","identity":{"cognitoIdentityPoolId":null,"cognitoIdentityId":null,"apiKey":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","principalOrgId":null,"cognitoAuthenticationType":null,"userArn":null,"apiKeyId":"xxxxxxxxxx","userAgent":"ESP8266HTTPClient","accountId":null,"caller":null,"sourceIp":"xxxxxxxxxxxxxx","accessKey":null,"cognitoAuthenticationProvider":null,"user":null},"domainName":"xxxxxxxxxxxxxxxxxxxxxxx","apiId":"xxxxxxxxxx"},"body":"{\"type\":\"magnet\",\"src_address\":\"81XXXXXX\",\"battery\":1950,\"pole\":2,\"changed\":false}","isBase64Encoded":false}
2022/12/16/[$LATEST]edaed414aefe428888c3416a3d511568 2022-12-16T14:53:21.633000 END RequestId: d8fbf8dc-4a08-41a5-885e-fbeb9b841281
2022/12/16/[$LATEST]edaed414aefe428888c3416a3d511568 2022-12-16T14:53:21.633000 REPORT RequestId: d8fbf8dc-4a08-41a5-885e-fbeb9b841281  Duration: 12.04 ms      Billed Duration: 13 ms  Memory Size: 128 MB     Max Memory Used: 57 MB  Init Duration: 134.96 ms

Todo

おかん家に設置するまでにやること

  • ユニバーサル基板への回路実装,ケース詰め.

それ以後にやること

  • サーバのSSL証明書検証
  • SSLクライアント認証
  • ゲートウェイからサーバに向けたハートビートメッセージの送信

引っかかったところ

MWSDKでビルドがエラーになる

MWSTAGEを使わずにターミナルでビルドしようとした時にエラーが発生しました.

$ make TWELITE=BLUE
Makefile:58: /MkFiles/mw.mk: No such file or directory
make: *** No rule to make target `/MkFiles/mw.mk'.  Stop.

これは,パスを通すことで解決しました.

$ MWSDK_ROOT=/path/to/MWSTAGE/MWSDK make TWELITE=BLUE

cf. TWELITE STAGE を試す - Qiita

I2Cがうまく動かない

はじめ,TWELITEとESP-WROOM-02の通信はI2Cで行おうとしていましたが,色々試してもうまくいかなかったのでUARTに変更しました.

どうやらESP8266のI2Cスレーブ動作は不安定?なようで,それが関係しているのかもしれません. 通信速度を20kHzにして試してもみましたが,それでもダメでした. (TWELITEの関数は(結線してなくても)TRUEで返ってくるので,本当に送信できているのか,送信できているけど受信がうまくいっていないのか,原因が特定できず疲弊したので,UARTに変更しました.)

cf. c++ - ESP8266 I2C slave does not acknowledge data - Stack Overflow

cf. ESP8266 to ESP8266 i2c · Issue #3046 · esp8266/Arduino

refs


ottijp
都内でアプリケーションエンジニアをしています
© 2024, ottijp