2026年8月16日 星期日

以「水井三寶智慧互動展覽系統」為場域型專題教材

網際網路應用|課程大綱

以「水井三寶智慧互動展覽系統」為場域型專題教材

ESP32 → Edge Web → Internet → Django → Data → Knowledge → AI/RAG

模組名稱智慧生活與物聯網
課程名稱網際網路應用
計畫名稱水井村智慧減碳節水三生一體實踐計畫

一、課程簡介

本課程以「水井三寶智慧互動展覽系統」作為《網際網路應用》的場域型專題教材,將抽象的網路協定、位址、Client/Server、Web API與雲端資料概念,轉化為學生可以看見、操作、量測與除錯的真實系統。學生從白馬、烏龜、姻緣花三項地方文化作品出發,理解按鈕、感測器、JQ6500語音與WS2812B燈光如何由ESP32控制;再以手機連入ESP32 Edge Web,實際觀察AP、STA、IP、MAC、DNS、Domain、Port及HTTP Request的作用;進一步將匿名互動事件以JSON及REST API送往Django,建立Digital Twin、資料庫與雲端儀表板。課程不以「會做網頁」為終點,而是追問「一個按鈕按下後,資料去了哪裡?」讓學生沿著實體互動、區域網路、Internet、Web Server、API、Database一路追蹤資料生命週期。最後再由Data走向Knowledge與AI/RAG,思考地方故事如何被整理為可搜尋、可引用、可延伸的文化知識。藉由水井村USR真實場域,學生不只學習網際網路技術,也理解科技如何服務文化保存、地方教育與大學社會責任,培養需求分析、系統整合、網路診斷與知識應用能力。

二、課程核心問題

一個按鈕按下後,資料去了哪裡? ↓ ESP32 → Edge Web → Wi-Fi → IP / DNS → HTTP / JSON / REST API ↓ Django → Database → Digital Twin ↓ Data → Knowledge → AI/RAG

三、學習目標

  • 理解ESP32與周邊裝置通訊,以及實體事件如何轉為數位資料。
  • 理解AP、STA、LAN、IP、MAC、DNS、Domain、Port等網路概念。
  • 理解Browser、Client、Server、Edge Web及HTTP資料流程。
  • 理解GET/POST、Header、Body、JSON與REST API。
  • 將ESP32匿名事件送至Django,理解Database與Dashboard。
  • 能以分層方法診斷Wi-Fi、DNS、HTTPS、API與Cloud問題。
  • 理解Data、Knowledge與AI/RAG的關係。
  • 從USR場域需求思考網際網路技術的社會實踐價值。

四、五層架構與課程主軸

層級系統角色課程重點
Layer 1|文化作品層白馬、烏龜、姻緣花需求、情境、實體與數位系統邊界
Layer 2|智慧互動層ESP32+ToF+按鈕+JQ6500+RGBGPIO、UART、事件、裝置控制
Layer 3|Edge Web層ESP32內嵌網站AP/STA、IP、Web Server、HTTP
Layer 4|Digital Twin / Data層Django+Database+DashboardDNS、HTTPS、JSON、REST API、資料庫
Layer 5|文化知識層文化網站+AI/RAGData → Knowledge、RAG、知識服務

五、系列教材文章

#教材主題核心概念文章連結
1ESP32 × JQ6500 UART 通訊UART序列通訊、語音模組、封包命令閱讀教材
2Layer 2|智慧互動層GPIO、按鈕事件、JQ6500故事播放、互動狀態閱讀教材
3Layer 3|ESP32 Edge WebWeb Server、HTTP、手機控制、192.168.4.1、Edge Computing閱讀教材
4Layer 4|ESP32 × DjangoClient/Server、HTTP、Django、事件資料、Digital Twin閱讀教材
5ESP32 AP+STA 共存SoftAP、Station、LAN與Internet、本地控制與雲端連線閱讀教材
6Layer 4 V1.7|AP+STA+Django整合實測Wi-Fi診斷、DNS、HTTPS、Queue、Local First / Cloud Later閱讀教材
7水井三寶智慧互動展覽系統|五層架構文化作品、智慧互動、Edge Web、Digital Twin/Data、文化知識閱讀教材
8WS2812B × ESP32 燈光控制RGB LED、單線數位控制、色彩編碼、故事狀態回饋閱讀教材
9一個按鈕按下後,資料去了哪裡?Browser → Edge → HTTP → JSON → Django → Database → Dashboard閱讀教材
10IP、MAC、DNS、Domain與PortMAC、IP、Gateway、DNS、Domain、Port、網路診斷閱讀教材
11Data → Knowledge → AI/RAG事件資料、文化知識庫、Chunk、Metadata、Embedding、Vector Search、RAG閱讀教材
12HTTP+JSON+REST APIGET/POST、Header、Body、JSON、REST Endpoint、HTTP Status、Django API閱讀教材

六、建議學習路徑

裝置通訊:ESP32 × JQ6500 × WS2812B ↓ 智慧互動:按鈕 / 感測 → 故事 → 狀態 ↓ Edge Web:手機 → AP → 192.168.4.1 → HTTP ↓ 網路基礎:AP / STA → MAC → IP → Gateway → DNS → Domain → Port ↓ Internet應用:HTTP → JSON → REST API → HTTPS ↓ Cloud / Data:Django → Database → Dashboard → Digital Twin ↓ Knowledge / AI:Data → Knowledge Base → Retrieval → AI/RAG

七、從「做作品」轉向「理解系統」

本課程不把Arduino程式、ESP32接線或Django網站視為彼此獨立的單元,而是要求學生追蹤一筆資料的完整旅程。學生不只要知道「程式可以跑」,還要能回答:手機為什麼找到192.168.4.1?ESP32為什麼同時需要AP與STA?Domain如何透過DNS找到Server?JSON如何進入HTTP Body?Django為什麼回201?當Cloud HTTP=-1時,問題究竟發生在Wi-Fi、DNS、TLS還是API?

核心教學觀念:會使用網路工具只是起點;能畫出資料流、說明協定角色、判斷故障所在層級,才是真正理解「網際網路應用」。

八、USR × 網際網路應用

水井三寶讓網際網路課程不再只是虛擬案例。學生面對的是地方文化作品、展覽觀眾、現場網路、設備可靠度與文化知識保存等真實需求。技術因此不只是完成作業,而是成為連結地方故事、智慧互動、教育推廣與資料累積的工具。透過場域實作,學生可以理解大學社會責任不只是「到社區服務」,而是運用專業知識與地方共同解決問題,並留下可以持續運作、持續學習與持續擴充的系統。

九、關鍵字

ESP32IoTEdge WebAP / STAIP / MAC / DNSHTTPJSONREST APIDjangoDigital TwinAI/RAGUSR

[水井村USR] HTTP+JSON+REST API

HTTP+JSON+REST API

從「水井三寶智慧互動展覽系統」看懂ESP32如何把資料送到Django

HTTP Request × Header × JSON Body × REST Endpoint × Django API × Response

當ESP32已經能連上Internet,下一個問題就是:它到底如何把「烏龜故事被播放」這件事送到Django?答案不是單靠Wi-Fi,而是透過HTTP、JSON與REST API三個重要概念協同工作。這篇文章就用水井三寶Layer 4的資料流,帶學生看懂一筆匿名事件如何從ESP32送到雲端。

一、先從一筆事件開始

{
  "event_uuid":"SHUIJING-001-0000000062",
  "event_type":"STORY_START",
  "story":"002",
  "source":"web",
  "duration_ms":0,
  "completed":null,
  "network_status":"online",
  "metadata":{
    "firmware":"Layer4-V1.7",
    "jq_confirmed":true
  }
}

這段資料本身還沒有「送上網」。它只是ESP32中的一個JSON字串。接下來才輪到HTTP與REST API登場。

二、HTTP是什麼?

HTTP可以理解成Client與Server之間溝通的規則。水井三寶同時用到GET與POST:

Method水井三寶例子用途
GET/play?track=2手機要求ESP32播放烏龜故事
POST/api/exhibition/events/ESP32把匿名事件送到Django
一句話記:GET常用來取得資源或提出查詢;POST常用來把資料送給Server處理。

三、一個HTTP Request有哪三個部分?

Request Line POST /api/exhibition/events/ HTTP/1.1 Headers Content-Type: application/json X-Device-ID: SHUIJING-001 X-Device-Key: ******** Body { "event_type":"STORY_START", "story":"002" }
部分作用
Request Line使用什麼Method、要去哪一個Path
Headers提供內容格式、裝置識別、驗證資訊
Body真正要送給Server的資料

四、JSON是什麼?

JSON是一種文字格式,適合不同系統之間交換結構化資料。

{
  "story":"002",
  "source":"web",
  "completed":true
}
KeyValue意義
story"002"烏龜故事
source"web"由Edge Web啟動
completedtrue故事完整播放
JSON的價值:ESP32、JavaScript、Python、Django等平台都可以很容易解析,因此非常適合IoT與Web API。

五、為什麼要寫 Content-Type?

Content-Type: application/json

這一行是在告訴Django:「這次HTTP Body裡裝的是JSON。」如果Server不知道資料格式,就無法正確解析內容。

六、REST API是什麼?

REST API是一種設計Web服務的方式:把系統功能整理成清楚的URL Endpoint,再搭配HTTP Method進行操作。

https://shuijingtreasures.pythonanywhere.com/api/exhibition/events/
https:// 安全的HTTP通訊 shuijingtreasures.pythonanywhere.com Domain / Server /api/exhibition/events/ REST API Endpoint
Endpoint可以理解成「API的入口地址」。

七、為什麼ESP32不能直接呼叫Django函式?

ESP32和Django位於不同設備、不同執行環境,因此ESP32不能直接執行Server上的Python函式,只能透過網路把Request送到URL,再由Django URL Router找到對應View。

ESP32 ↓ HTTP POST /api/exhibition/events/ ↓ Django URL Router ↓ api_event() ↓ Database

八、Device ID與API Key放在哪裡?

X-Device-ID: SHUIJING-001
X-Device-Key: ********

它們放在HTTP Header,讓Django知道是哪一台設備,以及這台設備是否有權限傳送資料。

正式API Key不應公開放在部落格、簡報或公開GitHub倉庫。教材只示範格式即可。

九、ESP32端的HTTP POST概念

WiFiClientSecure client;
HTTPClient https;

https.begin(
  client,
  "https://shuijingtreasures.pythonanywhere.com/api/exhibition/events/"
);

https.addHeader(
  "Content-Type",
  "application/json"
);

https.addHeader(
  "X-Device-ID",
  DEVICE_ID
);

https.addHeader(
  "X-Device-Key",
  DEVICE_KEY
);

int code = https.POST(jsonBody);
建立HTTPS Client ↓ 指定REST API URL ↓ 加入Headers ↓ 放入JSON Body ↓ POST ↓ 等待HTTP Response

十、Server如何告訴ESP32成功或失敗?

Status Code常見意義
200Request成功
201資料建立成功
400Request內容有問題
401驗證失敗
404API路徑不存在
500Server內部錯誤

水井三寶Cloud Test成功時,可看到:

Cloud HTTP = 201
Response = {"ok":true,...}
CLOUD POST OK

這代表DNS、HTTPS、API URL、裝置驗證與Django資料接收都已經成功。

十一、為什麼 Cloud HTTP = -1 不是Django回的狀態碼?

實作過程中曾出現:

Cloud HTTP = -1

後來追查發現問題發生在DNS解析階段,也就是HTTP Request根本還沒到Django。

DNS失敗 ↓ 找不到Server IP ↓ 無法建立TCP/TLS連線 ↓ HTTP Request沒有到Django ↓ 自然也不會有401 / 404 / 500
除錯原則:Cloud失敗時,不要第一時間就修改Django;先確認Wi-Fi、DNS、TLS與HTTP是否真的走到Server。

十二、為什麼採用 Local First, Cloud Later?

如果每次故事一開始就同步做HTTPS POST,可能讓JQ6500播放、Edge Web與網路傳輸互相干擾。因此系統採取:

故事播放 ↓ 建立JSON Event ↓ 先存LittleFS Queue ↓ 播放完成 ↓ 系統空閒 ↓ HTTP POST ↓ Django
設計原則:現場互動優先;雲端同步延後。

十三、HTTP、JSON、REST API怎麼分工?

技術主要工作水井三寶角色
HTTP規定Client與Server怎麼請求與回應ESP32 POST事件到Django
JSON描述資料格式故事、來源、完成狀態等事件內容
REST API定義Server提供的URL服務入口/api/exhibition/events/
一句話記:HTTP是「怎麼送」,JSON是「送什麼」,REST API是「送到哪個功能入口」。

十四、一筆「烏龜故事」事件的完整旅程

使用者按「002 烏龜故事」 ↓ ESP32 Edge Web ↓ JQ6500開始播放 ↓ 建立 JSON ↓ LittleFS Queue ↓ ESP32 STA ↓ DNS找到PythonAnywhere ↓ HTTPS ↓ POST /api/exhibition/events/ ↓ Headers:Device ID / API Key ↓ JSON Body ↓ Django View ↓ Database ↓ HTTP 201 Response ↓ Dashboard

十五、和水井三寶五層架構的關係

層級HTTP / JSON / REST API的角色
Layer 2 智慧互動層產生故事與感測事件
Layer 3 Edge Web層本地HTTP GET控制ESP32
Layer 4 Digital Twin / Data層HTTP POST+JSON+REST API送到Django
Layer 5 文化知識層未來可透過API提供文化內容與AI/RAG服務

十六、真正理解API,要能回答七個問題

Client是誰? ESP32 Server是誰? Django Protocol? HTTPS Endpoint? /api/exhibition/events/ Method? POST 資料格式? JSON 成功如何判斷? HTTP Status + Response Body

十七、課堂思考題

問題一:如果JSON格式正確,但API URL打錯,可能得到哪一類HTTP狀態?
問題二:為什麼Device ID與API Key適合放Header,而故事內容放Body?
問題三:GET與POST都能帶資料,為什麼事件上傳通常選POST?
問題四:如果Django已回201,但Dashboard沒有資料,問題可能已經移到哪一層?

十八、結語:REST API是Edge與Cloud之間的橋

水井三寶的ESP32負責感測、故事播放與現場控制,Django負責跨場次資料、Dashboard與後續分析。兩邊位於不同設備、使用不同語言,卻能透過HTTP+JSON+REST API協同工作。

因此,REST API真正重要的地方,不只是讓ESP32「可以傳資料」,而是建立清楚的系統邊界:Edge負責即時互動,Cloud負責資料服務。HTTP定義溝通方式,JSON定義資料語言,而REST API定義雙方合作的入口。

HTTP GET POST JSON REST API Endpoint Header HTTPS ESP32 Django

[水井村USR] Data → Knowledge → AI/RAG

Data → Knowledge → AI/RAG

從「水井三寶智慧互動展覽系統」第五層看懂資料如何成為文化知識

Event Data × Database × Cultural Knowledge × Retrieval × LLM × RAG

前面的水井三寶教材已經讓一筆「烏龜故事被播放」的事件,從ESP32經過HTTP、JSON與REST API送到Django。但資料送到Database並不是終點。真正值得思考的是:「烏龜今天播放37次」和「烏龜為什麼代表守水?」是同一種資料嗎?答案是否定的。這正是水井三寶五層架構從Layer 4走向Layer 5,以及未來導入AI/RAG最重要的分界。

一、先分清楚:Data不等於Knowledge

假設Django儀表板顯示:

白馬故事:52次
烏龜故事:37次
姻緣花故事:46次
總故事:21次
今日互動人次:156

這些是非常有價值的Data(資料),它告訴我們系統發生了什麼。

但如果觀眾問:

「為什麼水井村會有白馬與烏龜?」
「姻緣花和地方記憶有什麼關係?」
「水井三寶是哪三件作品?」
「這些作品和生產、生態、生活三生一體有什麼關係?」

這些問題就不能只靠播放次數回答。它需要地方故事、創作者資料、作品說明、影音、教材與USR實踐內容,這些才逐步形成Knowledge(知識)

一句話記:Data告訴我們「發生了什麼」;Knowledge幫助我們理解「這代表什麼、為什麼」。

二、Layer 4和Layer 5到底差在哪裡?

比較Layer 4:Digital Twin / DataLayer 5:文化知識
核心事件、狀態、統計故事、脈絡、意義、教材
典型內容故事播放次數、時間、來源、完成率白馬、烏龜、姻緣花的文化故事
資料型態結構化資料文字、圖片、影音、文件等多元內容
主要工具Django Model、Database、Dashboard文化網站、知識庫、未來RAG
回答問題今天有多少互動?這個故事的文化意義是什麼?
第五層不是「再做一個網站」。網站只是呈現知識的介面;第五層真正的核心是把地方文化整理成可保存、可搜尋、可教學、可被AI檢索的知識資源。

三、從Data到Information,再到Knowledge

可以把轉換過程理解成:

Data 「002故事被播放」 「20:22:39」 「source = web」 ↓ Information 「今天烏龜故事共播放37次」 「手機操作占60%」 ↓ Knowledge 「觀眾為什麼對烏龜故事有興趣?」 「烏龜在水井三寶文化中的意義是什麼?」 ↓ AI / RAG 讓觀眾用自然語言詢問文化知識

從原始事件到統計,是「整理資料」;從統計到文化脈絡,則需要另外建立知識內容,不能只靠數字自動產生。

四、水井三寶的Knowledge從哪裡來?

第五層可以逐步整理以下知識來源:

知識類型內容例子
地方故事白馬、烏龜、姻緣花、水井村與地方記憶
作品資料作品名稱、創作者、材料、設計理念、創作歷程
工藝知識玉米籜、蓪草、姻緣花燈、地方工藝製作
教育教材繪本、教案、親子活動、科技教育教材
影音內容故事語音、影片、訪談、活動紀錄
USR實踐生產、生態、生活三生一體與大學社會責任歷程
互動資料Layer 4匿名事件與展覽統計

五、傳統搜尋和AI問答有什麼不同?

傳統網站通常要求使用者先知道要點哪一頁:

首頁 ↓ 水井三寶 ↓ 烏龜 ↓ 故事介紹 ↓ 閱讀內容

AI問答則可以讓使用者直接問:

「為什麼烏龜代表珍惜水資源?」
「請用小學生聽得懂的方式介紹水井三寶。」
「姻緣花和地方工藝有什麼關係?」

但這裡出現一個新問題:大型語言模型不一定知道水井村的地方知識,即使回答得很流暢,也可能產生錯誤內容。

六、這就是為什麼需要RAG

RAG是 Retrieval-Augmented Generation,中文常譯為「檢索增強生成」。

核心概念不是讓AI憑記憶回答,而是:

使用者問題 「姻緣花代表什麼?」 ↓ Retrieval 檢索 從水井三寶知識庫找相關資料 ↓ 找到: 作品介紹 創作者資料 地方故事 USR教材 ↓ 把相關內容交給LLM ↓ Generation 生成 ↓ 根據水井三寶資料回答
一句話理解RAG:先「查資料」,再「請AI根據查到的資料回答」。

七、為什麼不直接問Chatbot就好?

一般LLM可能具備廣泛知識,但「水井三寶」屬於高度地方化、專案化的內容。這類知識可能不在模型訓練資料中,也可能在作品持續發展後改變。

直接LLMRAG
主要依賴模型既有知識先查水井三寶自己的知識庫
地方內容可能不足可以納入地方採集與USR資料
更新通常不容易立即反映更新知識庫即可提供新內容
回答來源較難控制可要求依檢索內容回答並提供來源

八、RAG不是把整個網站一次丟給AI

真正的RAG通常會先對文化內容做前處理:

文化文章 / 教材 / 訪談 / 作品資料 ↓ 清理與整理 ↓ 切成較小的 Chunk ↓ 建立 Metadata ↓ Embedding ↓ Vector Database ↓ 等待使用者查詢

例如一篇長文章可以切成:

Chunk 001:白馬的故事
Chunk 002:烏龜與水文化
Chunk 003:姻緣花的文化意義
Chunk 004:創作者與作品歷程
Chunk 005:水井三寶與三生一體

九、Embedding是在做什麼?

Embedding可以簡化理解成:把文字轉換成一組數值向量,讓系統可以比較「語意上像不像」。

例如使用者問:

「哪一個角色和珍惜水資源有關?」

即使文章中沒有完全相同的句子,向量檢索仍可能找到:

「烏龜慢慢觀察土地與水,
提醒我們珍惜自然。」

這和傳統只比對關鍵字的搜尋方式不同。

十、Metadata為什麼很重要?

每個知識Chunk除了文字,也應保存來源資訊:

{
  "title":"水井三寶作品介紹",
  "category":"地方文化",
  "character":"turtle",
  "source":"official",
  "language":"zh-Hant",
  "updated_at":"2026-08"
}

這讓未來RAG可以限制:

只找「官方作品資料」
只找「烏龜」相關內容
只找「教育教材」
只找最新版本內容

十一、一個完整RAG問答會怎麼走?

① 使用者 「請告訴我烏龜和水井村的關係」 ↓ ② Web / Django 接收問題 ↓ ③ Embedding 把問題轉成向量 ↓ ④ Vector Search 找最相關的文化資料 ↓ ⑤ Retrieve 取回Top-K相關Chunk ↓ ⑥ Prompt 問題 + 檢索資料 + 回答規則 ↓ ⑦ LLM 根據資料生成回答 ↓ ⑧ Response 回答 + 來源

十二、Django在第五層還可以扮演什麼角色?

Django在Layer 4主要接收事件;到了Layer 5,可以進一步成為文化知識與AI服務的入口:

/api/exhibition/events/     → Layer 4事件
/api/knowledge/search/      → 搜尋文化知識
/api/ai/ask/                → AI/RAG問答
/api/treasures/white-horse/ → 白馬知識
/api/treasures/turtle/      → 烏龜知識
/api/treasures/flower/      → 姻緣花知識

這樣就形成:

ESP32 / Browser ↓ Django ↙ ↘ Data Knowledge 事件庫 文化知識庫 \ / \ / AI/RAG

十三、Layer 4資料能不能直接拿來做RAG?

可以使用,但用途不同。

例如Layer 4告訴我們:

今天:
白馬 52次
烏龜 37次
姻緣花 46次

AI可以根據這些結構化資料回答:

「今天哪個故事最多人選?」
「三個故事的播放比例是多少?」

文化知識庫則回答:

「白馬象徵什麼?」
「誰參與水井三寶作品創作?」
「水井三寶如何連結三生一體?」
因此未來更完整的AI,不只是RAG查文章,而可能同時查詢結構化Data+非結構化Knowledge

十四、未來可以形成兩種AI工具

AI角色資料來源問題例子
展覽數據助理Django事件資料庫今天哪個故事最熱門?
文化導覽助理RAG文化知識庫請介紹姻緣花的故事

再進一步,也可以讓兩者合作:

「今天白馬故事最多人選,請結合白馬的文化意義,產生一段展覽觀察摘要。」

十五、AI回答文化故事時,最重要的是「有根據」

文化AI不能只追求回答流暢,還必須重視:

原則說明
Grounding回答必須根據知識庫資料
Source能指出資料來源
Version知道資料更新時間
Authority區分官方、訪談、學生整理等來源
Uncertainty資料不足時應說不知道,而不是自行編故事
文化數位化最怕「AI把地方故事講得很好聽,卻不是地方真正的故事」。因此RAG的價值不只是提升回答能力,更重要的是讓AI回到地方資料與文化脈絡。

十六、五層架構到這裡終於完整串起來

Layer 1
文化作品層
白馬、烏龜、姻緣花實體作品,是文化的起點。
Layer 2
智慧互動層
ESP32、ToF、按鈕、JQ6500、WS2812B讓作品能感測、發聲與發光。
Layer 3
Edge Web層
手機透過ESP32內嵌網站控制作品、查看設備狀態。
Layer 4
Digital Twin / Data層
匿名事件經HTTP+JSON+REST API進入Django,形成Database與Dashboard。
Layer 5
文化知識層
地方故事、作品、工藝、影音、教育與USR內容形成Knowledge Base,未來再透過AI/RAG提供智慧文化導覽。

十七、從五層架構看資料價值如何增加

實體文化 Layer 1 ↓ 互動訊號 Layer 2 ↓ Web控制 Layer 3 ↓ Data Layer 4 ↓ Knowledge Layer 5 ↓ AI / RAG ↓ 新的文化學習與導覽體驗

這條路徑也說明了為什麼水井三寶不是單純的ESP32作品:硬體只是入口,真正長期累積的資產是資料、文化內容與知識。

十八、課堂實作可以怎麼做?

可以把學生分成四個階段:

階段任務
1. Data讀取Django事件資料,統計三個故事播放次數
2. Knowledge把白馬、烏龜、姻緣花文章整理成知識文件
3. Retrieval把文件切Chunk、加入Metadata並進行檢索
4. AI/RAG讓LLM只根據檢索內容回答文化問題

十九、課堂思考題

問題一:「烏龜故事今天播放37次」屬於Data、Information還是Knowledge?為什麼?
問題二:為什麼Layer 5不能只把Layer 4的Database直接改名叫「知識庫」?
問題三:如果LLM已經很強,為什麼地方文化仍然需要RAG?
問題四:RAG回答水井三寶故事時,為什麼來源與Metadata特別重要?
問題五:未來要如何讓AI同時回答「今天誰最熱門」和「這個角色代表什麼」?

二十、結語:真正的第五層,是把地方記憶變成可以延續的知識

從ESP32送出一筆事件,到Django形成Dashboard,我們完成的是Data;把作品故事、創作者、工藝、教育與USR歷程整理起來,我們開始建立Knowledge;當這些知識能被檢索、被引用,再交給LLM產生符合不同觀眾需求的回答,就進一步形成AI/RAG服務。

因此,水井三寶五層架構的最後一層並不是為了「加上AI」而加AI。真正的目標是先把地方知識整理好,再讓AI成為連結人與知識的新介面。

Data告訴我們發生了什麼;Knowledge保存地方為什麼重要;AI/RAG則讓更多人能用自己的問題,走進這些知識。

Data Knowledge AI RAG Embedding Vector Search Django LLM 文化數位化 USR

[水井村USR] IP、MAC、DNS、Domain與Port

IP、MAC、DNS、Domain與Port

從「水井三寶智慧互動展覽系統」看懂網際網路位址與服務

MAC → IP → DNS → Domain → Port → HTTP/HTTPS

當手機可以打開 192.168.4.1,ESP32也顯示 STA=ONLINE,為什麼Django有時還是收不到資料?這個問題正好可以帶學生理解網際網路中幾個最重要、也最容易混淆的概念:MAC、IP、DNS、Domain與Port。它們不是同一件事,而是在不同階段回答不同問題:你是誰?你在哪裡?我要找誰?服務開在哪裡?

一、先看水井三寶的真實網路環境

目前水井三寶智慧互動展覽系統同時有兩條重要網路路徑:

【本地控制】 手機 ↓ Wi-Fi ESP32 SoftAP ↓ http://192.168.4.1 【雲端同步】 ESP32 STA ↓ Wi-Fi Router ↓ Gateway ↓ DNS ↓ Internet ↓ shuijingtreasures.pythonanywhere.com ↓ Django API

這兩條路徑雖然都使用Wi-Fi,但目的完全不同。第一條是LAN內的本地控制;第二條才真正需要Internet與DNS。

二、MAC Address:你是哪一張網路卡?

MAC Address可以理解成網路介面的「硬體識別碼」。ESP32的Wi-Fi介面有自己的MAC,手機也有自己的MAC。

MAC主要回答:
「區域網路裡,這個網路介面是誰?」

在同一個LAN內,資料傳遞最後仍需要靠資料鏈結層識別實際設備。IP可以改變,但MAC通常是網路介面的基礎識別資訊。

ESP32 MAC:
AA:BB:CC:DD:EE:FF

手機 MAC:
11:22:33:44:55:66

對學生來說,最簡單的理解方式是:

MAC像「網路卡的身分證號」;IP像「目前所在位置的地址」。

三、IP Address:資料要送到哪一台設備?

在水井三寶系統中,最常看到兩個IP:

ESP32 AP IP:
192.168.4.1

ESP32 STA IP:
192.168.1.119

這兩個IP屬於同一顆ESP32,但代表不同網路介面角色。

IP用途誰會使用
192.168.4.1ESP32 SoftAP本地控制頁連到Shuijing-Treasures AP的手機
192.168.1.119ESP32連到外部Wi-Fi後取得的STA IP路由器與區域網路

所以同一台ESP32可以同時:

AP角色: 我提供一個Wi-Fi給別人連 IP = 192.168.4.1 STA角色: 我自己去連另一台Wi-Fi IP = 192.168.1.119
這就是AP+STA共存的核心:一邊當本地Server,一邊當Internet Client。

四、Private IP與Public IP有什麼差別?

192.168.x.x這類位址是Private IP,只在區域網路內使用,不能直接在Internet上被全球路由。

例如:

ESP32:192.168.1.119
Router:192.168.1.1

ESP32如果要存取Internet,通常必須經過Router,再由Router以Public IP代表內部設備與外界通訊。

ESP32 192.168.1.119 ↓ Router / NAT 192.168.1.1 ↓ Public IP ↓ Internet

五、Default Gateway:離開這個LAN,要先找誰?

當ESP32要連PythonAnywhere時,目標已經不在自己的區域網路內,因此資料必須先交給Default Gateway。

水井三寶實測曾顯示:

STA IP = 192.168.1.119
Gateway = 192.168.1.1
Gateway回答:
「如果目的地不在我這個LAN,我下一站要把封包交給誰?」

六、Domain Name:人類比較容易記住的名稱

與其讓程式直接記一串Server IP,我們通常使用Domain Name:

shuijingtreasures.pythonanywhere.com

這比IP好記,也方便Server未來搬移。

因此Domain可以理解成:

給人看的服務名稱。

但電腦不能只靠名稱送封包,它仍需要把Domain轉成IP,這就是DNS的工作。

七、DNS:把Domain翻譯成IP

DNS可以想成「Internet電話簿」。

shuijingtreasures.pythonanywhere.com ↓ DNS ↓ Server IP Address

水井三寶V1.7最重要的一次除錯,就是發現:

WiFi status = 3
STA IP = 192.168.1.119
Gateway = 192.168.1.1
DNS = 192.168.1.1
RSSI = -20

Resolving:
shuijingtreasures.pythonanywhere.com

DNS result = -54
ERROR: DNS FAILED

這個案例非常適合用來提醒學生:

Wi-Fi連線成功,不代表Internet服務一定可用。
當DNS失敗,即使STA已取得IP,仍然找不到Domain對應的Server。

最後系統改用Public DNS:

DNS1 = 8.8.8.8
DNS2 = 1.1.1.1

DNS正常後,Cloud Test才真正成功。

八、Domain與DNS不要混在一起

概念例子作用
Domainshuijingtreasures.pythonanywhere.com人類容易記住的Server名稱
DNS8.8.8.8把Domain查成IP的服務

一句話記:

Domain是「名字」,DNS是「查名字的服務」。

九、Port:同一台Server上,要找哪一個服務?

IP只能找到「哪一台主機」,但同一台主機上可能同時運行很多不同服務。

例如:

Web Server
SSH
Database
Email
API
...

Port就是用來區分服務。

服務常見Port
HTTP80
HTTPS443
SSH22

水井三寶ESP32本地Edge Web使用:

http://192.168.4.1

沒有寫Port時,HTTP預設使用80。

而Django雲端API使用:

https://shuijingtreasures.pythonanywhere.com/...

HTTPS預設使用443。

IP回答「哪台電腦」;Port回答「那台電腦上的哪個服務」。

十、URL其實把很多資訊組在一起

例如水井三寶Edge Web:

http://192.168.4.1/play?track=2

可以拆成:

部分內容意義
Protocolhttp使用HTTP
Host192.168.4.1ESP32本地IP
Port80省略時使用HTTP預設Port
Path/play播放功能
Querytrack=2播放第2個故事

再看Django API:

https://shuijingtreasures.pythonanywhere.com/api/exhibition/events/

可拆成:

https
  ↓
Domain
shuijingtreasures.pythonanywhere.com
  ↓
Port 443
  ↓
Path
/api/exhibition/events/

十一、把MAC、IP、DNS、Domain與Port放在同一條資料流

手機按「002 烏龜故事」 ↓ Wi-Fi區域網路 ↓ MAC 找到LAN中的實際網路介面 ↓ IP 找到ESP32:192.168.4.1 ↓ Port 80 找到ESP32 Web Server ↓ HTTP GET /play?track=2 ↓ 故事播放 之後雲端同步: ESP32 STA 192.168.1.119 ↓ Gateway 192.168.1.1 ↓ DNS 8.8.8.8 ↓ Domain shuijingtreasures.pythonanywhere.com ↓ Server IP ↓ Port 443 ↓ HTTPS ↓ Django API

十二、五個名詞,用一句話一起記

名稱一句話記憶
MAC這張網路卡是誰?
IP設備目前在哪裡?
Domain人類想找的服務叫什麼名字?
DNS這個名字對應哪個IP?
Port主機上的哪個服務?

十三、最容易搞錯的幾件事

1
有IP,不代表DNS一定正常。
ESP32可以取得192.168.1.119,但仍可能解析不了Domain。
2
能開192.168.4.1,不代表Internet正常。
因為這只是ESP32 SoftAP內的本地LAN通訊。
3
Domain不是IP。
Domain必須先透過DNS解析成IP。
4
IP相同,Port不同,可以是完全不同的服務。

十四、遇到「雲端連不上」應該怎麼查?

不要一開始就修改Django。應該由下往上逐層檢查:

① Wi-Fi connected? ↓ ② 有沒有取得 IP? ↓ ③ Gateway 正常? ↓ ④ DNS 可以解析 Domain? ↓ ⑤ TCP / Port 443 可連? ↓ ⑥ HTTPS 成功? ↓ ⑦ Django API URL 正確? ↓ ⑧ Device ID / API Key 正確? ↓ ⑨ JSON格式正確? ↓ ⑩ Database / Dashboard 有資料?
這就是分層除錯的價值:不是看到「Cloud失敗」就全部一起查,而是先判斷問題究竟在哪一層。

十五、這和OSI七層模型有什麼關係?

本篇出現的概念可以粗略放進OSI / TCP/IP架構中:

概念大致所在層級
Wi-Fi、MACData Link
IP、Router、GatewayNetwork
TCP、PortTransport
DNS、HTTP、HTTPSApplication

這也是下一步理解OSI七層模型的重要基礎。

十六、課堂思考題

問題一:
如果手機可以打開192.168.4.1,但是Django沒有收到資料,MAC、IP、DNS、Domain、Port中,哪些已經可以確定正常?哪些還不能?
問題二:
ESP32的STA IP從192.168.1.119變成192.168.1.125,為什麼Django網址不需要跟著改?
問題三:
為什麼 https://... 沒有寫 :443,瀏覽器仍知道要連443?
問題四:
如果DNS失敗,直接把Server IP寫進程式可以暫時解決嗎?這樣做又會產生什麼維護問題?

十七、結語:網際網路不是一條線,而是一連串「找到正確對象」的過程

從水井三寶實作可以看見,網際網路通訊不是單純「ESP32有Wi-Fi,所以就能上雲端」。資料必須先找到正確的網路介面、正確的IP、正確的Gateway、正確的Server名稱,再經由DNS取得Server IP,最後還要找到正確的Port與應用服務。

因此,MAC、IP、DNS、Domain與Port並不是五個孤立的名詞,而是一條完整通訊鏈上的不同角色。當學生能用一筆「烏龜故事事件」解釋這五個概念,就代表他已經開始真正理解網際網路是如何運作的。

MAC IP Gateway DNS Domain Port HTTP HTTPS ESP32 Django

[水井村USR] 一個按鈕按下後,資料去了哪裡?

一個按鈕按下後,資料去了哪裡?

從「水井三寶智慧互動展覽系統」看懂網際網路資料流

Browser × Edge Web × Wi‑Fi × IP × HTTP × JSON × Django × Database

對初學者來說,「按下一個按鈕,故事就播放了」好像只是ESP32的一個控制功能;但從網際網路角度來看,這個動作其實會經過一連串不同層次的資料處理。這篇文章用「按下烏龜故事」作為例子,追蹤一筆事件如何從使用者手指,經過ESP32、Wi‑Fi、HTTP、JSON、Django與資料庫,最後出現在雲端儀表板上。

一、按下的是什麼?

水井三寶有兩種啟動方式:實體按鈕與手機Edge Web。實體按鈕由ESP32直接讀GPIO;手機則先連上ESP32的AP,再開啟 http://192.168.4.1

手機操作時真正發生的第一件事:瀏覽器送出一個HTTP Request,而不是直接播放MP3。

二、一個Web按鈕,其實是一個URL

例如「002 烏龜故事」可對應:

http://192.168.4.1/play?track=2

瀏覽器會送出類似:

GET /play?track=2 HTTP/1.1
Host: 192.168.4.1
概念水井三寶例子作用
IP Address192.168.4.1找到ESP32
HTTPGETBrowser與Web Server溝通
URL Path/play告訴Server要做什麼
Query Stringtrack=2指定播放第2個故事
重點:網頁不是網際網路。網頁只是應用層的一部分,背後還有Wi‑Fi、IP、TCP與HTTP。

三、資料先到ESP32 Edge Web

Browser ↓ HTTP GET ESP32 Edge Web ↓ 解析 track=2 ↓ 啟動 STORY_TURTLE ├─ JQ6500:播放002 ├─ WS2812B:烏龜藍色呼吸 └─ System State:PLAYING

四、到這裡為止,其實還沒有上Internet

手機連的是ESP32自己的AP,因此這是區域網路內的本地通訊。即使展場Internet完全中斷,192.168.4.1仍然可以工作。

能開啟192.168.4.1,不代表Internet一定正常;Internet斷線,也不代表Edge Web一定不能用。

五、故事播放後,ESP32建立事件資料

{
  "event_uuid":"SHUIJING-001-0000000062",
  "event_type":"STORY_START",
  "story":"002",
  "source":"web",
  "duration_ms":0,
  "completed":null,
  "network_status":"online",
  "metadata":{
    "firmware":"Layer4-V1.7",
    "jq_confirmed":true
  }
}

這是一個JSON物件,用來把系統狀態整理成適合網路傳輸的文字格式。

六、為什麼不直接送雲端?

Local First 先完成:JQ6500播放、燈光、按鈕與Web回應 ↓ 事件先寫入 LittleFS Queue ↓ Cloud Later 空閒後再送 Django

這樣即使Wi‑Fi暫時斷線,事件也不會立即遺失。

七、真正上Internet時,資料經過哪些地方?

ESP32 STA ↓ Wi‑Fi Router ↓ Default Gateway ↓ DNS ↓ Internet ↓ shuijingtreasures.pythonanywhere.com ↓ HTTPS / Django API

八、DNS的工作:把名稱變成IP

ESP32知道的是網域名稱,但Internet路由需要IP,因此必須先做DNS解析。

shuijingtreasures.pythonanywhere.com ↓ DNS IP Address
診斷觀念:Wi‑Fi → Gateway → DNS → TCP/TLS → HTTP → API,每一層都可能失敗。

九、ESP32如何把JSON送到Django?

POST /api/exhibition/events/ HTTP/1.1
Host: shuijingtreasures.pythonanywhere.com
Content-Type: application/json
X-Device-ID: SHUIJING-001
X-Device-Key: ********

{
  "event_type":"STORY_START",
  "story":"002",
  "source":"web"
}
項目作用
HTTP POST送資料給Server
Header放Content-Type、Device ID、API Key
JSON Body真正的事件內容

十、Django收到後做什麼?

Django URL Router ↓ api_event() ↓ 檢查 Device ID / API Key ↓ 解析 JSON ↓ 寫入 ExhibitionEvent ↓ Database ↓ Dashboard

十一、一筆「烏龜故事」事件的完整旅程

1. 使用者點選「002 烏龜故事」 2. Browser送出 HTTP GET 3. ESP32收到 /play?track=2 4. JQ6500播放002 5. WS2812B切換烏龜燈效 6. 建立 STORY_START JSON 7. 寫入 LittleFS Queue 8. ESP32 STA連Router 9. DNS解析網域 10. HTTPS POST送到Django 11. Django驗證裝置 12. JSON寫入Database 13. Dashboard統計「002 烏龜故事 +1」

十二、這和水井三寶五層架構有什麼關係?

層級角色
第一層|文化作品白馬、烏龜、姻緣花實體作品
第二層|智慧互動ESP32、按鈕、ToF、JQ6500、RGB
第三層|Edge Web192.168.4.1、HTTP、本地控制與診斷
第四層|Digital Twin / DataJSON、HTTPS、Django、Database、Dashboard
第五層|文化知識品牌故事、影音、教育、工藝、USR與未來AI/RAG

十三、這個案例可以學到哪些《網際網路》概念?

Browser / ServerLANWi‑Fi AP / STAIP AddressGatewayDNSHTTP GETHTTP POSTJSONREST APIHTTPSDatabaseEdge Computing

十四、課堂思考題

問題一:手機能開192.168.4.1,但Django收不到資料,可能是哪一段有問題?
問題二:ESP32顯示STA ONLINE,是否代表Internet一定正常?為什麼?
問題三:為什麼事件要先進LittleFS Queue,而不是每次按下按鈕就立即POST到Django?

十五、結語:真正的網際網路,不是一張網頁

水井三寶案例讓我們看見,網際網路真正有趣的地方,不在於「做出一個網頁」,而是理解一筆資料如何從實體世界產生,再經過本地網路、IP、DNS、HTTP、JSON、API與Database,最後轉化成可被理解的資訊。

當學生按下「002 烏龜故事」時,他不只是啟動一段音檔;他其實啟動了一條從文化作品 → Edge → Internet → Cloud → Data的完整資料鏈。這正是把《網際網路》從課本名詞變成真實系統最有價值的地方。

[水井村USR]WS2812B讓水井三寶會發光:ESP32燈光控制原理、接線與程式實作

WS2812B讓水井三寶會發光:ESP32燈光控制原理、接線與程式實作

水井三寶智慧互動展覽系統|智慧互動層燈光控制專題

在水井三寶智慧互動展覽系統中,聲音負責說故事,燈光則讓觀眾「看見故事正在發生」。這篇把WS2812B燈光控制獨立整理,從工作原理、接線、LED分區,到白馬追光、烏龜呼吸與姻緣花綻放的程式邏輯,完整做成可直接上課與實作的教材。

一、WS2812B是什麼?

WS2812B是一種可定址RGB LED,每顆LED內部整合驅動控制電路。多顆串接時,只需要一條DATA線,就能逐顆指定顏色與亮度。Arduino端使用Adafruit_NeoPixel函式庫,水井三寶目前採 NEO_GRB + NEO_KHZ800,由ESP32 GPIO13控制62顆LED。

ESP32 DATA ↓ LED #0 → LED #1 → LED #2 → … → LED #61 每一顆取走自己的顏色資料,再把後續資料傳給下一顆

二、正式接線方式

ESP32 × WS2812B 正式接線圖|水井三寶 V1.7 外接 5V 電源 +5VGND ESP32 GPIO13 GND 邏輯電平轉換 74AHCT125 等 330–470Ω WS2812B 5V DIN GND 500–1000µF 62顆 LED 分區 0–23:底座 24顆 24–33:白馬 10顆 34–45:烏龜 12顆 46–61:姻緣花 16顆
展覽版電源原則:LED燈條使用獨立5V電源;ESP32與燈條必須共地。DATA進入第一顆LED前建議串接300~500Ω電阻,電源端可加500~1000µF電容。ESP32是3.3V邏輯,5V燈條的長期展覽版建議加入適當的邏輯電平轉換器。

三、62顆LED不是一整條,而是四個燈區

燈區LED編號數量角色
底座0–2324待機與環境柔光
白馬24–3310暖金追光
烏龜34–4512水藍呼吸
姻緣花46–6116粉紅漸次綻放

四、燈光控制不是裝飾,而是故事的第二語言

故事燈效意義
001 白馬暖金追光向前、行動、奔跑感
002 烏龜藍色呼吸沉穩、守水、守護土地
003 姻緣花粉紅逐顆點亮花朵慢慢綻放
004 水井三寶總故事三角色輪替白馬→烏龜→姻緣花依序出場
005 創作者資訊三區共同暖光溫暖、穩定、不搶作品主體

五、為什麼白馬用追光?

白馬的主光點會沿著10顆LED移動,後方保留較暗的尾光,因此不是整區同時亮,而是形成「奔跑」的速度感。

六、為什麼烏龜用呼吸燈?

烏龜燈區使用藍色,亮度從低到高、再由高到低反覆變化,形成穩定呼吸感。這比快速閃爍更適合「守水、沉穩、長久陪伴土地」的角色設定。

七、姻緣花如何「開花」?

姻緣花不是整區一起閃,而是控制目前亮起的LED數量,由1顆慢慢增加到16顆,再逐步縮回。這種漸次點亮的動畫更接近「花開」而不是一般警示燈。

八、燈效如何跟故事狀態機連動?

IDLE ↓ 底座暖色微呼吸 READY ↓ 三角色低亮提示 選擇故事 ↓ JQ6500 PLAYING + 對應角色燈效 ↓ 故事播放完成 ↓ COOLDOWN → READY / IDLE

正式系統由 currentStory 決定燈效,因此聲音與燈光會同步對應故事。燈光也成為「狀態可視化」介面:即使觀眾沒有看手機,也能知道目前正在播放哪個角色。

九、程式設計重點:不要用長時間delay()

水井三寶還要同時處理ToF、按鈕、JQ6500、Edge Web與Wi-Fi,因此燈效大量使用 millis() 控制更新節奏,避免動畫阻塞其他任務。

教學重點:Arduino入門常用 delay() 做動畫;真正的IoT系統要進一步學會非阻塞式時間控制。燈光再漂亮,也不能讓感測器、Web或故事播放停住。

十、完整獨立測試程式

下面程式只保留WS2812B燈光模組,適合先測接線、燈區與動畫。正式系統再把這些函式整合回Layer 2~Layer 4。


#include <Arduino.h>
#include <Adafruit_NeoPixel.h>

#define LED_PIN 13
#define LED_COUNT 62
#define BASE_START 0
#define BASE_COUNT 24
#define HORSE_START 24
#define HORSE_COUNT 10
#define TURTLE_START 34
#define TURTLE_COUNT 12
#define FLOWER_START 46
#define FLOWER_COUNT 16

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

enum Story {
  STORY_NONE=0, STORY_HORSE=1, STORY_TURTLE=2,
  STORY_FLOWER=3, STORY_ALL=4, STORY_CREATOR=5
};
Story currentStory = STORY_NONE;

void setZone(int start, int count, uint32_t color){
  for(int i=0;i<count;i++) strip.setPixelColor(start+i,color);
}

void ledIdle(){
  static unsigned long last=0;
  static int b=4, dir=1;
  if(millis()-last<80) return;
  last=millis();
  b+=dir;
  if(b>=14) dir=-1;
  if(b<=4) dir=1;
  strip.clear();
  setZone(BASE_START,BASE_COUNT,strip.Color(b,b/2,0));
  strip.show();
}

void ledReady(){
  strip.clear();
  setZone(HORSE_START,HORSE_COUNT,strip.Color(20,8,0));
  setZone(TURTLE_START,TURTLE_COUNT,strip.Color(0,8,18));
  setZone(FLOWER_START,FLOWER_COUNT,strip.Color(18,0,7));
  strip.show();
}

void ledHorse(){
  static unsigned long last=0;
  static int pos=0;
  if(millis()-last<80) return;
  last=millis();
  strip.clear();

  for(int i=0;i<HORSE_COUNT;i++){
    int dist=(i-pos+HORSE_COUNT)%HORSE_COUNT;

    if(dist==0)
      strip.setPixelColor(HORSE_START+i,strip.Color(100,45,0));
    else if(dist<=2)
      strip.setPixelColor(HORSE_START+i,strip.Color(30,10,0));
  }

  pos++;
  if(pos>=HORSE_COUNT) pos=0;
  strip.show();
}

void ledTurtle(){
  static unsigned long last=0;
  static int b=10, dir=1;
  if(millis()-last<70) return;
  last=millis();
  b+=dir;
  if(b>=80) dir=-1;
  if(b<=10) dir=1;
  strip.clear();
  setZone(TURTLE_START,TURTLE_COUNT,strip.Color(0,b/2,b));
  strip.show();
}

void ledFlower(){
  static unsigned long last=0;
  static int count=1;
  static bool growing=true;

  if(millis()-last<120) return;
  last=millis();
  strip.clear();

  for(int i=0;i<count;i++)
    strip.setPixelColor(FLOWER_START+i,strip.Color(80,5,25));

  strip.show();

  if(growing){
    count++;
    if(count>=FLOWER_COUNT){count=FLOWER_COUNT;growing=false;}
  }else{
    count--;
    if(count<=2){count=2;growing=true;}
  }
}

void ledAllStory(){
  static unsigned long last=0;
  static int phase=0;
  if(millis()-last<900) return;
  last=millis();
  phase++;
  if(phase>2) phase=0;

  strip.clear();

  if(phase==0)
    setZone(HORSE_START,HORSE_COUNT,strip.Color(70,30,0));
  else if(phase==1)
    setZone(TURTLE_START,TURTLE_COUNT,strip.Color(0,25,70));
  else
    setZone(FLOWER_START,FLOWER_COUNT,strip.Color(70,5,25));

  strip.show();
}

void ledCreator(){
  strip.clear();
  uint32_t warm=strip.Color(45,28,10);
  setZone(HORSE_START,HORSE_COUNT,warm);
  setZone(TURTLE_START,TURTLE_COUNT,warm);
  setZone(FLOWER_START,FLOWER_COUNT,warm);
  strip.show();
}

void updateStoryLED(){
  switch(currentStory){
    case STORY_HORSE: ledHorse(); break;
    case STORY_TURTLE: ledTurtle(); break;
    case STORY_FLOWER: ledFlower(); break;
    case STORY_ALL: ledAllStory(); break;
    case STORY_CREATOR: ledCreator(); break;
    default: ledReady(); break;
  }
}

void setup(){
  Serial.begin(115200);
  strip.begin();
  strip.setBrightness(100);
  strip.clear();
  strip.show();
}

void loop(){
  unsigned long section=(millis()/10000UL)%6;

  switch(section){
    case 0: ledIdle(); break;
    case 1: currentStory=STORY_HORSE; updateStoryLED(); break;
    case 2: currentStory=STORY_TURTLE; updateStoryLED(); break;
    case 3: currentStory=STORY_FLOWER; updateStoryLED(); break;
    case 4: currentStory=STORY_ALL; updateStoryLED(); break;
    case 5: currentStory=STORY_CREATOR; updateStoryLED(); break;
  }
}

十一、從RGB燈條到文化互動語言

WS2812B真正有價值的不是「顏色很多」,而是每顆LED都可以被程式個別控制。當白馬用追光、烏龜用呼吸、姻緣花用綻放來呈現各自故事時,LED就不再只是裝飾,而成為文化敘事的一部分。

設計理念:聲音說故事,燈光表達故事情緒,作品本體仍然是主角。科技不取代文化,而是讓觀眾多一種理解文化的方式。

2026年8月15日 星期六

[水井村USR] 水井三寶智慧互動展覽系統

水井三寶智慧互動展覽系統

Shuijing Treasures Smart Interactive Exhibition System

五層架構與設計理念:從文化作品,到互動裝置、Edge Web、Digital Twin,再到文化知識平台

「水井三寶智慧互動展覽系統」的核心,不是把一件文化作品變成單純的科技展示品,而是讓科技成為文化被理解、被互動、被記錄、被延伸的橋梁。因此整個系統刻意採用五層架構,讓每一層都有清楚角色:文化作品負責承載價值,智慧互動負責創造體驗,Edge Web負責現場控制,Digital Twin / Data負責留下匿名資料,文化知識層則負責把故事、教育、工藝與USR持續累積成長。

一、五層架構總覽

第五層|文化知識層 水井三寶網站、品牌故事、繪本、影音、教育、工藝、USR、未來AI/RAG ▲ │ 第四層|Digital Twin / Data層 Django匿名事件、展覽儀表板、跨場次資料 ▲ │ 第三層|Edge Web層 ESP32內嵌網站、現場控制、設備診斷、即時匿名統計 ▲ │ 第二層|智慧互動層 ESP32+ToF+三按鈕+JQ6500+RGB ▲ │ 第一層|文化作品層 水井三寶實體作品,文化展示為主,不直接觸碰

這五層並不是五套彼此獨立的系統,而是一條「由文化出發,再回到文化」的完整鏈結。第一層是核心,第二、三、四層提供互動、控制與資料能力,第五層再將資料與內容重新轉化為教育、品牌與文化傳播的長期價值。

二、第一層|文化作品層

水井三寶實體作品,文化展示為主,不直接觸碰

第一層是整個系統最重要的一層。白馬、烏龜與姻緣花不是互動裝置的配件,而是展覽真正的主角。系統設計的第一原則,就是科技不能破壞作品本體,也不能讓參觀者因為操作而直接觸碰文化作品

因此互動按鈕、燈光、聲音、感測器與控制設備,應盡量整合在木盒、底座或展示台中。參觀者操作的是「展覽介面」,不是作品本身。這樣可以兼顧保存、安全與展示尊嚴。

設計理念:作品是核心,科技退居幕後。不是把文化變成科技,而是用科技讓文化更容易被理解。

三、第二層|智慧互動層

ESP32+ToF+三按鈕+JQ6500+RGB

第二層負責把「觀看」轉化成「參與」。ESP32是互動控制核心;三顆按鈕分別對應白馬、烏龜與姻緣花;JQ6500負責播放故事音檔;RGB燈光則提供視覺回饋;ToF感測器則用來判斷是否有人靠近展區。

這一層的價值不只是「會播聲音」或「會亮燈」,而是建立一個能避免誤動作、能確認播放狀態、能支援展覽現場大量人流的互動邏輯。尤其在人多的展場,感測器與狀態機必須避免因路人經過、連續按鍵或多人同時操作而造成混亂。

第二層可視為「實體互動引擎」,主要任務是快速、穩定、即時,而且即使沒有Internet也必須能正常工作。

四、第三層|Edge Web層

ESP32內嵌網站,現場控制、設備診斷、即時匿名統計

第三層讓ESP32不再只是藏在盒子裡的控制板,而成為一個可被手機直接管理的Edge設備。工作人員只要連上ESP32的本地AP,就可以開啟內嵌網站,不需要額外安裝App。

Edge Web可以提供故事控制、音量設定、設備狀態、JQ6500播放狀態、Wi-Fi狀態、ToF距離、Queue大小與即時匿名統計。它同時也是維護工具:當展場出現「有燈沒聲音」、「有網路但沒同步」等問題時,工作人員可以直接從手機判斷問題在哪一層。

設計理念:現場控制應該留在Edge,不應依賴雲端。即使外網中斷,192.168.4.1仍應可以進入控制頁面。

五、第四層|Digital Twin / Data層

Django接收匿名事件,建立展覽儀表板與跨場次資料

第四層將實體展覽轉化成可觀察、可比較的Digital Twin / Data系統。ESP32不記錄個人姓名、不做人臉辨識,也不追蹤個人身分,而是只記錄匿名事件,例如:故事啟動、完整播放、Web操作、實體按鈕操作、展區喚醒、裝置狀態與錯誤事件。

Django接收這些事件後,可以建立展覽儀表板,顯示白馬、烏龜、姻緣花故事的互動次數、播放完成率、互動來源與設備健康狀態。當展覽移到不同場域、不同日期或不同活動時,也可以累積成跨場次資料。

這一層的重點不是「蒐集越多資料越好」,而是只記錄對展覽改善有用、又不涉及個人識別的資料。資料的價值,在於協助回答:哪個故事最受歡迎?觀眾是否完整聽完?實體按鈕和Web控制哪一種使用較多?哪一場展覽的互動最高?

六、第五層|文化知識層

水井三寶網站承接品牌故事、繪本、影音、教育、工藝、USR,未來再加入AI/RAG

第五層不是單純的「網站資料庫」,而是整個系統最長期的文化知識層。展場中的一段語音只能講幾十秒或幾分鐘,但水井三寶的品牌故事、地方記憶、創作者、工藝技法、繪本、影音、教育課程、USR成果,都需要一個可以持續累積的知識平台。

因此,ESP32內嵌網站負責「現場」,水井三寶網站負責「延伸」。參觀者在現場聽完故事後,可以再透過QR Code進入完整網站,繼續閱讀作品故事、觀看影音、了解地方文化與USR實踐。

未來如果加入AI與RAG,這一層還可以進一步發展成「水井三寶文化知識問答」,讓參觀者用自然語言詢問白馬、烏龜、姻緣花、水井村、工藝、USR與地方故事,讓文化知識從靜態瀏覽進入互動問答。

七、為什麼一定要分成五層?

層級 主要角色 即使其他層失效,仍應保留什麼?
第一層|文化作品 文化核心與展示主體 作品仍能被正常觀看與保存
第二層|智慧互動 按鈕、聲音、燈光、感測 即使沒有Internet,仍能互動與播放
第三層|Edge Web 本地控制、診斷、即時統計 即使雲端離線,仍能從192.168.4.1管理
第四層|Digital Twin / Data 匿名事件、跨場次分析、設備健康 網路恢復後可從Queue補同步
第五層|文化知識 品牌、教育、USR、知識累積 內容可持續成長,不受單一展場限制

八、五層架構背後的四個設計原則

文化優先Local First匿名資料可擴充

第一,文化優先。所有科技都服務於作品,不讓作品變成科技展示的配角。第二,Local First。故事播放與現場控制要在本地完成,雲端不能干擾基本互動。第三,匿名資料。只記錄事件,不記錄個人身分。第四,可擴充。未來可以增加AI、RAG、更多故事、更多展場與更多教學內容,而不必推翻原本架構。

九、這不是五個功能,而是一條文化數位轉譯鏈

文化作品 ↓ 被看見 ↓ 智慧互動 ↓ 被參與 ↓ Edge Web ↓ 被控制與理解 ↓ Digital Twin / Data ↓ 被記錄與分析 ↓ 文化知識平台 ↓ 被延伸、被教學、被再創作

從這個角度來看,「水井三寶智慧互動展覽系統」的真正價值,不只是完成一套ESP32裝置,而是建立一種地方文化數位化的方法:實體作品保留原貌,科技負責提升體驗,資料負責留下足跡,網站負責延伸知識,未來AI再負責讓文化被更自然地提問與理解。

十、結語

「水井三寶智慧互動展覽系統」五層架構,讓文化、硬體、Web、資料與知識不再混在同一層。第一層守住文化,第二層創造互動,第三層保障現場,第四層累積資料,第五層延伸知識。這樣的設計也讓系統更適合真正的展覽情境:某一層暫時失效時,不會讓整個展覽一起失效。

對USR而言,這五層架構還有另一層意義:它把地方故事從「一次性的展示內容」,轉化成可以持續累積、教育、分析、再利用與再傳播的地方文化數位資產。科技因此不只是工具,而是文化保存、教育與地方連結的一座橋。