在夏天最不希望遇到的事,就屬於一打開家門,熱烘烘的風就吹到臉上。我一直想要有智慧家電,讓我能再回到家前就打開冷氣機,不過換新的冷氣機實在是太貴了。不如自己動手做,Raspberry Pi 板子還是比新冷氣機便宜。不過現在市面上已經產品可以遙控不同品牌的冷氣機,而且價格在3000 NTD以下,所以要動手做之前還是要考量時間成本。不過老話一句,自己做帶來的成就感是無價的 ??
_______________________________________________________________________________
用Raspberry Pi 去遙控冷氣其實不難,但是如果很多東西都是第一次碰的話,就會花很多時間去評估使用哪種方法。這篇我會列出步驟,還有我曾經遇的問題。這樣想要自己做的人,就可以事先避免浪費時間。
先偷看我做的陽春 iPhone App 介面長怎麼樣。這樣心裡才會有底。
很好,只有幾個功能:讀溫濕度、開機、設定溫度。
你一定會想這簡直就是爛爆了,做得這麼殘缺,居然沒有暖氣、除濕這些常見的功能...
不是我不想做,是因為我的Sampo冷氣遙控器是一次送出所有的設定。舉例來說,當我按下溫度下降的按鈕,送出的指令卻是 "冷氣 + 27度 + 風扇上下擺動 + 空氣清淨 "。因為沒有官方文件,我花了一下午還是無法分離各功能的波形。這是我做之前沒有想到的問題,所以最後才做閹割版本。
_______________________________________________________________________________
實作示意圖:
_______________________________________________________________________________
實作需要的設備:
- Raspberry Pi 2 B 板子
- 溫濕度計 DHT 22
- 良興有賣,如果熟悉GPIO的連線位置的話,15分鐘內可以完成
- 我使用Adafruit提供的Python程式。不需要理解Python怎麼做,只要安裝後就可以直接用,不需要校正
- 設定方式 - DHT22 Raspberry Pi Humidity Temperature Sensor Tutorial
- 紅外線模組
- 可以自己買零件組,但是因為我是第一次使用,為了保險,我從良興買模組
- 接收模組有LED燈,如果收到訊號就會閃,可以幫助除錯
- 良興上賣的發射器模組,功率太低,傳送聚集不到兩公尺。後來還是等要自己買零件兜起來(BJT型號為2N3904,價格不到10NTD),可以參考這篇文章 - 自製主動式紅外線遙控發射器
- 雖然發射模組很爛,但還是建議買一個,可以幫助除錯
- 接收程式可以下載網路的程式,或是用Linux提供的程式 LIRC。雖然我是使用LIRC,但設定方式很不方便。如果遇到像Sampo這樣的冷氣機,不按照一般LIRC格式,所以會發生錄失敗。這時候就得改用LIRC Raw模式去錄製。
- 一般設定方式請參考這篇 - Raspberry Pi + LIRC 紅外線遙控實做
- 固定IP 或是 有網址的伺服器
- 為了讓手機可以控制冷氣機,需要額外的機器接收手機的指令,接著這台機器再轉送指令到 RaspberryPi
- 我是用Amazon AWS 機器。他有免費方案,可以使用
_______________________________________________________________________________
當硬體都設定好了,就差 RaspberryPi 端要打 SSH Tunnel的指令。
先在RaspberryPi 建立 createTunnel.sh,然後替換底下的變數
- ADDR_AWS: server位置
- AWS_ID_FILE: RaspberryPi 連線到AWS server的密碼檔案位置
- AWS_UID: AWS server端的登入ID
- PI_UID: RaspberryPi的登入ID
#!/bin/bash
PORT_PI=19922
PORT_AWS=10022
ADDR_AWS="xxxxxxx.ap-northeast-1.compute.amazonaws.com"
AWS_ID_FILE="/home/pi/bash_shell/EC2Key.pem"
AWS_UID="ec2-user"
PI_UID="pi"
createTunnel(){
/usr/bin/ssh -f -N -R $PORT_AWS:localhost:22 -L $PORT_PI:$ADDR_AWS:22 $ADDR_AWS -i $AWS_ID_FILE -l $AWS_UID
if [[ $? -eq 0 ]]; then
echo Tunnel to AWS created successfully
else
echo An error occured creating a tunnel to AWS. Return code: $?
fi
}
closeTunnel(){
#get pid of tunnel
PIDS=`ps aux | grep ssh | grep $PORT_AWS | grep ec2-user | awk {'print $2'}`
if [[ -n $PIDS ]]; then
for pid in $PIDS; do
#echo $pid
sudo kill -9 $pid
done
fi
}
/usr/bin/ssh -p $PORT_PI localhost -i $AWS_ID_FILE -l $AWS_UID ssh $PI_UID@localhost -p $PORT_AWS ls > /dev/null
if [[ $? -ne 0 ]]; then
echo Creating new tunnel connection to AWS
closeTunnel
sleep 5
createTunnel
fi
當tunnel斷線時,可能5分鐘之內都還無法再度連線,所以最少有5個連線需要再等待server回覆。一旦server有能力接受tunnel時,RaspberryPi就會有5個連線,這樣會拖垮效能。解決方式就是使用flock指令,保證只會有一個連線需求。建立 createTunnelLock.sh 來將lock加入。這個script需要指定上面所寫的 createTunnel.sh 的位置,把他填入shell_script的變數內就可以了
!/bin/bash
lock_file=/tmp/lock.create_ssh_tunnel
shell_script=/home/pi/bash_shell/createTunnel.sh
echo "befor critical section"
# lock the file handle; this part will block
(
flock -n 200 || exit 1
$shell_script
) 200>$lock_file # open a file handle; this part will always succeed
echo "after critcal section"
一旦建立SSH tunnel後,server就可以對 RaspberryPi下指令,甚至是重新啟動 RaspberryPi,所以控制冷氣也當然能辦到。剩下的就是使用JSON格式的指令,將開關冷氣的命令從手機傳送到AWS server ,讓server解讀完後,透過SSH tunnel去控制,這個步驟是比較直觀的,我就先不提了。至於HTTPS得設定,AWS有提供硬體解SSL的功能,可以參考文件去設定。當這些都設定完後,就是寫 iOS了,因為UI設計實在是看人喜好,我就不提了。簡單的測試可以先用 XCode的playground 上面執行,對於除錯會有很大的幫助。