BridgeCraft logobridgecraft
週報顧問服務作品集關於聯絡登入
聯絡

bridgecraft

從資料視覺化到 AI Agent,一直在找下一個 meta

文章主題指南週報顧問服務Labs作品集系統架構關於聯絡RSS

© 2026 BridgeCraft — Waiting7777. All rights reserved.

← 所有文章
用 AI 幫我開發睡眠分析工具 — 一個週末專案的完整紀錄

用 AI 幫我開發睡眠分析工具 — 一個週末專案的完整紀錄

2026年5月12日 · Waiting7777 · 5 分鐘閱讀

AI開發工具個人專案生活改善
📂 AI 系列📂 開發工具 系列📂 個人專案 系列📂 生活改善 系列

用 AI 快速打造夜間睡眠監控系統 — 8 小時搞定個人專案

> Patch Note

最近發現 AI 開發工具改變了個人專案的投入產出比。以前覺得「太麻煩,算了」的想法,現在會變成「其實可以試試看」。這次用週末 8 小時,跟 AI 協作打造了一個睡眠監控系統,用來分析半夜被吵醒的原因。雖然問題很日常,但實作過程蠻有意思的,值得記錄一下。

住在吵雜的城市,半夜被莫名其妙的聲音弄醒是常態。最煩的是你永遠不知道是什麼把你吵醒的 — 腦袋還在睡眠模式,等你完全清醒,聲音早就停了。沒辦法定位問題,就沒辦法解決問題。結果就是亂猜:換隔音窗?買白噪音機?搬家?全都是賭博。

所以我決定做個工具來搞清楚這件事。

環境與前置

這個專案其實建立在我現有的 smart home 基礎上。本來就有 Home Assistant 在跑,配了一堆感應器:motion、door、temperature、humidity、CO₂、air quality 什麼的。這次只需要加上音訊收集和睡眠數據整合。

新增的硬體:

  • 兩支便宜的 USB 麥克風,一支放室內,一支面向街道
  • 一台 Raspberry Pi 4 做音訊處理
  • 現有的 Garmin 手錶提供睡眠數據

軟體 stack:

  • Home Assistant 做設備整合和自動化
  • Python + pyaudio 做音訊檢測
  • Node.js + Express 做後端 API
  • React 做前端(Progressive Web App)
  • SQLite 存資料

選 Raspberry Pi 是因為便宜、省電,而且可以 24/7 跑。pyaudio 處理音訊算是標配,雖然文檔不太友善,但社群支援度高。前端用 React 是因為想做成像音樂編輯器的 timeline UI,需要比較複雜的互動。

重點是整套系統只在我在家睡覺時才啟動。透過 Home Assistant 的 automation,偵測到我在家、在床上、而且是睡眠時間,才會開始錄音。其他時候完全關閉,連麥克風權限都沒有。

實作步驟

Step 1: 音訊檢測

最核心的是音量檢測邏輯。不能一直錄音(隱私問題),也不能錯過重要聲音。我的做法是即時監控音量,超過閾值才開始錄音,並且會包含觸發前後幾秒的內容:

import pyaudio
import numpy as np
import wave
import threading
from collections import deque

class AudioDetector:
    def __init__(self, threshold=0.01, pre_record_time=3, post_record_time=2):
        self.threshold = threshold
        self.pre_record_time = pre_record_time
        self.post_record_time = post_record_time
        self.buffer = deque(maxlen=int(44100 * pre_record_time))  # 3秒緩衝
        
    def detect_sound(self):
        p = pyaudio.PyAudio()
        stream = p.open(
            format=pyaudio.paInt16,
            channels=1,
            rate=44100,
            input=True,
            frames_per_buffer=1024
        )
        
        while self.is_active:
            data = stream.read(1024)
            audio_data = np.frombuffer(data, dtype=np.int16)
            volume = np.sqrt(np.mean(audio_data**2))
            
            self.buffer.append(audio_data)
            
            if volume > self.threshold:
                self.save_audio_clip(list(self.buffer))
                
        stream.stop_stream()
        stream.close()

一開始我設定的閾值太低,結果冰箱運轉、空調切換都會觸發。後來調高到只有比較明顯的聲音才會記錄。這個數值需要根據環境調整,沒有標準答案。

Step 2: Home Assistant 整合

讓 Raspberry Pi 跟 Home Assistant 溝通,這樣才能做到「只在睡眠時間啟動」的邏輯:

import requests
import json

class HomeAssistantClient:
    def __init__(self, ha_url, access_token):
        self.ha_url = ha_url
        self.headers = {
            'Authorization': f'Bearer {access_token}',
            'Content-Type': 'application/json'
        }
    
    def get_person_state(self, person_id):
        response = requests.get(
            f'{self.ha_url}/api/states/{person_id}',
            headers=self.headers
        )
        return response.json()['state']
    
    def is_bedtime(self):
        # 檢查是否在家、在臥室、且是睡眠時間
        person_state = self.get_person_state('person.waiting7777')
        current_time = datetime.now().time()
        sleep_start = time(22, 30)  # 10:30 PM
        sleep_end = time(8, 0)      # 8:00 AM
        
        is_home = person_state == 'home'
        is_sleep_time = current_time >= sleep_start or current_time <= sleep_end
        
        return is_home and is_sleep_time

Home Assistant 的 REST API 還算好用,就是 bearer token 要記得定期更新。我一開始偷懶用 long-lived access token,後來改成 OAuth 比較安全。

Step 3: 睡眠數據整合

Garmin Connect 有 API 可以拿睡眠數據,包含睡眠階段、心率、HRV 這些:

// 後端 API 整合 Garmin 數據
const axios = require('axios');

class GarminClient {
    constructor(clientId, clientSecret) {
        this.clientId = clientId;
        this.clientSecret = clientSecret;
        this.accessToken = null;
    }
    
    async getSleepData(date) {
        const response = await axios.get(
            `https://apis.garmin.com/wellness-api/rest/sleepData`,
            {
                headers: {
                    'Authorization': `Bearer ${this.accessToken}`
                },
                params: {
                    uploadStartTimeInSeconds: Math.floor(date.getTime() / 1000),
                    uploadEndTimeInSeconds: Math.floor((date.getTime() + 86400000) / 1000)
                }
            }
        );
        
        return response.data.sleepMovement;
    }
}

Garmin 的睡眠數據結構還蠻詳細的,會標記每個時間點的睡眠階段(deep、light、REM、awake),這是整個專案最關鍵的數據。

Step 4: Timeline UI

前端最有挑戰性的是做出類似音樂編輯器的 timeline。需要多軌道顯示、縮放、同步捲動:

import React, { useState, useRef, useEffect } from 'react';

const SleepTimeline = ({ sleepData, audioEvents, sensorEvents }) => {
    const [zoom, setZoom] = useState(1);
    const [currentTime, setCurrentTime] = useState(0);
    const timelineRef = useRef(null);
    
    const renderSleepStages = () => {
        return sleepData.map((stage, index) => (
            <div
                key={index}
                className={`sleep-stage sleep-${stage.stage}`}
                style={{
                    left: stage.startTime * zoom,
                    width: stage.duration * zoom,
                    backgroundColor: stage.stage === 'awake' ? '#ff4444' : 
                                   stage.stage === 'deep' ? '#2196f3' : '#90caf9'
                }}
                onClick={() => handleStageClick(stage)}
            >
                {stage.stage}
            </div>
        ));
    };
    
    const renderAudioEvents = () => {
        return audioEvents.map((event, index) => (
            <div
                key={index}
                className="audio-event"
                style={{ left: event.timestamp * zoom }}
                onClick={() => playAudio(event.audioFile)}
            >
                🔊
            </div>
        ));
    };
    
    return (
        <div className="timeline-container" ref={timelineRef}>
            <div className="track sleep-track">
                <div className="track-label">Sleep Stages</div>
                <div className="track-content">
                    {renderSleepStages()}
                </div>
            </div>
            <div className="track audio-track">
                <div className="track-label">Audio Events</div>
                <div className="track-content">
                    {renderAudioEvents()}
                </div>
            </div>
        </div>
    );
};

最有用的功能是會自動標記睡眠階段轉換的時間點。當我從深度睡眠轉到淺眠,或者直接醒來,時間軸上會用紅色標示。點擊這些時間點就能聽到當下的環境音。

我一開始想用 Canvas 做動畫,後來發現用 CSS transform 配合 React state 就夠了,而且手機上也跑得順。

效果與數據

週末花了大概 8 小時完成核心功能,之後幾天陸續加了一些改進。用了兩個星期後,有些有趣的發現:

睡眠干擾統計:

  • 60% 是外面的交通噪音(特別是垃圾車和機車)
  • 25% 是樓上鄰居(主要是腳步聲和椅子移動)
  • 10% 是室內設備(冰箱、空調、熱水器)
  • 5% 查不出原因(可能是太輕微的聲音)

最有價值的發現是垃圾車固定在凌晨 3:15 經過,而且會連續吵醒我三天。知道原因後解決方案就很明確了:換個朝向的房間睡覺,或者用耳塞。

系統運作狀況:

  • 每晚平均記錄 8-12 個音訊事件
  • 儲存空間每天大概 50MB(音訊檔案)
  • Raspberry Pi CPU 使用率平均 15%
  • 電池續航力對整體系統沒影響(都是插電設備)

Progressive Web App 的推播通知很實用,早上起床滑手機就能馬上看昨晚的分析報告。

Meta 判讀

這種個人專案在目前的 AI 工具 meta 裡算是很典型的例子。以前會因為「工程量太大」而放棄的想法,現在變成週末可以搞定的 side project。

AI 輔助開發降低了很多門檻:

  • 不熟悉的 API 整合(Garmin Connect、Home Assistant)
  • UI 元件的實作細節(timeline、audio player)
  • 數據處理邏輯(音訊分析、時間同步)

但核心的系統架構、產品設計、debug 還是要自己來。AI 更像是把「Google + StackOverflow + 文檔閱讀」的流程加速了 5-10 倍。

這類工具的投資價值不高(用戶基數太小),但對於 prototype 和 MVP 開發來說,現在是最好的時代。個人開發者可以用很低的成本驗證想法。

結論

整體來說很值得做。不只是因為解決了睡眠問題,更重要的是驗證了一個想法:AI 工具已經把個人專案的門檻降低到「有想法就能快速實作」的程度。

推薦給有類似困擾的人試試。如果你已經有 smart home 設備,加上音訊監控的成本很低(一台 Pi + 麥克風大概 3000 塊)。沒有現成系統的話,可能要先評估一下投入產出比。

下一步打算加上 AI 音訊識別,自動分類噪音類型。不過目前手動分析已經夠用了,先把基本功能穩定下來再說。

延伸閱讀

  • 繼 Cursor 之後 下一個爆紅的 AI 開發工具會是什麼?
  • 把個人網站變得 agent-friendly:一個週末補完 9 個 well-known 路由
  • LangChain Middleware 實戰 — 讓你的 AI Agent 更靈活的擴展方式

每週一篇 — 技術趨勢背後的商業邏輯

分享:

Waiting7777

WoW Arena 冠軍轉前端,用電競 meta 思維拆解技術趨勢。

關於作者

相關文章

YC 裡越來越多二次創業者 — AI 時代為什麼老手反而更吃香創業創投+4

YC 裡越來越多二次創業者 — AI 時代為什麼老手反而更吃香

為什麼 AI 時代反而讓「老手」更吃香?從 YC 的數據看 repeat founder 的優勢在哪,以及這對第一次創業的人有什麼啟示。

2026年8月12日 · Waiting7777 · 7 分鐘閱讀

繼續閱讀 →
OpenChamber:專為 AI Agent 設計的開發環境,跟 IDE 的差別在哪?AI Agents開發工具+5

OpenChamber:專為 AI Agent 設計的開發環境,跟 IDE 的差別在哪?

拆解 OpenChamber 的設計邏輯:為什麼 agent 需要專屬的開發環境、跟直接在 terminal 跑 Claude Code 有什麼本質差異,以及這個方向的商業潛力在哪。

2026年8月11日 · Waiting7777 · 8 分鐘閱讀

繼續閱讀 →
AI coding 工具燒錢有多快?Databricks 告訴你怎麼控成本AI開發工具+4

AI coding 工具燒錢有多快?Databricks 告訴你怎麼控成本

從「Databricks 燒完錢才搞出控制工具」這個角度切入,拆解 AI coding 工具的真實成本結構,以及企業在 scale up 後才發現的坑。對比 Rippling 同樣在燒錢後才蓋 ROI 工具,這是一個系統性問題。

2026年8月8日 · Waiting7777 · 7 分鐘閱讀

繼續閱讀 →

這篇文章對你有幫助嗎?

每週一篇 — 技術趨勢背後的商業邏輯

AI 產業在變什麼、工程師該注意什麼——拆清楚寄到你的信箱。