
啟動 App 並開啟管理頁面,同時保留 Python Console,先以頁面目前文字與 D2 實體狀態建立基準。
本日不要先點擊 Web 按鈕,而是完全使用 D9 操作,這樣才能排除遠端命令,確認更新確實由現場事件發起。
若有兩個瀏覽器或兩個分頁,也可以同時開啟,後面用來確認一次 MCU 回報能更新多個畫面。
測試前兩個畫面都應顯示相同初始內容,若其中一個頁面尚未完成載入,先等待 Socket.IO 建立連線,再按 D9,避免把尚未連線造成的漏接誤判為推送功能錯誤。
短按 D9 一次,MCU 應偵測 HIGH 轉成 LOW 的下降緣,只呼叫一次 toggle_led(),D2 在亮與滅之間切換。
將按鈕持續按住兩秒,LED 不應連續跳動,放開時也不再切換,這表示 Day 7 與 Day 8 建立的按下判斷與去彈跳仍未被後續 Bridge 功能破壞。
toggle_led() 完成 ledState 與 D2 更新後,會呼叫以下程式。
Bridge.call("led_status", ledState);
這條回報不在 Web 專用函式中,因此現場按鈕與遠端命令都會產生相同的 led_status,Python 不需要知道此次切換來自哪個入口。
若 LED 有動作但 Python 沒有 ON/OFF,先檢查狀態回報是否仍放在共同的 toggle_led(),不要只在 on_toggle_led() 中回報。
Python 收到布林值後執行 on_led_status(),將 True 或 False 轉成 ON/OFF,放入 {"status": label},再以 ui.send_message("led_update", ...) 推送。
Console 應新增一筆與 LED 相符的文字,一次 D9 操作對應一次狀態輸出,不能在沒有硬體切換時自行產生資料。
這一層只整理與轉送結果,沒有自己的 ledState,因此不會因操作來源不同而形成另一套答案。
JavaScript 的 socket.on("led_update") 收到資料後,狀態文字應切換成 ON 或 OFF,顏色同步套用 .on 或 .off。
若同時開啟兩個瀏覽器,兩邊應顯示相同結果,因為 Python 主動推送的是同一個 MCU 狀態事件,而不是只回覆某一個按鈕操作者。
這項結果也說明 client_id 只用於辨認 Web 命令來源,MCU 狀態更新不應被限制在原本操作者,現場事件沒有特定瀏覽器發起,更需要以主動推送更新所有管理畫面。
若 Python 已正確輸出但只有部分畫面沒更新,應檢查該瀏覽器的 Socket.IO 連線或 Console 錯誤,不必改動 MCU。
連續測試現場回報
依序進行短按、稍長按與連續短按,每次都觀察 LED、Python 與所有瀏覽器是否同步變化,按住期間不應新增多筆訊息。
可先慢速操作五次,再以正常使用速度操作五次,三個位置應持續交替 ON/OFF,不出現頁面停在舊狀態或多跳一次。
本日的重點不是增加功能,而是證明控制箱旁的一個實體動作,能忠實傳到上層與所有管理畫面。
ledState。現在現場按鈕與遠端按鈕都能更新同一個管理畫面,最後還要確認快速交替操作時不會出現兩份狀態,下一篇要整理最終狀態責任。
下一篇|解決現場與網頁各說各話