【SwitchBot + Laravel】1人暮らしの親を見守る機能をつくってみた!

こんにちは!
九保すこひです(フリーランスのITコンサルタント、エンジニア)

さてさて、少し前に5年に1度の国勢調査が行われ、結果が気になる部分があります。

それは・・・・・・・

少子高齢化がどうなってるか?

です。

なぜなら、財政問題が待ったなし!だからですね。

そして、あわせて気になるのが「単身高齢者の増加」です。
次のグラフを見てください。

出典:日本生命ウェブサイトより。「第162回 増える一人暮らしの高齢者 2020年は672万人、2040年には896万人の見通し」

なんと、65歳以上の単身高齢者は、2040年に896万人(約13人に1人)になる

と推計されてるんですね。
記事執筆時からすると、たった15年でこうなるわけです。

そこで!

最近気にいってるSwitchBotの人感センサーをつかって、この社会問題に少しでも役に立つ機能を作ってみることにしました。

起きてるはずの時間に動きがなかったら通知する」

という機能です。

つまり、動けなくなっている可能性があれば、家族や介護施設に自動で知らせるのが目的ですね。

ということで、今回の記事は次のような方に向けて書いています。
ぜひ最後まで読んでくださいね!

  • 「プログラムで社会問題を解決したい」
  • 「高齢者をIoTで見守れたらと思う」
  • 「技術で人を支える仕組みを作りたい」
  • 「自分のスキルを人に役立てたい」
  • 「うちの親、一人暮らしだけど本当に大丈夫だろうか…」
  • 「最低限の家族の見守りは自動化したい」
  • 「施設に入れるほどではないけど、見守りはほしい」
  • 「手軽に見守り機能をつくりたい」
  • 「本人に気をつかわせない見守り方法をつくりたい」
  • 「ウェブサイトと物理アクションを連携した機能をつくりたい」

「歳を重ねて増える幸せもあります。
そう。バッテラとかね👍」

実装に必要なもの・実行環境

今回は以下2つの機械で実装します。

SwitchBot人感センサー

SwitchBotハブミニ

また、実行環境は以下のとおりです。

  • Laravel 12.x
  • Vue 3
  • Inertia
  • TypeScript

今回は大事なテーマなので真面目にやっていきましょう!

SwitchBot人感センサーを起動する

開封したらまず電池をいれて(説明書を見ながら)スマホアプリとペアリングしてください。

※インストールするとき、ペットいる/いないの設定をすることになります。

ちなみに設定ページではセンサーの感度を変更できます。
今回は最大限の検知をつかいますが、環境にあわせて変更してください。

※Long設定だと「あ!今ので検知されたんだ」ぐらいのロングレンジで反応してくれます。

また、センサーが検知したときにライトを光らせることもできます。
お好みで有効/無効にしておいてください。

WebHookをつくる

この部分は、前回記事【SwitchBot + Laravel】開閉センサーで薬の飲み忘れを防ぐ機能をつくってみた!とほぼ同じなので以下を参考にして設定をしておいてください。

参考記事:WebHookをつくる5ステップ

ちなみにデバイスIDとコンフィグの設定は以下のようになります。

.env

SWITCHBOT_MOTION_SENSOR_DEVICE_ID="(ここにあなたのデバイスID)"

config/services.php

<?php

return [

// 省略

'switchbot' => [
'access_token' => env('SWITCHBOT_ACCESS_TOKEN'),
'secret_token' => env('SWITCHBOT_SECRET_TOKEN'),
'devices' => [
'motion_sensor' => env('SWITCHBOT_MOTION_SENSOR_DEVICE_ID'),
],
],

];

ちなみに前回記事ではWebHookの初回登録でしたが、ngrokをつかって開発すると更新もよく使うので以下にまとめておきます。

リクエスト

POST https://api.switch-bot.com/v1.1/webhook/updateWebhook

【Headers】

  • Content-type:application/json(注:すでに入っていると思うので変更してください)
  • Authorization:(あなたのアクセストークン)

【Body】

  • action:setupWebhook
  • url:(ngrokで取得したURL)
  • deviceList:ALL

rawタブで以下を貼りつけると楽です👍

{
"action":"updateWebhook",
"config":{
"url":"(ngrokで取得したWebHook URL)",
"enable":true
}
}

そして、登録と同じように成功すると以下のように返ってきます。

{
"statusCode": 100,
"body": {},
"message": "success"
}

もしWebHookの新規追加や削除やしたい場合は、本家の以下ページをご覧ください。

LaravelでWebHookを受け取る部分をつくる3ステップ

では、ここからはLaravelの作業に移ります!

1. DBまわりをつくる

まずはデータベース関連です。
以下コマンドを実行してください。

php artisan make:model MotionSensorHistory -m

すると、モデルとマイグレーションが作成されるので中身を次のようにします。

database/migrations/****_**_**_******_create_motion_sensor_histories_table.php

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('motion_sensor_histories', function (Blueprint $table) {
$table->id();
$table->string('device_id')->comment('デバイスID');
$table->string('detection_state')->comment('検知状態'); // DETECTED or NOT_DETECTED
$table->timestamps();
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('motion_sensor_histories');
}
};

ではマイグレーションを実行しておきましょう。

php artisan migrate

実際のテーブルはこうなりました。

2. WebHookのコントローラーをつくる

次にコントローラーです。

※注:前回記事で作成した人はすでに存在しているので不要です。

php artisan make:controller SwitchBotWebhookController

中身はこうなります。

app/Http/Controllers/SwitchBotWebhookController.php

<?php

namespace App\Http\Controllers;

use App\Models\MotionSensorHistory;
use Illuminate\Http\Request;

class SwitchBotWebhookController extends Controller
{
public function store(Request $request)
{
$deviceId = $request->input('context.deviceMac'); // デバイスID(コロンなし)
$deviceType = $request->input('context.deviceType'); // デバイスタイプ

if ($deviceType === 'WoPresence') { // 人感センサーの場合(本来Enumを使うべき)

$detectionState = $request->input('context.detectionState'); // 動作検知状態

// 本来はここで中身をデータ確認すべきですが、省略

$contactSensorHistory = new MotionSensorHistory;
$contactSensorHistory->device_id = $deviceId;
$contactSensorHistory->detection_state = $detectionState;
$result = $contactSensorHistory->save();

if ($result === false) {

abort(500);

}

return response(200);

}

abort(404);
}
}

ちなみに、検知状態(detection_state)に入ってくるのは、

  • DETECTED:人感センサーで検知された
  • NOT_DETECTED:その後、しばらく検知がなかった

の2つです。

今回の機能としてはDETEDTEDだけで問題ないのですが、データは多いほうがいいのでどちらも保存し、必要に応じてWHERE句でフィルターをかけるようにします。

3. ルートをつくる

最後にルートです。
ここは前回と同じなので、以下を参照してください。

参照:ルートをつくる

タイマー実行で緊急事態かどうかをチェックする部分をつくる

では、WebHookから取得したデータをチェックして、対象者に動きがない(=緊急事態である)のをチェックできるようにします。

これをcrontabsystemdで定期的にタイマー実行するわけですね。

メール送信部分をつくる

先にMailableをつくっておきます。
以下コマンドを実行してください。

php artisan make:mail MotionNotDetected

中身はこうなります。

app/Mail/MotionNotDetected.php

<?php

namespace App\Mail;

use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;

class MotionNotDetected extends Mailable
{
use Queueable, SerializesModels;

/**
* Create a new message instance.
*/
public function __construct(private bool $motionDetected, private Carbon $startDt, private Carbon $endDt)
{
}

/**
* Get the message envelope.
*/
public function envelope(): Envelope
{
$subject = $this->motionDetected === true
? '対象者の動作が検知されています。'
: '【至急!】対象者の動作が検知されていません';

return new Envelope(
subject: $subject,
);
}

/**
* Get the message content definition.
*/
public function content(): Content
{
$timeRange = $this->startDt->format('H:i') . ' 〜 ' . $this->endDt->format('H:i');
$htmlString = $this->motionDetected === true
? '<p>'. $timeRange .'に対象者の動作検知がありました。</p>'
: '<p>'. $timeRange .'に対象者の動作検知がありませんでした。<br />至急、安否を確認してください。</p>';

return new Content(
htmlString: $htmlString,
);
}

/**
* Get the attachments for the message.
*
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
*/
public function attachments(): array
{
return [];
}
}

Artisanコマンド部分をつくる

続いてタイマーで実行する本体です。
以下のコマンドを実行してください。

php artisan make:command CheckMotionCommand

中身は次のようにします。

app/Console/Commands/CheckMotionCommand.php

<?php

namespace App\Console\Commands;

use App\Mail\MotionNotDetected;
use App\Models\MotionSensorHistory;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Mail;

class CheckMotionCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'check:motion';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Check motion sensor histories';

/**
* Execute the console command.
*/
public function handle()
{
Carbon::setTestNow(
Carbon::now()->hour(9)->minute(0)->second(0) // テストのため、9:00に固定
);

$deviceId = str_replace(
':',
'',
config('services.switchbot.devices.motion_sensor')
);
$dt = now();

// 以下、本来は設定などから取得すべき
$checkHours = [9, 15, 21]; // チェックする時間帯(朝・昼・夜を想定)
$checkMinutes = 180; // 過去何分間をチェックするか

if(in_array($dt->hour, $checkHours, true)) {

// 過去180分間に動作検知がないかチェックする
$startDt = $dt->copy()->subMinutes($checkMinutes);
$exists = MotionSensorHistory::query()
->where('device_id', $deviceId)
->where('detection_state', 'DETECTED')
->whereBetween('created_at', [$startDt, $dt])
->exists();

// 結果をメール送信
$to = 'to-family@example.com'; // 通知先メールアドレス
Mail::to($to)->send(new MotionNotDetected($exists, $startDt, $dt));

}
}
}

これで作業は完了です!
お疲れ様でした😊✨

ちなみに:人感センサーは明るさも検知できる

WebHookには送られてこないのですが、人感センサーは部屋が明るい/暗いを自動で検知できますので紹介します。

※どうやら開閉センサーならWebHookに明るさ情報も送ってくるようです。なぜ…🤔

ホーム画面で対象の人感センサーを選択し、右上に出てくる歯車マークをタップします。

設定画面が出てくるので「Light Sensor」を選択。

説明書きが表示されるので「Next」ボタンを押す。

以下の表示になるので部屋を暗くしてから実行ボタンを押してください。

次に、そのまま部屋を明るくします。

すると、数秒で自動的に画面が切り替わり、設定が完了します。

なお、この「部屋が明るい/暗い」の情報はSwitchBot APIから取得できます。

テストしてみる

では、実際に試してみましょう。
先に以下3つを実行しておきます。

  • ngrokでWebHook URLを作成
  • PostmanでWebHook URLを保存
  • php artisan serveでウェブサイト起動

では、この状態で設置した人感センサーの前を横切ってみます。

ザッザッザッ(ドラクエ風)

どうなるでしょうか・・・・・・

はい!

WebHookを通して、動作検知のデータが保存されました。
まずは成功です😊✨

続いて、動作検知されていない場合のメール送信をテストします。

いったんデータを全て消して、以下を実行します。

php artisan check:motion

うまくいくでしょうか・・・・・・

はい!
緊急メールが送信されてきました。

すべて成功です😊✨

企業様へのご提案

今回の機能は、特に介護事業者の方にマッチしています。

というのも、各ご家庭にSwitchBot人感センサーとハブを用意しても、システムは1つでOKだからです。

また、ランニングコストはサーバー料金(例:エックスサーバー・スタンダードプランだと693円〜。2025/11/12現在)だけでOKです。

つまり、わずか月額500円で提供しても、2人契約すればペイできるということになりますね。

初期費用で人感センサーやハブの購入費用にしてもいいかもしれませんね。

さらに重要なのが、もし「見守りサービス」が契約終了しても人感センサーなどの機械は残るので、別の場所に設置することができ、大幅なコストダウン&初期費用の収益化につながるという点です。

もしそういったシステムをご希望でしたら、いつでもお気軽にご相談ください。

お待ちしております😊✨

おわりに

ということで、今回はSwitchBot人感センサーをつかった「1人暮らしの親を見守る機能」をつくってみました。

現在、日本は少子高齢化が進んだ結果、人手が不足している反面、介護される側は増えていく状況にあります。

移民政策も様々な問題点があることが指摘されており、やはり当面は「いかに人手を使わない手段を導入するか?」が重要になってくるんじゃないでしょうか。

もしITの技術で社会問題を解決できたらいいですね!
ぜひ皆さんもいろいろ考えてください。

ではでは〜!

「EVトゥクトゥクの冬運用、
きちーーーーーーー😂(けど乗る!)」

このエントリーをはてなブックマークに追加       follow us in feedly  
お問い合わせ、お待ちしております。
開発のご依頼はこちら: お問い合わせ
どうぞよろしくお願いいたします! by 九保すこひ