赤ちゃんの体温を可視化したい

これはno plan inc.の Advent Calendar 2024の13日目の記事です。

こんにちは。no plan株式会社の仕事してないのにtimesでよくつぶやいてるiemongです。
先日、子どもを授かりまして、今日が出産予定日でした。

しかし、まだ産まれていません!!!

なので書くことがそんなにないのですが、折角なんで子育て準備してることについて書こうと思います。


子育てグッズを買い漁ってた頃、寝具どうしたらいいんだろうと思い、no planの子育てチャンネルで聞いたところスワドルアップをオススメされました。

モロー反射を防いでくれるらしく、ぐっすり寝てくれそうだなと思って買おうと思ったのですが、12月生まれなのでオールシーズン用と冬用で結構悩んで冬用にしました。

その時ふと「赤ちゃんが暑いか寒いか客観的に判断できたら楽なのに」と思いました。

そこでサーマルカメラを自作することにしました。

用意したもの

M5StickというマイコンとM5StickC用のサーマルカメラモジュールを購入しました。サーマルカメラたけぇ。

つくる

M5StickなどのM5シリーズのマイコンはUIFlowというビジュアルプログラミングツールでブロックを繋いで簡単にプログラミングできるので気に入ってます。

とりあえず、loopで温度を取得して、ひたすら24x32の配列データをNext.jsのサーバーにPOSTするようにしました。
自宅でしか使わないので、ローカルネットワーク経由でAPI叩きまくっています。
将来的に、記録を見返したいとなったら適当な間隔でDBに保存するかも。

M5StickCからPOSTしたデータを、ストリーム APIを使ってNext.jsのページから取得できるようにしました。SSEってやつですね。

// src/app/api/thermal/route.ts

export const dynamic = 'force-dynamic'
import { NextResponse } from 'next/server'

let controller: ReadableStreamDefaultController | null = null
const encoder = new TextEncoder()

export async function GET() {
  const stream = new ReadableStream({
    start(c) {
      controller = c
    },
    cancel() {
      controller = null
    }
  })

  return new NextResponse(stream, {
    headers: {
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      'Connection': 'keep-alive',
    },
  })
}

export async function POST(request: Request) {
  try {
    const data = await request.json()

    if (controller) {
      controller.enqueue(encoder.encode(`data: ${JSON.stringify(data.thermal_value)}\n\n`))
    }

    return NextResponse.json({ success: true })
  } catch {
    return NextResponse.json({ error: 'Error' }, { status: 500 })
  }
}

EventSource APIを使ってサーマルカメラの値を取得してあげます。

// src/app/page.tsx

'use client'

import ThermalCanvas from '@/components/ThermalCanvas'
import { useEffect, useState } from 'react'

type ThermalData = number[]

export default function ThermalPage() {
  const [thermalData, setThermalData] = useState<ThermalData | null>(null)

  useEffect(() => {
    const eventSource = new EventSource('/api/thermal')

    eventSource.onmessage = (event) => {
      const data = JSON.parse(event.data)
      setThermalData(data)
    }

    return () => {
      eventSource.close()
    }
  }, [])

  if (!thermalData) {
    return <div>データ待機中...</div>
  }

  return (
    <div className="p-4 grid place-content-center h-screen">
      <ThermalCanvas data={thermalData} />
    </div>
  )
}


つかってみる

自分の手にかざしてみましたが、温かそうですね。

手にサーマルカメラを映して手の温度を測っている画像
ベットにM5Stick Cを取り付けた画像

赤ちゃんまだいないので、家にあったえびちゅうのクッションの上にあずきのチカラ を置いてシミュレーションしてみました。何この画像?って感じですが、パソコンの画面にあずきのチカラの温もりが写ってると思います。
定位置が決まったらアタッチメントを3Dプリントしたいなぁ。

まとめ

以上、子育て準備についてご紹介しました。本当にサーマルカメラ便利なのか謎ですが、エンジニアなりの子育てをこれから頑張っていきたいと思います。最後まで読んでいただきありがとうございました。


この記事が参加している募集

そういえば、推しのアイドルグループのEPの発売したので、とりあえず聞いてみてほしい