Project Icon

monitor

基于蓝牙的设备存在检测系统

monitor是一个开源的蓝牙存在检测系统,可识别信标、手机等蓝牙设备。它基于MQTT协议,支持多设备分布式部署,适用于家庭自动化场景。系统提供灵活配置,实现精准室内定位和自动化控制。项目支持多种蓝牙设备类型,为智能家居开发提供了实用的技术方案。

监控

TL;DR: 被动蓝牙存在检测信标、手机和其他蓝牙设备。对基于MQTT的家庭自动化很有用,特别是当脚本运行在分布在整个房产中的多个设备上时。

version mosquitto

常见问题解答

安装说明
从头开始设置树莓派

树莓派Zero W安装说明

SD卡设置

  1. 这里下载最新版的raspbian

  2. etcher.io下载etcher

  3. raspbian lite buster镜像刻录到SD卡上。说明在这里。

  4. 挂载刻录好的SD卡的boot分区(拔出后再插入)

  5. 要启用ssh,在根目录创建一个无扩展名的空文件叫ssh

  6. 设置Wi-Fi,在根目录创建wpa_supplicant.conf文件,添加家庭Wi-Fi的详细信息:

country=US
    ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
    update_config=1

network={
    ssid="您的网络名称"
    psk="您的网络密码"
    key_mgmt=WPA-PSK
}
  1. 第一次启动时,插入SD卡并开启树莓派Zero W。第一次启动时,新创建的wpa_supplicant.conf文件和ssh将被移动到适当的目录。通过路由器找到Pi的IP地址。

配置和设置

  1. 通过SSH登录到树莓派(默认密码: raspberry):
ssh pi@theipaddress
  1. 更改默认密码:
sudo passwd pi
  1. 更新和升级:
sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get dist-upgrade -y
sudo reboot
  1. 如果需要,安装蓝牙固件:
#为Pi Zero W安装蓝牙驱动
sudo apt-get install pi-bluetooth

  1. 重启:
sudo reboot
  1. 安装Mosquitto 1.5+(重要步骤!):

# 获取仓库密钥
wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key

#添加仓库
sudo apt-key add mosquitto-repo.gpg.key

#下载适当的列表文件 
cd /etc/apt/sources.list.d/
sudo wget http://repo.mosquitto.org/debian/mosquitto-buster.list

#更新缓存并安装 
sudo apt-cache search mosquitto
sudo apt-get update
sudo apt-get install -f libmosquitto-dev mosquitto mosquitto-clients libmosquitto1
监控设置

设置 monitor

  1. 克隆 monitor Git:
#安装git
cd ~
sudo apt-get install git

#克隆此仓库
git clone https://github.com/andrewjfreyer/monitor.git

#进入 `monitor` 目录
cd monitor/

#(可选) 切换到beta分支以获取最新的更新和功能(可能不稳定)
git checkout beta       

  1. 首次运行:

将创建配置文件,使用默认首选项。任何未安装的可执行文件都将被报告。所有这些都可以通过 apt-get install ... 进行安装。

sudo bash monitor.sh
  1. 编辑 mqtt_preferences 文件:
sudo nano mqtt_preferences
  1. 编辑 known_static_addresses (手机、笔记本电脑、一些智能手表):
sudo nano known_static_addresses

或者,向 monitor/setup/ADD STATIC DEVICE 发送一个MQTT消息,消息包含MAC地址和别名,用空格分隔:

topic: monitor/setup/ADD STATIC DEVICE message: 00:11:22:33:44:55 alias

使用 monitor/setup/DELETE STATIC DEVICE 并给出包含MAC地址的消息从所有 monitor 节点中删除一个设备。

  1. 阅读帮助文件:
sudo bash monitor.sh -h

现在基本设置就完成了。您的代理应该正在接收消息,每次树莓派启动时 monitor 服务都会重新启动。按照当前的配置,您应该几次从命令行运行 sudo bash monitor.sh 以了解脚本的工作方式。


背景和技术细节

亮点

monitor 向指定的代理发送一个包含置信度值(0到100)的JSON格式的MQTT消息,当一个指定的蓝牙设备对 name 查询做出响应时。默认情况下,在接收到先前未见过的设备(如以外围模式广告连接能力的设备)的匿名广告后,会触发 name 查询。

示例JSON数据包:

topic: monitor/{{monitor安装名称}}/{{mac地址}}
message: {
    "id":"{{mac地址}}",
    "confidence":"{{从0到100}}",
    "name":"{{如果可用}}",
    "manufacturer":{{如果可用}}",
    "type":"KNOWN_MAC",
    "retained":"{{消息保留?}}",
    "timestamp":"{{发送此消息的格式化日期}}",
    "version":"{{monitor版本}}"
 }

此外,还可以选择向同一代理报告当公开广告的信标设备或iBeacon设备广告时的JSON格式的MQTT消息。

示例JSON数据包:

topic: monitor/{{monitor安装名称}}/{{mac地址或ibeacon uuid}}
message: {
    "id":"{{mac地址或ibeacon uuid}}",
    "report_delay":"{{第一次检测到到这条消息的延迟秒数}}",
    "flags":"{{GAP标志}}",
    "movement":"stationary",
    "confidence":"{{从0到100}}",
    "name":"{{如果可用}}",
    "power":"{{如果可用}}",
    "rssi":"{{如果可用}}",
    "mac":"{{如果是ibeacon,与uuid关联的当前mac地址}}",
    "manufacturer":{{如果可用}}",
    "type":"{{GENERIC_BEACON_PUBLIC or APPLE_IBEACON}},
    "retained":"{{消息保留?}}",
    "timestamp":"{{发送此消息的格式化日期}}",
    "version":"{{monitor版本}}"
 }

关于蓝牙存在问题的简单类比

想象你被蒙上眼睛在一个大房间里和其他人在一起。我们想知道哪些朋友在场,哪些朋友不在场:

First Picture

房间里的一些人会定期发出声音(比如吃薯片、打喷嚏、咳嗽等),另一些人则安静地坐着,除非你专门叫他们的名字,还有一些人会定期大声宣布自己的名字,无论你是否想让他们这么做:

Second Picture

这里的问题是,你不能大喊"谁在这里",因为这样大家都会同时说自己的名字,你就无法分辨了。同样,出于显而易见的原因,你也不能简单地问"谁不在这里?"

所以,你像点名一样。房间里的每个人只有在叫他们的名字时才会回应。

Third Picture

所以,一种点名的方法是一个一个地大声喊出朋友的名字,然后等待一会儿再喊一次。

一旦一个朋友停止响应(一段时间内),你就presumed他或她已经离开了:

Simple Loop

这种技术应该可以正常工作,但有一个小问题。你一直在对着房间大喊,这意味着你很难听到轻微的响应,其他人也很难进行对话。还有什么其他的方法吗?我们能利用那些随机的声音吗?

是的!一个更聪明的方法是等待一个不知名的声音,然后开始询问一个你知道不在场的朋友是否刚刚到达:

复杂循环

这样,你就不必一直向房间里的所有朋友询问了。高效!

这个技术是对 monitor 如何为手机(好友列表)和信标(大声宣布名称)等设备工作的一个非常简化的描述。这也让人了解了 monitor 如何使用匿名声音来减少向蓝牙环境发送询问的次数。

蓝牙低功耗规范旨在使用户连接蓝牙设备更加简单。不再需要引脚码、代码验证、"发现模式"等 - 大部分情况下是如此。它还被设计得比以前的蓝牙实现更加私密。但是,当您想要能够在没有干预的情况下连接到未知设备时,要保持隐私是很困难的。

monitor 结合使用了名称请求、匿名广告和信标广告,以逻辑确定(1)何时发出名称请求以确定设备是否在场,以及(2)何时发出名称请求以确定设备是否离开。该脚本还会监听信标。

例如,如果 known_static_addresses 文件中列出了两个手机地址,且这两个设备都在场,则永远不会发生到达扫描。同样,如果这两个地址都离开,则永远不会发生离开扫描。如果只有一个设备在场,到达扫描只会扫描当前不在的设备。

为了减少名称请求的数量,monitor 会监听匿名广告,并为每个新的匿名地址触发到达扫描。

该脚本还会在向 monitor/scan/arrive 主题发布 mqtt 消息时触发到达扫描。广告触发的扫描可以通过使用触发器参数 -ta 禁用,这会导致 monitor 在收到 mqtt 消息时触发到达扫描。

如果 monitor 已经很长时间没有收到某个特定的匿名地址,它会触发一次离开扫描。该脚本还会在向 monitor/scan/depart 主题发布 mqtt 消息时触发离开扫描。到期触发的扫描可以通过使用触发器参数 -td 禁用,这会导致 monitor 仅在收到 mqtt 消息时触发离开扫描。

为了进一步减少扫描,monitor 可以过滤用于到达扫描的哪些类型的匿名广告。这些被称为"过滤器",定义在名为 behavior_preferences 的文件中。过滤器是 bash RegEx 字符串,可以通过或拒绝与过滤器匹配的匿名广告。

我个人在家中使用了四个树莓派零 w,其中我们的主要 monitor 节点或传感器位于一楼。我们位于二楼、三楼和车库的其他"节点"仅在收到 mqtt 消息时设置为触发使用 - 它们将使用选项 -tad 仅扫描到达离开。一楼的节点被设置为通过包含 -tr 标志("报告"到其他节点何时触发到达或离开扫描)向这些节点发送 mqtt 抵达/离开扫描指令。 以下是英语文本的中文翻译:

首层持续监控信标(-b)广告和匿名广告,这些可能由我们在known_static_addresses文件中列出的手机发送。对于新的匿名广告,monitor将启动一次ARRIVAL扫描,以查找缺席的手机。如果发现其中一台设备,将向Home Assistant发送一个mqtt消息,报告扫描到的手机"在家"并且置信度为100%。此外,还将向二楼、三楼和车库发送一个mqtt消息,以触发这些楼层的扫描。通过此配置,当我们离开家时,可以通过前门或车库门触发一个10秒延迟的monitor/scan/departmqtt触发器,从而触发我们之前已知存在的设备的离开扫描。10秒的延迟给我们一个机会在"离开"扫描被触发之前退出蓝牙范围。不同的房子/公寓可能需要不同的延迟。

更具体地说,每个monitor节点都使用相同的设备名称,以便Home Assistant可以轻松跟踪状态。例如,在每个节点上,我的known_static_addresses文件看起来像这样(注意00:00:00:00:00:00是一个示例地址 - 这应该是你手机的私有静态蓝牙地址):

00:00:00:00:00:00 alias #忽略此注释

我想跟踪的地址与我想在Home Assistant中使用的别名之间用空格隔开。如果您更喜欢使用地址而不是别名,请在behavior_preferences文件中将PREF_ALIAS_MODE设置为false

通过这种方式,Home Assistant接收mqtt消息并将值存储为几个mqtt传感器的输入。这些传感器的输出被组合以提供准确的数字占用置信度:

- platform: mqtt
  state_topic: 'monitor/first floor/alias'
  value_template: '{{ value_json.confidence }}'
  unit_of_measurement: '%'
  name: '一楼'

- platform: mqtt
  state_topic: 'monitor/second floor/alias'
  value_template: '{{ value_json.confidence }}'
  unit_of_measurement: '%'
  name: '二楼'

- platform: mqtt
  state_topic: 'monitor/third floor/alias'
  value_template: '{{ value_json.confidence }}'
  unit_of_measurement: '%'
  name: '三楼'

- platform: mqtt
  state_topic: 'monitor/garage/alias'
  value_template: '{{ value_json.confidence }}'
  unit_of_measurement: '%'
  name: '车库'

这些传感器可以使用min_max组合:

- platform: min_max
  name: "家中占用置信度"
  type: max
  round_digits: 0
  entity_ids:
    - sensor.third_floor
    - sensor.second_floor
    - sensor.first_floor
    - sensor.garage

之后,我在自动化中使用sensor.home_occupancy_confidence实体来控制代表用户在家或不在家的input_boolean的状态。

例如:

- alias: 有人在家
  trigger:
    - platform: numeric_state
      entity_id: sensor.home_occupancy_confidence
      above: 10
  action:
    - service: input_boolean.turn_on
      data:
        entity_id: input_boolean.occupancy

- alias: 没人在家
  trigger:
    - platform: numeric_state
      entity_id: sensor.home_occupancy_confidence
      below: 10
  action:
    - service: input_boolean.turn_off
      data:
        entity_id: input_boolean.occupancy

如果您更喜欢在Home Assistant中使用device_tracker平台,一个独特的解决方案是使用未记录的device_tracker.see服务:

例如:

- alias: Andrew 在家
  trigger:
    - platform: numeric_state
      entity_id: sensor.andrew_occupancy_confidence
      above: 10
  action:
    - service: device_tracker.see
      data:
        dev_id: andrew
        location_name: home
        source_type: bluetooth

- alias: Andrew 不在家
  trigger:
    - platform: numeric_state
      entity_id: sensor.andrew_occupancy_confidence
      below: 10
  action:
    - service: device_tracker.see
      data:
        dev_id: andrew
        location_name: not_home
        source_type: bluetooth

更多信息,请参见此处此处

如果您只有一个节点,@limych 提供的附加组件可能是一个很好的选择!

如果有多个节点和大量用户,@Odianosen25 有一个AppDaemon应用程序可以轻松地将这个系统集成到Home Assistant中。更多信息可以在这里找到。

选项默认值描述
PREF_ARRIVAL_SCAN_ATTEMPTS1这是monitor在决定设备尚未到达之前发送名称请求的次数。数值越高,到达检测的错误就越少,但在多设备安装中识别所有设备已回家的时间也可能越长。
PREF_DEPART_SCAN_ATTEMPTS2这是monitor在决定设备尚未离开之前发送名称请求的次数。数值越高,离开检测的错误就越少,但在多设备安装中识别所有设备已离开的时间也可能越长。
PREF_BEACON_EXPIRATION180这是在没有观察到广告的情况下,信标被视为过期的秒数。
PREF_MINIMUM_TIME_BETWEEN_SCANS15这是"到达"扫描或"离开"扫描之间所需的最小秒数。增加该值将降低干扰,但也会增加到达和离开检测时间。
PREF_PASS_FILTER_ADV_FLAGS_ARRIVE.*请参见上文。
PREF_PASS_FILTER_MANUFACTURER_ARRIVE.*请参见上文。
PREF_FAIL_FILTER_ADV_FLAGS_ARRIVENONE请参见上文。
PREF_FAIL_FILTER_MANUFACTURER_ARRIVENONE请参见上文。
PREF_ALIAS_MODEtrue禁用或启用别名模式;如果禁用,MQTT消息将使用设备的MAC地址发送。
  1. 高级配置选项:

除了上述描述的选项外,还有许多高级选项可供用户设置。要修改任何这些选项,请将一行添加到behavior_preferences文件中。

选项默认值描述
PREF_INTERSCAN_DELAY3这是name请求之间的固定延迟。增加该值将降低干扰,但会降低响应性。降低该值将会风险蓝牙硬件故障。
PREF_RANDOM_DEVICE_EXPIRATION_INTERVAL75这是匿名广告MAC地址被视为过期的间隔。增加此值将减少到达扫描频率,但也会增加内存占用(最小)并减少离开扫描的频率。
PREF_RSSI_CHANGE_THRESHOLD-20如果一个信标的RSSI至少变化这个值,则该信标将通过mqtt再次报告。
PREF_RSSI_IGNORE_BELOW-75如果一个匿名广告"更远"(RSSI更低),忽略该广告。
PREF_HCI_DEVICEhci0选择monitor应该使用的hci设备。
PREF_COOPERATIVE_SCAN_THRESHOLD60一旦对已知设备的信心低于该值,向其他monitor节点发送MQTT消息,以开始到达扫描或离开扫描。
PREF_MQTT_REPORT_SCAN_MESSAGESfalse此值为true或false,确定monitor是否发布扫描开始和扫描结束。
PREF_PERCENT_CONFIDENCE_REPORT_THRESHOLD59此值定义了信标开始报告信心下降的阈值。
PREF_PASS_FILTER_PDU_TYPE各种。请参见FAQ。这些是monitor应该注意的PDU类型。
PREF_DEVICE_TRACKER_REPORTfalse如果为true,此值将导致monitor... /device_tracker报告'home'或'not_home'消息,以符合device_tracker mqtt协议。
PREF_DEVICE_TRACKER_HOME_STRINGhome如果PREF_DEVICE_TRACKER_REPORT为true,这是在设备处于"home"状态时报告给device_tracker的字符串。
PREF_DEVICE_TRACKER_AWAY_STRINGnot_home如果PREF_DEVICE_TRACKER_REPORT为true,这是在设备处于"not_home"状态时报告给device_tracker的字符串。
PREF_DEVICE_TRACKER_TOPIC_BRANCHdevice_tracker如果PREF_DEVICE_TRACKER_REPORT为true,这是用于发布设备跟踪器消息的MQTT主题路径的最后一个路径元素。
PREF_ADVERTISEMENT_OBSERVED_INTERVAL_STEP15这是用于估算MQTT消息中报告的广告间隔的最小间隔(以秒为单位)。
PREF_DEPART_SCAN_INTERVAL30如果使用周期性扫描模式,这是自动触发离开扫描的最小间隔(以秒为单位)。
PREF_ARRIVE_SCAN_INTERVAL15如果使用周期性扫描模式,这是自动触发到达扫描的最小间隔(以秒为单位)。

RSSI跟踪

该脚本还可以跟踪一天中的RSSI变化。这可用于非常基本的房间或楼层级别的跟踪。只有在known_static_addresses中的设备被配对到monitor节点后,才能跟踪其RSSI。以下是配对方法:

  1. 停止monitor服务:
sudo systemctl stop monitor
  1. 运行monitor并使用-c标志,后跟要连接的已知设备的MAC地址:
sudo bash monitor.sh -c 00:11:22:33:44:55

在此之后,按照monitor给出的提示进行操作,您的设备将被连接。之后,当您重新启动monitor时,它将定期(大约每1.5分钟一次)连接到您的手机,采取三个RSSI样本,平均样本,并向与置信度报告相同的路径报告一个字符串消息,并添加*/rssi*路径组件。因此,如果一个monitor节点被命名为'first floor',将向以下位置报告一个rssi消息:

topic: monitor/first floor/00:11:22:33:44:55/rssi
message: -99 through 0

如果无法获得RSSI测量值,则发送值-99。

报告已知状态

还可以通过向类似monitor/first floor/KNOWN DEVICE STATES的MQTT消息发送消息来告知monitor报告所有当前已知的设备状态。monitor.sh将遍历所有已知的静态地址,并报告当前的置信度级别。这可能在home assistant中很有用,在home assistant重启后获取当前状态。

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号