Nginx+Mariadb+PHP+Python

雖然透過ThingSpeak呈現溫濕度圖表非常的方便,只要註冊申請帳號,透過api傳送資料到ThingSpeak,就會自動把圖畫出來,但在一些特殊狀況下,如沒有對外的網路,那就沒有辦法把資料上傳到ThingSpeak,所以此篇在Raspberry Pi上建立Nginx+Mariadb,透過Python讀取DHT22溫濕度後把資料寫到Mariadb資料庫,然後讀取資料庫中的歷史資料,用python + bokeh + pandas產生圖表網頁,讓使用者可以連到本機的網站觀看目前Raspberry Pi的溫濕度狀況,如下圖…

目前把整個溫濕度所需要安裝的套件,設定的內容及程式原始碼,透過Ansible去處理,使用方式和moodlebox一樣,使用moodlebox的原始程式,修改成go38box,整個ansible的資料夾架構及設定方式與moodlebox相同,安裝方式請參考

網站架構

溫濕度網站的架構非常的簡單,就只是一般的網頁,此網頁樣版來自於https://templated.co/azure,只做小部分修改,在溫濕度圖的地方使用兩個iFrame把溫度與濕度的html嵌入到首頁中,然後固定時間會重新載入溫濕度的html檔,所以在整個網站顯示的部分沒什麼特別的程式,也沒有使用到php,會安裝php主要是因為使用phpmyadmin去管理設定資料庫

相關檔案

  • 網站路徑:/var/www/html/temperature

  • 首頁:index.html

  • 溫度:db_temp.html

  • 濕度:db_humidity.html

這邊要注意的部分為db_temp.html及db_humidity.html兩個檔案,此兩個檔案為link,來源為/home/go38box/DHT22/db_temp.html/home/go38box/DHT22/db_humidity.html,另外phpmyadmin也是用link的方式建立,來源為/usr/share/phpmyadmin,檔案清單如下:

go38box@go38box:/var/www/html/temperature $ ls -al
total 52
drwxrwxr-x 6 www-data www-data  4096 Apr 26 00:33 .
drwxr-xr-x 3 root     root      4096 Apr 26 00:33 ..
drwxrwxr-x 3 www-data www-data  4096 Apr 26 00:33 css
lrwxrwxrwx 1 root     root        36 Apr 26 00:33 db_humidity.html -> /home/go38box/DHT22/db_humidity.html
lrwxrwxrwx 1 root     root        32 Apr 26 00:33 db_temp.html -> /home/go38box/DHT22/db_temp.html
drwxrwxr-x 8 www-data www-data  4096 Apr 26 00:33 .git
drwxrwxr-x 2 www-data www-data  4096 Apr 26 00:33 images
-rw-rw-r-- 1 www-data www-data  2199 Apr 26 00:33 index.html
drwxrwxr-x 2 www-data www-data  4096 Apr 26 00:33 js
-rw-rw-r-- 1 www-data www-data 17128 Apr 26 00:33 LICENSE.txt
lrwxrwxrwx 1 root     root        21 Apr 26 00:33 phpmyadmin -> /usr/share/phpmyadmin
-rw-rw-r-- 1 www-data www-data    12 Apr 26 00:33 README.md
go38box@go38box:/var/www/html/temperature $

index.html HEAD

下方內容放在<head>內,主要功能為固定時間讓iframe重新載入來更新溫濕度,setInterval為設定多久執行一次,設定方式為(秒*1000),如下(60秒*1000),就是每分鐘重新載入一次

index.html BODY

下方內容放在<body>內,主要顯示溫濕度的html檔,有兩個<iframe>,name分別為iftemp及ifhumidity,這個名稱需要和<head>的設定相同

Nginx設定

設定檔「/etc/nginx/sites-available/default」,內容如下,主要修改了root,預設的網站根目錄為「/var/www/html」目前修改成「/var/www/html/temperature」,用ansible安裝是不需要再手動設定

資料庫

DHT22所讀取的溫濕度會寫到Raspberry PI本機中建立的mariadb資料庫中,可以透過下方的網址及帳號密碼登入觀看及設定

目前建立一個名稱為temperature的資料庫,裡面有3張資料表,欄位說明及結構如下

資料表 temp

temp儲存溫濕度的記錄,欄位說明如下:

  • datetime:資料的日期時間

  • temp:溫度,取到小數點第一位

  • humidity 濕度,取到小數點第一位

資料結構如下圖:

資料表 smtp

smtp資料表,存放有關寄送溫濕度異常E-MAIL的設定,此表中只會有一筆設定資料,如果要修改參數可以直接修改欄位內容即可

  • id:此id為key值,因為此資料表為設定用,所以只需要一筆資料,程式會讀取id=0的該筆資料當做設定值

  • hostname:網站網址,目前預設為 go38box.local

  • from_addr:寄件者E-MAIL,目前使用gmail當作smtp來寄送mail

  • to_addr:收件者E-MAIL

  • smtp_addr:gmail的smtp網址為 smtp.gmail.com

  • smtp_port:gmail的smtp port為 587

  • smtp_password:smtp的密碼,使用gmail當作smtp寄送mail,所以此密碼為from_addr 的E-MAIL密碼,目前此欄位有加密

  • send_time:最後一次寄送E-Mail的時間(程式會自動更新此欄位)

  • send_status:目前溫濕度狀態,1為異常、0為正常,此欄位請不要修改(程式會自動更新此欄位)

  • send_wait_time:每執行一次都會檢查是否異常,此欄位儲存單位是秒數,主要在溫濕度一直在異常狀態下不會重復的寄送,例如此欄位目前預設值為3600秒,也就是1小時,當送出一封異常E-MAIL後,會自動更新欄位中的send_time最後送出異常E-Mail的時間,每次執行會用目前的時間和send_time相減,看是否超過此欄位所設定的時間(1小時),如果超過則會再寄送一次異常E-MAIL

  • send_check_time:每執行一次都會檢查是否正常,此欄位儲存單位是秒數,如果上一次寄送異常E-MAIL的時間和目前時間相比是否大於所設定的send_check_time,大於的話才會切換為正常,必免溫濕度剛好在設定的邊界值跳動會一直送出異常與正常的E-MAIL,例如目前設定660,代表11分鐘內,不會寄送恢復正常的E-MAIL,如果超過,則會更新send_timesend_status設為0

資料表 config

  • id:此id為key值,因為此資料表為設定用,所以只需要一筆資料,程式會讀取id=0的該筆資料當做設定值

  • send_mail:此欄位主要設定是否要寄送E-MAIL,0(不寄送),1(寄送)

  • temp_max:設定溫度正常範圍的最高溫度,目前預設為30度

  • temp_min:設定溫度正常範圍的最低溫度,目前預設為10度

  • humidity_max:設定濕度正常範圍的最高濕度,目前預設為70%

  • humidity_min:設定濕度正常範圍的最低濕度,目前預設為40%

  • time_offset:當程式取得新的溫濕度後,會先抓資料庫中最後一筆資料回來做參考比對,檢查與最後一筆資料的時間是否超過time_offset的設定值,目前預設為100秒,如果與上一筆資料時間相差超過100秒,則會直接寫入資料庫,如果沒有超過,則會再比對目前溫濕度是否和最後一筆的溫濕度相差超過difference的設定值,如果超過也是不寫入資料庫中,主要就是去DHT22元件的異常值

  • difference:溫濕度的正負差,目前設定為5

  • thingspeak_key:如果有申請thingspeak,也想把資料上傳到thingspeak的話,註冊後會取得一組thingspeak_key,要上傳的話把key填入此欄位,如果不想上傳的話就清空此欄位,請參考文內的ThingSpeak 說明

Python 主程式

在開始前,請先閱讀開發環境及設備取得溫濕度 這兩個章節,確認溫濕度元件已接上RaspberryPi並且可以讀取到溫濕度

加解密程式

以下的程式主要是用在smtp資料表欄位「smtp_password」,注意裡面有一個變數key,下方測試是使用「1234A#CD」,而溫濕度程式在使用的是「@Go38Box」

以上程式執行結果

Last updated

Was this helpful?