
用 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
Waiting7777
WoW Arena 冠軍轉前端,用電競 meta 思維拆解技術趨勢。
這篇文章對你有幫助嗎?
每週一篇 — 技術趨勢背後的商業邏輯
AI 產業在變什麼、工程師該注意什麼——拆清楚寄到你的信箱。

