作成経緯
このご時世になり、テレワークの普及、お家時間の増加等で椅子に座りっぱなしの時間が増えた方が多いかと思います。(私もその一人です…。。)
そこで問題となってくるのは椅子に座りっぱなしが原因となる体の不調かと思います。
「1時間や2時間に1度は数分運動した方がよい」という話を色々なところで聞きますよね。
しかし、仕事に集中しているとあっと言う間に時間が過ぎてあまり意識できません。
そこでobnizを利用して、なかなか自分では気付きづらい「椅子に座りすぎ」を検知して通知を行うシステムを作成しようと考えました。
システム概要
- obniz Boradに接続した超音波センサからディスプレイから物体への距離を30秒毎に計測する。
- 計測した距離情報をスプレッドシートの最終行に追記する。
- スプレッドシートに距離情報を追記したタイミングで、直近2時間で一度もディスプレイから1m以上離れていなければ、運動不足を警告する内容をLINEに送信。
あらかじめ私がいつも使用しているディスプレイから、私が椅子に座った際の体の位置までの距離を計測し、「1m以上離れている場合は離席している」と判断することとしました。
設計図
部品
部品名 | 接続 | 参考URL |
---|---|---|
obniz Board | - | - |
HC-SR04(距離センサー) | gnd:0, echo:1, trigger:2, vcc:3 | https://obniz.com/ja/sdk/parts/HC-SR04/README.md |
実際に設置した状態が↓の画像のようになります。
高さを調整するために箱の上に置いています。
ディスプレイに固定することも考えたのですが、箱の上に置くだけで安定して稼働できたのでそのまま利用しています。
利用サービス
サービス名 | 利用用途 |
---|---|
Google スプレッドシート | 取得した距離情報の蓄積場所 |
Google Apps Script | 警告送信の判定、警告送信の要求、スプレッドシートの不要データ削除 |
LINE Notify | 警告メッセージ送信 |
LINE(自アカウント) | 警告メッセージ受信 |
以下からは簡易的ではありますが、GASとLINE Notifyの設定方法となります。
Google Apps Scriptの設定方法
①
距離情報を蓄積するスプレッドシートのツールタブからスクリプトエディタを選択します。
②
コードを記載し、右上のデプロイから「新しいデプロイ」を選択します。
③
左メニューの歯車マークから「ウェブアプリ」を選択し、左メニューにウェブアプリが表示されていることを確認しデプロイを選択します。
説明欄は任意ですが、何のためのGASスクリプトなのかを記載します。
④
デプロイ実行後、表示される「ウェブアプリ」のURLをobniz側のコードに設定します。
※GASのコードを更新した場合はコードの保存だけではなく、忘れないように「デプロイを管理」からバージョンを更新するようにしましょう。
obnizから呼び出す際、コードを保存するだけでは更新内容が反映されません。
LINE Notifyの設定方法
①
LINE Notifyに通知対象のアカウントでログインし、「トークンを発行する」を選択します。
②
トークン名と通知対象アカウントを指定します。
トークン名は通知メッセージに含まれます。
通知対象のアカウントでログインしている場合、「1:1でLINE Notifyから通知を受け取る」を選択します。
③
画面に表示されたトークンをGASのコードにて設定します。
画面に記載の通り、ここで表示されるアクセストークンはこの画面を閉じると②度と表示されないので紛失しないように気をつけましょう。
ここで取得したトークンをGAS側のコードに設定します。
ソースコード(obniz)
※script部分を抜粋して記載
obniz
<script>
//-----------------------------
// setting
//-----------------------------
//使用obnizIDを設定する
let obniz = new Obniz("xxxx-xxxx");
//GAS設定時に取得したURLを設定
let gasUrl =
"https://script.google.com/macros/s/xxxxxxxxxxxxxxxxxxxxxxxxx";
obniz.onconnect = async () => {
// 30秒ごとに距離を計測、取得
obniz.repeat(async () => {
await obniz.wait(1000);
// HC-SR04を利用して距離を計測
let hcsr04 = obniz.wired("HC-SR04", {
gnd: 0,
echo: 1,
trigger: 2,
vcc: 3,
});
hcsr04.measure(function (distance) {
// 送信データ定義
let sendData = {
param: distance,
};
//POST時パラメータ定義
let postParam = {
method: "POST",
mode: "no-cors",
"Content-Type": "application/x-www-form-urlencoded",
body: JSON.stringify(sendData),
};
// GASのdoPost関数を実行
fetch(gasUrl, postParam);
});
//GET時パラメータ定義
let getParam = {
method: "GET",
mode: "no-cors",
"Content-Type": "application/x-www-form-urlencoded",
};
// GASのdoGet関数を実行
fetch(gasUrl, getParam);
//取得間隔の秒数を変更する場合、↓を書き換える(msで指定)
}, 30000);
};
</script>
ソースコード(Google Apps Script)
main.js
function doPost(e) {
//obnizから渡された距離情報を取得
let data = JSON.parse(e.postData.getDataAsString());
let distance = data.param;
//現在日時を取得
let now = new Date();
//スプレッドシートの最終行の1つ下の行に現在時刻と距離情報を追記
let spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
let sheet = spreadsheet.getActiveSheet();
sheet.appendRow([now,distance]);
}
function doGet() {
//スプレッドシート内の最終行を取得
let spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
let sheet = spreadsheet.getActiveSheet();
let lastRow = sheet.getLastRow();
//配列初期化
let baseArray = [];
//直近の測定120回分(2時間分)の距離情報を取得して配列化
for (let i = 0; i < 120; i++) {
//取得対象のセルから値を取得
let int = lastRow-i;
let range = sheet.getRange("B"+int);
let value = range.getValue();
baseArray.push(value);
}
//取得した24個の距離情報のうち、距離が1000以下の値の数を特定
let judgArray = baseArray.filter(function(item) {
return item > 1000;
})
console.log("判定に引っかかった要素数:"+judgArray.length);
if (judgArray.length > 0) {
// 通知を行わない
console.log("警告通知不要");
} else {
// 通知を行う
console.log("警告通知を行う");
// LINEへ警告メッセージを送信する
// 通知メッセージ設定
let messageText = `\n【警告】2時間以上席に座っています。\n
そろそろ体を動かそう!`
//LINEトークン設定
//LINE Notifyの設定時に取得したトークンをここで設定する
let token = "xxxxxxxxxxxxxxxxxxx"
//通知内容設定
let options = {
"method" : "post",
"headers" : {
"Authorization" : "Bearer "+ token
},
"payload" : {
"message" : messageText
}
}
//通知送信要求
let url = "https://notify-api.line.me/api/notify"
UrlFetchApp.fetch(url, options)
}
}
function del() {
//スプレッドシート内の最終行を取得
let spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
let sheet = spreadsheet.getActiveSheet();
let lastRow = sheet.getLastRow();
if(lastRow > 2000){
sheet.deleteRows(1,1500);
console.log("古い1500件の距離情報を削除しました。")
}
}
※GASのトリガー機能を利用し、毎日0:00-1:00の間にdel関数が自動的に呼ばれるように設定しています。
デモ動画
本来のソースコードでは最低でも2時間に1度しかLINE通知が行われません。
デモ動画撮影のために以下の条件にソースコードを書き換えて撮影しています。
・5秒ごとに距離情報を取得し、20秒座っていると判断した場合にLINEに警告通知
この動画はiPhoneで撮影しているのですが、おそらく超音波であろう音(ササッっと鳴っている音)を拾っているのが分かり驚きました。
実際にこの超音波らしき音は耳では聞こえません。
実際に使用してみた
私がデスクで作業している間にこのシステムを動作させました。
その際に実際に取得できたスプレッドシートの内容が以下の通りです。
13:46:55の段階で取得した値は446mmなのでまだイスに座っていますが、13:47:28の段階で取得した値が1094mmのため、離席していることが分かります。
確かこの時間帯に昼食を食べるためにイスから離れていました。
さらにスプレッドシートの下を見ていくと、14:11:45の時点で取得した値は1856mmなのでイスには座っていませんが、14:12:20に取得した値は611mmのため、イスに座っていることが分かります。
昼食を食べ終え、イスに戻ってきたのでしょう。
デモ動画では見えづらいのですが、「2時間座りっぱなし」と判断した場合は下記のようなLINE通知がきます。
感想
このご時世でGWは帰省も旅行もできないため、いい機会だと思いobnizを利用して開発を行いたいと思っていました。
そう思っていたところ当コンテストの存在を知り、奮起して開発を行うことができました。
大変有意義な機会を与えてくださりありがとうございました!
他の参加者の方々の作品を見るのもとても楽しみです!
電子工作の知識は全く無いのですが、obnizは「とりあえず動かす」までがとても簡単に行うことができ、楽しく開発することができました。
JavaScriptで書けるという点も、とてもハードルが低くとっつきやすいと改めて実感しました。
これからもobnizを利用した開発をアイデアが浮かび次第、行っていきたいです。
また、Google Apps ScriptやLINE Notifyの通知といった、今まで触れたことのなかった技術にも触れることができ、とても有意義な経験となりました。
最後に、、、
みなさん、体はしっかり動かしましょう!!!健康第一!!
-
kuboshii
さんが
2021/05/06
に
編集
をしました。
(メッセージ: 初版)
-
kuboshii
さんが
2021/05/16
に
編集
をしました。
ログインしてコメントを投稿する