flat35hd99のアイコン画像
flat35hd99 2021年05月16日作成 (2021年05月16日更新)
製作品 製作品 閲覧数 686
flat35hd99 2021年05月16日作成 (2021年05月16日更新) 製作品 製作品 閲覧数 686

研究室のポストの書類配達を通知する。

研究室のポストの書類配達を通知する。

課題

春から研究室に配属された大学生です。4年生の共同の部屋には、研究室全員のポスト(郵便物、または学内からのお知らせなどが届く)があります。

研究室のポストの様子

4年生は普段からここで活動しているためいつでも確認できますが、修士・博士課程の学生や教員はわざわざ確認しにこないといけない状態です。そして研究者というのはどうもこういう、定常的、または定期的になにかを行うということが苦手らしく、ポストの半分ほどはおそらく数ヶ月は放置されているだろうというくらい資料があふれています。

今回はこの「研究室のポストのものを各人が適切に回収できていない」課題をObnizを使って解決することにしました。

束縛条件

さて、課題は決まったので、次はこの課題を解決するための方法を考えたいところですが、今回の場合、いろいろな条件があるため、その条件内でうまく実行できる方法を考えないといけません。以下にその条件を整理します。

該当ポストには、いろんな人が荷物を届けてくれます。

  • 学部事務員
  • 学科事務員
  • 研究室秘書
  • 大学生協の方
  • 大学図書館の方

また、ポストは一つだけではなく、上に示した写真のように、各人ごとにボックスが割り当てられています。

そして、これが一番難しい問題かもしれませんが、物理系の研究室なので学生自体の技術力は高い人が多いというわけではなく、次年度以降引き継ぎ可能な人材が確保できる保証がありません。また、私を含む全員は研究こそ本分です。

以上のことから、例えば次のような方法では実施が困難です。理由を添えて説明します。

  • 特定の人が届けてくれるわけではないため、届けてくれた人になにかアクションをお願いするのは難しい。
  • ボックスが複数個あるため、開閉を検出する仕組みでは設置コストが肥大化し、大学生の財布に優しくない。
  • 製作や管理、または撤去の時間コストは大きくできない。

さて、そういうわけで、なかなかに厳しい条件の中で課題解決することになりました。

解決方法

以上を踏まえ、「メールまたはSlackなどの常に利用しているサービスに、配達時通知が届く。通知は配達者がボタンを押すことで実行される」という方法を採ることにしました。

各ボックスに検出器を設置することを第一に考えましたが、先ほどの理由から数がざっと10個はあり、設置の費用と時間のコストが割にあっているとは言えませんでした。

しかし、この方法でも

特定の人が届けてくれるわけではないため、届けてくれた人になにかアクションをお願いするのは難しい。

という条件を十分満たせているとは言えません。そこで、

push me
こんな感じの紙を貼っておきました。押せばいいというのはわかるので、たぶんうまく行くと思われます。

この方法の一番の問題店

ボタンが一個しかないため、通知の意味は「誰かになにか届いた」となり、通知が届いてもあんまり確認する気にはなれません。自動化できればこういう記事としてはいいと思いますが、今回は少し工夫を加えることで解決方法として採用することにしました。すなわち、

  • 配達は1週間に一回あるかどうかのため、通知が来るまでは気にしなくていい。
  • なにか届いたという通知は4年生が受け取っておく。毎週のミーティング前に通知を受け取っていた場合は確認しておく。

という方法で、解決方法の困難も解消することにしました。

実装方法

Obniz 1Yを支給していただいたので、そのスリープ機能を利用することにしました。

材料を示します。

  • Obniz 1Y: 1個
  • ブレッドボード、ワイヤー: 適量
  • USB Cのケーブル: 1個
  • 5V電源(実験段階ではパソコンのUSBから供給)
  • コンデンサ(今回は100μFを使用): 1個
  • スイッチ(今回は4足のタクトスイッチを使用): 1個

回路図を示します。

回路図

はじめはコンデンサをつけず、スイッチをオンにすると0ピンの電圧が変わることでwake upする実装をしていましたが、どうもワイヤーやパーツが動く少しの電位変化でもwake upすると仕様のようだとわかりました。今回はスイッチのオンオフという大きな変化だけを検出したいため、緩衝材としてコンデンサを挟むことで、わずかな電位の変化を検出しないようにしました。

100μFは持っているコンデンサの中で一番大きい電気容量だったため使用し、正常に動作したため利用しました。小さすぎるとわずかな電位の変化を抑えることができないため、これは適宜環境に応じて変更する必要があります。

ソースコードを以下に示します。

最初のhtmlはobnizのもの、もう一つはGoogle Apps Scriptのコードです。

obniz側でイベントが発火したことをGoogle Apps ScriptにPOSTして、そのお知らせを受けると登録したメールアドレスにメールが飛ぶという仕組みです。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />

    <link
      rel="stylesheet"
      href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
    />
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>

    <script src="https://unpkg.com/obniz@3.x/obniz.js"></script>
  </head>

  <body>
    <div id="obniz-debug"></div>

    <script>
      /* eslint-disable no-undef, no-unused-vars */
      let webhook_url = "https://script.google.com/macros/s/YOURAPPIDHERE/exec";
      //Timeout 25s
      let tid = setTimeout(() => {
        //HIGH -> LOW 立ちさがりを検知するまでスリープ
        obniz.sleepIoTrigger(false);
      }, 25000);
      //-----------------------------
      // obniz setting
      //-----------------------------
      let obniz = new Obniz("7654-2375");
      obniz.onconnect = async () => {
        //slack post
        await fetch(webhook_url, {
          method: "POST",
          mode: "no-cors",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ authenticateString: "hogehoge" })
        })
          .then(() => console.log("success"))
          .catch(error => console.log(error));
        //HIGH -> LOW 立ちさがりを検知するまでスリープ
        obniz.sleepIoTrigger(false);
        //program finish wait...
        await obniz.wait(1000);
        clearTimeout(tid);
        if (typeof done === "function") {
          done();
        }
      };

    </script>
  </body>
</html>
function doPost (event) {
  const jsonString = event.postData.getDataAsString();
  const data = JSON.parse(jsonString)
  if (data.authenticateString !== "hogehoge") {
    return
  }
  GmailApp.sendEmail("hoge@example.com", "ポスト投函がありました", "研究室のポストに投函があったよ。")
}

wake upはobniz cloudのServerless Eventをtriggerします。そのためこのコードは通常のAppとしてではなく、それに適した方法・場所に設置します。

GAS側については、これを「デプロイ」することで利用することができます。GAS側でデプロイすると、エントリーポイントとなるURLが表示されるため、これをobniz側のwebhook_urlに入れます。

GAS側の注意点として、このエントリーポイントにはURLがわかれば誰でもpostすることができるため、今回は超適当にjson内に認証コード(authenticateString)を入れてそれが合っているかどうかでメールを飛ばすかどうか判断しています。

もしこれと同じものを使いたい場合、コピペして以下の場所を変更してください

  1. GAS: Gmailで通知を飛ばす対象のメアドを書き換えます。hoge@example.com
  2. GAS: 認証コードを変更します(hogehoge)
  3. GAS: デプロイします。
  4. Obniz: 認証コードを変更します。(hogehoge)
  5. Obniz: デプロイ時に取得したURLをwebhook_url変数に入れます。

これで動くはずです。

動作状況

動いている様子を示します。

ここに動画が表示されます

今後

  • 研究室にSlackが導入されたら通知先をSlackに変更したいです。弊研究室はいまだにMLです。
  • いい感じの箱に入れてあげたいです。
    キャプションを入力できます
ログインしてコメントを投稿する