Last active 10 months ago

此系統使用 Raspberry Pi 讀取 DHT11 感測器的溫濕度資料,並根據溫度範圍控制 LED 燈號。資料會定時儲存至 MySQL 資料庫,並透過 schedule 套件自動執行。程式透過 Supervisor 設定為背景服務,確保持續執行並記錄日誌。

environment_db_setup.sql Raw
1CREATE DATABASE environment;
2
3USE environment;
4
5CREATE TABLE environment_data (
6 id INT AUTO_INCREMENT PRIMARY KEY,
7 humidity FLOAT NOT NULL,
8 temperature FLOAT NOT NULL,
9 recorded_at DATETIME DEFAULT CURRENT_TIMESTAMP
10);
11
sensor_monitor.py Raw
1import Adafruit_DHT
2import schedule
3import time
4from gpiozero import LED
5import pymysql.cursors
6from datetime import datetime
7import os
8import logging
9
10# 日誌設定
11logging.basicConfig(level=logging.INFO, filename='sensor.log',
12 format='%(asctime)s - %(levelname)s - %(message)s')
13
14# 資料庫設定
15DB_HOST = os.getenv('DB_HOST', '127.0.0.1') # 預設為本地端
16DB_USER = os.getenv('DB_USER', 'db_user') # 資料庫使用者名稱
17DB_PASSWORD = os.getenv('DB_PASSWORD', 'db_password') # 資料庫密碼
18DB_NAME = os.getenv('DB_NAME', 'environment') # 資料庫名稱
19
20# LED 腳位設定
21green_led = LED(17) # 綠燈
22yellow_led = LED(27) # 黃燈
23red_led = LED(22) # 紅燈
24
25# DHT11 感測器設定
26sensor = Adafruit_DHT.DHT11 # 感測器型號
27pin = 4 # 感測器連接的 GPIO 腳位
28
29
30# LED 控制函數
31def control_leds(temp):
32 green_led.on() if temp < 25.0 else green_led.off()
33 yellow_led.on() if 25.0 <= temp < 30.0 else yellow_led.off()
34 red_led.on() if temp >= 30.0 else red_led.off()
35
36
37# 定時執行的核心任務
38def job():
39 try:
40 # 讀取感測器數據
41 humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)
42 now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
43
44 if humidity is not None and temperature is not None:
45 logging.info(f"{now} - Temp: {temperature:.1f}°C, Humidity: {humidity:.1f}%")
46
47 # 儲存數據到資料庫
48 try:
49 connection = pymysql.connect(
50 host=DB_HOST,
51 user=DB_USER,
52 password=DB_PASSWORD,
53 db=DB_NAME,
54 charset='utf8mb4',
55 cursorclass=pymysql.cursors.DictCursor
56 )
57
58 with connection.cursor() as cursor:
59 sql = "INSERT INTO environment_data (humidity, temperature) VALUES (%s, %s)"
60 cursor.execute(sql, (humidity, temperature))
61 connection.commit()
62
63 except Exception as db_err:
64 logging.error(f"資料庫連線錯誤: {db_err}")
65 finally:
66 if 'connection' in locals():
67 connection.close()
68
69 # 控制 LED
70 control_leds(temperature)
71 else:
72 logging.warning("感測器讀取失敗,無法取得數據")
73
74 except Exception as e:
75 logging.error(f"執行任務時發生錯誤: {e}")
76
77
78# 排程設定,每 5 分鐘執行一次
79schedule.every(300).seconds.do(job)
80
81try:
82 while True:
83 schedule.run_pending()
84 time.sleep(1)
85except KeyboardInterrupt:
86 logging.info("程式已被使用者中斷")
87 green_led.off()
88 yellow_led.off()
89 red_led.off()
90
sensor_monitor_supervisor.conf Raw
1[program:sensor_monitor]
2command=/usr/bin/python3 /path/to/sensor_monitor.py
3directory=/path/to/
4autostart=true
5autorestart=true
6redirect_stderr=true
7stdout_logfile=/path/to/sensor_monitor.log
8