自己動手實現智慧家居之溫溼度資料採集儲存(DHT11,MySql)
【前言】
一個熱愛技術的人一定向往有一個科技感十足的環境吧,那何不親自實踐一下屬於技術人的座右銘:“技術改變世界”。
就讓我們一步步動手搭建一個屬於自己的“智慧家居平臺”吧(不要對這個名詞擡槓啦,技術在手,怎麼設計實現因人而異),本文只做拋磚引玉,各路大神如果有更好的想法可以各顯神通,當然能在評論區留下更好的想法讓大家共同學習是再好不過啦。
在文章最後附有所有原始碼,有需要的可以自行下載,感謝Star~
【系列目錄】
- 樹莓派GPIO簡介(Python版)
- 溫溼度資料採集儲存(DHT11,MySql)
- 溫溼度數碼管展示(四位共陽數碼管)
- 構建App展示溫溼度報表(ApiCloud,Python Flask)
- 普通家用排插整合繼電器手工改造
- App遠端控制“自制智慧”排插
- 使用花生棒內網穿透實現外網訪問
- App遠端監控(攝像頭模組整合)
【本節概要】
上一節我們介紹了樹莓派以及樹莓派的GPIO的簡單使用,這一節基於上一節的知識點採集屋內的溫度和溼度資料,並且構建python指令碼將採集到的資料寫入到mysql資料庫持久化。
效果圖:
那麼接下來我們就一步步講解這個折騰的過程...
【硬體採購】
”某寶“購買一個DHT11模組,大概¥6,為了方便線路靈活連線,我們購買了麵包板和杜邦線若干。
硬體採購完畢,我們開始搞軟體部分~~~
【DHT11模組獲取溫溼度】
DHT11硬體介面
DHT11有三個IO介面,一個VCC(正極)接3.3v,一個GND接GND,剩下一個DATA接樹莓派的任意一個GPIO。在裝置上有印刷的字型標明瞭引腳,可以根據指示接到樹莓派上。
使用開源類庫Adafruit_DHT獲取溫溼度
讀取溫度和溼度我們可以使用已經封裝好的開源庫:Adafruit_DHT
import Adafruit_DHT
# Use read_retry method. This will retry up to 15 times to
# get a sensor reading (waiting 2 seconds between each retry).
# this is bcm code
humidity, temperature = Adafruit_DHT.read_retry(Adafruit_DHT.DHT11, 4)
構建資料儲存部分
為了便於我們讀寫MySql,我們需要一個 MySqlHelper.py,內容如下:
# coding=utf-8
import pymysql
from Utility.Configs import Cfg_MySql
class MySqlHelper:
conn = None
def __init__(self, db):
cfg_mysql = Cfg_MySql()
self.conn = pymysql.connect(host=cfg_mysql.get('host'), port=int(cfg_mysql.get('port')), user=cfg_mysql.get('user'), passwd=cfg_mysql.get('passwd'), db=db)
def getConnAndCur(self):
return self.conn,self.conn.cursor()
def executeSql(self,sql):
conn,cur = self.getConnAndCur()
cur.execute(sql)
conn.commit()
cur.close()
conn.close()
# 用完記得釋放
# cur.close()
# conn.close()
mysql的連線資訊是通過ini配置檔案儲存的,我們還需要一個 Configs.py 讀寫配置檔案,內容如下:
# coding=utf-8
import configparser
# 樹莓派的ubuntu系統裡面如果要使用計劃任務,則必須寫成絕對路徑,意味著這裡需要加字首
# RASPBERRY_PI_PATH = '/7tniy/SevenTiny.SmartHome'
# Windows除錯不需要加絕對路徑
RASPBERRY_PI_PATH_ROOT = ''
# get configuration
config = configparser.ConfigParser()
config.read(RASPBERRY_PI_PATH_ROOT + 'SmartHome.ini',encoding='UTF-8')
class Cfg_MySql:
__tag = 'MySql'
def __init__(self):
pass
def get(self, name):
return config.get(self.__tag, name)
我們的配置檔案 SmartHome.ini 放在專案根目錄即可。內容如下:
[MySql]
connectionstring = 1
host = 192.168.0.1
port = 3306
user = prod
passwd = 123456xxx
資料庫表結構:
/*
Navicat MySQL Data Transfer
Source Server :
Source Server Version : 50644
Source Host :
Source Database : SmartHome
Target Server Type : MYSQL
Target Server Version : 50644
File Encoding : 65001
Date: 2019-10-08 21:38:09
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for DailyMonitor
-- ----------------------------
DROP TABLE IF EXISTS `DailyMonitor`;
CREATE TABLE `DailyMonitor` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`DateTime` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP,
`Year` int(11) DEFAULT NULL,
`Month` int(11) DEFAULT NULL,
`Day` int(11) DEFAULT NULL,
`Hour` int(11) DEFAULT NULL,
`Temperature` double(255,0) DEFAULT NULL,
`Humidity` double(255,0) DEFAULT NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=1211 DEFAULT CHARSET=utf8;
主監控指令碼 SmartHomeScreen.py 內容
- 建立mysql連線
- 通過DHT11獲取溫溼度
- 將資料非同步寫入MySql(每小時一次)
# coding=utf-8
from Utility.MySqlHelper import MySqlHelper
import _thread
import Adafruit_DHT
import time
import datetime
import RPi.GPIO as GPIO
import sys
sys.path.append('..')
def WriteToDb(timenow, year, month, day, hour, temp, humi):
smartHomeDb = MySqlHelper("SmartHome")
smartHomeDb.executeSql("INSERT INTO DailyMonitor (DateTime,Year,Month,Day,Hour,Temperature,Humidity) VALUES ('{0}',{1},{2},{3},{4},{5},{6})".format(
timenow, year, month, day, hour, temp, humi))
# 已經寫入資料庫的小時標識,插入資料的同時,修改為下一個小時,用於比較是否需要寫入
hasWriteToDbHour = datetime.datetime.now().hour
while(True):
# time
timenow = datetime.datetime.now()
# Use read_retry method. This will retry up to 15 times to
# get a sensor reading (waiting 2 seconds between each retry).
# this is bcm code
humidity, temperature = Adafruit_DHT.read_retry(Adafruit_DHT.DHT11, 4)
print('time:{0},humidity:{1}%,temperature:{2}*C'.format(
datetime.datetime.now(), humidity, temperature))
# 非同步將資料寫入mysql
if hasWriteToDbHour == timenow.hour:
_thread.start_new_thread(WriteToDb, (timenow, timenow.year,
timenow.month, timenow.day, timenow.hour, temperature, humidity))
if hasWriteToDbHour == 23:
hasWriteToDbHour = 0
else:
hasWriteToDbHour = hasWriteToDbHour + 1
time.sleep(2)
【溫溼度監控】
我們通過SSH遠端連線到樹莓派的終端
通過FTP將我們的專案上傳到樹莓派伺服器
採用後臺程序的方式執行我們的主指令碼(關閉終端程序不會退出)
nohup python SmartHomeScreen.py
這樣我們的資訊採集指令碼就一直在工作中了,每小時會採集一次溫溼度,並存儲到資料庫表中。
【注意事項】
- 樹莓派中預設安裝的python版本是2.7,我們的程式碼是採用python3編寫的,可能有不相容的情況,需要重新安裝python3.6以上版本
- 我們的GPIO類庫是不能在沒有GPIO支援的裝置上除錯的,也就是說在windows本地除錯毫無意義,並且安裝GPIO的包會出現各種問題,建議直接將程式碼複製到樹莓派除錯,無需在本地除錯
【總結】
通過本節內容,我們實現了利用樹莓派的GPIO和DHT11溫溼度採集模組24小時實時採集環境中的溫溼度,並且持久化到了MySql中,作為我們後續監控面板和監控報表的基礎資料。
後續章節我們會介紹利用我們採集的24小時溫溼度資料製作溫溼度報表... 效果預熱:
【原始碼地址】
Github:https://github.com/sevenTiny/SevenTiny.SmartH