透過 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 目錄中:

  1. web_sensor.py:包含 Bottle 伺服器的 Python 程式碼。
  2. main.html:網頁的 HTML 程式碼。
  3. style.css:網頁的 CSS 樣式表。
  4. 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函式庫來顯示溫度計,並定義了兩個函式:callbackgetReadingcallback函式用於處理從/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/(如果是在其他電腦)。

建立工作流程

建立工作流程的步驟如下:

  1. 開啟Node-RED編輯器,滾動到節點列表的底部,找到Raspberry Pi節點。
  2. 將「rpi gpio」節點拖到編輯區域,雙擊它以組態GPIO引腳。
  3. 選擇要使用的GPIO引腳(例如GPIO 25),然後點選「Done」。
  4. 將另一個「rpi gpio」節點拖到編輯區域,雙擊它以組態另一個GPIO引腳。
  5. 選擇要使用的GPIO引腳(例如GPIO 18),然後點選「Done」。
  6. 將兩個節點連線起來,以建立工作流程。

新增推文節點

要新增推文節點,需要:

  1. 找到推文節點,將其拖到編輯區域。
  2. 雙擊推文節點,以組態Twitter憑據。
  3. 將推文節點連線到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,請按照以下步驟:

  1. 登入您的 IFTTT 帳戶。
  2. 點選「Create an Applet」按鈕。
  3. 選擇 Webhooks 通道作為觸發器(THIS)。
  4. 選擇「Receive a web request」作為觸發器。
  5. 輸入事件名稱(例如「cpu_too_hot」)。
  6. 選擇 Email 通道作為動作(THAT)。
  7. 選擇「Send me an email」作為動作。
  8. 設定電子郵件主題和內容,使用特殊值 OccurredAt 和 Value1 作為變數。

取得 API 金鑰

要取得 API 金鑰,請按照以下步驟:

  1. 登入您的 IFTTT 帳戶。
  2. 點選 Services 標籤。
  3. 找到 Webhooks 並點選它。
  4. 點選 Documentation 標籤。
  5. 在此頁面上,您可以看到您的 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)

解釋

  1. 程式首先設定 IFTTT 事件和金鑰,以及最大溫度和通知間隔。
  2. get_cpu_temp 函式使用 os.popen 命令取得 CPU 溫度。
  3. send_notification 函式構建 IFTTT 通知 URL,並使用 requests 函式庫送出通知。
  4. 主迴圈不斷檢查 CPU 溫度,如果溫度超過最大值,則觸發通知並開始長時間睡眠,以防止通知過於頻繁。

注意

  • 請將 YOUR_IFTTT_KEY 替換為您的 IFTTT 金鑰。
  • 可以根據需要調整 MAX_TEMPMIN_T_BETWEEN_WARNINGS 的值。
  • 本程式使用 IFTTT 的 Maker 通道,請確保您已經設定好了相關的事件和動作。

Raspberry Pi 在物聯網應用開發中扮演著重要角色,本文涵蓋了從基礎的LED控制到進階的感測器資料採集與 IFTTT 通知等多種應用場景。透過多維比較分析,我們可以看到,使用 Python 結合 Bottle 框架可以快速構建網頁應用,實作遠端監控和控制;Node-RED 則提供了更直觀的視覺化程式設計方式,降低了開發門檻。然而,這些方案也存在一定的技術限制,例如 Bottle 框架的效能瓶頸以及 Node-RED 在複雜邏輯處理上的不足。整合價值分析顯示,結合不同工具和技術可以充分發揮各自優勢,例如使用 Bottle 框架提供網頁介面,並利用 IFTTT 整合各種網路服務,實作更豐富的功能。展望未來,隨著邊緣運算的興起,Raspberry Pi 等低功耗裝置將在物聯網領域扮演更重要的角色。玄貓認為,掌握這些技術對於構建更具智慧和互動性的物聯網應用至關重要。