跳转到内容

HLK-FM22x 人脸识别模块

hlk_fm22x 组件允许您在 ESPHome 中使用 HLK-FM225 和 HLK-FM223 人脸识别模块。

HLK-FM225 人脸识别模块
HLK-FM225 人脸识别模块 (数据手册, AliExpress)。图片由 AliExpress 提供。
HLK-FM223 人脸识别模块
HLK-FM223 人脸识别模块 (数据手册, AliExpress)。图片由 AliExpress 提供。

模块可以由 5V 输出供电。由于与阅读器的通信是通过 UART 完成的(默认波特率为 115200),您需要在配置中设置一个 UART 总线,并将 rx_pin 连接到阅读器的 TX,将 tx_pin 连接到阅读器的 RX

# 示例配置条目
hlk_fm22x:
on_face_scan_matched:
...
on_face_scan_unmatched:
...
on_face_scan_invalid:
...
on_face_info:
...
on_enrollment_done:
...
on_enrollment_failed:
...

配置由三部分组成:核心组件、可选的独立传感器、可选的注册二进制传感器和可选的版本文本传感器。

基本配置:

  • uart_id (可选, ID): 手动指定 UART 集线器的 ID。
  • id (可选, ID): 手动指定用于代码生成的 ID。
  • on_face_scan_matched (可选, 自动化): 当扫描并识别到已注册的人脸时执行的操作。请参阅 on_face_scan_matched
  • on_face_scan_unmatched (可选, 自动化): 当扫描到未知人脸时执行的操作。请参阅 on_face_scan_unmatched
  • on_face_scan_invalid (可选, 自动化): 当人脸扫描失败时执行的操作。请参阅 on_face_scan_invalid
  • on_face_info (可选, 自动化): 当人脸信息可用时执行的操作。请参阅 on_face_info
  • on_enrollment_done (可选, 自动化): 当人脸注册步骤成功时执行的操作。请参阅 on_enrollment_done
  • on_enrollment_failed (可选, 自动化): 当人脸注册步骤失败时执行的操作。请参阅 on_enrollment_failed

配置变量:

  • face_count: 存储在模块上的已注册人脸数量。

  • 传感器的所有选项。

  • last_face_id: 由 on_face_scan_matched 设置的最后一个匹配的已注册人脸。

  • 传感器的所有选项。

  • status: 模块内部状态寄存器的整数表示。

  • 传感器的所有选项。

使用此配置选项,您可以在人脸扫描与已注册人脸匹配时编写复杂的自动化。 要使用变量,请使用 lambda 模板,匹配的人脸 ID 可以在该 lambda 中通过名为 face_id 的变量访问,人脸名称通过名为 name 的变量访问。

on_face_scan_matched:
- text_sensor.template.publish:
id: face_state
state: !lambda 'return "Authorized face " + name + " (" + to_string(face_id) + ")";'
# 根据 face_id 推送 tag_scanned 事件
- homeassistant.tag_scanned: !lambda |-
switch (face_id) {
case 0:
return "person_a";
case 1:
return "person_b";
...
default:
return "person_unknown";
}

使用此配置选项,您可以在扫描到未知人脸时编写复杂的自动化。

on_face_scan_unmatched:
- text_sensor.template.publish:
id: face_state
state: "Unauthorized face"

使用此配置选项,您可以在扫描失败时编写复杂的自动化,例如当没有人脸可见时。这与 on_face_scan_unmatched 不同,后者是在扫描到未知人脸时触发。 要使用变量,请使用 lambda 模板,错误号可以在该 lambda 中通过名为 error 的变量访问。

on_face_scan_invalid:
- text_sensor.template.publish:
id: face_state
state: !lambda 'return "Invalid face. Error number: " + to_string(error);'

使用此配置选项,您可以在人脸信息可用时编写复杂的自动化。 模块在注册和扫描过程中发送人脸信息,主要用于调试。 要使用变量,请使用 lambda 模板,状态可以在该 lambda 中通过名为 status 的变量访问。 零值表示正常,数据手册包含各种错误状态代码(例如 6 表示人脸太远)。 还有其他值可以确定人脸在帧中的位置(lefttoprightbottom)以及其旋转(yawpitchroll)。

on_face_info:
- text_sensor.template.publish:
id: face_info
state: !lambda |-
switch (status) {
case 0:
return "Normal";
case 1:
return "No face detected";
case 2:
return "Face too high";
case 3:
return "Face too low";
...
default:
return "Unknown status " + to_string(status);
}

使用此配置选项,您可以在人脸注册步骤成功时编写复杂的自动化。 要使用变量,请使用 lambda 模板,注册到的槽位号可以在该 lambda 中通过名为 face_id 的变量访问。 请注意,该值仅在人脸在所有方向上注册后才有效(否则将为 -1)。 方向值是一个位掩码,表示到目前为止已捕获的方向。值为 0x1f 表示所有方向都已捕获,人脸 ID 应该有效。

on_enrollment_done:
- text_sensor.template.publish:
id: face_state
state: !lambda 'return "Enrolled into slot " + to_string(face_id);'

使用此配置选项,您可以在人脸注册失败时编写复杂的自动化。 要使用变量,请使用 lambda 模板,错误号可以在该 lambda 中通过名为 error 的变量访问。

on_enrollment_failed:
- text_sensor.template.publish:
id: face_state
state: !lambda 'return "Failed to enroll face. Error: " + to_string(error);'

启动带有名称和方向的人脸注册过程。 要成功注册人脸,您需要从所有方向连续成功扫描人脸。 一个方向失败将需要从头开始重新注册人脸。

on_...:
then:
- hlk_fm22x.enroll:
name: "My name"
direction: 1
# 更新模板文本传感器以提供视觉反馈
- text_sensor.template.publish:
id: face_state
state: "Look directly at the camera"

配置选项:

  • name (必需, string, 可模板化): 与人脸关联的名称。最多 32 个 ASCII 字符。
  • direction (必需, int, 可模板化): 扫描人脸的方向。1 为正面,2 为右侧,4 为左侧,8 为向下,16 为向上。

扫描并尝试匹配已注册的人脸。触发一个 on_face_scan 触发器。

on_...:
then:
- hlk_fm22x.scan:

从指定的槽位号删除已注册的人脸。

on_...:
then:
- hlk_fm22x.delete:
face_id: 0
# 简写形式
- hlk_fm22x.delete: 0

配置选项:

  • face_id (必需, int, 可模板化): 要删除的已注册人脸的槽位号。

删除所有已注册的人脸。

on_...:
then:
- hlk_fm22x.delete_all:

重置模块。在注册或扫描失败后模块没有正确响应时可能有用。 如果此命令失败,它将标记模块为失败状态。

on_...:
then:
- hlk_fm22x.reset:
  • id (可选, ID): 如果您有多个组件,手动指定 HLK-FM22x 阅读器的 ID。

使用以下代码,您可以快速设置一个节点,并在 Home Assistant 的开发者工具中使用动作。 例如,要调用 hlk_fm22x.enroll,选择动作 esphome.test_node_enroll,并在动作数据中输入

{ "name": "My name", "direction": 1 }
uart:
rx_pin: GPIOXX
tx_pin: GPIOXX
baud_rate: 115200
hlk_fm22x:
on_face_scan_invalid:
- homeassistant.event:
event: esphome.test_node_face_scan_invalid
data:
error: !lambda 'return error;'
on_face_scan_matched:
- homeassistant.event:
event: esphome.test_node_face_scan_matched
data:
face_id: !lambda 'return face_id;'
name: !lambda 'return name;'
on_face_scan_unmatched:
- homeassistant.event:
event: esphome.test_node_face_scan_unmatched
on_face_info:
- homeassistant.event:
event: esphome.test_node_face_info
data:
status: !lambda 'return status;'
left: !lambda 'return left;'
top: !lambda 'return top;'
right: !lambda 'return right;'
bottom: !lambda 'return bottom;'
yaw: !lambda 'return yaw;'
pitch: !lambda 'return pitch;'
roll: !lambda 'return roll;'
on_enrollment_done:
- homeassistant.event:
event: esphome.test_node_enrollment_done
data:
face_id: !lambda 'return face_id;'
direction: !lambda 'return direction;'
on_enrollment_failed:
- homeassistant.event:
event: esphome.test_node_enrollment_failed
data:
error: !lambda 'return error;'
api:
actions:
- action: enroll
variables:
name: string
direction: int
then:
- hlk_fm22x.enroll:
name: !lambda 'return name;'
direction: !lambda 'return direction;'
- action: scan
then:
- hlk_fm22x.scan:
- action: delete
variables:
face_id: int
then:
- hlk_fm22x.delete:
face_id: !lambda 'return face_id;'
- action: delete_all
then:
- hlk_fm22x.delete_all:
- action: reset
then:
- hlk_fm22x.reset: