Skip to content

Commit adb7cda

Browse files
OnFreundclaudebdraco
authored
Add HLK-FM22x Face Recognition Module documentation (#4573)
Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: J. Nick Koston <nick@koston.org>
1 parent 7500f03 commit adb7cda

File tree

5 files changed

+395
-0
lines changed

5 files changed

+395
-0
lines changed

content/components/_index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,7 @@ ESPHome to cellular networks. **Does not encompass Wi-Fi.**
10511051
"Exposure Notifications","components/exposure_notifications","exposure_notifications.png",""
10521052
"GPS","components/gps","crosshairs-gps.svg","dark-invert"
10531053
"Grow Fingerprint Reader","components/fingerprint_grow","fingerprint.svg","dark-invert"
1054+
"HLK-FM22x Face Recognition Module","components/hlk_fm22x","face.svg","dark-invert"
10541055
"Modbus Controller","components/modbus_controller","modbus.png",""
10551056
"Sprinkler","components/sprinkler","sprinkler-variant.svg","dark-invert"
10561057
"Status LED","components/status_led","led-on.svg","dark-invert"

content/components/hlk_fm22x.md

Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
---
2+
description: "Instructions for setting up an HLK-FM22x Face Recognition component in ESPHome."
3+
title: "HLK-FM22x Face Recognition Module"
4+
params:
5+
seo:
6+
description: Instructions for setting up an HLK-FM22x Face Recognition component in ESPHome.
7+
image: face.svg
8+
---
9+
10+
The `hlk_fm22x` component allows you to use your HLK-FM225 and HLK-FM223 face recognition modules with ESPHome.
11+
12+
{{< img src="hlk-fm225.jpg" alt="HLK-FM225 Face Recognition Module" caption="HLK-FM225 Face Recognition Module ([datasheet](https://h.hlktech.com/Mobile/download/fdetail/294.html), [AliExpress](https://www.aliexpress.com/item/1005007267992270.html)). Image by [AliExpress](https://www.aliexpress.com/item/1005007267992270.html)." width="50.0%" class="align-center" >}}
13+
14+
{{< img src="hlk-fm223.jpg" alt="HLK-FM223 Face Recognition Module" caption="HLK-FM223 Face Recognition Module ([datasheet](https://h.hlktech.com/Mobile/download/fdetail/295.html), [AliExpress](https://www.aliexpress.com/item/3256806438681135.html)). Image by [AliExpress](https://www.aliexpress.com/item/3256806438681135.html)." width="50.0%" class="align-center" >}}
15+
16+
## Component/Hub
17+
18+
The module can be powered by the 5V output. As the communication with the reader is done using UART (default baud rate is 115200), you need to have an [UART bus](uart) in your configuration with the `rx_pin` connected to the reader's `TX` and the `tx_pin` connected to the reader's `RX`.
19+
20+
```yaml
21+
# Example configuration entry
22+
hlk_fm22x:
23+
on_face_scan_matched:
24+
...
25+
on_face_scan_unmatched:
26+
...
27+
on_face_scan_invalid:
28+
...
29+
on_face_info:
30+
...
31+
on_enrollment_done:
32+
...
33+
on_enrollment_failed:
34+
...
35+
```
36+
37+
### Configuration variables
38+
39+
The configuration is made up of three parts: The central component, optional individual sensors, the optional enrolling binary sensor, and the optional version text sensor.
40+
41+
**Base Configuration:**
42+
43+
- **uart_id** (*Optional*, ID): Manually specify the ID of the UART hub.
44+
- **id** (*Optional*, ID): Manually specify the ID used for code generation.
45+
- **on_face_scan_matched** (*Optional*, [Automation](automations)): An action to be performed when an enrolled face is scanned and recognized. See [`on_face_scan_matched`](#on_face_scan_matched-trigger).
46+
- **on_face_scan_unmatched** (*Optional*, [Automation](automations)): An action to be performed when an unknown face is scanned. See [`on_face_scan_unmatched`](#on_face_scan_unmatched-trigger).
47+
- **on_face_scan_invalid** (*Optional*, [Automation](automations)): An action to be performed when the face scan failed. See [`on_face_scan_invalid`](#on_face_scan_invalid-trigger).
48+
- **on_face_info** (*Optional*, [Automation](automations)): An action to be performed when face information is available. See [`on_face_info`](#on_face_info-trigger).
49+
- **on_enrollment_done** (*Optional*, [Automation](automations)): An action to be performed when a face enrollment step is successful. See [`on_enrollment_done`](#on_enrollment_done-trigger).
50+
- **on_enrollment_failed** (*Optional*, [Automation](automations)): An action to be performed when a face enrollment step failed. See [`on_enrollment_failed`](#on_enrollment_failed-trigger).
51+
52+
## Binary Sensor
53+
54+
**Configuration variables:**
55+
56+
- All options from [Binary Sensor](binary_sensor/index).
57+
58+
## Sensor
59+
60+
- **face_count**: The number of enrolled faces stored on the module.
61+
- All options from [Sensor](sensor/index).
62+
63+
- **last_face_id**: The last matched enrolled face as set by [`on_face_scan_matched`](#on_face_scan_matched-trigger).
64+
- All options from [Sensor](sensor/index).
65+
66+
- **status**: The integer representation of the internal status register of the module.
67+
- All options from [Sensor](sensor/index).
68+
69+
## Text Sensor
70+
71+
- **version**: The module's firmware version.
72+
- All options from [Text Sensor](text_sensor/index).
73+
74+
- **last_face_name**: The last matched enrolled face as set by [`on_face_scan_matched`](#on_face_scan_matched-trigger).
75+
- All options from [Text Sensor](text_sensor/index).
76+
77+
## `on_face_scan_matched` Trigger
78+
79+
With this configuration option you can write complex automations whenever a face scan is matched to an enrolled face.
80+
To use the variables, use a [lambda](lambda) template, the matched face id is available inside that lambda under the variable named `face_id` and the face name under the variable named `name`.
81+
82+
```yaml
83+
on_face_scan_matched:
84+
- text_sensor.template.publish:
85+
id: face_state
86+
state: !lambda 'return "Authorized face " + name + " (" + to_string(face_id) + ")";'
87+
# Pushing a tag_scanned event based on face_id
88+
- homeassistant.tag_scanned: !lambda |-
89+
switch (face_id) {
90+
case 0:
91+
return "person_a";
92+
case 1:
93+
return "person_b";
94+
...
95+
default:
96+
return "person_unknown";
97+
}
98+
```
99+
100+
## `on_face_scan_unmatched` Trigger
101+
102+
With this configuration option you can write complex automations whenever an unknown face is scanned.
103+
104+
```yaml
105+
on_face_scan_unmatched:
106+
- text_sensor.template.publish:
107+
id: face_state
108+
state: "Unauthorized face"
109+
```
110+
111+
## `on_face_scan_invalid` Trigger
112+
113+
With this configuration option you can write complex automations whenever a scan fails, e.g. when no face is visible. This is different from `on_face_scan_unmatched` which is triggered when an unknown face is scanned.
114+
To use the variable, use a [lambda](lambda) template, the error number is available inside that lambda under the variable named `error`.
115+
116+
```yaml
117+
on_face_scan_invalid:
118+
- text_sensor.template.publish:
119+
id: face_state
120+
state: !lambda 'return "Invalid face. Error number: " + to_string(error);'
121+
```
122+
123+
## `on_face_info` Trigger
124+
125+
With this configuration option you can write complex automations whenever face information is available.
126+
The module sends face info during enrollment and scanning, and it's mostly useful for debugging.
127+
To use the variables, use a [lambda](lambda) template, the status is available inside that lambda under the variable named `status`.
128+
A zero value means normal, and the datasheet contains various error status codes (e.g. 6 for the face being too far).
129+
There are additional values to determine the position (`left`, `top`, `right`, `bottom`) of the face in the frame as well as its rotation (`yaw`, `pitch`, `roll`).
130+
131+
```yaml
132+
on_face_info:
133+
- text_sensor.template.publish:
134+
id: face_info
135+
state: !lambda |-
136+
switch (status) {
137+
case 0:
138+
return "Normal";
139+
case 1:
140+
return "No face detected";
141+
case 2:
142+
return "Face too high";
143+
case 3:
144+
return "Face too low";
145+
...
146+
default:
147+
return "Unknown status " + to_string(status);
148+
}
149+
```
150+
151+
## `on_enrollment_done` Trigger
152+
153+
With this configuration option you can write complex automations whenever an enrollment step for a face is successful.
154+
To use the variables, use a [lambda](lambda) template, the slot number enrolled into is available inside that lambda under the variable named `face_id`.
155+
Note that the value is only valid after the face has been enrolled in all directions (otherwise it will be -1).
156+
The direction value is a bitmask representing the directions that have been captured so far. A value of `0x1f` means all directions have been captured and the face id should be valid.
157+
158+
```yaml
159+
on_enrollment_done:
160+
- text_sensor.template.publish:
161+
id: face_state
162+
state: !lambda 'return "Enrolled into slot " + to_string(face_id);'
163+
```
164+
165+
## `on_enrollment_failed` Trigger
166+
167+
With this configuration option you can write complex automations whenever a face failed to be enrolled.
168+
To use the variable, use a [lambda](lambda) template, the error number is available inside that lambda under the variable named `error`.
169+
170+
```yaml
171+
on_enrollment_failed:
172+
- text_sensor.template.publish:
173+
id: face_state
174+
state: !lambda 'return "Failed to enroll face. Error: " + to_string(error);'
175+
```
176+
177+
## `hlk_fm22x.enroll` Action
178+
179+
Starts the face enrollment process with a name and direction.
180+
To successfully enroll a face, you need to successfully and consecutively scan the face from all directions.
181+
A failure in one direction will require enrolling the face again from the start.
182+
183+
```yaml
184+
on_...:
185+
then:
186+
- hlk_fm22x.enroll:
187+
name: "My name"
188+
direction: 1
189+
# Update the template text sensor for visual feedback
190+
- text_sensor.template.publish:
191+
id: face_state
192+
state: "Look directly at the camera"
193+
```
194+
195+
**Configuration options:**
196+
197+
- **name** (**Required**, string, templatable): The name associated with the face. Up to 32 ASCII characters.
198+
- **direction** (**Required**, int, templatable): The direction to scan the face for. `1` for center, `2` for right, `4` for left, `8` for down, and `16` for up.
199+
200+
## `hlk_fm22x.scan` Action
201+
202+
Scans and tries to match to an enrolled face. Triggers one of the on_face_scan triggers.
203+
204+
```yaml
205+
on_...:
206+
then:
207+
- hlk_fm22x.scan:
208+
```
209+
210+
## `hlk_fm22x.delete` Action
211+
212+
Removes the enrolled face from the slot number defined.
213+
214+
```yaml
215+
on_...:
216+
then:
217+
- hlk_fm22x.delete:
218+
face_id: 0
219+
# Shorthand
220+
- hlk_fm22x.delete: 0
221+
```
222+
223+
**Configuration options:**
224+
225+
- **face_id** (**Required**, int, templatable): The slot number of the enrolled face to delete.
226+
227+
## `hlk_fm22x.delete_all` Action
228+
229+
Removes all enrolled faces.
230+
231+
```yaml
232+
on_...:
233+
then:
234+
- hlk_fm22x.delete_all:
235+
```
236+
237+
## `hlk_fm22x.reset` Action
238+
239+
Resets the module. Can be useful after a failed enrollment or scan if the module isn't responding correctly.
240+
If this command fails it will mark the module as failed.
241+
242+
```yaml
243+
on_...:
244+
then:
245+
- hlk_fm22x.reset:
246+
```
247+
248+
## All actions
249+
250+
- **id** (*Optional*, ID): Manually specify the ID of the HLK-FM22x reader if you have multiple components.
251+
252+
## Test setup
253+
254+
With the following code you can quickly setup a node and use Home Assistant's action in the developer tools.
255+
E.g. for calling `hlk_fm22x.enroll` select the action `esphome.test_node_enroll` and in action data enter
256+
257+
```json
258+
{ "name": "My name", "direction": 1 }
259+
```
260+
261+
### Sample code
262+
263+
```yaml
264+
uart:
265+
rx_pin: GPIOXX
266+
tx_pin: GPIOXX
267+
baud_rate: 115200
268+
269+
hlk_fm22x:
270+
on_face_scan_invalid:
271+
- homeassistant.event:
272+
event: esphome.test_node_face_scan_invalid
273+
data:
274+
error: !lambda 'return error;'
275+
on_face_scan_matched:
276+
- homeassistant.event:
277+
event: esphome.test_node_face_scan_matched
278+
data:
279+
face_id: !lambda 'return face_id;'
280+
name: !lambda 'return name;'
281+
on_face_scan_unmatched:
282+
- homeassistant.event:
283+
event: esphome.test_node_face_scan_unmatched
284+
on_face_info:
285+
- homeassistant.event:
286+
event: esphome.test_node_face_info
287+
data:
288+
status: !lambda 'return status;'
289+
left: !lambda 'return left;'
290+
top: !lambda 'return top;'
291+
right: !lambda 'return right;'
292+
bottom: !lambda 'return bottom;'
293+
yaw: !lambda 'return yaw;'
294+
pitch: !lambda 'return pitch;'
295+
roll: !lambda 'return roll;'
296+
on_enrollment_done:
297+
- homeassistant.event:
298+
event: esphome.test_node_enrollment_done
299+
data:
300+
face_id: !lambda 'return face_id;'
301+
direction: !lambda 'return direction;'
302+
on_enrollment_failed:
303+
- homeassistant.event:
304+
event: esphome.test_node_enrollment_failed
305+
data:
306+
error: !lambda 'return error;'
307+
308+
api:
309+
actions:
310+
- action: enroll
311+
variables:
312+
name: string
313+
direction: int
314+
then:
315+
- hlk_fm22x.enroll:
316+
name: !lambda 'return name;'
317+
direction: !lambda 'return direction;'
318+
- action: scan
319+
then:
320+
- hlk_fm22x.scan:
321+
- action: delete
322+
variables:
323+
face_id: int
324+
then:
325+
- hlk_fm22x.delete:
326+
face_id: !lambda 'return face_id;'
327+
- action: delete_all
328+
then:
329+
- hlk_fm22x.delete_all:
330+
- action: reset
331+
then:
332+
- hlk_fm22x.reset:
333+
```
334+
335+
## See Also
336+
337+
- {{< apiref "hlk_fm22x/hlk_fm22x.h" >}}
258 KB
Loading
157 KB
Loading

0 commit comments

Comments
 (0)