2016年5月7日 星期六

[Raspberry Pi]DHT11溫濕度模組 x Node.js = DHT11 Server


這次要來嘗試自DHT11取得的溫溼度資訊以網頁(Web)的形式公布,也就是HTML Server
最後要突破路由器的限制逆風高灰,讓任何的客戶端都能從網際網路連上伺服器,上面就寫著DHT11讀到的溫濕度資訊

整個架構概念如下:
  1. 將DHT11定時(1分鐘一次)讀出的溫濕度寫到某個檔案(th.out)裡
  2. 開啟一個HTML Server,在客戶端連入時,讀取th.out內的資訊,秀在主頁面上
  3. 為了能穿透路由器,讓客戶端能從網際網路連入,我們需要某種類似DDNS的穿牆服務
OK,戰鬥開始!第一步,將DHT11的讀出值定時寫入特定檔案

從先前的Adafruit提供的python程式,我們已經可以很輕鬆的讀出資訊顯示在Console上,只要再利用Bash Script做點小小加工就可以讓DHT11全天候運轉偵測溫濕度:

開啟新Script
#vim outputTh.sh
設定為可執行
#chmod u+x outputTh.sh

在Script寫下:
#!/bin/bash
while :
do
        date > th.out #先輸出當前時間
        $(./Adafruit_Python_DHT/examples/AdafruitDHT.py 11 4) >> th.out   #輸出DHT11資訊,注意相對路徑
        sleep 60 #在此暫停60秒

done

主要功能是開啟一個無限迴圈,每60秒讀出目前時間以及DHT11資訊,並輸出(覆蓋)th.out

執行此Script!(因為牽涉到底層存取,請給他sudo下去)
#sudo ./outputTh.sh

在此先做個確認,理論上輸出檔案內容應該會長這樣:
20160507 14:14:03
Temp=29.0*C  Humidity=62.0%

最後讓此Script在背景以nohup執行
$nohup sudo ./outputTh.sh &


第二步,設定DHT11 Server(HTML Server)

這裡選擇最好上手的Node.js,這是個整合的很好的伺服器端執行環境,可以把他想像成事件驅動架構,對開發者而言,只要搞懂各事件(Event)的發出時機,並且寫下相對應的處理常式(Event Handler)即可

首先是安裝Node.js
#sudo apt-get install -y nodejs

接著開啟一個Java Script:
#vim server.js

內容寫這樣:

var http = require("http")  '引入http模組

http.createServer(function(request,response){
 response.writeHead(200 , {"Content-type":"text/plain"});
 response.write(fs.readFileSync('./date.out'));
 response.end();

}).listen(8888);

以上Script要這樣解釋:


  1. 程式走到第三行時,會從http模組呼叫createServer函式
  2. createServer()引數1是客戶端連上時要做的回應動作,既然是一連串的動作所以是一個函式而不是變數,就是所謂的回呼啦(Call-back)
  3. 在這裡的回應動作是,讀出th.out的內容在主畫面上輸出
  4. 而createServer()會吐回一個伺服器物件,呼叫此物件的listen(),表示啟動監聽連入需求,這裡使用的監聽埠口為8888

值得一提的是,node.js的任何函式幾乎都有同步/非同步兩個版本,一開始使用了fs.readfile,(註:讀取檔案的非同步版本),結果實際讀取檔案的時機不見得在函式呼叫後,所以可能會在response.end()前都沒讀出buffer,常常以exception收場

所以這裡讀取檔案的函式必須要用同步呼叫(Blocking IO),即為fs.readFileSync()的return值就是讀出的字串

最後以Node.js啟動剛剛寫好的Script
#nodejs server.js

此時來做個小小測試,看看是否能在區域網路內看到網頁,開瀏覽器連上:
http://192.168.1.1:8888


好的,區域網路內連上DHT11 Server沒問題了,最後記得讓DHT11 Server登出後也能在背景執行:
$nohup nodejs server.js &


第三步,先別管DHT11 Server了,你聽過ngrok嗎?看看他們官網的圖示,他們就是有辦法讓你的伺服器暴露在路由器之外,

首先是安裝,在apt-get上沒有此套件,我們直接下載執行檔解壓縮即可

下載:
$wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip
解壓縮:
$unzip ngrok.zip

取得!接著的動作十分簡單,可以想像這個軟體做的動作就是左耳進右耳出,把封包轉送出/ngrok伺服器,啟動ngrok,引數打入:

$ngrok http 8888

意義就是以http協定轉接DHT11 Server監聽埠口(port:8888),嘿!逼哩八啦他還給你一個很神秘的網址,把他貼上瀏覽器就知道………哇!DHT11 Server走入人群了!


用手機從3G網路測試看看…嗯…沒問題!
以後回家前就可以先知道家裡溫濕度如何了(那又怎樣