AWS IoTの利用手順

AWS IoTに関する基本的な内容をまとめてみたものです。AWS IoTに関する、Web上にすでにある解説コンテンツをまとめたサイトの抜粋です。
AWS IoTの利用手順

AWS IoTを使うための手順

1) デバイスの作成
まずは、「Register -> Things」メニューの中の、 Register Thingsを選択して、デバイスを作成します。名称を指定して登録すると、AWS IoTの中にその名称のThingsおよびシャドウが作成されます。
その次に、そのデバイスのRuleを設定します。Ruleとは、どのデータに対してどういう条件のときにアクションを実行するかを決める情報です。

2) 証明書の作成
次にデバイスに登録する証明書を作成します。「Security -> Certificates」メニューの中の、Create a certificatesを選択して、証明書を作成します。

3) ポリシーの作成
次にデバイスに対して、AWS IoTの各種操作を許可するためのポリシーを作成します。全ての操作を許可するのか、一部の操作だけを許可するのか、許可する操作の定義です。「Security -> Policies」メニューの中の、Create a policyを選択して、ポリシーを作成します。

4) 証明書にデバイスとポリシーを割り当てる
作成した証明書とポリシーを関連づけします。証明書を作成した後に、「attach a policy」を選択して、関連付けしたいポリシーを設定、「attach a thing」を選択して割り当てしたいデバイスの設定をします。

マネジメントコンソールの設定は以上です。

デバイスの作成からデータを受信できるまで

AWS マネジメントコンソールは、Amazon IoT リソースのすべてにアクセスして管理するためのウェブベースのインターフェイスを提供しますが、プログラムから AWS IoT へのアクセスは、AWS CLI と AWS SDK を使用して有効にできます。

ハードウェアデバイス、センサー、モバイルアプリケーション、モノを接続するには、AWS IoT デバイス SDK を使用します。AWS IoT に接続が実装された AWS スターターキットから 1 つ選択します。それに加えて、AWS IoT は、幅広い種類のサードパーティ製のツールおよびゲートウェイでサポートされています。

AWS IoTデバイスSDK
AWS IoT デバイス SDK にはオープンソースライブラリ、サンプルの付属した開発者ガイドおよび移植ガイドが含まれているので、お客様の選択したハードウェアプラットフォームに革新的な IoT サービスを構築できます。

証明書と秘密鍵
マネジメントコンソールで作成した証明書と秘密鍵は、マネジメントコンソールからダウンロードしてデバイス側に設定します。

以上の作業で、デバイスからのデータのpublish/subscribeが可能となります。

AWS IoTへの各種アクセス方法

AWS IoT サービスには AWS マネジメントコンソール、AWS SDK、AWS CLI、AWS IoT API を使用してアクセスできます。接続されたデバイスからは AWS IoT デバイス SDK を使用して AWS IoT サービスと簡単に通信できます。
AWS IoT API およびコマンドは、コントロールプレーンオペレーションと、データプレーンオペレーションに大きく分かれています。コントロールプレーンオペレーションでは、セキュリティの設定、デバイスの登録、ルーティングデータのルールの設定、ログ記録の設定などのタスクを実行することができます。データプレーンオペレーションでは、接続されたデバイスから AWS IoT へ大規模に低レイテンシーかつ高スループットレートでのデータ取り込みを可能にします。

続きを読む

AWS IoTのルールエンジンとシャドウ

AWS IoTに関する基本的な内容をまとめてみたものです。AWS IoTに関する、Web上にすでにある解説コンテンツをまとめたサイトの抜粋です。
ルールエンジンとシャドウ

ルールエンジンによりデバイスのデータに基づいたアクションを設定

AWS IoTでは、ルールエンジンによって、接続されたデバイスによって生成されるデータを収集し、処理し、分析し、データに基づいたアクションを実行するアプリケーションを構築します。

ルールエンジンで直感的にルールを設定し、SQL に似たシンタックスでインバウンドデータを自動的にフィルタおよび変換できます。AWS IoT サービスから他のいくつかの AWS のサービスまたはお客様がお使いのサードパーティサービスへルーティングするルールを設定できます。

例)
• 受信メッセージのフィルタリングおよび変換、DynamoDB へ時系列データとして保存。
• センサーからのデータが特定のしきい値を超えた時、SNS を経由してプッシュ通知を送信。
• ファームウェアファイルを S3 に保存。
• Kinesis を使用して複数のデバイスからのメッセージを同時に処理。
• 受信データのカスタム処理を行うため Lambda を呼び出し。
• 自動再発行して、デバイスのグループへコマンドを送信。

ルールはSQLライクな構文にて指定

AWS IoT のルールは 2 つの主要な部分で構成されます。

SQLステートメント:
SQL ステートメントでは、ルールを適用するトピック、必要に応じて実行するデータ変換、およびルールを実行する際の条件を指定します。ルールは指定されたトピックに発行されたすべてのメッセージに適用されます。

アクションリスト:
受信メッセージがSQLステートメントで定義された条件と一致した時、アクションリストで定義されたアクションが実行されます。

ルールの定義は JSON ベースのスキーマを使用しています。直接 JSON を編集、または AWS マネジメントコンソールのルールエディタを使用できます。

デバイスシャドウによるデバイスの状態管理の仕組み

デバイス シャドウは、デバイスの現在のステータス、アプリケーションから要求されたステータスを管理するJSONドキュメントであり、デバイスシャドウには、デバイスがオフライン状態のときでも、各デバイスについて最後に報告された状態と、希望する今後の状態が保持されます。最後に報告された時点の状態の取得や、希望する今後の状態の設定は、API またはルールエンジンによって実行されます。

デバイスシャドウでは、REST API が常時利用できるため、デバイスと協働するアプリケーションの構築が容易になります。さらに、アプリケーションではデバイスの現在の状態を取得することなく、希望する今後の状態を設定できるようになります。希望する状態と最後に報告された時点の状態との相違は AWS IoT によって比較され、相違を補うようデバイスに対してコマンドが送られます。

デバイスのシャドウには、デバイスの状態を最大 1 年間無料で保存できます。最低 1 年間に 1 度更新していれば、デバイスのシャドウは無期限に継続できます。更新しなかった場合は消去されます。

続きを読む

AWS IoTの実現するセキュアな双方向通信

AWS IoTに関する基本的な内容をまとめてみたものです。AWS IoTに関する、Web上にすでにある解説コンテンツをまとめたサイトの抜粋です。
AWS IoTの実現するセキュアな双方向通信

IoTサービスでサポートする通信プロトコル

AWS IoT では数十億のデバイスと数兆のメッセージをサポートし、それらのメッセージを AWS エンドポイントおよび他のデバイスに確実かつ安全に処理しルーティングします。AWS IoT では、断続的な接続を許容し、デバイスのコードフットプリントを削減し、必要なネットワーク帯域幅を削減するよう特にデザインされた HTTP、WebSockets、および MQTT といった軽量の通信プロトコルをサポートしています。

HTTP:
HTTPプロトコルでの通信をサポートしており、デバイス側からrestAPIで呼ぶことが可能
MQTT:
MQTTは軽量でリソースの限られているデバイスとの通信に広く使われているプロトコル。
AWS IoTは、MQTT 3.1.1ベースで実装
WebSockets:
MQTT over WebSocketsをサポートしているので、ブラウザベースのアプリケーションがAWS IoTと接続しているデバイスと双方向通信を行うことが可能。WebSocketはTCP port443での通信が可能のため、大部分のファイアウォールやwebプロキシーサーバを通すことが可能

軽量でリソースを消費しないMQTTプロトコル

MQTT は軽量の pub/sub プロトコルでネットワーク帯域幅とデバイスリソースを最小限に抑えるよう設計されています。MQTT では TLS を使用した安全な通信もサポートされています。MQTT は IoT ユースケースで頻繁に使用されています。MQTT v3.1.1 では OASIS 標準で、AWS IoT デバイスゲートウェイはほとんどの MQTT の仕様をサポートしています。

MQTTの軽量・リソースを消費しない点をHTTPS通信と比較すると、下記のようになります
(出展; http://stephendnicholas.com/posts/power-profiling-mqtt-vs-https)
・スループットが93倍
・メッセージ送信において消費電力が1/12
・メッセージ受信において消費電力が1/180
・コネクション維持において消費電力が1/2
・ネットワークオーバーヘッドが1/8

デバイスとの双方向通信

AWS IoTは、長期間のセッション保持によるクラウドを介したメッセージの送受信を実現します。クライアント(デバイスやアプリ)は制御信号やコマンドなどをクラウドから受信することができます。

AWS IoT では、断続的な接続を許容し、デバイスのコードフットプリントを削減し、必要なネットワーク帯域幅を削減するよう特にデザインされた HTTP、WebSockets、および MQTT といった軽量の通信プロトコルをサポートしています。AWS IoT では他の業界標準およびカスタムプロトコルをサポートし、複数の異なるプロトコルを使用しているデバイス同士でも相互に通信できます。

AWS IoT ではデバイスの最新の状態情報を保存し、いつでも読み込みまたは設定できるので、デバイスが常にオンラインであるかのようにアプリケーションに出現させることができます。これはデバイスとの通信が切断されていてもアプリケーションがデバイスの状態を読み込むことができ、デバイスが再接続された時にもデバイスの状態を設定し実装できることを意味します。

また、AWS IoTのMQTTでの通信では、ベストエフォート型と品質保障型のふたつの通信モードをもっています。ベストエフォート型はメッセージの到達は保障していませんが、オーバーヘッドは少なく、保障型ではメッセージの到達を保障しているものの、オーバーヘッドがベストエフォート型よりは大きくなります。

TLSによる相互認証

AWS IoT では接続するすべてのポイントで認証とエンドツーエンドの暗号化を提供し、デバイスと AWS IoT 間で身元が証明されたデータのみが交換されます。それに加え、詳細なアクセス権限のポリシーを適用することによってデバイスとアプリケーションに安全にアクセスできます。

AWS IoT では、AWS の認証メソッド (「SigV4」と呼ばれます) および X.509 証明書ベースの認証がサポートされています。HTTP による接続ではこれらの方法のいずれかを使用できます。MQTT による接続では証明書ベースの認証、WebSockets による接続では SigV4 を使用できます。AWS IoT では、AWS IoT によって生成された証明書、および推奨される認証機関 (CA) によって署名された証明書を使用できます。それぞれの証明書に対するロールやポリシーの選択をマッピングでき、デバイスに触れることなく、デバイスやアプリケーションによるアクセスを認証したり、考えが変わったときにすべてのアクセスを取り消したりできます。

続きを読む

AWS IoTとは

AWS IoTに関する基本的な内容をまとめてみたものです。AWS IoTに関する、Web上にすでにある解説コンテンツをまとめたサイトの抜粋です。
AWS IoTとは

AWS IoTとは

AWS IoSサービスにより、さまざまなデバイスを AWS の各種 Services や他のデバイスに接続し、データと通信を保護し、デバイスデータに対する処理やアクションを実行することが可能になります。

AWS IoTデバイスSDK
AWS IoT には、ハードウェアデバイスやモバイルアプリケーションを簡単に、すばやく接続できるようサポートする SDK が準備されています。AWS IoT デバイス SDK を使用すれば、AWS IoT との間で MQTT、HTTP、または WebSockets プロトコルを介した接続、認証、メッセージ交換が可能になります。このデバイス SDK では C、JavaScript および Arduino がサポートされており、クライアントライブラリ、開発者ガイドおよびメーカー向けの移植ガイドが付属しています。

認証と認可
AWS IoT では、接続するすべてのポイントでの相互認証と暗号化が提供されており、デバイスと AWS IoT 間では身元が証明されたデータのみが交換されます。

コミュニケーションプロトコル
AWS IoT とデバイスの間では MQTT、HTTP、または WebSockets プロトコルを介した接続、認証、メッセージ交換が可能です。MQTTは、M2M/IoTでよく使用されるOASISスタンダードのプロトコル。ライトウェイトでリソースや回線帯域が限られているデバイスでよく利用されます。MQTTはhttpsと比較して、スループットで93倍、メッセージ送信の消費電力で1/12、メッセージ受信の消費電力で1/180となります。

ルールエンジンによって、AWS Lambda、Amazon Kinesis、Amazon S3、Amazon Machine Learning、Amazon DynamoDB、Amazon CloudWatch、および Amazon Elasticsearch Service (組み込みの Kibana と統合されている) などの AWS エンドポイントへのメッセージのルーティングも行えます。

AWS IoTのコンポーネント

デバイスゲートウェイ
接続されたデバイスから、指定されたトピックについて複数の受信者にデータをブロードキャストすることができます。デバイスゲートウェイでは MQTT、WebSocket、および HTTP 1.1 プロトコルがサポートされており、専用プロトコルやレガシープロトコルのサポート実装も容易に行えます。デバイスゲートウェイは、インフラストラクチャのプロビジョニングが不要でありながら、10 億台以上のデバイスにも対応できるよう自動的にスケールされます。

レジストリ
レジストリによって、デバイスの ID が確定され、デバイスの属性や機能といったメタデータが追跡されます。各デバイスには、デバイスのタイプや接続方法にかかわらず、一貫した形式の一意の ID がレジストリによって割り当てられます。

シャドウ
AWS IoT では、それぞれのデバイスについて「シャドウ」を作成できます。シャドウにはデバイスの最新の状態が保存されるため、アプリケーションや他のデバイスからのメッセージの読み出し、およびデバイスとの通信が実行できます。デバイスのシャドウには、デバイスがオフライン状態のときでも、各デバイスについて最後に報告された状態と、希望する今後の状態が保持されます。最後に報告された時点の状態の取得や、希望する今後の状態の設定は、API またはルールエンジンによって実行できます。

ルールエンジン
ルールエンジンによって、接続されたデバイスによって生成されるデータを収集し、処理し、分析し、データに基づいたアクションを実行するアプリケーションを構築することが可能になります。ルールエンジンでは、お客様が定義したビジネスルールに基づいて、AWS IoT に向けて発行された入力メッセージが評価、変換され、別のデバイスやクラウドサービスへと配信されます。1 つのデバイスからのデータにも、多数のデバイスからのデータにも同じルールを適用でき、アクションを単独で実行することも、多数のアクションを並行して実行することも可能です。

ルールエンジンによって、AWS Lambda、Amazon Kinesis、Amazon S3、Amazon Machine Learning、Amazon DynamoDB、などの AWS エンドポイントへのメッセージのルーティングも行えます。AWS Lambda、Amazon Kinesis および Amazon Simple Notification Service (SNS) を使用して外部のエンドポイントに届けることも可能です。

KinesisとIoTの違い

Kinesisを使ってIoTのシステムを実現している例もありますが、IoTサービスはより包括的にデバイスとクラウドを接続するためのサービスを用意していますので、まずはデバイスとの入り口をIoTサービスで対応して、Kinesisサービスにつなぐという構成が、AWSでのIoTシステムの構成かと思います。
具体的なKinesisとIoTの違いとして一番明確なのは、デバイスとの間のコミュニケーションプロトコルです。IoTはMQQTに対応していますが、Kinesisはhttpsのみとなります。IoTはシャドウのような仕組みも持っており、IoTシステムを構築するためのトータルなシステムを組み上げる仕組みを包括的に用意しています。

デバイスデータに対するさまざまな処理を簡単に実現する仕組み

AWS IoTでは、「ルールエンジン」に定義したビジネスルールに基づいて、デバイスデータを迅速にフィルタリング、変換、活用することができます。各種処理は、AWS Lambda、Amazon Kinesis、Amazon S3、Amazon Machine Learning、Amazon DynamoDB、Amazon CloudWatch、および Amazon Elasticsearch Service といった AWS の各種サービスを呼び出すことにより実行させます。

各種AWSのサービスには、「ルールエンジン」がAWS IoTにPublishされたメッセージを評価し、ルールに基づいて配信されます。

また、Amazon Kinesis、AWS Lambda、Amazon S3などのサービスを経由して、外部のエンドポイントを呼び出すことも可能です。

(例) センサデータをKinesisを経由してエンタプライズアプリケーションへ

・各種デバイスからのセンサデータをIoTにて受信
・ルールエンジンにて、受信したセンサデータへのフィルタリングおよびデータ変換を実施
・AWS Kinesisにストリームデータとしてパブリッシュ
・Kinesisで収集されたデータをデータベースやBIなどの分析アプリケーションに転送

例) デバイスデータをIoTからAmazon SNSを経由してスマホにプッシュ通知

・各種デバイスからのデータやイベント通知をIoTで受信
・スマホに通知すべき条件判定をIoTのルールエンジンにて実行
・通知条件に合致する場合には、Amazon SNSを経由して、アップル社APNS、Google社のGCMに
・配信リクエストを送信することにより、スマホへのプッシュ通知として、デバイスのデータやイベントの通知を実現

続きを読む

情報活用ダッシュボード「MotionBoard」が ソラコムのIoT通信プラットフォーム「SORACOM」とクラウド …

対応しているクラウドサービスは、AWS が提供する「Amazon Kinesis」「Amazon Kinesis Firehose」「AWS IoT」、Microsoft が提供する「Microsoft Azure Event … 続きを読む

IoTでペットヘルスケア[実装編:AWSサービス間の連携]

本記事で取り扱うこと

IoTでペットヘルスケア[構想編]
IoTでペットヘルスケア[実装編:センサデータの取得~AWS IoT連携]
の続編です。

IoTでペットヘルスケア[構想編]で紹介したアーキテクチャのうち、下記の赤枠内の実装(AWS IoTからその他のAWSのサービスへの連携)について、順を追って説明します。手順は現時点(2017/5)のものであるため、時間が経過している場合には、より便利なものが出ている可能性もありますので最新の情報をご確認ください。
AWS Design_pets_healthcare_実践編02.png

また、当初は複雑な処理について、Step FunctionsやDynamoDBも活用するところまで本記事でご紹介しようと考えていましたが、長くなりすぎるため、一旦は個別に手動で実装する方法をご紹介したいと思います。可能であれば、応用編として自動化、サービス化を視野に入れた実装も別記事として作成したいと思います。

AWS IoTからのデータ連携

デバイスからAWS IoTへ送られてきたデータはRuleで条件付けを行い条件に該当したデータに対してActionで定義された動作を行う事ができます。Ruleは送られてきたデータ一つに対して複数作成できます。Actionは、以下の図の通り、一つのルールに複数個定義することができます。
base_01.png

Ruleの作成

Ruleでは、SQLの構文に似た形で条件を定義する事できます。今回は、以下の内容のルールを1つ作成し、ここから複数のActionへ分岐させます。対象データは前回の記事でデバイスから送信してきたデータです。

  • 取得対象の項目

    • 全て(countPerMin、timestamp、deviceId、clientId)
  • 対象のトピック
    • topic/y_raspberrypi_01/sensor/motion_sensor
  • 条件
    • countPerMinが10より大きい場合

      • 1分間の検知回数。0~120の値となる。

では、AMCでの手順を見ていきます。まずはRulesのページを開きます。
rule_01.jpg
Create a ruleを選択を選択して作成を開始します。

rule_02.jpg
以下の項目を設定します。設定中も画面中ほどにSQL文だとこうなる、というのが表示されますので参考にしながら設定することができます。

  • NameとDescription

    • ルールの名前と説明について任意のものを入力します。
  • SQLバージョン
    • 使える構文に差がありますので、基本的にはGAの最新版(現在は2016-03-23)を利用します。詳細はこちらを参照ください。
  • Attribute
    • 送信されてきたデータから利用したい値を指定します。
    • countPerMinなどの項目を直接指定したり、”*”のようにワイルドカード指定も可能です。
  • Topic filter
    • 条件の対象となるトピック名を指定します。いわゆるFROM句です。こちらが設定項目となってることからも分かりますが、Ruleの概念はリージョン内の全てのTopicを対象にしています。
    • ワイルドカードとして”#”(前方一致)や、”+”(部分一致)も利用する事ができます。
  • Condition
    • データ取得の条件を入力します。いわゆるWHERE句です。
    • 空欄の場合、指定したトピックの全てのデータが該当します。

上記の項目について、図のように設定し、Ruleを作成します。
#Add actionを選択すれば、Ruleと一緒にactionも作成可能です。本記事では次項で作成します。

Actionの作成

連携先のAWSサービス毎にActionを定義します。利用可能なAction一覧が表示されますので、必要なものを選択して作成していきます。が、それに先立ち、IAM Roleの作成を行いましょう。

Action_01.jpg

IAM Roleの作成

さて、Actionを作成する前にAWS IoTのサービスに対して、他のサービスを操作する権限を与える必要があります。そのためのIAM Roleを事前に作成しておきましょう。Action作成画面からも作成することができますが、Action作成のたびに都度作成していると管理が煩雑になりますので、必要な権限を設計して作成したほうが良いでしょう。

今回は、以下のマネージドポリシー(管理ポリシー)をアタッチしたAWS IoTサービス用Roleを作成します。

  • AWSIoTRuleActions
  • CloudWatchFullAccess
  • AWSIoTRuleActions

CloudWatch連携

今回はトイレの利用履歴を管理したいため、”Sends message data to CloudWatch”を選択します。こちらでは、Ruleにて該当するデータが送られてきた場合に、CloudWatchのメトリクスへデータを送信できるActionです。

action_cw01.jpg

  • Metric name

    • 任意のメトリック名を指定。今回はRestroom Using。
  • Metric namespaces
    • メトリックをまとめる名前空間を指定。今回はPersonal/Karin。
  • Unit
    • メトリックの単位を指定。今回はCount。
  • Value
    • メトリックとして送る値を指定。今回は1。
    • 本当はCountPerMinを指定したかったのですが、指定してもうまくCloudWatchへ送信できず、残念ながらAWS IoTのAction機能ではできない様子。
    • どれくらい検知されたのかも記録してグラフ化したければ、Lambdaへ連携してカスタムメトリクスへPushするか、Elasticsearchへ連携する必要がありそうです。今回はメールやLINEでの通知でカバーできるので深追いせず。
  • Timestamp
    • メトリクスのタイムスタンプを指定。今回は空欄(Action実行時の日時を利用)。
  • IAM Role name
    • 先程作成したRoleを指定します。

以上の設定を行うと、トイレの利用を検知すると、CloudWatchのメトリクスに登録され、以下のようにグラフ化して見ることができます。

rule_02.jpg
点がある(値が1になっている)部分が利用しているところで、1分検知されると出ます。複数回or長時間入っていれば、複数の点として記録されます。これでいつ、どれくらい入ったのか(逆に入っていないのか)、間隔に変動があるか、視覚的に分かるようになりました。

SNS連携

次に、トイレの利用を検知した際にPushで通知してくれるようにします。

  • まずは、SNSのトピックを作成します。
    SNSのTopicsページで”Create new topic”を選択すると、以下のウインドウが開きますので、任意の名前を入れて”Create topic”を選択します。

sns_01.jpg

  • 次に、トピックをサブスクライブするメールアドレスを登録します。

    • Topic ARNに上記で作成したトピックのARNを入力します。
    • ProtocolにEmailを選択します。(※後述のAWS IoTの出力設定とあわせる必要があります。)
    • Endpointへ通知したいメールアドレスを入力します。
    • “Create subscription”を選択すると、メールアドレスにConfirmationのメールが送信されますので、リンクをクリックします。

sns_02.jpg

  • 最後にAWS IoT側から連携の設定を行います。

    • SNS target

      • 作成したSNSトピック名を指定します。
    • Message format
      • RAWを選択します。

        • JSON形式を利用したい場合は、SNSのsubscriptionもSNSにして作成する必要があります。
    • IAM Role name
      • 先程作成したRoleを指定します。

sns_02.jpg

上記の設定を行うと、トイレ利用を検知すると以下のようなメール通知が行われます。AWS IoTへ送信されてきた生データをそのままメール通知しているため味気ないですが、どのくらいトイレにいたのか(countPerMin)も知ることができるようになりました。より複雑な条件付けは必要ですが、SNSはSMSにも対応していますので、緊急時は会社携帯にだって連絡させることも可能です。

sns_mailsample.jpg

Lambda連携

今回は、LINEへメッセージを送信するためのファンクションをLmabdaで実装します。ただし、必要な入力データとしてメッセージ送信先の情報やLINE botアカウント用の認証情報が必要になるため、デプロイする前にLINE botの作業へ移りますのでご注意ください。

  • Serverless Frameworkの準備

メッセージ送信用のServerless Frameworkのプロジェクトを作成します。
(Serverless Frameworkの使い方はこちらを参照ください)

#Install via npm:
npm install -g serverless
#グローバルインストールである必要はないので、任意で。
#Set-up your Provider Credentials. Watch the video on setting up credentials
# Create a new Serverless Service/Project
serverless create --template aws-nodejs --path pushMessage
# Change into the newly created directory
cd pushMessage
  • 連携先となるLambdaファンクションを作成

Lambda用のコードとしては、以下のようなものをServerless Frameworkを利用してデプロイするために準備します。テンプレートとしてhandler.jsが作成されているため、内容を以下に置き換えます。

handler.js
// load modules
var https = require('https');

//load environment variable
const toToken = process.env.toToken;
const channelAccessToken = process.env.channelAccessToken;

module.exports.pushMessage = (event, context, callback) => {

    console.log('EVENT:', JSON.stringify(event, null, 2));
    var userate = "(" + event.countPerMin + "/120)";

    // Request Body
    var request_body = JSON.stringify({
        to: toToken,
        messages: [
            {
                "type": "text",
                "text": "トイレ使ったにゃん♪ 早くかたづけるにゃん♪" + "\r\n" + userate
                }
            ]
    });

    // Request Headers
    var send_options = {
        host: 'api.line.me',
        path: '/v2/bot/message/push',
        headers: {
            "Content-type": "application/json; charset=UTF-8",
            "Authorization": " Bearer " + channelAccessToken
        },
        method: 'POST'
    };

    // API request
    var req = https.request(send_options, function (res) {
        res.on('request_body', function (chunk) {
            console.log(res.statusCode + chunk.toString());
        });
        req.on('error', function (err) {
            console.log('ERROR: ' + err.message);
            callback(err);
        });
    });
    req.write(request_body);
    req.end();
    callback(null, "function executed successfully");
};
  • serverless.ymlの準備

serverless.ymlは以下のような感じです。こちらもテンプレートを置き換えます。先程のLambdaファンクションに加えて、実行のためのRoleを作成する内容となっています。
※環境変数(environment)に記載している[Placeholder_toToken][Placeholder_channelAccessToken]は、LINEの情報を入手後に置き換えていただくためのプレースホルダです。

serverless.yml
service: pushMessage

provider:
  name: aws
  runtime: nodejs6.10
  stage: dev  #default stage, overwrite by --stage option
  region: ap-northeast-1  #利用するリージョンの設定
  memorySize: 128 # Overwrite the default memory size. Default is 1024
  timeout: 5
  environment:
    region: ${opt:region,self:provider.region}
  iamRoleStatements:
    - Effect: Allow # note that these rights are given in the default policy and are required if you want logs out of your lambda(s)
      Action:
        - logs:CreateLogGroup
        - logs:CreateLogStream
        - logs:PutLogEvents
      Resource: "*"

functions:
  pushMessage:
    handler: handler.pushMessage
    environment:
      toToken: [Placeholder_toToken]
      channelAccessToken: [Placeholder_channelAccessToken]

  • 後述の手順(LINE bot連携)を実施し、プレースホルダ部分を置き換え、serverless.ymlを更新します。

LINE bot連携

LINEでは、独自サービスというLINEユーザの双方向のコミュニケーション用にAPIを公開してます。今回はそちらで利用可能なPush APIを利用します。その際に必要な情報の取得が少々面倒(というか分かりにくい)ため、手順を記載します。なお、こちらの利用には通常の(BOT用ではない)LINEアカウントがある前提となっていますので、お持ちでない方はLINEのアカウント登録から実施ください。

Botアカウントの作成

  • まずはLINE BUSINESS CENTERにアクセスし、ログインします。

    • サイト右上にログインボタンが有りますので選択します。
    • アカウントは既存のLINEアカウント(で登録しているメールアドレス)です。
  • ログイン後の上記ページで、Messaging APIを選択します。
    LINE_04.jpg

  • “Developer Trialを始める”を選択します。

    • このページの最下部のプランに紹介されています通り、Push APIが使えるのはDeveloper Trialもしくはプロ(API)です。Trialは友達数に制限(50人まで)があるものの、ご自宅のワンちゃんニャンちゃんの情報をPushしてほしい人数と比べると十分だと思いますので、こちらを選択します。(プロ、高いんです・・・。)

LINE_05.jpg

  • 会社/事業者情報の登録を行います。

    • 基本的に、任意に内容を埋めてください。
    • 今回のような用途の場合、個人を選択することになると思いますが、”会社/事業者名”のところは、LINE Botアカウントを友達登録する際に表示され、かつ、LINE Botアカウントが有効な状態(サービス中)では変更できませんので、公開範囲なども踏まえて入力ください。

LINE_06.jpg

  • このBussinessアカウントを選択した状態で、改めてMessaging APIの利用を選択すると、Botアカウントの設定を開始できます。

    • アカウント名、業種を入力して”確認する”に進みます。
    • Botアカウント用のアイコン写真もここでアップロードできますが、後からも変更可能です。

LINE_07.jpg

  • 申し込みが完了すると、以下の画面に遷移しますので、”LINE@MANAGERへ”を選択します。
    LINE_08.jpg

  • Bot設定から”APIを利用する”を選択します。

    • 通常の1対1のトークなどが不可になり、Bot用のアカウントとしてのみ利用可能な状態になります。
      LINE_09.jpg
  • 再度、Bot設定を開き、リクエストや詳細な挙動の設定を行います。

    • Webhookの送信:利用する

      • 後述のLINEユーザID取得に利用します。
    • Botのグループトーク参加:利用する
      • こちらは任意ですが、グループトークに対してメッセージを贈りたい場合は”利用する”を選択します。
    • 自動応答メッセージ:利用しない
      • 話しかけられた際の挙動として、応答できない旨のメッセージがデフォルト設定されていますが、そちらを無効にします。
    • 友達登録追加時の挨拶:どちらでもOK

LINE_10.jpg

channelAccessTokenの取得

  • LINE BUSINESS CENTERのアカウントリストを開き、Messaging API の”LINE Developers”を選択します。

LINE_11.jpg

  • Channel Access Tokenの”ISSUE”ボタンを選択肢、トークンを発行します。

    • こちらの値をserverless.ymlの環境変数として[Placeholder_channelAccessToken]を置き換えます。

LINE_12.jpg

LINEユーザIDの取得

Push APIはリファレンスにもある通り、送信先のLINE ID(グループトークのIDなども含む)を指定しなければなりません。(※ID指定無しに友達登録している人全員に送る、ということができません。)
そこで、今回は簡易的にそのIDを取得する手順を記載します。本格的なBOTサービスを運用する場合は、IDを取得してからデータベースに保存するところまで自動化するべきだとおもいますが、今回は仕組みのご紹介ということで。

Webhook受け先の作成

LINEのBotアカウントに対してイベントが発生した際、内容をWebhookで飛ばす事ができます。LINEユーザのIDもその中に情報として含まれており、その他の取得方法がない・・・と思います。※もっと簡単な取得方法があったら申し訳ないです。
というわけで、Webhookを受け、内容を確認するための準備を行います。Webサーバをお持ちの方は、そちらで受け取れば良いのですが、ない方はわざわざサーバを立てるのも面倒だと思いますので、API Gateway + Lambda Functionで代用してしまいます。

  • Lambda Functionの作成
    送られてきたeventの中身を確認できればなんでも良いのですが、今回は以下のファンクションを利用します。渡されたeventをログ出力するだけの内容です。ファンクションの詳細な設定は、デフォルトでOKです。
dumpEvent.js
'use strict';
exports.handler = (event, context, callback) => {
    console.log('event =  ', JSON.stringify(event));
    callback(null, event);  // Echo back the first key value
};
  • トリガーの設定

ファンクションの”トリガー設定を追加”からAPI Gatewayを選択します。

LINE_13.jpg

API名、デプロイされるステージは任意でOKです。セキュリティはオープンを選択します。(※認証無しになるため、IDの確認後は、APIを削除します)
LINE_14.jpg

  • API Gatewayの設定

メソッドの”統合リクエスト”の設定を開き、”Lambdaプロキシ統合の仕様”のチェックを外します。

LINE_15.jpg

  • Webhook URLの登録

Lambdaのトリガー設定からURLをコピーします。
LINE_16.jpg

LINE developerから”EDIT”を選択し、上記のURLを設定します。
rule_02.jpg

  • イベントの送信

登録したいIDが送信されるイベントを発生させます。例えば、Botアカウントのユーザ登録や、トークへの招待ですが、なんでもOKです。友達登録はdeveloperのページにQRコードが有りますので、そちらを利用してください。

  • ログの確認

dumpEventファンクションのログを表示(CloudWatch Logsを確認)すると、以下のようなログが出ているはずです。userIdやroomId(トークルームの場合)の部分がtoTokenに指定するIDとなりますので、こちらで[Placeholder_toToken]を置き換えます。。ユーザの場合はUから始まる文字列、トークルームの場合はRから始まる文字列です。

rule_02.jpg

LambdaのFunctionのデプロイ

  • serverless.ymlの編集が完了したら、以下のコマンドでデプロイします。

    • ※作成するリソースも多くないため、手動で作成しても問題ありません。
serverless deploy -v

デプロイが完了すると、AWS IoTのRuleにマッチした際、Lambda Functionへ連携されてLINE botが通知してくれるようになりました。

LINE_20.jpg

おわりに

今回は、比較的シンプルにAWS IoTから他のサービスへ連携する部分をご紹介しました。簡易な内容であれば少し設定をするだけで利用できますし、凝ったことをしたければLambdaへeventを飛ばしてしまえばある意味なんでもできてしまいます。これで召使いの外出中の不安が少し減りますが、、、できれば一緒にいたいですね。

LINE_20.jpg

続きを読む

IoTでペットヘルスケア[実装編:センサデータの取得~AWS IoT連携]

本記事で取り扱うこと

IoTでペットヘルスケア[構想編]
IoTでペットヘルスケア[実装編:センサデータの取得~AWS IoT連携] ←本記事(構想編の続編)です
IoTでペットヘルスケア[実装編:AWSサービス間の連携]←次回です

IoTでペットヘルスケア[構想編]で紹介したアーキテクチャのうち、下記の赤枠内の実装(センサデータの取得からAWS IoTへデータを取り込むまでの部分)について、順を追って説明します。手順は現時点(2017/5)のものであるため、時間が経過している場合には、より便利なものが出ている可能性もありますので最新の情報をご確認ください。

AWS Design_pets_healthcare_実装編01.png

Raspberry Pi 3の準備

利用機材

以下を準備します。

  • Raspberry Pi3 Model B
  • GrovePi+
  • Grove – PIR Motion Sensor
  • microSDカード(今回は16GB)
  • USB Micro B(給電用)
  • その他(セットアップ用)
    • HDMIケーブル
    • モニタ(HDMI対応)
    • USB接続マウス
    • USB接続キーボード
    • microSDカード・リーダライタ

その他以外を接続すると、以下のような状態になります。
raspberrypi.jpg

OSのインストール

RASPBIAN JESSIE WITH PIXELをインストールします。
シンプルにインストールするだけですが、以下のとおりです。

  1. RASPBIAN JESSIE WITH PIXELをダウンロード、解凍します。

    • 今回は以下のリリースを利用。

      • Version:April 2017
      • Release date:2017-04-10
      • Kernel version:4.4
  2. 解答したイメージファイルをmicroSDカードへDDで書き込む。

  3. microSDカードをRaspberry Piへ挿入、セットアップ用のその他機器を接続して給電用USBケーブルを接続する。

[オプション] 日本語環境を設定

初期インストール時は英語環境になっているため、必要であれば日本語環境化しましょう。

  1. OS起動後、MenuからRaspberry Pie Configurationをクリックします。

    • このあたりのメニューの名前はOSのバージョンで少しずつ変わっていますので、それらしいものをお探しください。
  2. Localisationのタブを選択し、以下を設定する。(※設定後、再起動を促されますが、Noを選択する)

    • Locale

      • Language: ja(Japanese)
      • Country: JP(Japan)
      • Character Set: UTF-8
    • Time zone
      • Area: Japan
    • Keyboard
      • Country: Japan
      • Variant: Japanese
  3. 日本語フォントをインストールする。
    • ログイン時のデフォルトユーザ(pi)でターミナルを開き、下記を実行します。
$ sudo apt-get install jfbterm

上記の手順を実行後、OSを再起動すれば日本語化されます。

[オプション] エディタのインストール

好みの問題かもしれませんが、初期のviは使いづらいためvimをインストールします。

$ sudo apt-get update
$ sudo apt-get install vim

[オプション] tmpのRAMDISK化

長期間の稼働を前提とするため、念のためにファイルI/Oが継続的に行われる部分についてはRAMDISK化しておきます。(そんなに大量に読み書きするわけではないため、気休め程度ですが。)

/etc/fstabに以下を追記し、再起動後に正常にマウントされていることを確認します。

tmpfs           /tmp            tmpfs   defaults,size=32m 0       0
tmpfs           /var/tmp        tmpfs   defaults,size=16m 0       0
tmpfs           /var/log        tmpfs   defaults,size=32m 0       0

ネットワーク接続

Raspberry Piをインターネットへ接続できるように設定します。
有線でも無線でも、お好きなほうでOKですが、設置場所を考えると無線のほうが取り回しが楽なのでいいかもしれません。GUIからも設定できるため、特に難しいことはないので説明は割愛します。

GrovePiのライブラリをインストール

GrovePiとセンサーを利用するためのライブラリを導入します。

  • GrovePiのライブラリをクローンしてインストール
$ mkdir /home/pi/grovepi
$ cd /home/pi/grovepi
$ sudo git clone https://github.com/DexterInd/GrovePi
$ cd /home/pi/grovepi/GrovePi/Script
$ sudo chmod +x install.sh
$ sudo ./install.sh

途中でインストールの継続を聞かれるのでY(Yes)を選択。

  • GrovePi+の接続確認。
    GrovePi+が接続されている状態で、以下のコマンドを実行します。
$ sudo i2cdetect -y 1

WS000004.JPG
上記のように04が見えていれば、正常にGrovepi+を認識できています。

PIR Motion Sensorのデータ取得

  • PIR Motion SensorをD8ポートに接続します。

接続ポートは他でもOKですが、次項のサンプルコードではD8前提となっています。

  • センサデータ取得のサンプルコード

0.5秒毎にセンサデータの取得(動きを検知)して、1分ごとの集計結果をファイルに出力するサンプルです。デーモン化する前提ですので、不要な部分はコメントアウトしてあります。動作確認時はコメントアウトを外してprint部分をすれば、0.5秒おきの検知結果を標準出力へ出します。
#長期間運用する場合は、デーモン化してしまうのでsyslogが溢れないようにコメントアウトしたままのほうが良いと思います。

grove_pir_motion_sensor_d.py
import os
import sys
import time
import grovepi
import datetime

def getMotionSensor():
    pir_sensor = 8
    motion=0
    grovepi.pinMode(pir_sensor,"INPUT")
    countPerMin = 0
    i = 0

    while True:
        try:
            if i >= 120:
                d = datetime.datetime.today()
                output = "{ " + "\"countPerMin\":" + str(countPerMin)    + ",\"timestamp\":\"" +d.strftime("%Y-%m-%dT%H:%M+09:00")+ "\" }"
                print output

                f = open('/tmp/motionDetected.json', 'w')
                f.write(output)
                f.close()                     

                i = 0
                countPerMin = 0
            else:
                i = i + 1

        # Sense motion, usually human, within the target range
            motion=grovepi.digitalRead(pir_sensor)
            if motion==0 or motion==1:  # check if reads were 0 or 1 it can be 255 also because of IO Errors so remove those values
                if motion==1:
                    countPerMin += 1
                    #print ('Motion Detected')
                    #print i
                #else:
                    #print ('-')
            time.sleep(.5)

        except IOError:
            print ("Error")

def fork():
        pid = os.fork()

        if pid > 0:
                f = open('/var/run/motionsensor.pid','w')
                f.write(str(pid)+"\n")
                f.close()
                sys.exit()

        if pid == 0:
                getMotionSensor()


if __name__=='__main__': 
    fork()   
  • テスト実行

    • ハードウェアのPinを読みに行くため、root権限での実行が必要です。
    • うまく動作すれば、/tmp/motionDetected.jsonへ以下のような内容が出力されます。
{ "countPerMin":0,"timestamp":"2017-05-05T14:47+09:00" }

こちらのセンサーは、もう少し短い間隔でデータを取得することも可能ですが、ネコ様がトイレに入って出てくるまでの動きを検知したいので、0.5秒おきに検知を行い、1分間(最大120回検知)の中でどのくらい動きがあったのかを返すためのデータ出力を行っています。最終的には、この検知回数を元に通知を行っていきます。

純粋にセンサーしかない場合はともかくとして、ラズパイやEdisonなどの処理能力があるものであれば、センサーの生データそのものよりも、少し加工して使いやすくしたものを作り出したほうがよいのでは、と思います。

データ取得スクリプトのデーモン化

データ取得のスクリプトをOS起動時やプロセス停止時に自動で起動するため、デーモン化します。
#最近はinit.dから変わっていますので、久しぶりに触る方はご注意ください。・・・一瞬、困ったのは私だけ?w

  • 上記のgrove_pir_motion_sensor_d.pyを/usr/local/libに配置します。
  • /etc/systemd/system に motionsensord.serviceを作成します。
motionsensord.service
[Unit]
Description=Pir Motion Sensor Daemon
[Service]
ExecStart=/usr/local/lib/grove_pir_motion_sensor_d.py
Restart=always
Type=forking
PIDFile=/var/run/motionsensor.pid
[Install]
WantedBy=multi-user.target
  • サービス設定を読み込み、手動でデーモンを起動して動作確認します。

設定のリロード、手動起動

$ sudo systemctl daemon-reload
$ sudo systemctl start motionsensord

デーモンのステータスやファイル出力を確認

$ sudo systemctl status motionsensord

出力結果の例
WS000005.JPG

  • 自動起動を有効にします。
$ sudo systemctl enable motionsensord

OS再起動後も動作していれば正常に設定できています。

AWS IoTの準備

1年ほど前と比較して、非常に簡単になっています。基本はAWS IoTに示されれる手順に沿って実行するだけです。
#この説明いらないのでは・・・と思いつつ、AWS IoT初学者の方もいらっしゃると思いますので、一通りの流れを紹介ということで。

デバイスの登録

Raspberry PiをAWSに接続するための設定を行います。

connect_01.jpg
AMCからAWS IoTのコンソールを開き、Connect のページを選択します。Configuring a deviceの”Get started”を選択します。

WS000008.JPG
接続までの流れ説明ページが表示されるので、”Get started”を選択します。

WS000009.JPG
環境に応じてSDKをセットアップするためのKitが準備されていますので、利用したいものを選択します。今回はRaspbianなのでLinux/OSXを選択します。また、AWS IoTへの部分を記述する際の言語も選択します。今回はNode.jsを利用します。最後に”Next”を選択します。

WS000010.JPG
AWS IoT上で管理するデバイスの名前を指定します。こちらは、管理者がどのデバイス(今回だとRaspberry Piのどのマシンなのか)が分かればよいため、任意の名前でOKです。指定後、”Next step”を選択
※どこかに設定した値と一致させなければならない、といったことはありません。

WS000011.JPG
接続用Kitのダウンロードを行います。内容を確認後、”Next step”を選択します。

ちなみに、ここまでの操作により、以下の手順が自動的に行われています。(1年前は個別に行う手順でしたので関係が分かりやすかったのですが、今は便利になった反面、何が行われているのか少々分かり難くなっています。)

  • デバイスがAWS IoTにデータを送る権限の定義(ポリシー作成)

    • A policy to send and receive messages の部分です
  • デバイスに配置する認証キーの作成
    • A certificate and private key の部分です。Kitに含めれます。
  • デバイスと認証キー、ポリシーの関連付け
    • 3つを関連付け、特定のデバイスに権利を持たせて認証し、AWS IoTのトピック(MQTTでつかうチャネルのようなもの)へPublish/Subscribeできる状態とします。

デバイスの設定

WS000012.JPG
ダウンロードしたファイルをデバイス(Raspberry Pi)へ転送し、示されている手順を実行します。
※こちらの画面は接続確認にそのまま利用しますので、開いたままにしておいてください。

start.shを実行すると、以下の処理が実行されます。

  • 証明書の確認
  • aws-iot-device-sdkをはじめ、各種モジュールのインストール
  • AWS IoTとの接続テスト
start.sh
start.sh
# stop script on error
set -e

# Check to see if root CA file exists, download if not
if [ ! -f ./root-CA.crt ]; then
  printf "\nDownloading AWS IoT Root CA certificate from Symantec...\n"
  curl https://www.symantec.com/content/en/us/enterprise/verisign/roots/VeriSign-Class%203-Public-Primary-Certification-Authority-G5.pem > root-CA.crt
fi

# install AWS Device SDK for NodeJS if not already installed
if [ ! -d ./node_modules ]; then
  printf "\nInstalling AWS SDK...\n"
  npm install aws-iot-device-sdk
fi

# run pub/sub sample app using certificates downloaded in package
printf "\nRuning pub/sub sample application...\n"
node node_modules/aws-iot-device-sdk/examples/device-example.js --host-name=av8pngo3zyi88.iot.ap-northeast-1.amazonaws.com --private-key=y_raspberrypi_01.private.key --client-certificate=y_raspberrypi_01.cert.pem --ca-certificate=root-CA.crtroot@raspberrypi:~/workspace/cat_healthcare/gitrepo/connect_device_package#

デバイスに接続し、start.shを実行すると、下記のようにconnectと表示されれば接続が成功しています。
WS000015.JPG

さきほどのAWS IoTの画面に戻ると、Step3の下に、デバイスからPublishされたメッセージが届いているのが分かります。これはstart.shから実行された接続確認用のコードから送られています。
WS000013.JPG

続いて、Step 4のテキストボックスに任意の文字列を入れ、Send messageを選択すると、デバイス(Raspberry Pi)側がSubscribeしているTopicにPublishすることができます。今回はテスト用に”test publish message AAAA”と送ってみました。すると、以下のようにデバイス側で受信することができています。
WS000014.JPG

以上でデバイス側の設定は完了です。

センサデータ取得の連携設定

取得したセンサーのデータを実際にAWS IoTへ送信します。

AWS IoTへのPublish

サンプルですので、べた書き部分が多いですが、以下のようなスクリプトを作成します。今回はconnect_device_packageを利用しやすくるため、同ディレクトリに配置してしまいます。

publish_data_pirmotion.js
var awsIot = require('aws-iot-device-sdk');
var fs = require('fs');

var clientId_suffix = 'MotionSensor01';
var deviceId = 'y_raspberrypi_01';
var sensor = 'motion_sensor';
var MQTT_clientID = deviceId + "_" + clientId_suffix;

var topicname = "topic/" + deviceId + "/sensor/" + sensor;

var device = awsIot.device({
    keyPath: 'y_raspberrypi_01.private.key',
    certPath: 'y_raspberrypi_01.cert.pem',
    caPath: 'root-CA.crt',
    clientId: MQTT_clientID,
    region: 'ap-northeast-1'
});


device.on('connect', function () {

    console.log('connect');
    setInterval(function () {

        var messageJson = JSON.parse(fs.readFileSync('/tmp/motionDetected.json', 'utf8'));
        messageJson.clientId = MQTT_clientID;
        messageJson.deviceId = deviceId;

        var message = JSON.stringify(messageJson);

        console.log("Publishing.. " + topicname);
        device.publish(topicname, message);
    }, 60000);
});

処理としては、モーションセンサのデータ取得結果(motionDetected.json)に対してdeviceIdやclientIdをデータとして含め、1分毎にAWS IoTへ送信しているだけになります。

注意点としては、MQTTの仕様として、同一のトピックに対して接続する際にclientIdごとにコネクションを確立しており、複数のデバイス間で重複していると、セッションの奪い合い(お互いに接続、接続断を繰り返してしまう)ことになります。そのため、一意になるようにclientIdを生成して上げる必要があります。今回はデバイスの名前にセンサーの名前を組み合わせて生成しました。

MQTTのトピック名についても、センサーの種類ごとに分けて生成していく想定になっています。センサーの種類を増やす際には、これらのスクリプトやトピックごと増やすアーキテクチャとなります。AWS IoT側からデータを利用する際は、このトピック名を対象として選択することになるため、複数種類のデータを取り扱う際には、十分に検討して設計が必要です。例えば、途中のパスによって値のグルーピングを行う等。

動作確認は、AWS IoTのテスト用コンソールを利用します。
WS000017.JPG
AWS Iotの”Test”ページを開き、トピック名を入力して”Subscribe to topic”を選択します。

すると、Subscriptionsの中に指定したトピック名が表示されますので、選択します。1分毎にデータを送っているため、成功していれば、以下のようにメッセージを受信(Subscribe)できます。
WS000019.JPG

以上でモーションセンサーで実際に取得したデータをAWS IoTへ連携することができるようになりました。

Publish用スクリプトのデーモン化

publish_data_pirmotion.jsもセンサデータ取得用のスクリプトと同様にデーモン化してしまいます。昔はnode.jsだとforeverなどを利用していた気がしますが、systemdの場合は、Pythonスクリプトと同様でOKです。

  • /etc/systemd/system に publish_motionData.serviceを作成します。
publish_motionData.service
[Unit]
Description=publish motion data
After=syslog.target network.target
[Service]
Type=simple
ExecStart=/root/.nvm/versions/node/v6.1.0/bin/node  publish_data_pirmotion.js
WorkingDirectory=/root/workspace/cat_healthcare/gitrepo/connect_device_package
KillMode=process
Restart=always
[Install]
WantedBy=multi-user.target

#rootで作成しちゃっていますので、上記のような内容になっています。

  • サービス設定を読み込み、手動でデーモンを起動して動作確認します。

設定のリロード、手動起動

$ sudo systemctl daemon-reload
$ sudo systemctl start publish_motionData

デーモンのステータスやファイル出力を確認

$ sudo systemctl status publish_motionData
  • 自動起動を有効にします。
$ sudo systemctl enable publish_motionData 

OS再起動後もAWS IoTへデータが送られていることを確認できればOKです。

センサーの設置

Cat’s Restroomにセンサーを設置します。

我が家では、以下のように個室風のトイレが設置されています。
Cat'sRestroom_外観.jpg
少々わかりにくいのですが、上記の写真のようになっています。2つのカラーボックスを棚として開いている側を向き合わせて置き、片方の背板を出入り口用に切り取っています。中は市販のネコトイレ(すのこ式)です。
#ホワイトペレット最高!

その中に対して、以下のようにセンサーを設置しました。図は真横から見たときの断面図・・・絵心なさすぎてすいません。
RestroomSensor01.png

入り口の背板(上部)の内側にモーションセンサーを取り付け、トイレ内部の動きを検知するようにしています。配線は2つのカラーボックスの間から通して、ネコ様の出入りの邪魔にならないようにしています。また、トイレ内の上部を中心に検知する配置のため、トイレ掃除等を誤検知しにくく・・・もなっているはずです。
#誤検知については、AWS IoT側で受け取ったデータを処理する際に条件付け(しきい値判定など)を行うことでも回避しています。

この配置で、0.5秒に一回のセンサーデータ取得を行うと、ネコ様がトイレに入るとバッチリ検知ができるようになりました。

おわりに

今回、センサデータを取得してAWS IoTへデータ連携を行うところまでできるようになりました。次回はAWS IoT側で受け取ったデータを活用して召使いへ連携していく部分について記載したいと思います。

また、他にもセンサーはあるのですが、長くなりすぎるため別立てして拡張編でも書いたほうがよさそうです。

次回:IoTでペットヘルスケア[実装編:AWSサービス間の連携]
cat01.jpg

続きを読む

IoTでペットヘルスケア[構想編]

はじめに

ペットヘルスケアについて

皆さん、ご自宅のワンちゃん、ニャンちゃんの健康が心配になることはないでしょうか。
外出中に具合が悪くなっていないか、家にいる時でも具合悪いのを我慢していないか、など。特に急性の病気の場合、少しでも早く気がついてあげて病院に連れていきたいところです。

ネコの場合、特に尿路系の病気は1~2日で命に関わることもあり、大変心配です。突発性膀胱炎、膀胱結石、尿道結石、etc・・・。いろいろな要因がありますが、うちの子はなりやすさの要素にヒットする部分が多く(♂ネコ、純血種、ドライフード、肥満!)、より心配です。ご飯にはかなり気を配って(日によっては私より高い物食べてます!w)いるものの、それ以外にも要因があるということです。

まずはこのあたりのクリティカルなところを早期発見できれば・・・というのがモチベーションです。

picture02.jpg

IoTやAI関連について

丁度1年ほど前にIoTのお勉強も兼ねてAWS IoTやRaspberryPiを利用して、ちょっとしたものを作成したのですが、この1年で同じサービスでも使いやすさがグッと向上しているようです。分野として期待されていることもあり、大変進歩が早いので情報をまとめてもすぐに陳腐化する懸念も否めないのですが、現時点でのベストプラクティスとまでは行かなくても便利な使い方や、構築の一通りの流れをご紹介できればいいな、と思います。AI系のサービスはできれば取り込みたいです。

取り扱う技術的な要素

以下を利用する予定ですので、ご興味のあるかたは是非。ただし、個別の要素について深掘りすると言うよりは、どう組み合わせて使うかという観点でご紹介します。そのため、それぞれについて詳しく知りたい方は別の記事や、マニュアル(本記事からも参照する予定)をご覧いただくほうが良いと思います。

  • Amazon Web Services(AWS)

    • IoT、Lambda、CloudWatch、SNS、Rekognition、etc
  • RaspberryPi
    • Raspberry Pi 3 Model B、GrovePi+、各種センサー類
  • LINE bot
    • Messaging API

実現したいこと

尿路系の症状をいち早く検知

病気についてはこちらが詳しいので割愛しますが、多くの病気では症状の一つとしてトイレの利用状況に現れます。

  • おしっこの回数が増える(or 1分以上かかる)
  • おしっこが少ない
  • おしっこするとき声を出して痛がる
  • トイレ以外で粗相する(つまりトイレを使っていない)

などなどです。特に、回数については多くの病気で共通した症状として現れます。これらを検知して飼い主 召使いへ連絡することで早期発見・治療へとつなげること、また検知の仕組みがあること自体で召使いも安心できるようにすることです。そのために、まずは日頃から普通の状態を観測しておき、なにか変化があった際に異常だと分かるようにしていきます。

アーキテクチャ概要(全体)

以下の図のようなアーキテクチャを想定しています。ゆくゆくは色んなネコ様に使っていただきたく、スケールもし易いようにサーバレスなアーキテクチャにします。

AWS Design_pets_healthcare.png

  1. ネコさん用トイレ(Cat’s Restroom)に設置したセンサからデータを取得し、Raspberry Pi 3からAWS IoTへ送信します。
  2. AWS IoTから各種AWSサービスに連携し、必要な処理を行った上で召使いへ通知します。
    • CloudWatch

      • トイレ利用履歴を保存します。
      • グラフ化機能を利用して、直近の利用履歴を確認できるようにします。
    • SNS
      • トイレ利用を検知し、召使いへメールやSMSで連絡します
    • Lambda
      • LINEを経由してメッセージ送信を行います。

        • 召使いがLINE botを登録したら、メッセージ送信に必要な情報を取得します。
      • より複雑な条件判定を行い、召使へ通知を行います。
        • 例:トイレの回数が異常に多い場合には、会社携帯へもSMS!(召使いは早退します)
    • (Rekognition)
      • トイレの画像から状況を判断して通知します。(仮)

書いていたらちょっと複雑になってきたきもしますが、仕組みは単純で、AWS IoTにデータを一旦集めたのち、必要な処理へ分岐できるようになっています。分岐後は、あの手この手で召使いへ連絡します。

Rekognitionはできれば使いたいところですが、ウ○チへの砂の賭け方などにムラがあり、結構厳しいのでは・・・と思っています。匂い(ガス)センサーのほうが確実だとは思うのですが、センサー自体の取扱いが少々難しいため、後回しです。

今後

以下の記事に分割して作成予定です。
IoTでペットヘルスケア[実装編:センサデータの取得~AWS IoT連携]
IoTでペットヘルスケア[実装編:AWSサービス間の連携]

#それぞれが長くなりそうな場合、更に分割するかもしれません。

おわりに

本当はずっと家にいてネコ様の召使い業務に勤しみたいところを苦肉の策で・・・というのが本音ですが、ご奉仕のためにも稼がねばなりませんので仕方ないです。できることをやらねば、ということで!
#リモートワークしたいなぁ・・・田舎の広い家で盛大にキャットウォークを作ってあげたい!(これが真の本音)

続きを読む