『瀚思彼岸』» 智能家居技术论坛

 找回密码
 立即注册
查看: 21763|回复: 61

[经验分享] 自己寫個藍牙搜尋器檢查是否進入某區域並更新到HA

  [复制链接]

27

主题

387

帖子

3103

积分

元老级技术达人

积分
3103
金钱
2696
HASS币
40

教程狂人

发表于 2018-1-4 14:11:35 | 显示全部楼层 |阅读模式
本帖最后由 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

Image_20180104_001.png
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

Image_20180104_004.png
執行check_iphone.sh檢查結果是否正常
bash check_iphone.sh
Image_20180104_005.png

程式執行都正常後,要一直讓他持續自動跑不中斷可用下面指令,如果系統操作會慢,請調大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
Image_20180104_002.png

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

Image_20180104_003.png
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
























评分

参与人数 1金钱 +20 收起 理由
+ 20 谢谢分享,非常详细,学习了!.

查看全部评分

回复

使用道具 举报

220

主题

1284

帖子

7847

积分

超级版主

Rank: 8Rank: 8

积分
7847
金钱
6533
HASS币
86

教程狂人论坛风云人物突出贡献

发表于 2018-1-4 14:24:53 | 显示全部楼层
回复

使用道具 举报

27

主题

387

帖子

3103

积分

元老级技术达人

积分
3103
金钱
2696
HASS币
40

教程狂人

 楼主| 发表于 2018-1-4 14:28:29 | 显示全部楼层
lidicn 发表于 2018-1-4 14:24
ha自带有两个版本的bluetooth tracker
https://home-assistant.io/components/device_tracker.bluetooth_le ...

這個我也有試過
不過我HA是裝在群暉上的
藍牙搜尋器(不裝HA)我是打算在不同的地方放幾個
這樣的話內建的device_tracker.BLE功能就用不到了
回复

使用道具 举报

123

主题

4626

帖子

1万

积分

管理员

囧死

Rank: 9Rank: 9Rank: 9

积分
16013
金钱
11302
HASS币
45
发表于 2018-1-4 14:49:15 | 显示全部楼层
感谢楼主分享,是不错的思路,有蓝牙的试试咯!
回复

使用道具 举报

40

主题

3057

帖子

1万

积分

超级版主

Nero

Rank: 8Rank: 8

积分
11135
金钱
8028
HASS币
182
发表于 2018-1-4 15:00:43 | 显示全部楼层
本帖最后由 neroxps 于 2018-1-4 20:27 编辑

赞!!!我之前用 vmware workstations 实验过,用来显示在家与否十分方便

竟然iphone也可以监控。等我蓝牙USB到了试试。
我之前是用Rest_API 直接针对 device_tracker 进行操作。

#!/bin/bash
ha_api_passwd=""
mac=""
ha_url=""
dev_id=""

while true; do
        dev_db_name=$(hcitool name $mac)
        if [[ $dev_db_name == "iPhone" ]]; then
                echo "在家"
                curl -X POST \
                        -H "x-ha-access: ${ha_api_passwd}" \
                        -H "Content-Type: application/json" \
                        -d '{"dev_id":"'"${dev_id}"'","location_name":"home"}' \
                        ${ha_url}/api/services/device_tracker/see > /dev/null 2>&1
        else
                echo "离家"
                curl -X POST \
                        -H "x-ha-access: ${ha_api_passwd}" \
                        -H "Content-Type: application/json" \
                        -d '{"dev_id":"'"${dev_id}"'","location_name":"not_home"}' \
                        $ha_url/api/services/device_tracker/see > /dev/null 2>&1
        fi
        sleep 2
done

回复

使用道具 举报

27

主题

387

帖子

3103

积分

元老级技术达人

积分
3103
金钱
2696
HASS币
40

教程狂人

 楼主| 发表于 2018-1-4 15:08:00 | 显示全部楼层
neroxps 发表于 2018-1-4 15:00
赞!!!我之前用 vmware workstations 实验过,用来显示在家与否十分方便

竟然iphone也可以监控。等我蓝 ...

我一開始也是用Rest API來更新狀態到HA
但我在0.59.2的版本上使用Rest API去更新一個原本不存在的entity_id時(例如windgoiphone_status)
會發現全部HA的自動化都會被turn off再turn on ,導致一些不應該發生的action產生
不知道這是不是0.59.2的bug
所以後來我就改用MQTT了
回复

使用道具 举报

40

主题

3057

帖子

1万

积分

超级版主

Nero

Rank: 8Rank: 8

积分
11135
金钱
8028
HASS币
182
发表于 2018-1-4 15:15:33 | 显示全部楼层
windgo 发表于 2018-1-4 15:08
我一開始也是用Rest API來更新狀態到HA
但我在0.59.2的版本上使用Rest API去更新一個原本不存在的entity_i ...

谢谢你的发现啊,iphone也能监控是在是太赞了。

可惜我没有树莓派, esxi上放了无线网卡也不行,我买了个USB蓝牙接收器还在路上,等到货了试试,再不行可能真的要买台香橙派之类的了。
回复

使用道具 举报

27

主题

387

帖子

3103

积分

元老级技术达人

积分
3103
金钱
2696
HASS币
40

教程狂人

 楼主| 发表于 2018-1-4 15:28:22 | 显示全部楼层
neroxps 发表于 2018-1-4 15:15
谢谢你的发现啊,iphone也能监控是在是太赞了。

可惜我没有树莓派, esxi上放了无线网卡也不行,我买了 ...

USB藍牙只要是4.0支援BLE功能的應該就是可以的
因為我有在樹莓派跟群暉+USB藍牙測試過都ok
IPhone是使用藍牙廣播 所以沒有BLE功能也可以搜尋到
但要注意搜尋前要先把IPhone藍牙開關一下好找到MAC
有MAC之後就可以直接用sudo hcitool name MAC_ADDRESS查了
回复

使用道具 举报

40

主题

3057

帖子

1万

积分

超级版主

Nero

Rank: 8Rank: 8

积分
11135
金钱
8028
HASS币
182
发表于 2018-1-4 15:45:55 | 显示全部楼层
windgo 发表于 2018-1-4 15:28
USB藍牙只要是4.0支援BLE功能的應該就是可以的
因為我有在樹莓派跟群暉+USB藍牙測試過都ok
IPhone是使用 ...

我是ESXI直通无线网卡,可能是ESXI直通有问题,等USB蓝牙接收器到了再试试。
回复

使用道具 举报

1

主题

282

帖子

1222

积分

金牌会员

Rank: 6Rank: 6

积分
1222
金钱
940
HASS币
0
发表于 2018-1-4 21:22:51 | 显示全部楼层
感受一下和大神之间的差距
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian

GMT+8, 2024-4-25 04:46 , Processed in 0.076287 second(s), 36 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表