DesignSpark Electrical Logolinkedin
Menu 検索
フォーラムで質問

「絶対出席したい君」Androidアプリ+Raspberry Piでアラームシステム

概要

目覚まし時計を使ってもアラームをすぐ止めて二度寝をしてしまったり、アラームの音に気付かないなどして朝起きられずについ授業に遅れてしまう大学生のために、玄関のドアのカギを開くことでアラームを止める目覚ましシステムを開発しました。システムでは3つの機能を実装しました。

  1. 鍵の開閉を用いたアラーム
  2. 鍵の閉め忘れをSlackに通知
  3. 友人の鍵の開閉をSlackに通知

 

開発の背景

このシステムの開発には、朝すっきり目覚める事ができない人が多いという背景があります。目覚まし時計によって目は覚めるがなかなか布団から出れない人、二度寝をしてしまう人、目覚ましの音に気づかない人など、様々なパターンが挙げられます。そのため、設定した時間にきちんと起きる事ができるシステムがあればとても価値のあるものになると考えました。これに加え、よく眠るための工夫をしている人に対し目覚めのために工夫している人は少ないというアンケート結果から、起きるためのアイテムは様々な人から興味を持ってもらえるのではないかと考えました。

私達は寝ている人が必ず起きられるように、目覚まし時計の音を止める動作と玄関のドアの開閉を結びつけることを考えました。玄関のドアまで歩くことで通常の目覚ましより体を使うことになります。また、ドアを開けるという動作で外気に触れ日光を浴びることが出来ます。この二点より、布団から出やすくする、二度寝を防止するという目標を達成させることができるのではないかと考えました。ただし、都度ドアまで行きアラームをセットするのは大変なので、androidアプリから設定できるようなシステムを制作しました。

また、目覚まし時計を止めるトリガーをドアの開閉ではなく鍵の開閉と結びつけることで、安全面や外出状況などもある程度予測できると考えました。そのため、私達の制作したシステムは目覚まし機能に加えて、鍵の閉め忘れ通知と友人間での外出状況の共有という2つを加えたものとなります。

 

システム概要

システムは大きく分けてRaspberry Pi, Android端末の2つのマシンで構成されています。Android端末側では、アプリからアラームを鳴らすスケジュールの設定、Slackによる鍵の状態の確認を行います。Raspberry Piはスケジュールに合わせアラームを鳴らすタイミングの待機、Android端末から受け取ったアラームのスケジュールの受理、鍵の状態の確認及びSlackへの通知を行います。

Android端末とRaspberry Piの対応関係

 

使い方

このシステムを使用する際ユーザが行う動作はドアに装置を設置することとアラームをセットすることです。装置の設置は以下の図のように行います。今回は鍵の状態検知にスイッチを使用しました。アラームのセットはAndroidアプリを用いて時間割と講義に何分前に起こすかを入力し、URLでクエリパラメータをRaspberry Piに送信します。これによって指定の時間にRaspberry Piに接続したスピーカからアラームが鳴るようになります。アラームを止めるにはドアの鍵を開けます。さらにこの動作とは別に鍵の状態を常に監視し、一定時間以上ドアが開いているとSlackに通知を送るシステムもバックグラウンドで動作しています。鍵が一定時間以上開いていると以下の図のような通知がSlackに届きます。また友人の家のドアの開閉を検知しSlackに通知を送ることもできます。

装置の設置例

Slack通知例


実装

androidアプリ

アラームの設定を行うAndroidアプリはMainActivityクラスとHttpGetTaskクラスの2つで構成されています。

MainActivityクラスはアラーム起動時間の入力とRaspberryPiに送信するクエリパラメータの生成を行うクラスです。アプリの画面は下の図のような画面で、画面上部はURLとクエリパラメータの確認と生成ボタン、中段はSpinnerによるプルダウンメニューとEditTextによる数値の入力欄、下段が送信ボタンという構成です。

アプリ起動時の画面

まず始めに、ユーザーはプルダウンメニューから各曜日の最初の講義の時間を選択し、自宅から大学までの距離を考慮した出発時間となるように講義の何分前にアラームを鳴らすか数値で設定します。プルダウンメニューには1~6限となし、という7つの選択肢があります。それぞれ講義の時間を表し、なしを選択した場合は生活習慣を整えるために一限の時間にセットされます。分数指定の入力欄には、入力前の空欄状態では薄いグレーの文字で「分数を数字で入力」と表示し、誤入力を防止しています。各種入力の例とプルダウンメニューの様子を以下のに示します。

各種設定例とプルダウンメニューの様子

これらの入力を元にして、RaspberryPiのphpに受け渡すためのクエリパラメータを加えたURLを生成します。上段の「URLを作成」ボタンを押すと、プルダウンメニューと入力された分数からphpにわたす形に整形し、URLを形成します。そして、「送信」ボタンを押すと、HttpGetTaskにURLを引数として引き渡します。

HttpGetTaskクラスは受け取ったURLにアクセスするクラスです。そのため、AsyncTaskを継承しています。受け取ったURLにアクセスすることで、RaspberryPiで動作しているset_schedule.phpにアラームの設定情報を渡します。

 

アラーム

 Raspberry PiはスケジュールをAndroid端末から受け取るset_schedule.phpモジュール、アラームの制御を行うalarm.pyモジュールの2つで構成されています。以下に各モジュールの動作とフローチャートを示します。

set_schedule.php

  1. クエリのチェックを行う
  2. クエリの数が6個なら問題なし、それ以外ならabortする
  3. データベース用ファイルを開く
  4. ファイルが開けなかった場合abortする
  5. データベース用ファイルにクエリを保存

本来はセキュリティ上の観点からクエリの内容をチェックするべきだが今回はデモで動かすだけの実装だったので省略しました。

set_schedule.phpのフローチャート

alarm.py

  1. 初期化処理
    1. pygame.mixerの初期化
    2. 音源のロード
    3. wiringpiの初期化
  2. クエリをデータベースから読み出す
  3. クエリからスケジュールを設定
  4. 現在時刻を取得
  5. 設定された時間と現在時刻が一致したらアラームを鳴らす。一致しなければ4に戻る
  6. Raspberry Piに接続されたスイッチの状態を取得
  7. スイッチが押されたならばアラームを止める。押されていなければ6に戻る

alarm.pyのフローチャート

Slack

鍵の閉め忘れを検知しSlackに通知を送る機能と友人の家のドアの開閉をSlackに通知する機能を持つsw_slack.pyを実装しました。二つの機能について処理の流れをそれぞれ下にまとめます。どちらの機能でも使用する鍵の状態検知はRaspberry PiのGPIOを制御するモジュールであるWiringPiを用いてスイッチの値を取得することで行いました。またSlackへの通知はSlackWebというモジュールを用いて行いました。

鍵の閉め忘れを検知しSlackに通知を送る機能

  1. 鍵の状態を監視
  2. 開錠を検知
  3. 2.からn秒以上鍵が開いたままならばSlackに「ドアのかぎが開いたままです」と通知
  4. 1.から3.を繰り返す

 

友人の家のドアの開閉をSlackに通知する機能

通知の欲しい友人に設置したRaspberry PiのIPアドレスと友人の名前を紐づけた辞書をあらかじめ作成しておきます。この辞書を用いてどの家のドアの鍵の状態が変化したのかを取得します。今回授業で使用したRaspberry PiはIPアドレスを固定したためこのような手法にしました。改善案としてはMacアドレスを使用するなどがあります。

  1. 鍵の状態を監視
  2. 開錠を検知
  3. IPアドレスと現在時刻を取得
  4. 辞書からIPアドレスに対応する(名前)を取得
  5. Slackに「(名前)の家のドアが開きました」と通知
  6. 1.から5.を繰り返す(ただし現在時刻を取得していた場合はその時刻からn秒は通知しない)

 

まとめと課題

まとめ

3つの機能を実装しました。

  1. 鍵の開閉を用いたアラーム
  2. 鍵の閉め忘れをSlackに通知
  3. 友人の鍵の開閉をSlackに通知

課題

スケジュールの更新について

現在アラーム用のスクリプトは起動したタイミングでスケジュールを読み込むようになっており、スケジュールを更新したらそのたびにスクリプトを起動しなおさねければなりません。これでは手間がかかり面倒なので自動で更新するようにしたいです。

友人の鍵開閉をSlackに通知する機能について

鍵の開閉はプライバシーにかかわる重要な情報であるため、細かい設定やセキュリティーの強化を行う必要がある。

 

RamenWithManyOnions さんはまだ自己紹介を入力されていません...

8 Jul 2019, 2:35