本帖最后由 bugensui 于 2026-8-22 22:58 编辑
说实话,这玩意儿我去年就在某宝买过一个,当时它便宜,随手就扔钥匙扣上挂着了。那时候也没想着怎么折腾,就当个单纯的防丢挂件用。直到前两天,我在论坛看到大佬“雪晴科技HTH”推荐这东西,说它能完美接入Home Assistant,而且功能还不少。这下勾起了我的折腾欲,2块9的东西(用了3块优惠券,原价5.9元),要是真能变身智能按钮加蓝牙追踪,那性价比简直逆天了。
什么是 iTag?
iTag 这类产品其实是个通用的 BLE(低功耗蓝牙)标签。外观大多是个小水滴形状,里面藏着一个纽扣电池、一个蜂鸣器和一个物理按键。本质上,它就是一个标准的 BLE GATT 设备。虽然各家厂商出的固件可能稍有不同,但底层逻辑是一样的:通过不同的“特征(Characteristic)”来传输按键信号、电量信息或者触发蜂鸣器。
为什么选它?
对我这种家里还没装智能门锁、还在用机械钥匙的人来说,iTag 简直是刚需。
- 无线按钮:它支持单击和双击判定。挂在钥匙上,进门顺手一按就能触发开关灯或者控制指定设备。
- 居家/离家判定:利用 ESP32 的蓝牙连接上itag防丢器。只要钥匙在范围内,我就在,可以做自动化离家和回家场景。
- 寻物报警:找不到钥匙了?手机点一下,钥匙扣就开始尖叫。
- 超低成本:2块9,坏了丢了完全不心疼。
逆向与折腾:从抓包到接入
主要用到了esp32开发板,然后在esphome代码里启用(esp32_ble_tracker)BLE 扫描跟踪组件和(ble_client)BLE 客户端组件,如果家里有esp32芯片的智能设备,可以加几行代码进去就可以实现把itag防丢器接入HA。
折腾的第一步是逆向调试。我用了 Web Bluetooth API 工具连接了 iTag,发现它的按键信号是通过服务 0xFFE0 的特征 0xFFE1 推送的。不同芯片方案(有的用 Ti CC2541,有的用杰理)推送的 HEX 数据不一样,我这个单击发的是 0x01。
最大的坑在于那个模式控制寄存器 0x1802 / 0x2A06。它其实是个 3态互斥寄存器:写入 0x01 是寻物报警,0x00 是按键提示音,0x02 是静音。如果你把它当成普通的开关配置,肯定会打架。所以我最后在 ESPHome 里用了一个 select 选择器来统一管理,效果非常稳。
针对双击手感,我还微调了 ESPHome 的 on_multi_click 时间参数。因为人手操作总是有快慢,把判定窗口放宽到 0.6 秒后,识别率几乎达到了 100%。
完整的 ESPHome 配置代码
直接把下面这段代码粘进你的配置里,改下 MAC 地址就能用。我已经把电量查询、寻物开关、ITAG单击双击和ITAG连接状态全都写好了。
substitutions:
device_name: "itag_button"
itag_mac: "FF:****** F"
esphome:
name: esp32kf
friendly_name: esp32kf
on_boot:
priority: 600 # 优先级设为 600,确保在传感器组件加载完成后立即执行
then:
- text_sensor.template.publish:
id: last_action
state: "null" # 👈 重启后立即显示为 null
- binary_sensor.template.publish:
id: itag_button_pulse
state: OFF # 👈 顺便把按键脉冲也初始化为 OFF
esp32:
board: esp32dev
framework:
type: esp-idf
logger:
esp32_ble_tracker:
scan_parameters:
active: true
interval: 150ms
window: 100ms
ble_client:
- mac_address: ${itag_mac}
id: itag_client
on_connect:
then:
# 1. 立即更新传感器状态为“已连接/在家”
- binary_sensor.template.publish:
id: itag_connected_real
state: ON
- logger.log: "iTag 链路已建立,状态同步为:在家"
# 🔥 新增:延时 3 秒,给蓝牙链路预留稳定的时间
- delay: 3s
# 2. 写入静音/关闭报警指令 (防止离家报警)
- ble_client.ble_write:
id: itag_client
service_uuid: 'FFE0'
characteristic_uuid: 'FFE2'
value: [0x00]
on_disconnect:
then:
- binary_sensor.template.publish:
id: itag_connected_real
state: OFF
- logger.log: "iTag 链路已断开,状态同步为:离家"
sensor:
- platform: internal_temperature
name: "esp32 Temperature"
- platform: ble_client
type: characteristic
ble_client_id: itag_client
name: "iTag battery"
icon: "mdi:battery"
service_uuid: '180F'
characteristic_uuid: '2A19'
unit_of_measurement: "%"
accuracy_decimals: 0
update_interval: 2h
binary_sensor:
- platform: template
name: "钥匙扣实际状态"
id: itag_connected_real
device_class: connectivity
- platform: template
id: itag_button_pulse
internal: true
on_multi_click:
- timing:
- ON for at most 0.4s
- OFF for at least 0.4s
then:
- text_sensor.template.publish:
id: last_action
state: "单击 (Single Click)"
- delay: 500ms
- text_sensor.template.publish:
id: last_action
state: "null"
- timing:
- ON for at most 0.4s
- OFF for at most 0.4s
- ON for at most 0.4s
then:
- text_sensor.template.publish:
id: last_action
state: "双击 (Double Click)"
- delay: 500ms
- text_sensor.template.publish:
id: last_action
state: "null"
select:
- platform: template
name: "钥匙扣工作模式"
id: itag_work_mode
icon: "mdi:tune-vertical"
optimistic: true
restore_value: true
options:
- "静音模式"
- "按键提示音"
- "寻物蜂鸣"
set_action:
- logger.log:
format: "【模式切换】iTag 当前设为: %s"
args: ["x.c_str()"]
- if:
condition:
lambda: 'return x == "静音模式";'
then:
- ble_client.ble_write:
id: itag_client
service_uuid: '1802'
characteristic_uuid: '2A06'
value: [0x02]
- if:
condition:
lambda: 'return x == "按键提示音";'
then:
- ble_client.ble_write:
id: itag_client
service_uuid: '1802'
characteristic_uuid: '2A06'
value: [0x00]
- if:
condition:
lambda: 'return x == "寻物蜂鸣";'
then:
- ble_client.ble_write:
id: itag_client
service_uuid: '1802'
characteristic_uuid: '2A06'
value: [0x01]
text_sensor:
- platform: ble_client
ble_client_id: itag_client
service_uuid: 'FFE0'
id: djkj
characteristic_uuid: 'FFE1'
internal: true
notify: true
on_notify:
then:
- if:
condition:
lambda: 'return !x.empty() && ((uint8_t)x[0]) == 0x01;'
then:
- logger.log: "【iTag】捕获到硬件按键按下事件!"
- binary_sensor.template.publish:
id: itag_button_pulse
state: ON
- delay: 50ms
- binary_sensor.template.publish:
id: itag_button_pulse
state: OFF
- platform: template
name: "钥匙扣最后动作"
id: last_action
icon: "mdi:gesture-tap"
总结
折腾完之后,我发现这小玩意儿比我想象中要稳。虽然它只是个 2.9 元的硬件,但配合 ESPHome 和 HA 的自动化,能玩出的花样真的很多。如果你手里也有吃灰的防丢器,不妨动手试一试,这绝对是入坑智能家居成本最低、乐趣最高的方式之一了。
|