Enviro+はさまざまなタイプのセンサーを内蔵したRaspberry Pi用の新しい拡張ボードです。周辺環境のあらゆる環境データを収集するために使用できます。
詳細はこちら。https://shop.pimoroni.com/products/enviro-plus
これから作るもの
今日は光と近接を検知することで、家を守る超ハイテクなソリューションを作ってみます。このアイデアは私の家への入り口が昼間でも非常に暗いという点から来ています。つまり、光の変化はドアが開かれたことを示すものであり、距離センサーの変化は誰か、または何か(🐻)がセンサーに近づいたか通り過ぎたこと意味するからです。
データはFirebase DBに送り、Reactのフロントエンドから監視します。
完成したサンプルはここにあります。
https://tender-lamarr-33eddc.netlify.com
注意:このアイデアは明らかかつ非常に初歩的な解決策です。実際のホームセキュリティでの使用はしないでください。
もう一つ注意:このプロジェクトはRaspbian liteがインストールされたインターネットに接続できるRaspberry Piが既にセットアップされていることを前提としています。
スタートアップガイド
まずRaspberry Piにログインし、Pimoroniが提供するインストールスクリプトを実行します。
これは、依存関係をインストールするために最も簡単で推奨できる方法ですが、次のreadmeでは他にもさまざまな方法が説明されています。https://github.com/pimoroni/enviroplus-python
curl -sSL https://get.pimoroni.com/enviroplus | bash
インストールを終えたら、さらにいくつかの依存関係を手動で追加する必要があります。
sudo apt install python-pip pip install configparser pip3 install RPi.GPIO pip3 install spidev
コードの実行
これですべての依存関係がインストールされたので、今度はコードを書いて行きます。
スターター・プロジェクト(https://github.com/makeupsomething/entrance-monitor)をダウンロードし、feature/step-1
のブランチをチェックアウトして、サンプルを実行します。
git clone https://github.com/makeupsomething/entrance-monitor.git cd entrance-monitor git checkout feature/step-1 python3 entrance-monitor/index.py
アプリケーションが起動し、LCD画面にライトと近接の値が表示されます。ライトセンサーを覆って、値が変化することを確認してください。
次にコードの一部を見てみましょう。
キャンバスとフォントのセットアップ
#/New canvas to draw on./ img = Image.new('RGB', (WIDTH, HEIGHT), color=(0, 0, 0)) draw = ImageDraw.Draw(img) path = os.path.dirname(os.path.realpath(__file__)) #/Set up canvas and font/ font_size = 15 font = ImageFont.truetype("entrance-monitor/fonts/Asap/Asap-Bold.ttf", font_size) text_colour = (255, 255, 255) back_colour = (170, 0, 170) message = ""
ここでは、Pillowライブラリを使用して新しいイメージを作成し、次にフォントとテキストのデフォルトを設定していきます。テキストや背景色を自分なりに編集してみてください。
try: while True: lux = ltr559.get_lux() prox = ltr559.get_proximity() message = """Light: {:05.02f} Lux Proximity: {:05.02f} """.format(lux, prox) #/Calculate text position/ size_x, size_y = draw.textsize(message, font) x = (WIDTH - size_x) / 2 y = (HEIGHT / 2) - (size_y / 2) draw.rectangle((0, 0, 255, 80), back_colour) draw.text((x, y), message, font=font, fill=text_colour) disp.display(img) time.sleep(1.0) except KeyboardInterrupt: pass
ここがこのコードのメインとなります。
ltr559ライブラリを使用して光センサーから輝度、近接センサから近接値を取得しています。
次に、これらを文字列にフォーマットし、先に設定した空メッセージに割り当てます。文字列の長さに基づいてサイズを計算し、画面の中央に配置します。
最後に、長方形を描画し、Pillowライブラリを使用してテキストを追加し完成したイメージを表示させます。その後0.5秒スリープさせてからループさせています。
Firebase
FirebaseとはGoogleが所有するモバイルとウェブアプリケーション開発プラットフォームです。
https://firebase.google.com/?hl=ja
Firebaseのプロジェクトを作る
Firebaseアカウントを持っていない場合は、作成する必要があります。アカウントの作成は無料で、使用するために支払い情報を入力する必要はありません。
ログインしたら、 [プロジェクトの追加] ボタンをクリックします。
プロジェクトに名前を付け、 [続行] をクリックします。Google analyticsをプロジェクトに追加するには 「今はしない」 を選択し、最後に 「プロジェクトを作成」 をクリックします。
サーバのプロビジョニングには数分かかる場合があります。
データベースとルールのセットアップ
Firebaseには2つのデータベースソリューションがあります。
このデータベースを使用する際にはほとんどCloud Firestoreが推奨されていますが、今回使用するPythonライブラリはサポートされていないため、Realtime Databaseを使用します。今回の使い方は非常に単純なので違いはありません。
Firebaseコンソールのサイドバーに行き、 「開発>database」 をクリックします。
最初に「Cloud Firestoreを有効にするかどうか」のオプションが表示されます。
しかし今回のプロジェクトでは使用しませんので、ページを少し下にスクロールして、Realtime Datebaseの「データベースを作成」をクリックします。
データベースのルールを設定するポップアップが表示されるので、 「テストモードで開始」を選択し、「有効にする」 をクリックします。これは、私たちのデータベースが認証を持たないことを意味します。この設定が実際のアプリだとしたら問題がありますが、今回はテスト目的での使用するため今のところ気に留める必要はありません。
注意:繰り返しになりますが、データベースをテストモードにしておくのは危険です。本番アプリケーションでは絶対にしないでください。
次に、プロジェクトAPIキーとプロジェクトIDを取得する必要があります。
サイドバーの歯車アイコンをクリックし、「Project settings」を選択すると、そこにプロジェクトIDとapiキーが表示されます。すぐに必要になるのでメモしておいてください。
pyrebaseのインストールとfirebaseへの接続
プロジェクトをFirebaseにRaspberry Pi上で統合することができるようになりました。
これから私たちはpyrebase4を使います。これはオリジナルのpyrebaseライブラリからフォークしたもので、pythonからのfirebaseと互いに連携します。
pyrebase4をインストールします。
pip3 install pyrebase4
次に、プロジェクトフォルダ内でfeature/step-2
をチェックアウトします。
git checkout feature/step-2
今これを実行しようとすると、エラーが表示されます。これは、Firebaseプロジェクトに接続するためにデータを追加する必要があるためです。このプロジェクトは環境変数(API_KEYおよびPROJECT_ID)を検索するため、これらを設定します。
これが先にメモしておいたFirebase APIキーとプロジェクトIDです。
export API_KEY="apiKey" export PROJECT_ID="projectId"
では前回と同様にコードを走らせてみましょう。
python3 entrance-monitor/index.py
デバイスまたは端末の出力には違いはありませんが、Firebaseコンソールでデータベースを確認すると、データが更新されているはずです。光センサを手で覆ってみてデータが更新されるか確認してみてください。
コードを見てみましょう。
Firebaseの設定
Firebaseのインスタンスを次のように設定して接続しています。
config = { "apiKey": os.getenv('API_KEY'), "authDomain": os.getenv('PROJECT_NAME')+".firebaseapp.com", "databaseURL": "https://"+os.getenv('PROJECT_NAME')+".firebaseio.com", "storageBucket": os.getenv('PROJECT_NAME')+"appspot.com", } firebase = pyrebase.initialize_app(config) db = firebase.database()
データベースにデータを送信する
次に私たちのデータベースにデータを送信できるようにし、簡単なループを追加します。
data = {"light": lux, "proximity": prox, "createdAt": str(datetime.datetime.now())} db.child("data").push(data)
Firebase realtime databaseはJSONフォーマットでデータを受け取るので、輝度と近接値、そしてtimestampを含むオブジェクトを作成します。次に、それをdataというチャイルドコレクションにプッシュします。
しかし、これでは毎秒データを送信することになり、私たちのデータはFirebase上で制御不能となり、無料プランである1日の書き込み制限をかるく超えてしまいます。私たちが本当にしたいのは輝度や近接値が劇的に変化したのを検出したときだけです。それ以外には適当な間隔、例えば60秒ごとにステータス更新を送信できれば充分です。
まず輝度と近接値を追跡し次の値が大幅に異なるかどうかを検出する必要があります。また、データベースに最後にデータを送信してからの経過時間を追跡するためにcount
も追加します。60秒を超える場合は、現在の値を送信します。
whileループの外で宣言します。
prev_lux = 0 prev_prox = 0 count = 0
次にwhileループ内で、輝度と近接値の現在の値が前の値より大きいかどうかをチェックする必要があります。もし値が大きかった場合はすぐにデータベースを更新します。もし輝度と近接値の現在の値が前の値より小さかった場合には、新しい前の値を設定しカウント値を増やします。
if(abs(prev_lux - lux) > 20 or abs(prev_prox - prev_prox) > 20 or count >= 60): data = {“light”: lux, “proximity”: prox, “createdAt”: str(datetime.datetime.now())} db.child(“data”).push(data) count = 0 prev_lux = lux prev_prox = prox count = count + 1
ついにデータを可視化する時がきました。
Reactのフロントエンド
React
Reactはユーザインタフェースを構築するためのJavaScriptライブラリで、Facebookと個々の開発者と企業のコミュニティによって維持されています。
プロジェクトの開始
リポジトリをフォークしてダウンロードします。
フロントエンドがどのように機能するかについては、この記事では詳しく説明しませんが簡単に書くと、デバイスからFirebaseフロントエンドまでのデータを(ほとんど)リアルタイムに取得できるものです。
プロジェクトを実行するには、Firebase APIキーとプロジェクトIDをプロジェクトに追加する必要があります。これらは、pythonプロジェクトで使用したのと同じAPIキーとプロジェクトIDです。
.envというファイルを作成し、次の行を追加します。
REACT_APP_API_KEY=apiKey REACT_APP_PROJECT_ID=projectId
では依存関係をインストールし、次のようにプロジェクトを実行しましょう。
npm install npm run start
Raspberry Pi上のアプリケーションがまだ実行中であることを確認するか、アプリケーションを再起動し、https://localhost:3000にアクセスしてライブ出力を確認します。