iT邦幫忙

2025 iThome 鐵人賽

DAY 19
0
自我挑戰組

IT工具與自我學IT的過程分享系列 第 19

Day 2|樹莓派 5 教學 × 應用:把 Pi 5 變成家中小小資料中心

  • 分享至 

  • xImage
  •  

Day 2|樹莓派 5 教學 × 應用:把 Pi 5 變成家中小小資料中心

今天主打「做得到」:

  1. 家用伺服器三合一(AdGuard Home + Jellyfin + 檔案分享)
  2. 「看到人就通知」的相機 + 小型 AI
  3. 休閒娛樂:Kiosk 看板 / 復古遊戲
    內文皆為 可直接複製貼上 的純文字,搭配 ASCII 小圖表。

0) 今日菜單(5 分鐘看懂)

[家用網路] → [Pi 5]
                 ├─ AdGuard Home:全家擋廣告 / 追蹤
                 ├─ Jellyfin:影片影音伺服器
                 ├─ 檔案分享:家中 NAS 小小版
                 └─ 相機 + AI:偵測到人 → LINE 通知

A. 家用伺服器:三合一實作

準備:建議先把系統碟換成 NVMe(官方 M.2 HAT)或至少用 A2 等級 microSD;資料放到 /srv

A-1 安裝 Docker 與 Compose

curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
# 重新登入以套用 docker 群組
sudo apt install -y docker-compose-plugin

A-2 建立目錄與 compose.yml

sudo mkdir -p /srv/{adguard, jellyfin, media}
sudo chown -R $USER:$USER /srv
cd /srv

tee compose.yml >/dev/null <<'YML'
services:
  adguard:
    image: adguard/adguardhome:latest
    container_name: adguard
    restart: unless-stopped
    ports:
      - "53:53/tcp"        # DNS
      - "53:53/udp"
      - "3000:3000/tcp"    # 初次設定精靈
      - "80:80/tcp"        # 網頁管理(之後可改)
    volumes:
      - ./adguard/work:/opt/adguardhome/work
      - ./adguard/conf:/opt/adguardhome/conf

  jellyfin:
    image: jellyfin/jellyfin:latest
    container_name: jellyfin
    restart: unless-stopped
    network_mode: host     # 播放更穩定
    volumes:
      - ./jellyfin/config:/config
      - ./jellyfin/cache:/cache
      - ./media:/media     # 你的影片/音樂
YML

啟動:

docker compose up -d
  • AdGuard Home:瀏覽 http://<Pi的IP>:3000 進精靈 → 設好你的 Pi 為家中 DNS。
  • Jellyfin:瀏覽 http://<Pi的IP>:8096 → 指向 /srv/media

迷你 NAS(Samba):最簡單照用戶權限做共享。

sudo apt install -y samba
sudo tee -a /etc/samba/smb.conf >/dev/null <<'CONF'
[public]
   path = /srv/media
   browseable = yes
   writeable = yes
   create mask = 0644
   directory mask = 0755
   guest ok = yes
CONF
sudo systemctl restart smbd

小圖表:家用伺服器資料流

[手機/電腦/TV] ──DNS查詢──> [AdGuard]
         │
         ├─影音串流──> [Jellyfin] ──讀取──> [/srv/media]
         │
         └─檔案上傳/下載──> [Samba 共享]

加分:把 :80 留給日後的反向代理(Nginx/Caddy),可做 HTTPS 與網域名稱;或把 AdGuard 管理介面改成 :8080 以免衝突。


B. 相機 + 小型 AI:看到人就通知(LINE Notify)

成本低、成就感高。偵測有人靠近門口 → 立刻傳訊。

B-1 安裝套件與準備模型

sudo apt install -y python3-picamera2 libcamera-apps
pipx install tflite-runtime requests pillow
# 準備一個 TFLite 物件偵測模型(檔名假設為 detect.tflite)
# (可選:下載 COCO 小模型;放到腳本同資料夾即可)

B-2 偵測 + 發訊程式(最小可跑版)

# save as watch_door.py
from picamera2 import Picamera2
from time import sleep, time
import tflite_runtime.interpreter as tflite
import numpy as np
import requests
from PIL import Image

LINE_TOKEN = "填入你的LINE Notify Token"

def line_notify(msg, image_path=None):
    headers = {"Authorization": f"Bearer {LINE_TOKEN}"}
    data = {"message": msg}
    files = {"imageFile": open(image_path, "rb")} if image_path else None
    requests.post("https://notify-api.line.me/api/notify",
                  headers=headers, data=data, files=files)

# 載入 TFLite 模型
interpreter = tflite.Interpreter(model_path="detect.tflite")
interpreter.allocate_tensors()
input_details  = interpreter.get_input_details()
output_details = interpreter.get_output_details()

picam = Picamera2()
picam.configure(picam.create_preview_configuration(main={"size": (640, 480)}))
picam.start(); sleep(1)

last_sent = 0
COOLDOWN = 15  # 同一波動作 15 秒內不重複通知

def preprocess(arr):
    h, w = input_details[0]['shape'][1:3]
    img = Image.fromarray(arr).resize((w, h))
    x = np.expand_dims(np.asarray(img, dtype=np.uint8), 0)
    return x

while True:
    frame = picam.capture_array()
    x = preprocess(frame)
    interpreter.set_tensor(input_details[0]['index'], x)
    interpreter.invoke()

    # 取出結果(不同模型輸出結構略有差異;這裡示意 COCO SSD)
    boxes   = interpreter.get_tensor(output_details[0]['index'])[0]
    classes = interpreter.get_tensor(output_details[1]['index'])[0]
    scores  = interpreter.get_tensor(output_details[2]['index'])[0]

    person_detected = any((c == 0 and s > 0.6) for c, s in zip(classes, scores))  # COCO: class 0=person

    now = time()
    if person_detected and now - last_sent > COOLDOWN:
        path = "snapshot.jpg"
        Image.fromarray(frame).save(path)
        line_notify("門口有人~(Pi 5 報告)", image_path=path)
        last_sent = now
    sleep(0.3)

B-3 設成開機自動執行(systemd)

mkdir -p ~/apps/doorwatch && mv watch_door.py ~/apps/doorwatch/
tee ~/.config/systemd/user/doorwatch.service >/dev/null <<'UNIT'
[Unit]
Description=Pi5 Door Watch (TFLite + Picamera2)

[Service]
ExecStart=/usr/bin/python3 /home/%u/apps/doorwatch/watch_door.py
Restart=always
Environment=PYTHONUNBUFFERED=1
WorkingDirectory=/home/%u/apps/doorwatch

[Install]
WantedBy=default.target
UNIT

systemctl --user daemon-reload
systemctl --user enable --now doorwatch

資料流小圖

[Camera] → [TFLite 推論] → (有人?) → [拍照] → [LINE Notify]

小挑戰:把 person 換成「辨識貓咪就丟訊息」;或限制時間:只有晚上 11 點到早上 6 點通知。


C. 休閒娛樂:Kiosk 看板 / 復古遊戲

C-1 兩行把 Pi 5 變「資訊看板(Kiosk 模式)」

sudo raspi-config  # 設定開機進桌面 & 自動登入(如果還沒設)
mkdir -p ~/.config/systemd/user
tee ~/.config/systemd/user/kiosk-browser.service >/dev/null <<'UNIT'
[Unit]
Description=Kiosk Browser (Chromium)

[Service]
ExecStart=/usr/bin/chromium-browser --kiosk --noerrdialogs --disable-infobars \
  --check-for-update-interval=31536000 --app=https://calendar.google.com/
Restart=always

[Install]
WantedBy=default.target
UNIT

systemctl --user daemon-reload
systemctl --user enable --now kiosk-browser

--app=URL 換成你要的公司儀表板 / 家庭行事曆 / Home Assistant 等網址。Pi 5 支援雙 4K,左邊放看板、右邊看 Jellyfin,超實用。

C-2 復古遊戲(RetroPie / EmulationStation 概念流程)

安裝 RetroPie → 配置手把 → 加入 ROMs → 開玩
  • 建議把 ROMs 放 /srv/media/roms,方便日後備份;手把用藍牙連比 USB 省線。

D. 觀察效能與穩定度(小圖表 / 小抄)

即時觀察

htop           # 美美的互動版 top
vcgencmd measure_temp   # 溫度
watch -n 2 "df -h | head -n 2; free -h"

健康檢查(建議每週執行一次)

CPU 溫度:   < 70°C(長期)    ✔ 良好
系統負載:   1min 負載 < 3     ✔ 正常
儲存空間:   使用率 < 80%      ✔ 安心
網路封包損失:< 1%            ✔ 穩定

E. 常見問題(FAQ)

  • AdGuard 開不起來?
    :53 被占用。關掉系統自帶的 systemd-resolved 或把容器的 DNS 端口改到 :5353,再把路由器指到該埠。

  • Jellyfin 撥放卡卡?
    改用 network_mode: host(已在 compose 範例),或把媒體檔放在 NVMe;Wi-Fi 太擁塞請改用有線。

  • LINE 圖片收不到?
    Token 是否有 notify 權限?files 參數拼對了嗎?圖片檔案大小 < 10MB。

  • 開機未自動跑 AI 程式?
    檢查 systemctl --user status doorwatch;必要時 journalctl --user -u doorwatch -e 查看錯誤。


F. 今日收穫清單 ✅

  • [ ] 啟動了 AdGuard + Jellyfin(基本家用伺服器 OK)
  • [ ] 建好 /srv 資料目錄並可從電腦存取
  • [ ] 相機 + AI 偵測能正常送 LINE 通知
  • [ ] Kiosk 模式能在開機後自動顯示看板
  • [ ] 學會用 htop / watch 觀察系統健康

明天(Day 3)預告

  • 全家族比較:Pi 5 / Pi 4 / Zero 2 W / 400 / Pico
  • 購買建議清單:不同預算與情境的搭配
  • 升級路線圖:NVMe、PoE、UPS、金屬殼散熱……讓 Pi 5 更穩更強!

上一篇
【三天學會樹莓派 5】從入門到實戰、再到全家族選購指南(含圖解 / 教學 / 比較)
下一篇
Day 3|全家族選購指南:Pi 5 vs Pi 4 / Zero 2 W / 400 / Pico(超好懂+圖表+實例)
系列文
IT工具與自我學IT的過程分享20
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言