本帖最后由 windgo 于 2018-1-8 11:06 编辑
請注意 這個功能要實現必須要懂一些程式概念
請務必都看懂文章了 再進行操作
2018/01/07更新程式碼,提昇搜尋結果效能
2018/01/08更新兩台掃描藍牙裝置的程式碼,請查看文章後段
大家好
之前有發過藍牙基站的介紹與使用方法
但必須要在手機上多開啟一個Owntracks APP
App的Enter事件反應很快
但是Leave事件大多要在5-10秒後才會反應
Enter/Leave的事件更新到MQTT server還必須要有網路
這都限制了一些使用場景
所以我開始尋找有沒有方法換個方式 在家裡搭建一個藍牙搜尋器
當搜尋到某個設備藍牙位址時,透過MQTT更新給HA主機去做自動化的判斷
我個人是拿來做門鎖開啟的功能 當藍牙搜尋到我的IPhone手機藍牙位址時
會推送訊息到手機上通知 並自動開啟門鎖 門關上後再透過自動化上鎖
這樣的安全性不高 但我家社區管理還不錯 所以我出門遛狗或買個東西時 自動開鎖對我很方便
大家可以去思考這樣的技術適合自己家裡怎樣的場景
前置軟硬體:
1.樹莓派或是Debian相關修改系統(如Docker,主要是要能安裝上bluez與bluepy)
2.擁有樹莓派3B的內建藍牙或USB藍牙,建議選擇藍牙4.0且支持BLE功能的購買
(本功能只需要藍牙即可,但BLE可以再支援更多種類的藍牙廣播設備)
3.安裝MQTT,使其能使用MQTT publish功能,更新設備狀態到HA主機上,可參考下面安裝教學
http://www.instructables.com/id/ ... to-on-Raspberry-Pi/
藍牙掃描操作步驟(有內建藍牙或是插上USB藍牙後,應該就可以使用以下指令):
1.檢查藍牙裝置狀態,必須為UP RUNNING
root@windgo_nas:~# sudo hciconfig
hci0: Type: BR/EDR Bus: USB
BD Address: 00:1A:7D:DA:71:11 ACL MTU: 310:10 SCO MTU: 64:8
UP RUNNING PSCAN
RX bytes:47175658 acl:114 sco:0 events:548541 errors:0
TX bytes:16278080 acl:48804 sco:0 commands:507109 errors:0
2.使用藍牙掃描功能(不包含使用藍牙BLE功能的設備),找到想搜尋的設備藍牙位址時,這當作Enter事件
如果要搜尋IPhone,必須把藍牙功能關閉再打開才能搜尋到
root@windgo_nas:~# sudo hcitool scan
Scanning ...
3C:BD:3E:5C:87:D7 AI-5880
00:9E:C8:83:A2:EA IPSTB
3.使用藍牙名稱查詢功能,這樣連scan搜尋不到的IPhone都可以有回應
如果沒回應表示設備已超出藍牙搜尋器掃描範圍,這當作Leave事件
root@windgo_nas:~# sudo hcitool name 3C:BD:3E:5C:87:D7
AI-5880
4.編輯一支shell script程式,自動執行上面步驟2與3的動作,並將結果透過MQTT更新給HA主機
請注意如果sleep的時間太短,會使得樹莓派一直在做藍牙搜尋的功能
個人測試會導致系統反應變很慢,所以請自行調整到適合的數值
程式運作邏輯如下
1.搜尋藍牙設備,有回應的話使用MQTT回報給HA數值enter,HA的sensor的狀態就會變為on
2.搜尋不到藍牙設備,等待2秒,再搜尋一次,還是沒回應的話才使用MQTT回報給HA數值enter,
HA的sensor的狀態就會變為off
3.休息2秒後,再重頭執行一次
touch check_iphone.sh
chmod 700 check_iphone.sh
nano check_iphone.sh
將下面6個變數的值修改為你要的
mac="80:BE:05:80:9A:39"
name="AI-5880"
MQTT_IP="192.168.31.184"
MQTT_SUB="/raspberry/iphone/windgo"
MQTT_PUBLISH_VALUE1="enter"
MQTT_PUBLISH_VALUE2="leave"
while [ i==0 ]
do
result="$(sudo hcitool name ${mac})"
if [ "${result}" == "${name}" ]; then
mosquitto_pub -d -h ${MQTT_IP} -t ${MQTT_SUB} -m ${MQTT_PUBLISH_VALUE1};
else
sleep 2;
result="$(sudo hcitool name ${mac})"
if [ "${result}" != "${name}" ]; then
mosquitto_pub -d -h ${MQTT_IP} -t ${MQTT_SUB} -m ${MQTT_PUBLISH_VALUE2};
else
mosquitto_pub -d -h ${MQTT_IP} -t ${MQTT_SUB} -m ${MQTT_PUBLISH_VALUE1};
fi
fi
sleep 2;
done
執行check_iphone.sh檢查結果是否正常
bash check_iphone.sh
程式執行都正常後,要一直讓他持續自動跑不中斷可用下面指令,如果系統操作會慢,請調大sleep的數字
nohup bash check_iphone.sh > /dev/null &
nohup 就算登出,程式還是會繼續執行
> /dev/null 不吐出系統log,畫面會比較乾淨,需要除錯的話請不要用此參數
& 背景執行程式,不影響繼續執行其他指令
想停止程式的話,可以參考以下作法:
搜尋程式執行的PID,會得到一串PID數字
ps -aux | grep check_iphone
透過PID砍掉程式,將上面得到PID數字kill
kill PID_number
5.修改HA的configuration.yaml
加入以下設定後重啟,請注意下面的參數需與上面程式所傳過來的數值要相同
binary_sensor:
- platform: mqtt
name: "windgoiphone_status"
state_topic: "/raspberry/iphone/windgo"
qos: 0
payload_on: "enter"
payload_off: "leave"
device_class: opening
6.設定完成,將要搜尋的藍牙設備開關藍牙功能來模擬
並檢查HA上的entity windgoiphone_status 狀態是否有跟著改變
如果要掃描多個藍牙裝置可以參考下面程式,但請注意這樣每個裝置被掃描到的時間會被拉長
(要等裝置2掃描完才會再掃裝置1)
再額外補充一個跟上面無關的藍牙BLE搜尋功能:
上面的作法只能做到搜尋藍牙設備是否在藍牙搜尋器的附近
而無法獲得使用BLE功能來廣播的藍牙設備,想抓到BLE藍牙設備的話,可以使用bluepy
並且可取得訊號強度來做多個藍牙搜尋器交叉計算的室內定位
讓我們來介紹一下如何bluepy安裝與使用
步驟(以樹莓派安裝最新版Hassbian和萝卜hassbian11.15的img為例,照著安裝上應該不會出現錯誤):
1.參考https://github.com/IanHarvey/bluepy網頁進行安裝
sudo apt-get install python-pip libglib2.0-dev
sudo pip install bluepy
2.使用blescan來獲得想搜尋的設備藍牙位址,包含詳細資料與dbm
pi@hassbian:~ $ sudo blescan
3.單獨只抓某個設備的藍牙位址,可獲得dbm資料
pi@hassbian:~ $ sudo blescan | grep ea:5a:75:29:6c:1c
Device (new): ea:5a:75:29:6c:1c (random), -75 dBm (not connectable)
4.編輯一個掃描BLE資料的程式,需python可執行,可調整為自己想抓或顯示的數值
touch ble.py
chmod 777 ble.py
nano ble.py
from bluepy.btle import Scanner, DefaultDelegate
class ScanDelegate(DefaultDelegate):
def __init__(self):
DefaultDelegate.__init__(self)
scanner = Scanner().withDelegate(ScanDelegate())
devices = scanner.scan(5.0)
for dev in devices:
print "Device %s (%s), RSSI=%d dB" % (dev.addr, dev.addrType, dev.rssi)
5.執行程式,獲得BLE設備的相關數值,可自行修改之前的程式來更新資訊到HA
sudo python ble.py
|