人体と電気と通知

こんにちは、この記事は tech.kayac.com Advent Calendar 2015 20日目の記事です。

さてみなさまはインターネットからの通知をどうやって受け取っているでしょうか? 過去にはメール、もしくはSMSなどがありましたが、スマートフォンが普及した昨今ではネイティブアプリによるリモートプッシュ通知が定着しメッセージの着信やゲームからのお知らせの受信が日常的になっているかと思われます。

普通プッシュ通知はスマートフォンが鳴ったり振動するなどして来たことを感じるものですが、かばんなどにスマホが入っているとそれに気づくことができません。 そこで、腕時計型の通知を受け取るためのデバイスや、メガネにLEDを付けるなどして知らせるデバイスなどが最近出てきています。 私もPebbleというスマートウォッチを利用していますが通知が来た時に非常に便利です。

しかしながら、これは本当に無駄がないでしょうか? スマートウォッチによる振動で通知を知らせるフローを考えてみます。

リモートプッシュサーバ -> アップル/Googleのサーバ -> スマホ -> スマートウォッチ -> 振動モーター -> 腕

この振動モーターって本当に要りますか??? だって人体に電気は直接流れるんですよ!!!

そうなのです。驚くべきことに人体に電気は流れ、さらに人間はその流れた電気を感じることができます。これ、通知に使えませんかねえ?

というわけで試してみました。

この記事のゴール

スマホの通知を全部受け取っているとビリビリしちゃいそうなので、今回はSlackの通知を受け取ってみようと思います。弊社では今年からIRC/SkypeからSlackへの移行を進めております。その件につきましては以下の記事を参照ください。

社内IRCをSlackに移行した時にやったこと

App StoreのレビューをSlackに流すbotを作ってみた

材料

  • EMSマシン
    • 人体に電気を流すと言っても死んでしまっては元も子もないので、人体に電気を流すのに特化したデバイスを使ってみます
    • 筋肉に電気を流して鍛えるアレです Amazonで2000円ぐらいでした。
  • ESP-WROOM-02
    • 今僕の中で一番アツいデバイス。格安のWiFiモジュールです。今回はSlackの通知を受け取るために使います
  • サーボモーター
    • 結局モーターは要ります

既存デバイスをバラさずにインターネットに繋げる

EMSマシンをバラしてボタンの部分を取っ払ってマイコンにつなげるのが一番手っ取り早いのですが、バラしたせいで感電死とか怖いしあとから普通に使いたいなと思ったので、何らかの方法で外部からスイッチをオン・オフできないかなと思いました。

というわけでこんな感じでサーボモーターを取り付けました。サーボモーターとは角度を指定するとその角度まで回ってくれるモーターで、今回はモーターに取り付けた棒の腕によってスイッチが押されるようになっています。

esp8266ems1.jpgのサムネール画像

雑なガムテープ芸です。

これをESP-WROOM-02のIO14に繋げます。

ESP-WROOM-02がどんなもんかは先日以下の様な記事を書いてみたので見てみてください。

1000円以下で買えるWiFiモジュールESP-WROOM-02でMackerelにメトリクスを送る

そんでもって以下のコードをESP-WROOM-02に書き込みます。

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WiFiClient.h>
#include <WiFiClientSecure.h>
#include <WiFiServer.h>
#include <WiFiUdp.h>
#include <ESP8266WebServer.h>

#include <Servo.h>
Servo servo;

const char* ssid = "...";
const char* password = "...";

ESP8266WebServer server(8266);

#define LED_PIN 12

void pushSwitch() {
  servo.write(70);
  delay(300);
  servo.write(90);
  delay(1000);
  for (int i = 0; i < 3; i++) {
    servo.write(70);
    delay(300);
    servo.write(90);
    delay(300);
  }
}

void handleRoot() {
  digitalWrite(LED_PIN, 1);
  server.send(200, "text/plain", "hello from esp8266!");
  pushSwitch();
  digitalWrite(LED_PIN, 0);
}

void setup() {
  pinMode(LED_PIN, OUTPUT);

  Serial.begin(115200);
  delay(10);
  Serial.println("booted!");

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(WiFi.localIP());

  servo.attach(14);

  server.on("/", handleRoot);
  server.begin();
}

void loop() {
  server.handleClient();
}

やっていることとしては

  • HTTP Serverを立ち上げてアクセスが来ると4回ぐらいスイッチを叩く
    • この1発目に1秒のディレイをとっているのは立ち上がるまでに時間がかかるみたいなのでそうしています
    • そのあと3発なのはONのスイッチを押すたびに出力が上がるっぽいのでこれぐらいなら気づくかなというところまであげています
    • ちなみに電気を切るのは手動でOFFスイッチを押すという原始的ソリューションにより実現しています
    • OFFせずにもう一回通知が来た場合は出力が大きくなるというエスカレーション機能付きです

これをSlackから叩けるようにインターネットに晒します。 ルータの設定をいじって8266番をこのデバイスが持っているローカルIPアドレスに設定してあげます。 我が家のルータではこんな感じです。

router_configuration1.pngのサムネール画像

さらにSlackのIntegrationからOutgoing Web Hooksを設定します。こんな感じです。

esp8266ems_slack_config.png

そんなわけで出来たので動画はこんな感じです。

esp8266ems_movie.gif

作り始める前までは通知が来るときに身構えて仕事にならないんじゃないかなと思いましたが、3段階目までだとまだ心地よいレベルだけれど気づけるのでいいかなと思いました。それ以上はSlackに生殺与奪権を握られている感じがしてスリルを味わえます。

まとめ

そんな感じで人体に電気を流すことで通知を受け取るデバイスを作ってみました。電気を流す以外にもたらいが落ちてくるとか水が降ってくるとか、輪ゴムの鉄砲を打たれるとか通知される手段というのはいろいろ考えられると思います。

みなさまも身の回りのものをインターネットにつなげて通知されてみてはいかがでしょうか。

明日は @Gemmbu さんによる 「Objective-C で RFC を斜め読みして WebSocket サーバを書いた話」です。