イドラさんの髭アンテナ

気になったデバイス・ガジェットと電子工作関連について

インターホンが押されたのをM5Stackでスマホに通知する

在宅勤務中にイヤホンをしていたり、エアコンの吹き出し音でインターホンが鳴ったのに気づかなかったことがあったので、鳴ったらスマホに通知すればいいのでは?ということでM5Stackで実装することにしました。

どうやって鳴ったことを取得するか?

うちはマンションでインターホンは共用部のものになるので、インターホンを外して裏側から取ってくるのは難しそうです。それではどうしたら良いのか?インターホンが鳴ったら画面が光るので、その光を画面に貼ったセンサーで取得することにしてみます。 同じような手法で検出していないか「M5Stack インターホン」などで検索してみたところ、以下のセンサーを使用している人がいました。
M5Stack用光センサユニット [U021]www.switch-science.com
ただこのユニットはページにも書いてあるとおり

アナログ値を出力するため、黒色のGrove Bポートに接続する必要があります。M5Stack Basic本体のGrove Aポートでは使用できません。

とのことでBasicしか今うちに無い・・・アナログポートにジャンパワイヤーで繋げば使えるでしょうけどせっかくI2C接続でコネクタが付いているところですのでケーブルを増やしたくない、他にもないか探したところ以下のものがありました。
M5Stack用環境光センサユニット(BH1750FVI-TR)www.switch-science.com
これならGroveケーブルだけで繋ぐことが出来そうです。
ライブラリもこのページからドキュメントページへのリンクが貼られていて、その先のGithubへもリンクされていましたのでこれを参考にして進めることにします。

ここでM5StackのGroveポートって色が違ってる(黒とか赤とか)のは良いんだけど他にもどんなのがあるんだろう?と疑問に思い調べてみたところ、現在はPort.A,B,Cがあるようです。以下のページに接続可能なセンサ類も載っていて詳しいので参照ください。
www.marutsu.co.jp

スマホへの通知をどうするか

これについてはインターホンが押されてすぐに通知が来ないと意味がありません。それではどうするのか?LINEで通知すれば良いのでは、ということで調べたところLINE Notifyなるサービスで通知することが出来るようです。これを使うと今後も色々な通知が出来るようになりそうですのでここで一度試してみることに。

使い方については以下のページの内容を参考にさせて頂きました。
sample.msr-r.net
大雑把にはLINEトークンを取得してM5Stackから notify-api.line.me にHTTPポストする時にトークンとメッセージを一緒に送るという感じです。

というわけで以下のようなコードで動かしてみました。

#include <M5Stack.h>
#include <WiFiClientSecure.h>

#include <hp_BH1750.h>  //  include the library
hp_BH1750 BH1750;       //  create the sensor

const char* ssid     = "Your-SSID";
const char* password = "Your-Password";
const char* host     = "notify-api.line.me";
const char* token    = "Your-LINE-Token";

unsigned long displayTime = 0;

boolean line_notify(String msg) {
  WiFiClientSecure client;
  client.setInsecure();
  if(!client.connect(host, 443)) {
    Serial.println("connect error!");
    return false;
  }
  String query = String("message=") + msg;
  String request = String("")
              + "POST /api/notify HTTP/1.1\r\n"
              + "Host: " + host + "\r\n"
              + "Authorization: Bearer " + token + "\r\n"
              + "Content-Length: " + String(query.length()) +  "\r\n"
              + "Content-Type: application/x-www-form-urlencoded\r\n\r\n"
              + query + "\r\n";
  client.print(request);
  return true;
}

void setup() {

  bool avail =
    BH1750.begin(BH1750_TO_GROUND);  // init the sensor with address pin
                                     // connetcted to ground result (bool)
                                     // wil be be "false" if no sensor found
  M5.begin();
  M5.Lcd.setTextSize(2);
  M5.Lcd.fillScreen(BLACK);

  if (!avail) {
      M5.Lcd.println("BH1750 sensor not found!");
      while (true) {
        delay(500);
     };
  }
  
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.printf("WIFI START:%s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    M5.Lcd.print(".");
  }
  M5.Lcd.println(" - READY");

  M5.Lcd.setCursor(0, 110); // x, y
  M5.Lcd.printf("intercom monitoring:");
}

char info[40];

void loop() {
  M5.update();

  // put your main code here, to run repeatedly:
  BH1750.start();                  // starts a measurement
  uint16_t lux = BH1750.getLux();  //  waits until a conversion finished

  if(lux>20) {    //輝度が20以上のとき
    line_notify("インターホンが押されました ");
    M5.Lcd.setTextSize(2); // size
    M5.Lcd.setCursor(0, 220); // x, y
    M5.Lcd.print("LINE-NOTIFY SEND");
    delay(30000); //押されてから30秒はLINEへ送信しない
    M5.Lcd.setCursor(0, 220); // x, y
    M5.Lcd.print("                  ");
  }
  M5.Lcd.setCursor(235, 110); // x, y
  M5.Lcd.printf("%3d", lux);
}

我が家のインターホンは押されてから30秒間は点いたままになっていたので、30秒間はLINEへの再通知をしないようにdelay(30000)で待機させています。

設置と動作

インターホンの画面下部分はタッチパネルのボタンが表示されることがあり、左下にコンセントがあるので画面左上にセンサーを貼り付けることにしました。

インターホン

インターホンが押された時にどれぐらいの輝度でメッセージを送るかは、何度か家人に押してもらってセンサーの位置を変えてテストしました。
玄関扉とマンション入口、通用口とカメラの画像によってセンサを貼った左上の取得輝度が違って送信されなかったりでしたが、しきい値を下げて反応するようにしています。部屋の照明など関係ない明かりで誤反応しないと良いんですが・・・。
ここ2~3日動かしたままにしてみましたが、熱くなったり止まったりすることもなく動いています。