電気と電子と電波の日記

自分のための備忘メモです

LINE Notifyでピンポン通知

我が家は狭小住宅にもかかわらず、玄関のドアホンのチャイムが聞こえにくいという妻からのクレーム。スマホに通知が送られれば良いとのことなので、ESP8266で玄関チャイムが押されたことを検出して、LINE Notifyでスマホに送ることを考えよう。

 

まず、玄関チャイムだが、我が家はPanasonicのVL-MV30。ドアホンの親機には、チャイムが押されたことに連動した接点出力端子がある。仕様は工事説明書に記載されている。(下図の例は機種違いだがほぼ同じ)

 

f:id:t1000zawa:20181104212423p:plain

f:id:t1000zawa:20181104212806p:plain

ESP8266は、RST端子がGNDに落ちたら起動するDeepSleepモードで待機させることにする。

最初、IFFFT経由のLINE Nortifyで実験を始めたが、前回実験したときはhttpでAPIを叩けたが、うまくいかず。仕方がないのでhttpsで送れるようにして試すが、どうにも遅い。イベントが発生してから15分くらいかかることもある。これでは使い物にならないので、LINE NotifyをAPIで直接叩くことにした。

LINE Notifyの自分のアカウントのパーソナルアクセストークンを発行する。「アクセストークンの発行(開発者向け)」から「トークンの発行」でトークン名と通知するトークルームを選ぶ。

私の場合家族用のグループをあらかじめ作ってあったので、そこを通知先とした。

notify-bot.line.me

 

いくつかの先人のブログを参考にして、スケッチ作成。スタンプも一緒に送れる。発行されたトークンはコピーして、ソースコードに貼り付ける。スタンプを選択するIDはここに書かれている。

https://developers.line.me/media/messaging-api/sticker_list.pdf

 

ドアホン親機の接点出力と接続して、電力スマートメーターから電源拝借して運用開始。今日午後からの超スピードリリースである。これで自宅のピンポンなればどこにいてもわかるようになった。f:id:t1000zawa:20181104215804j:image

電源借用できるなら、deepsleep使わなくてもGPIO常時監視でも良かった。レスポンスが問題になるようなら改修する。

f:id:t1000zawa:20181104220105j:image

 

 

 

(参考)今回のスケッチ

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <WiFiClientSecureAxTLS.h>
#include <WiFiClientSecureBearSSL.h>

const char* ssid = "SSID";
const char* password = "PASSWORD";
const char* lineApiToken = "LINE API TOKEN";

const String lineNotifyMessage = "チャイム鳴ったよ~";
int stickerPackage = 2;
int stickerId = 34;

const char* host = "notify-api.line.me";
const String url = "/api/notify";
const int httpsPort = 443;
const char* fingerprint = "bf16ae79d2ab7144bed8e755a2c70b3968dbb5d2"; 

WiFiClientSecure client;

void setup() {

WiFi.mode(WIFI_STA);
Serial.begin(115200);
Serial.print("connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);

for(int i = 0; WiFi.status() != WL_CONNECTED && i < 20; i++){
Serial.print(".");
}

Serial.println("");
Serial.println("WiFi connected");
delay(5000);
Serial.println("IP address: ");
Serial.println(WiFi.localIP());

String message = "";

message += lineNotifyMessage;
lineNotify(message, stickerPackage, stickerId);
delay(1000);

ESP.deepSleep(0, WAKE_RF_DEFAULT); // RSTがGND落ちるまでずっとDEEP SLEEPする
}

void loop() {}


void lineNotify(String message, int stkpkgid, int stkid){

Serial.print("connecting to ");
Serial.println(host);
Serial.print("requesting URL: ");
Serial.println(url);
String lineMessage = "message=" + message;

 

if (!client.connect(host, httpsPort)) {
Serial.println("Connection failed");
}

if (!client.verify(fingerprint, host)) {
Serial.println("Certificate ERROR");
}

if *1{
lineMessage += "&stickerPackageId=";
lineMessage += stkpkgid;
lineMessage += "&stickerId=";
lineMessage += stkid;
}

 

String header = "POST " + url + " HTTP/1.1 " +"Host: " + host + " " +"User-Agent: ESP8266 " +"Authorization: Bearer " + lineApiToken + " " +"Connection: close " +
"Content-Type: application/x-www-form-urlencoded " +"Content-Length: " + lineMessage.length() + "";

 

client.print(header);
client.print(" ");
client.print(lineMessage + " ");

delay(1000);

Serial.print(header);
Serial.print("request sent:");
Serial.println(lineMessage);
delay(1000);
String res = client.readString();
Serial.println(res);
client.stop();
}

 

(参考)シリアルモニタに表示されるログの例

 WiFi connected
IP address:
192.168.1.xx
connecting to notify-api.line.me
requesting URL: /api/notify
POST /api/notify HTTP/1.1
Host: notify-api.line.me
User-Agent: ESP8266
Authorization: Bearer  TOKEN
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 67
request sent:message=チャイム鳴ったよ~&stickerPackageId=2&stickerId=34
HTTP/1.1 200
Server: nginx
Date: Sun, 04 Nov 2018 11:45:55 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Keep-Alive: timeout=3
X-RateLimit-Limit: 1000
X-RateLimit-ImageLimit: 50
X-RateLimit-Remaining: 989
X-RateLimit-ImageRemaining: 50
X-RateLimit-Reset: 1541331981

1d
{"status":200,"message":"ok"}
0

 

 

*1:stkid != 0) && (stkpkgid != 0