Help us understand the problem. What is going on with this article?

LINE Thingsでごみの日通知アプリを作ってみた

作ったもの

ごみ箱に着けるタイプの”ゴミの日通知”IoTアプリ
LINE Things Awardに応募しました。
LINE bot上で動かせるLIFF(LINE Front-end Framework)を使って、obnizに情報を登録してobnizがゴミの日を通知してくれるアプリを作りました。

LINE thingsの良い所は独自のアプリを作らなくてもBLE経由でデバイスと接続しデバイスを操作する事ができる点と
デバイスからLINEへ自動的に通信を送る事ができる自動通信という機能を使ってbotからメッセージを送る事ができる点が良い点でした!

作った理由

  1. ゴミを捨てるのを忘れてしまう事が多い
    1. 家を出てから、今日燃えるゴミの日だったぁあああ 生ごみぃぃぃと嘆くのが嫌だ。
  2. ゴミ箱✖️IoTの方向性として
    1. ゴミの日カレンダーというサービスがあるので、それをデバイスに落とし込めば便利そうと思った。

使い方

  1. LIFFを立ち上げて住んでいる地区のゴミ捨て情報を入力する
  2. デバイス側にゴミの日情報を登録する
  3. ゴミの日前日になると、botからメッセージが来る(自動通信) デバイスのLEDライトが光る
  4. ゴミの日当日になると、デバイスから音が鳴りゴミ出しのリマインドをしてくれる

構成

スクリーンショット 2019-12-11 23.05.01.png

LINE ThingsのBLE通信ができるメリットを活かすならwifiに接続できるobnizではなくても良いと思ったが、家にあったので採用しました!使い易くて最高でした!

開発の流れ

  • LIFF側
    • 曜日登録画面の開発(友達にお願いした)
    • BLE連携部分の開発
  • デバイス側
    • LINE THINGS連携
    • BLEで受け取った情報の処理
    • ゴミの日判定処理
    • 通知処理

コード抜粋と開発のtips

BLE接続について

obnizとLIFF間で共通のUUIDを頼りに接続している

LIFFでデバイスを探しているところ.js
    device.gatt.connect().then(() => {
        // Get service
        device.gatt.getPrimaryService(USER_SERVICE_UUID).then(service => {
          liffGetUserService(service);
        }).catch(error => {
            uiStatusError(makeErrorMsg(error), false);
        });
        device.gatt.getPrimaryService(PSDI_SERVICE_UUID).then(service => {
            liffGetPSDIService(service);
        }).catch(error => {
            uiStatusError(makeErrorMsg(error), false);
        });

        // Device disconnect callback
        const disconnectCallback = () => {
            // Remove disconnect callback
            document.getElementById("log").innerText = "failed";
            device.removeEventListener('gattserverdisconnected', disconnectCallback);
            // Try to reconnect
            initializeLiff();
        };
        device.addEventListener('gattserverdisconnected', disconnectCallback);
    }).catch(error => {
        document.getElementById("log").innerText = "gets";
        uiStatusError(makeErrorMsg(error), false);
    });

データのやりとり

LIFFからデバイスにデータを送るところ.js
  function submitValue(array){
    let param = localStorage.getItem('param');
    let str = JSON.stringify( param );
    window.writeCharacteristic.writeValue(
      Uint8Array.from(str.split(""), e => e.charCodeAt(0))
    ).catch(error => {
      document.getElementById("log").innerText = error;
        uiStatusError(makeErrorMsg(error), false);
    });
  };
デバイスでデータを受け取るところ.js
  writeCharacteristic.onwritefromremote = function(address, newvalue) {
    let str = Array.from(newvalue, e => String.fromCharCode(e)).join("");
    param = JSON.parse(str);
  }

UUIDを用いて取得するCharacteristicオブジェクトを使ってcharasteristicに値を読み書きします。
便利。

charasteristic.js
  var writeCharacteristic = new obniz.ble.characteristic({
    "uuid" : writeCharacteristicUUID,
    "properties" : ["write"],
    "data" : [0x00]
  });

ごみの日チェック

ゴミの日チェック.js
    StartTimer = function() {
      // 30分ごとの処理
      timerID = setInterval(Timer, 1800000);
    }
    StopTimer = function() {
      clearInterval(timerID);
    }
    Timer = function() {
      if(!getParamFlag)
        return;
      }
      let today = new Date();

      checkDaysSchedule(today);
      // checkDaysSchedule(tomorrow);
    }

    function checkDaysSchedule(day){

      let date = weekdays[day.getDay()];
      let weekNum = Math.floor((day.getDate() - day.getDay() + 12 ) / 7);
      if(isSchedule) {
        checkSchedule(date, weekNum);
      }
    }

    function isSchedule(date){
      return param["schedule"][date] != null;
    }

    async function checkSchedule(date, weekNum){
    let schedule = param["schedule"][date];
      let garbageInfo = param["garbageInfo"][schedule];
      garbageInfo["frequency"].forEach(function(e) {
        if(e == weekNum){
          let output = "";
          output += date + "" + schedule + "日です。\n";
          output += garbageInfo["hour"] + "" + garbageInfo["min"] + "収集です。";
          obniz.display.print(output);

          NotifyToLine();
          swichLed(true);
        }
      })
    }

タイマー回して30分ごとに通知をする必要があるかどうかを判別しています!

苦労した点

  • BLEの接続段取り
  • Android端末だと上手く連携できずに、iPhoneを購入した結果貧しい生活を送ることになった点

楽しかった点

  • BLEでデバイスで値を受け取った時!!!
  • LINEから自動通信でメッセージを受け取った時!!!

また何か作ります!

参考にした記事

LINE Things 自動通信機能 ハンズオン

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした