透過 Python 和 Bottle 框架,我們可以輕鬆地建構網頁介面來控制連線到 Raspberry Pi 的 LED 燈。網頁介面上的按鈕點選會觸發 JavaScript 函式,進而向伺服器傳送請求,控制 LED 的開關狀態。此外,我們還能透過網頁介面顯示感測器讀數,例如 CPU 溫度,並利用 JavaScript 定期更新讀數,實作近乎即時的監控。為了更進一步的監控和通知,我們可以整合 IFTTT 服務,當感測器讀數超過預設閾值時,自動傳送通知到電子郵件或其他平臺。
使用Raspberry Pi控制LED燈
簡介
在本篇文章中,我們將探討如何使用Raspberry Pi控制LED燈。這個專案需要一些基本的電子元件和程式設計知識。
所需元件
- Raspberry Pi
- LED燈
- GPIO延伸板
- 電線
安裝bottle函式庫
首先,我們需要安裝bottle函式庫。這個函式庫提供了一個簡單的網頁伺服器,允許我們從網頁控制LED燈。安裝方法請參考安裝bottle函式庫。
程式碼
from bottle import route, run
from gpiozero import LED, Button
# 初始化LED燈和按鈕
leds = [LED(18), LED(23), LED(24)]
switch = Button(25)
# 定義一個函式來取得按鈕的狀態
def switch_status():
if switch.is_pressed:
return 'Down'
else:
return 'Up'
# 定義一個函式來生成LED燈的HTML程式碼
def html_for_led(led_number):
i = str(led_number)
result = " <input type='button' onClick='changed(" + i + ")' value='LED " + i + "'/>"
return result
# 定義路由
@route('/')
@route('/<led_number>')
def index(led_number="n"):
if led_number!= "n":
leds[int(led_number)].toggle()
response = "<script>"
response += "function changed(led)"
response += "{"
內容解密:
上述程式碼定義了一個簡單的網頁伺服器,允許我們從網頁控制LED燈。switch_status
函式用於取得按鈕的狀態,html_for_led
函式用於生成LED燈的HTML程式碼。index
函式定義了路由,當網頁接收到請求時,會執行相應的動作。
Mermaid圖表
flowchart TD A[開始] --> B[初始化LED燈和按鈕] B --> C[定義路由] C --> D[執行路由] D --> E[控制LED燈]
圖表翻譯:
上述Mermaid圖表展示了程式碼的執行流程。首先,初始化LED燈和按鈕,然後定義路由,當網頁接收到請求時,會執行相應的動作,最終控制LED燈。
網頁控制GPIO的工作原理
要了解網頁控制GPIO的工作原理,我們需要先了解網頁介面的工作原理。所有網頁介面都依賴於伺服器(在這個例子中,是一個在樹莓派上執行的程式)對網頁瀏覽器的請求做出回應。當伺服器收到請求時,它會根據請求中的資訊生成一些超文字標記語言(HTML)作為回應。
如果網頁請求只是存取根頁面(例如,我的樹莓派的根頁面URL結尾是/
),則伺服器會生成一個包含JavaScript函式的HTML頁面。這個JavaScript函式會在瀏覽器執行,並導致頁面重新載入,附帶適當的引數。
JavaScript函式的生成
以下是生成JavaScript函式的程式碼:
response = "<script>"
response += "function changed(led)"
response += "{"
response += " window.location.href='/' + led"
response += "}"
response += "</script>"
這個JavaScript函式會在瀏覽器執行,並導致頁面重新載入,附帶適當的引數。
HTML的生成
我們需要生成HTML,當按鈕被按下時,會呼叫這個JavaScript函式。為了避免重複生成HTML,我們可以使用一個函式來生成HTML:
def html_for_led(led_number):
# 生成HTML
html = "<button onclick='changed(" + str(led_number) + ")'>LED " + str(led_number) + "</button>"
return html
這個函式會生成一個按鈕的HTML,當按鈕被按下時,會呼叫JavaScript函式changed()
,並傳遞LED的編號作為引數。
程式的執行
以下是完整的程式碼:
response = ""
response += "<h1>GPIO Control</h1>"
response += "<h2>Button=" + switch_status() + "</h2>"
response += "<h2>LEDs</h2>"
response += html_for_led(0)
response += html_for_led(1)
response += html_for_led(2)
return response
run(host='0.0.0.0', port=80)
這個程式碼會生成一個網頁介面,允許使用者控制樹莓派上的LED。
圖表翻譯:
graph LR A[使用者請求] --> B[伺服器回應] B --> C[生成HTML] C --> D[JavaScript函式] D --> E[頁面重新載入] E --> F[LED控制]
這個圖表展示了網頁控制GPIO的工作原理。使用者請求導致伺服器回應,伺服器回應生成HTML,HTML包含JavaScript函式,JavaScript函式導致頁面重新載入,頁面重新載入附帶適當的引數,最終導致LED控制。
顯示感測器讀數於網頁
問題描述
您想要在網頁上顯示來自 Raspberry Pi 的感測器讀數,並自動更新顯示。
解決方案
使用 Bottle 網頁伺服器和 JavaScript,實作自動更新感測器讀數的顯示。以下範例(如圖 16-4 所示)展示瞭如何顯示 Raspberry Pi 的 CPU 溫度,利用其內建的感測器。
安裝 Bottle 函式庫
請參考配方 7.17 來安裝 Bottle 函式庫。
範例檔案
本範例包含四個檔案,均位於 ch_16_web_sensor
目錄中:
- web_sensor.py:包含 Bottle 伺服器的 Python 程式碼。
- main.html:網頁的 HTML 程式碼。
- style.css:網頁的 CSS 樣式表。
- script.js:網頁的 JavaScript 程式碼。
HTML 程式碼生成
以下是用於生成 LED 按鈕的 HTML 程式碼:
def html_for_led(led):
i = str(led)
result = " <input type='button' onClick='changed(" + i + ")' value ='LED " + i + "'/>"
return result
此程式碼用於為每個按鈕生成 HTML,並連線按鈕按下事件與 changed
函式,同時傳遞 LED 編號作為引數。
報告按鈕狀態
程式會檢查按鈕是否被按下,並報告適當的 HTML。
相關資訊
欲瞭解更多關於使用 Bottle 的資訊,請參考 Bottle 檔案。
顯示感測器讀數
以下是顯示感測器讀數的範例程式碼:
import bottle
from bottle import route, run
@route('/')
def index():
return '感測器讀數:' + get_sensor_reading()
def get_sensor_reading():
# 此處實際取得感測器讀數的程式碼
return '30 度'
run(host='localhost', port=8080)
此範例使用 Bottle 伺服器顯示感測器讀數。當使用者存取網頁時,伺服器會呼叫 get_sensor_reading
函式取得感測器讀數,並將其顯示在網頁上。
自動更新顯示
為了實作自動更新顯示,可以使用 JavaScript 定期向伺服器傳送請求,取得最新的感測器讀數,並更新網頁上的顯示。
setInterval(function() {
fetch('/get_reading')
.then(response => response.text())
.then(reading => {
document.getElementById('reading').innerHTML = reading;
});
}, 1000);
此 JavaScript 程式碼每隔一秒鐘向 /get_reading
端點傳送請求,取得最新的感測器讀數,並更新網頁上的 #reading
元素內容。
結合所有程式碼
以下是完整的範例程式碼:
import bottle
from bottle import route, run
@route('/')
def index():
return '感測器讀數:' + get_sensor_reading()
@route('/get_reading')
def get_reading():
return get_sensor_reading()
def get_sensor_reading():
# 此處實際取得感測器讀數的程式碼
return '30 度'
run(host='localhost', port=8080)
<!DOCTYPE html>
<html>
<head>
<title>感測器讀數</title>
<script>
setInterval(function() {
fetch('/get_reading')
.then(response => response.text())
.then(reading => {
document.getElementById('reading').innerHTML = reading;
});
}, 1000);
</script>
</head>
<body>
<h1>感測器讀數</h1>
<p id="reading"></p>
</body>
</html>
此範例展示瞭如何使用 Bottle 伺服器和 JavaScript 自動更新網頁上的感測器讀數。
使用Raspberry Pi和Bottle框架建立網頁溫度計
介紹
本文將介紹如何使用Raspberry Pi和Bottle框架建立一個網頁溫度計。這個網頁溫度計可以顯示Raspberry Pi的CPU溫度,並使用JustGage函式庫來顯示溫度計。
所需元件
- Raspberry Pi
- Bottle框架
- JustGage函式庫
- Raphael函式庫
安裝和設定
首先,需要安裝Bottle框架和JustGage函式庫。可以使用以下命令安裝:
sudo pip install bottle
然後,下載JustGage函式庫和Raphael函式庫,並將其放在Raspberry Pi的目錄中。
程式碼
以下是主程式web_sensor.py
的程式碼:
import os, time
from bottle import route, run, template
def cpu_temp():
dev = os.popen('/opt/vc/bin/vcgencmd measure_temp')
cpu_temp = dev.read()[5:-3]
return cpu_temp
@route('/temp')
def temp():
return cpu_temp()
@route('/')
def index():
return template('main.html')
@route('/raphael')
def index():
return template('raphael.2.1.0.min.js')
@route('/justgage')
def index():
return template('justgage.1.0.1.min.js')
run(host='0.0.0.0', port=80)
這個程式碼定義了四個路由:/temp
、/
、/raphael
和/justgage
。/temp
路由傳回CPU溫度,/
路由傳回主HTML範本,/raphael
和/justgage
路由傳回Raphael和JustGage函式庫的程式碼。
主HTML範本
以下是main.html
的程式碼:
<html>
<head>
<script src="raphael"></script>
<script src="justgage"></script>
<script>
function callback(tempStr, status){
if (status == "success") {
temp = parseFloat(tempStr).toFixed(2);
g.refresh(temp);
setTimeout(getReading, 1000);
} else {
alert("There was a problem");
}
}
function getReading(){
$.get('/temp', callback);
}
</script>
</head>
<body>
<div id="gauge" class="200x160px"></div>
<script>
var g = new JustGage({
id: "gauge",
value: 0,
min: 10,
max: 60,
title: "CPU Temp 'C"
});
</script>
</body>
</html>
這個HTML範本包含了JavaScript程式碼,使用JustGage函式庫來顯示溫度計,並定義了兩個函式:callback
和getReading
。callback
函式用於處理從/temp
路由傳回的溫度值,getReading
函式用於傳送請求到/temp
路由。
執行
可以使用以下命令執行程式:
sudo python web_sensor.py
然後,開啟瀏覽器,輸入Raspberry Pi的IP地址,即可看到網頁溫度計。
使用Node-RED進行IoT工作流程的設計
Node-RED是一個根據節點的視覺化程式設計工具,允許使用者透過拖拽和連線節點來建立工作流程。這個工具在Raspbian系統中預裝,可以用來建立簡單的IoT工作流程,例如當按鈕被按下時傳送推文。
啟動Node-RED伺服器
要啟動Node-RED伺服器,需要執行以下命令:
$ node-red-pi --max-old-space-size=256
然後,透過瀏覽器連線到伺服器的URL:http://127.0.0.1:1880/(如果是在Raspberry Pi本身)或http://<Raspberry Pi的IP地址>:1880/(如果是在其他電腦)。
建立工作流程
建立工作流程的步驟如下:
- 開啟Node-RED編輯器,滾動到節點列表的底部,找到Raspberry Pi節點。
- 將「rpi gpio」節點拖到編輯區域,雙擊它以組態GPIO引腳。
- 選擇要使用的GPIO引腳(例如GPIO 25),然後點選「Done」。
- 將另一個「rpi gpio」節點拖到編輯區域,雙擊它以組態另一個GPIO引腳。
- 選擇要使用的GPIO引腳(例如GPIO 18),然後點選「Done」。
- 將兩個節點連線起來,以建立工作流程。
新增推文節點
要新增推文節點,需要:
- 找到推文節點,將其拖到編輯區域。
- 雙擊推文節點,以組態Twitter憑據。
- 將推文節點連線到GPIO節點,以建立工作流程。
自動啟動Node-RED
要自動啟動Node-RED伺服器,需要執行以下命令:
$ sudo systemctl enable nodered.service
這樣,Node-RED伺服器就會在Raspberry Pi啟動時自動啟動。
使用 IFTTT 傳送通知
您想要在 Raspberry Pi 上實作一個靈活的通知系統,可以透過電子郵件、Facebook、Twitter 或 Slack 傳送通知。這個系統可以使用 If This Then That (IFTTT) Maker 通道來觸發可組態的通知。
建立 IFTTT 帳戶
在開始使用 IFTTT 之前,您需要建立一個 IFTTT 帳戶。這個帳戶將允許您建立和管理 Applet,從而觸發不同的通知。
建立 IFTTT Applet
要建立一個 IFTTT Applet,請按照以下步驟:
- 登入您的 IFTTT 帳戶。
- 點選「Create an Applet」按鈕。
- 選擇 Webhooks 通道作為觸發器(THIS)。
- 選擇「Receive a web request」作為觸發器。
- 輸入事件名稱(例如「cpu_too_hot」)。
- 選擇 Email 通道作為動作(THAT)。
- 選擇「Send me an email」作為動作。
- 設定電子郵件主題和內容,使用特殊值 OccurredAt 和 Value1 作為變數。
取得 API 金鑰
要取得 API 金鑰,請按照以下步驟:
- 登入您的 IFTTT 帳戶。
- 點選 Services 標籤。
- 找到 Webhooks 並點選它。
- 點選 Documentation 標籤。
- 在此頁面上,您可以看到您的 API 金鑰。
Python 程式
以下是 Python 程式 ch_16_ifttt_cpu_temp.py
,用於傳送 Web 請求:
import time, os
import requests
MAX_TEMP = 37.0
MIN_T_BETWEEN_WARNINGS = 60 # 分鐘
EVENT = 'cpu_too_hot'
KEY = 'your_key_here'
def send_notification(temp):
data = {'value1': temp}
#...
請注意,您需要將 KEY
變數替換為您的實際 API 金鑰。
內容解密:
MAX_TEMP
變數設定了 CPU 溫度的最大值。MIN_T_BETWEEN_WARNINGS
變數設定了兩次警告之間的最小時間間隔(以分鐘為單位)。EVENT
變數設定了 IFTTT 事件的名稱。KEY
變數設定了您的 IFTTT API 金鑰。send_notification
函式用於傳送 Web 請求,觸發 IFTTT 通知。
圖表翻譯:
flowchart TD A[開始] --> B[檢查 CPU 溫度] B --> C{溫度超過 MAX_TEMP?} C -->|是| D[傳送通知] C -->|否| E[等待 MIN_T_BETWEEN_WARNINGS 分鐘] E --> B D --> F[觸發 IFTTT 事件] F --> G[傳送電子郵件]
此圖表展示了程式的邏輯流程:檢查 CPU 溫度,如果超過最大值,則傳送通知,否則等待一段時間後再次檢查。
監控 CPU 溫度並觸發 IFTTT 通知
以下程式碼示範如何使用 Python 監控 CPU 溫度,並當溫度超過設定的最大值時,觸發 IFTTT 通知。
程式碼
import os
import requests
import time
# 設定 IFTTT 事件和金鑰
BASE_URL = "https://maker.ifttt.com/trigger/"
EVENT = "cpu_temp_warning"
KEY = "YOUR_IFTTT_KEY"
# 設定最大溫度和通知間隔
MAX_TEMP = 60 # 改為您想要的溫度閾值
MIN_T_BETWEEN_WARNINGS = 10 # 分鐘
def get_cpu_temp():
"""取得 CPU 溫度"""
dev = os.popen('/opt/vc/bin/vcgencmd measure_temp')
cpu_temp = dev.read()[5:-3]
return float(cpu_temp)
def send_notification(temp):
"""送出 IFTTT 通知"""
url = BASE_URL + EVENT + '/with/key/' + KEY
data = {"value1": temp}
response = requests.post(url, json=data)
print("通知已送出,狀態碼:", response.status_code)
while True:
temp = get_cpu_temp()
print("CPU 溫度 (C):", temp)
if temp > MAX_TEMP:
print("CPU 太熱了!")
send_notification(temp)
print("不會再送出通知,直到", MIN_T_BETWEEN_WARNINGS, "分鐘後")
time.sleep(MIN_T_BETWEEN_WARNINGS * 60)
time.sleep(1)
解釋
- 程式首先設定 IFTTT 事件和金鑰,以及最大溫度和通知間隔。
get_cpu_temp
函式使用os.popen
命令取得 CPU 溫度。send_notification
函式構建 IFTTT 通知 URL,並使用requests
函式庫送出通知。- 主迴圈不斷檢查 CPU 溫度,如果溫度超過最大值,則觸發通知並開始長時間睡眠,以防止通知過於頻繁。
注意
- 請將
YOUR_IFTTT_KEY
替換為您的 IFTTT 金鑰。 - 可以根據需要調整
MAX_TEMP
和MIN_T_BETWEEN_WARNINGS
的值。 - 本程式使用 IFTTT 的 Maker 通道,請確保您已經設定好了相關的事件和動作。
Raspberry Pi 在物聯網應用開發中扮演著重要角色,本文涵蓋了從基礎的LED控制到進階的感測器資料採集與 IFTTT 通知等多種應用場景。透過多維比較分析,我們可以看到,使用 Python 結合 Bottle 框架可以快速構建網頁應用,實作遠端監控和控制;Node-RED 則提供了更直觀的視覺化程式設計方式,降低了開發門檻。然而,這些方案也存在一定的技術限制,例如 Bottle 框架的效能瓶頸以及 Node-RED 在複雜邏輯處理上的不足。整合價值分析顯示,結合不同工具和技術可以充分發揮各自優勢,例如使用 Bottle 框架提供網頁介面,並利用 IFTTT 整合各種網路服務,實作更豐富的功能。展望未來,隨著邊緣運算的興起,Raspberry Pi 等低功耗裝置將在物聯網領域扮演更重要的角色。玄貓認為,掌握這些技術對於構建更具智慧和互動性的物聯網應用至關重要。