自己動手實現智能家居之溫濕度數據採集存儲(DHT11,MySql)

  • 2019 年 10 月 9 日
  • 筆記

【前言】

一個熱愛技術的人一定嚮往有一個科技感十足的環境吧,那何不親自實踐一下屬於技術人的座右銘:「技術改變世界」。

就讓我們一步步動手搭建一個屬於自己的「智能家居平台」吧(不要對這個名詞抬杠啦,技術在手,怎麼設計實現因人而異),本文只做拋磚引玉,各路大神如果有更好的想法可以各顯神通,當然能在評論區留下更好的想法讓大家共同學習是再好不過啦。

在文章最後附有所有源代碼,有需要的可以自行下載,感謝Star~

【系列目錄】

  1. 樹莓派GPIO簡介(Python版)
  2. 溫濕度數據採集存儲(DHT11,MySql)
  3. 溫濕度數碼管展示(四位共陽數碼管)
  4. 構建App展示溫濕度報表(ApiCloud,Python Flask)
  5. 普通家用排插集成繼電器手工改造
  6. App遠程控制「自製智能」排插
  7. 使用花生棒內網穿透實現外網訪問
  8. App遠程監控(攝像頭模塊集成)

【本節概要】

上一節我們介紹了樹莓派以及樹莓派的GPIO的簡單使用,這一節基於上一節的知識點採集屋內的溫度和濕度數據,並且構建python腳本將採集到的數據寫入到mysql數據庫持久化。

效果圖:

那麼接下來我們就一步步講解這個折騰的過程…

【硬件採購】

」某寶「購買一個DHT11模塊,大概¥6,為了方便線路靈活連接,我們購買了麵包板和杜邦線若干。

DHT11

麵包板

杜邦線

硬件採購完畢,我們開始搞軟件部分~~~

【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 內容

  1. 創建mysql連接
  2. 通過DHT11獲取溫濕度
  3. 將數據異步寫入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遠程連接到樹莓派的終端

PI

通過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.SmartHome