# 智慧家電:系統功能與代碼實現 在本章中,我們將深入探討系統的每個組成部分,包括 LINE Bot、Glitch 伺服器和 ESP32 設備。透過一個統一的 Python Flask 應用示例來展示如何集成這些組件,以實現遠程控制燈光的功能。 ### 系統概述 本系統包含三個核心部分: - **LINE Bot**:接收用戶的文字指令。 - **Glitch 伺服器**:作為中央伺服器,處理指令並存儲設備狀態。 - **ESP32**:執行實際的設備控制操作,如開關燈。 所有這些功能都通過一個單一的 Flask 應用實現,該應用在 Glitch 上托管。 #### Flask 應用結構 下面的 Flask 應用包括處理 LINE 消息的路由和管理設備狀態的 API。這些代碼片段都是同一個應用的不同部分,應一起運行在同一個伺服器實例上。 ##### Flask 應用的全局設置和路由定義 ```python from flask import Flask, request, jsonify, abort from linebot import ( LineBotApi, WebhookHandler ) from linebot.exceptions import InvalidSignatureError from linebot.models import MessageEvent, TextMessage, TextSendMessage from config import * app = Flask(__name__) line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN) handler = WebhookHandler(YOUR_CHANNEL_SECRET) # 設備狀態字典 device_status = {'light': 'off'} ``` #### LINE Bot 功能 LINE Bot 接收用戶的指令,並根據這些指令更新設備狀態。 ##### 代碼片段:處理 LINE 消息 ```python @app.route("/callback", methods=['POST']) def callback(): signature = request.headers['X-Line-Signature'] body = request.get_data(as_text=True) try: handler.handle(body, signature) except InvalidSignatureError: abort(400) return 'OK' @handler.add(MessageEvent, message=TextMessage) def handle_message(event): text = event.message.text.lower() if text == "turn_on": device_status['light'] = 'on' line_bot_api.reply_message( event.reply_token, TextSendMessage(text="Light has been turned on.") ) elif text == "turn_off": device_status['light'] = 'off' line_bot_api.reply_message( event.reply_token, TextSendMessage(text="Light has been turned off.") ) ``` #### 設備狀態管理 API 這個 API 路由為 ESP32 提供最新的設備狀態信息。 ##### 代碼片段:ESP32 設備狀態 API ```python @app.route("/esp32/command", methods=['GET']) def get_command(): return jsonify(device_status) ``` #### 啟動 Flask 應用 展示如何啟動整個 Flask 應用。 ##### 代碼片段:啟動應用 ```python if __name__ == "__main__": app.run() ``` #### 原代碼 ```python #!/usr/bin/env python # -*- coding: utf-8 -*- from flask import Flask, request, jsonify, abort from linebot import ( LineBotApi, WebhookHandler ) from linebot.exceptions import InvalidSignatureError from linebot.models import MessageEvent, TextMessage, TextSendMessage from config import * app = Flask(__name__) line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN) # 替换为您的 Channel access token handler = WebhookHandler(YOUR_CHANNEL_SECRET) # 替换为您的 Channel secret # 用于存储设备状态的字典 device_status = {'light': 'off'} # 默认灯是关的 @app.route("/callback", methods=['POST']) def callback(): signature = request.headers['X-Line-Signature'] body = request.get_data(as_text=True) try: handler.handle(body, signature) except InvalidSignatureError: abort(400) return 'OK' @handler.add(MessageEvent, message=TextMessage) def handle_message(event): text = event.message.text.lower() if text == "turn_on": device_status['light'] = 'on' line_bot_api.reply_message( event.reply_token, TextSendMessage(text="Light has been turned on.") ) elif text == "turn_off": device_status['light'] = 'off' line_bot_api.reply_message( event.reply_token, TextSendMessage(text="Light has been turned off.") ) else: line_bot_api.reply_message( event.reply_token, TextSendMessage(text="Unknown command.") ) @app.route("/esp32/command", methods=['GET']) def get_command(): return jsonify(device_status) if __name__ == "__main__": app.run() ``` #### ESP32 的接收逻辑 ESP32 定期向 Glitch 伺服器發起 HTTP GET 請求,查詢裝置的目前狀態。 然後,根據返回的數據控制相應的硬件,如燈光。 程式碼片段:ESP32 的 HTTP GET 請求 ```python #include <WiFi.h> #include <HTTPClient.h> const char* ssid = "nga"; const char* password = "0958188700"; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("WiFi connected"); } void loop() { if (WiFi.status() == WL_CONNECTED) { HTTPClient http; http.begin("http://translucent-charm-agustinia.glitch.me/esp32/command"); // 確保 URL 正確 int httpCode = http.GET(); if (httpCode == 200) { String payload = http.getString(); Serial.println("Received command: " + payload); // 解析 payload 中的指令並執行對應操作 } else { Serial.println("Error on HTTP request"); } http.end(); } delay(1000); // 10 秒請求一次,根據需要調整頻率 } ``` ### 系統工作原理 本系統由三個主要組件構成:LINE Bot、Glitch 伺服器和 ESP32 設備,每個組件都承擔著特定的功能,共同實現整個系統的遠程控制能力。以下是各個組件的工作原理和它們之間如何交互: #### 1. LINE Bot LINE Bot 是用戶與系統交互的前端界面。用戶通過發送消息如 "turn_on" 或 "turn_off" 來控制設備。這些消息通過 LINE Messaging API 發送到 Glitch 伺服器。 - **接收消息**:當用戶在 LINE 應用上發送消息時,LINE 平台將這些消息以 Webhook 的形式推送到 Glitch 伺服器上的 `/callback` 路由。 - **處理消息**:Glitch 伺服器解析這些消息,並根據消息內容更新全局設備狀態字典 `device_status`。此字典記錄了設備的當前狀態(例如燈的開關狀態)。 #### 2. Glitch 伺服器 Glitch 伺服器扮演中心伺服器的角色,負責接收和處理來自 LINE Bot 的指令,同時也為 ESP32 提供一個查詢當前設備狀態的 API。 - **狀態管理**:伺服器根據從 LINE Bot 接收到的指令更新內部狀態,這些狀態存儲在 `device_status` 字典中。 - **提供狀態信息**:`/esp32/command` 路由允許 ESP32 定期查詢設備的最新狀態,確保設備行為與用戶指令同步。 #### 3. ESP32 設備 ESP32 是實際執行物理操作的組件。它定期向 Glitch 伺服器請求最新的設備狀態,並據此控制連接的硬體(如燈光)。 - **定期查詢**:ESP32 通過 HTTP GET 請求訪問 Glitch 伺服器的 `/esp32/command` 路由,獲取最新的設備狀態信息。 - **執行操作**:根據獲取的狀態信息,ESP32 會控制其 GPIO 端口連接的電器,如開關燈。 #### 整合原理 這個系統通過網路連接實現各組件之間的通信。用戶通過 LINE Bot 發送控制指令,Glitch 伺服器處理這些指令並更新設備狀態,ESP32 則實時檢查這些狀態並執行相應的物理操作。這種設計使得系統可以靈活地擴展到更多設備和功能,同時保持簡單和易於管理。