Skip to main content

Zk

Struct Zk 

Source
pub struct Zk { /* private fields */ }
Expand description

A connection to a single ZKTeco terminal.

Construct one with Zk::builder, then connect:

use zkteco::Zk;
let mut zk = Zk::builder("192.168.1.201").build();
zk.connect()?;
for user in zk.get_users()? {
    println!("{user}");
}
zk.disconnect()?;

Implementations§

Source§

impl Zk

Source

pub fn builder(ip: impl Into<String>) -> ZkBuilder

Begin configuring a connection to ip.

Examples found in repository?
examples/get_attendance.rs (line 13)
8fn main() -> zkteco::ZkResult<()> {
9    let mut args = std::env::args().skip(1);
10    let ip = args.next().expect("usage: get_attendance <ip> [port]");
11    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
12
13    let mut zk = Zk::builder(ip)
14        .port(port)
15        .timeout(Duration::from_secs(15))
16        .omit_ping(true)
17        .build();
18
19    zk.connect()?;
20    zk.disable_device()?;
21    let logs = zk.get_attendance()?;
22    zk.enable_device()?;
23    zk.disconnect()?;
24
25    println!("{} records", logs.len());
26    for a in logs {
27        println!(
28            "  {} user={} status={} {}",
29            a.timestamp,
30            a.user_id,
31            a.status,
32            a.punch_label()
33        );
34    }
35    Ok(())
36}
More examples
Hide additional examples
examples/get_users.rs (line 13)
8fn main() -> zkteco::ZkResult<()> {
9    let mut args = std::env::args().skip(1);
10    let ip = args.next().expect("usage: get_users <ip> [port]");
11    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
12
13    let mut zk = Zk::builder(ip)
14        .port(port)
15        .timeout(Duration::from_secs(10))
16        .omit_ping(true)
17        .build();
18
19    zk.connect()?;
20    // Disable user interaction while we read in bulk, then restore it.
21    zk.disable_device()?;
22    let users = zk.get_users()?;
23    zk.enable_device()?;
24    zk.disconnect()?;
25
26    println!("{} users", users.len());
27    for u in users {
28        println!(
29            "  uid={:<4} id={:<10} name={:<20} priv={} card={}",
30            u.uid, u.user_id, u.name, u.privilege, u.card
31        );
32    }
33    Ok(())
34}
examples/device_info.rs (line 11)
8fn main() -> zkteco::ZkResult<()> {
9    let (ip, port) = parse_args();
10
11    let mut zk = Zk::builder(ip)
12        .port(port)
13        .timeout(Duration::from_secs(10))
14        // Many devices live on networks that block ICMP; skip the ping probe.
15        .omit_ping(true)
16        .build();
17
18    zk.connect()?;
19    println!("connected: {zk}");
20
21    println!("firmware:    {}", zk.get_firmware_version()?);
22    println!("serial:      {}", zk.get_serialnumber()?);
23    println!("platform:    {}", zk.get_platform()?);
24    println!("device name: {}", zk.get_device_name()?);
25    println!("mac:         {}", zk.get_mac().unwrap_or_default());
26    println!("time:        {}", zk.get_time()?);
27
28    let sizes = zk.read_sizes()?;
29    println!("sizes:       {sizes:?}");
30
31    zk.disconnect()?;
32    Ok(())
33}
examples/live_capture.rs (line 14)
9fn main() -> zkteco::ZkResult<()> {
10    let mut args = std::env::args().skip(1);
11    let ip = args.next().expect("usage: live_capture <ip> [port]");
12    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
13
14    let mut zk = Zk::builder(ip)
15        .port(port)
16        .timeout(Duration::from_secs(30))
17        .omit_ping(true)
18        .build();
19
20    zk.connect()?;
21    println!("listening for punches (Ctrl-C to stop)...");
22
23    let mut capture = zk.live_capture(Duration::from_secs(10))?;
24
25    // Stop the loop on Ctrl-C by flipping the shared stop flag.
26    let stop = capture.stop_handle();
27    ctrlc_set(move || stop.store(true, Ordering::SeqCst));
28
29    for event in &mut capture {
30        match event? {
31            Some(att) => println!("punch: {att}"),
32            None => println!("(tick — no punch in the last interval)"),
33        }
34    }
35    println!("stopped.");
36    Ok(())
37}
examples/set_delete_user.rs (line 15)
10fn main() -> zkteco::ZkResult<()> {
11    let mut args = std::env::args().skip(1);
12    let ip = args.next().expect("usage: set_delete_user <ip> [port]");
13    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
14
15    let mut zk = Zk::builder(ip)
16        .port(port)
17        .timeout(Duration::from_secs(10))
18        .omit_ping(true)
19        .build();
20
21    zk.connect()?;
22    zk.disable_device()?;
23
24    // Populate next_uid / next_user_id by reading current users first.
25    let _ = zk.get_users()?;
26
27    // uid = 0 asks the crate to assign the next free uid / user_id.
28    let user = User::new(0, "Test User", USER_DEFAULT, "1234", "", "", 0);
29    zk.set_user(&user)?;
30    println!("created a user; uid counter now {}", zk.next_uid());
31
32    // Delete by user_id (uid = 0 triggers a lookup).
33    let created = zk.get_users()?;
34    if let Some(last) = created.iter().max_by_key(|u| u.uid) {
35        println!("deleting uid={} id={}", last.uid, last.user_id);
36        zk.delete_user(last.uid, &last.user_id)?;
37    }
38
39    zk.enable_device()?;
40    zk.disconnect()?;
41    Ok(())
42}
Source

pub fn is_connected(&self) -> bool

true while a session is open.

Source

pub fn is_enabled(&self) -> bool

true while the device is enabled (accepting user interaction).

Source

pub fn next_uid(&self) -> u16

The next user index this crate would auto-assign (populated by get_users).

Examples found in repository?
examples/set_delete_user.rs (line 30)
10fn main() -> zkteco::ZkResult<()> {
11    let mut args = std::env::args().skip(1);
12    let ip = args.next().expect("usage: set_delete_user <ip> [port]");
13    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
14
15    let mut zk = Zk::builder(ip)
16        .port(port)
17        .timeout(Duration::from_secs(10))
18        .omit_ping(true)
19        .build();
20
21    zk.connect()?;
22    zk.disable_device()?;
23
24    // Populate next_uid / next_user_id by reading current users first.
25    let _ = zk.get_users()?;
26
27    // uid = 0 asks the crate to assign the next free uid / user_id.
28    let user = User::new(0, "Test User", USER_DEFAULT, "1234", "", "", 0);
29    zk.set_user(&user)?;
30    println!("created a user; uid counter now {}", zk.next_uid());
31
32    // Delete by user_id (uid = 0 triggers a lookup).
33    let created = zk.get_users()?;
34    if let Some(last) = created.iter().max_by_key(|u| u.uid) {
35        println!("deleting uid={} id={}", last.uid, last.user_id);
36        zk.delete_user(last.uid, &last.user_id)?;
37    }
38
39    zk.enable_device()?;
40    zk.disconnect()?;
41    Ok(())
42}
Source

pub fn next_user_id(&self) -> &str

The next free user-id string (populated by get_users).

Source

pub fn sizes(&self) -> DeviceSizes

The most recent capacity snapshot (see read_sizes).

Source

pub fn connect(&mut self) -> ZkResult<()>

Open the socket, start a session, and authenticate if required.

Examples found in repository?
examples/get_attendance.rs (line 19)
8fn main() -> zkteco::ZkResult<()> {
9    let mut args = std::env::args().skip(1);
10    let ip = args.next().expect("usage: get_attendance <ip> [port]");
11    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
12
13    let mut zk = Zk::builder(ip)
14        .port(port)
15        .timeout(Duration::from_secs(15))
16        .omit_ping(true)
17        .build();
18
19    zk.connect()?;
20    zk.disable_device()?;
21    let logs = zk.get_attendance()?;
22    zk.enable_device()?;
23    zk.disconnect()?;
24
25    println!("{} records", logs.len());
26    for a in logs {
27        println!(
28            "  {} user={} status={} {}",
29            a.timestamp,
30            a.user_id,
31            a.status,
32            a.punch_label()
33        );
34    }
35    Ok(())
36}
More examples
Hide additional examples
examples/get_users.rs (line 19)
8fn main() -> zkteco::ZkResult<()> {
9    let mut args = std::env::args().skip(1);
10    let ip = args.next().expect("usage: get_users <ip> [port]");
11    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
12
13    let mut zk = Zk::builder(ip)
14        .port(port)
15        .timeout(Duration::from_secs(10))
16        .omit_ping(true)
17        .build();
18
19    zk.connect()?;
20    // Disable user interaction while we read in bulk, then restore it.
21    zk.disable_device()?;
22    let users = zk.get_users()?;
23    zk.enable_device()?;
24    zk.disconnect()?;
25
26    println!("{} users", users.len());
27    for u in users {
28        println!(
29            "  uid={:<4} id={:<10} name={:<20} priv={} card={}",
30            u.uid, u.user_id, u.name, u.privilege, u.card
31        );
32    }
33    Ok(())
34}
examples/device_info.rs (line 18)
8fn main() -> zkteco::ZkResult<()> {
9    let (ip, port) = parse_args();
10
11    let mut zk = Zk::builder(ip)
12        .port(port)
13        .timeout(Duration::from_secs(10))
14        // Many devices live on networks that block ICMP; skip the ping probe.
15        .omit_ping(true)
16        .build();
17
18    zk.connect()?;
19    println!("connected: {zk}");
20
21    println!("firmware:    {}", zk.get_firmware_version()?);
22    println!("serial:      {}", zk.get_serialnumber()?);
23    println!("platform:    {}", zk.get_platform()?);
24    println!("device name: {}", zk.get_device_name()?);
25    println!("mac:         {}", zk.get_mac().unwrap_or_default());
26    println!("time:        {}", zk.get_time()?);
27
28    let sizes = zk.read_sizes()?;
29    println!("sizes:       {sizes:?}");
30
31    zk.disconnect()?;
32    Ok(())
33}
examples/live_capture.rs (line 20)
9fn main() -> zkteco::ZkResult<()> {
10    let mut args = std::env::args().skip(1);
11    let ip = args.next().expect("usage: live_capture <ip> [port]");
12    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
13
14    let mut zk = Zk::builder(ip)
15        .port(port)
16        .timeout(Duration::from_secs(30))
17        .omit_ping(true)
18        .build();
19
20    zk.connect()?;
21    println!("listening for punches (Ctrl-C to stop)...");
22
23    let mut capture = zk.live_capture(Duration::from_secs(10))?;
24
25    // Stop the loop on Ctrl-C by flipping the shared stop flag.
26    let stop = capture.stop_handle();
27    ctrlc_set(move || stop.store(true, Ordering::SeqCst));
28
29    for event in &mut capture {
30        match event? {
31            Some(att) => println!("punch: {att}"),
32            None => println!("(tick — no punch in the last interval)"),
33        }
34    }
35    println!("stopped.");
36    Ok(())
37}
examples/set_delete_user.rs (line 21)
10fn main() -> zkteco::ZkResult<()> {
11    let mut args = std::env::args().skip(1);
12    let ip = args.next().expect("usage: set_delete_user <ip> [port]");
13    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
14
15    let mut zk = Zk::builder(ip)
16        .port(port)
17        .timeout(Duration::from_secs(10))
18        .omit_ping(true)
19        .build();
20
21    zk.connect()?;
22    zk.disable_device()?;
23
24    // Populate next_uid / next_user_id by reading current users first.
25    let _ = zk.get_users()?;
26
27    // uid = 0 asks the crate to assign the next free uid / user_id.
28    let user = User::new(0, "Test User", USER_DEFAULT, "1234", "", "", 0);
29    zk.set_user(&user)?;
30    println!("created a user; uid counter now {}", zk.next_uid());
31
32    // Delete by user_id (uid = 0 triggers a lookup).
33    let created = zk.get_users()?;
34    if let Some(last) = created.iter().max_by_key(|u| u.uid) {
35        println!("deleting uid={} id={}", last.uid, last.user_id);
36        zk.delete_user(last.uid, &last.user_id)?;
37    }
38
39    zk.enable_device()?;
40    zk.disconnect()?;
41    Ok(())
42}
Source

pub fn disconnect(&mut self) -> ZkResult<()>

Close the session and the socket.

Examples found in repository?
examples/get_attendance.rs (line 23)
8fn main() -> zkteco::ZkResult<()> {
9    let mut args = std::env::args().skip(1);
10    let ip = args.next().expect("usage: get_attendance <ip> [port]");
11    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
12
13    let mut zk = Zk::builder(ip)
14        .port(port)
15        .timeout(Duration::from_secs(15))
16        .omit_ping(true)
17        .build();
18
19    zk.connect()?;
20    zk.disable_device()?;
21    let logs = zk.get_attendance()?;
22    zk.enable_device()?;
23    zk.disconnect()?;
24
25    println!("{} records", logs.len());
26    for a in logs {
27        println!(
28            "  {} user={} status={} {}",
29            a.timestamp,
30            a.user_id,
31            a.status,
32            a.punch_label()
33        );
34    }
35    Ok(())
36}
More examples
Hide additional examples
examples/get_users.rs (line 24)
8fn main() -> zkteco::ZkResult<()> {
9    let mut args = std::env::args().skip(1);
10    let ip = args.next().expect("usage: get_users <ip> [port]");
11    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
12
13    let mut zk = Zk::builder(ip)
14        .port(port)
15        .timeout(Duration::from_secs(10))
16        .omit_ping(true)
17        .build();
18
19    zk.connect()?;
20    // Disable user interaction while we read in bulk, then restore it.
21    zk.disable_device()?;
22    let users = zk.get_users()?;
23    zk.enable_device()?;
24    zk.disconnect()?;
25
26    println!("{} users", users.len());
27    for u in users {
28        println!(
29            "  uid={:<4} id={:<10} name={:<20} priv={} card={}",
30            u.uid, u.user_id, u.name, u.privilege, u.card
31        );
32    }
33    Ok(())
34}
examples/device_info.rs (line 31)
8fn main() -> zkteco::ZkResult<()> {
9    let (ip, port) = parse_args();
10
11    let mut zk = Zk::builder(ip)
12        .port(port)
13        .timeout(Duration::from_secs(10))
14        // Many devices live on networks that block ICMP; skip the ping probe.
15        .omit_ping(true)
16        .build();
17
18    zk.connect()?;
19    println!("connected: {zk}");
20
21    println!("firmware:    {}", zk.get_firmware_version()?);
22    println!("serial:      {}", zk.get_serialnumber()?);
23    println!("platform:    {}", zk.get_platform()?);
24    println!("device name: {}", zk.get_device_name()?);
25    println!("mac:         {}", zk.get_mac().unwrap_or_default());
26    println!("time:        {}", zk.get_time()?);
27
28    let sizes = zk.read_sizes()?;
29    println!("sizes:       {sizes:?}");
30
31    zk.disconnect()?;
32    Ok(())
33}
examples/set_delete_user.rs (line 40)
10fn main() -> zkteco::ZkResult<()> {
11    let mut args = std::env::args().skip(1);
12    let ip = args.next().expect("usage: set_delete_user <ip> [port]");
13    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
14
15    let mut zk = Zk::builder(ip)
16        .port(port)
17        .timeout(Duration::from_secs(10))
18        .omit_ping(true)
19        .build();
20
21    zk.connect()?;
22    zk.disable_device()?;
23
24    // Populate next_uid / next_user_id by reading current users first.
25    let _ = zk.get_users()?;
26
27    // uid = 0 asks the crate to assign the next free uid / user_id.
28    let user = User::new(0, "Test User", USER_DEFAULT, "1234", "", "", 0);
29    zk.set_user(&user)?;
30    println!("created a user; uid counter now {}", zk.next_uid());
31
32    // Delete by user_id (uid = 0 triggers a lookup).
33    let created = zk.get_users()?;
34    if let Some(last) = created.iter().max_by_key(|u| u.uid) {
35        println!("deleting uid={} id={}", last.uid, last.user_id);
36        zk.delete_user(last.uid, &last.user_id)?;
37    }
38
39    zk.enable_device()?;
40    zk.disconnect()?;
41    Ok(())
42}
Source

pub fn enable_device(&mut self) -> ZkResult<()>

Re-enable the device (allow user interaction).

Examples found in repository?
examples/get_attendance.rs (line 22)
8fn main() -> zkteco::ZkResult<()> {
9    let mut args = std::env::args().skip(1);
10    let ip = args.next().expect("usage: get_attendance <ip> [port]");
11    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
12
13    let mut zk = Zk::builder(ip)
14        .port(port)
15        .timeout(Duration::from_secs(15))
16        .omit_ping(true)
17        .build();
18
19    zk.connect()?;
20    zk.disable_device()?;
21    let logs = zk.get_attendance()?;
22    zk.enable_device()?;
23    zk.disconnect()?;
24
25    println!("{} records", logs.len());
26    for a in logs {
27        println!(
28            "  {} user={} status={} {}",
29            a.timestamp,
30            a.user_id,
31            a.status,
32            a.punch_label()
33        );
34    }
35    Ok(())
36}
More examples
Hide additional examples
examples/get_users.rs (line 23)
8fn main() -> zkteco::ZkResult<()> {
9    let mut args = std::env::args().skip(1);
10    let ip = args.next().expect("usage: get_users <ip> [port]");
11    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
12
13    let mut zk = Zk::builder(ip)
14        .port(port)
15        .timeout(Duration::from_secs(10))
16        .omit_ping(true)
17        .build();
18
19    zk.connect()?;
20    // Disable user interaction while we read in bulk, then restore it.
21    zk.disable_device()?;
22    let users = zk.get_users()?;
23    zk.enable_device()?;
24    zk.disconnect()?;
25
26    println!("{} users", users.len());
27    for u in users {
28        println!(
29            "  uid={:<4} id={:<10} name={:<20} priv={} card={}",
30            u.uid, u.user_id, u.name, u.privilege, u.card
31        );
32    }
33    Ok(())
34}
examples/set_delete_user.rs (line 39)
10fn main() -> zkteco::ZkResult<()> {
11    let mut args = std::env::args().skip(1);
12    let ip = args.next().expect("usage: set_delete_user <ip> [port]");
13    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
14
15    let mut zk = Zk::builder(ip)
16        .port(port)
17        .timeout(Duration::from_secs(10))
18        .omit_ping(true)
19        .build();
20
21    zk.connect()?;
22    zk.disable_device()?;
23
24    // Populate next_uid / next_user_id by reading current users first.
25    let _ = zk.get_users()?;
26
27    // uid = 0 asks the crate to assign the next free uid / user_id.
28    let user = User::new(0, "Test User", USER_DEFAULT, "1234", "", "", 0);
29    zk.set_user(&user)?;
30    println!("created a user; uid counter now {}", zk.next_uid());
31
32    // Delete by user_id (uid = 0 triggers a lookup).
33    let created = zk.get_users()?;
34    if let Some(last) = created.iter().max_by_key(|u| u.uid) {
35        println!("deleting uid={} id={}", last.uid, last.user_id);
36        zk.delete_user(last.uid, &last.user_id)?;
37    }
38
39    zk.enable_device()?;
40    zk.disconnect()?;
41    Ok(())
42}
Source

pub fn disable_device(&mut self) -> ZkResult<()>

Disable the device (lock out users during bulk operations).

Examples found in repository?
examples/get_attendance.rs (line 20)
8fn main() -> zkteco::ZkResult<()> {
9    let mut args = std::env::args().skip(1);
10    let ip = args.next().expect("usage: get_attendance <ip> [port]");
11    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
12
13    let mut zk = Zk::builder(ip)
14        .port(port)
15        .timeout(Duration::from_secs(15))
16        .omit_ping(true)
17        .build();
18
19    zk.connect()?;
20    zk.disable_device()?;
21    let logs = zk.get_attendance()?;
22    zk.enable_device()?;
23    zk.disconnect()?;
24
25    println!("{} records", logs.len());
26    for a in logs {
27        println!(
28            "  {} user={} status={} {}",
29            a.timestamp,
30            a.user_id,
31            a.status,
32            a.punch_label()
33        );
34    }
35    Ok(())
36}
More examples
Hide additional examples
examples/get_users.rs (line 21)
8fn main() -> zkteco::ZkResult<()> {
9    let mut args = std::env::args().skip(1);
10    let ip = args.next().expect("usage: get_users <ip> [port]");
11    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
12
13    let mut zk = Zk::builder(ip)
14        .port(port)
15        .timeout(Duration::from_secs(10))
16        .omit_ping(true)
17        .build();
18
19    zk.connect()?;
20    // Disable user interaction while we read in bulk, then restore it.
21    zk.disable_device()?;
22    let users = zk.get_users()?;
23    zk.enable_device()?;
24    zk.disconnect()?;
25
26    println!("{} users", users.len());
27    for u in users {
28        println!(
29            "  uid={:<4} id={:<10} name={:<20} priv={} card={}",
30            u.uid, u.user_id, u.name, u.privilege, u.card
31        );
32    }
33    Ok(())
34}
examples/set_delete_user.rs (line 22)
10fn main() -> zkteco::ZkResult<()> {
11    let mut args = std::env::args().skip(1);
12    let ip = args.next().expect("usage: set_delete_user <ip> [port]");
13    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
14
15    let mut zk = Zk::builder(ip)
16        .port(port)
17        .timeout(Duration::from_secs(10))
18        .omit_ping(true)
19        .build();
20
21    zk.connect()?;
22    zk.disable_device()?;
23
24    // Populate next_uid / next_user_id by reading current users first.
25    let _ = zk.get_users()?;
26
27    // uid = 0 asks the crate to assign the next free uid / user_id.
28    let user = User::new(0, "Test User", USER_DEFAULT, "1234", "", "", 0);
29    zk.set_user(&user)?;
30    println!("created a user; uid counter now {}", zk.next_uid());
31
32    // Delete by user_id (uid = 0 triggers a lookup).
33    let created = zk.get_users()?;
34    if let Some(last) = created.iter().max_by_key(|u| u.uid) {
35        println!("deleting uid={} id={}", last.uid, last.user_id);
36        zk.delete_user(last.uid, &last.user_id)?;
37    }
38
39    zk.enable_device()?;
40    zk.disconnect()?;
41    Ok(())
42}
Source

pub fn get_firmware_version(&mut self) -> ZkResult<String>

Firmware version string.

Examples found in repository?
examples/device_info.rs (line 21)
8fn main() -> zkteco::ZkResult<()> {
9    let (ip, port) = parse_args();
10
11    let mut zk = Zk::builder(ip)
12        .port(port)
13        .timeout(Duration::from_secs(10))
14        // Many devices live on networks that block ICMP; skip the ping probe.
15        .omit_ping(true)
16        .build();
17
18    zk.connect()?;
19    println!("connected: {zk}");
20
21    println!("firmware:    {}", zk.get_firmware_version()?);
22    println!("serial:      {}", zk.get_serialnumber()?);
23    println!("platform:    {}", zk.get_platform()?);
24    println!("device name: {}", zk.get_device_name()?);
25    println!("mac:         {}", zk.get_mac().unwrap_or_default());
26    println!("time:        {}", zk.get_time()?);
27
28    let sizes = zk.read_sizes()?;
29    println!("sizes:       {sizes:?}");
30
31    zk.disconnect()?;
32    Ok(())
33}
Source

pub fn get_serialnumber(&mut self) -> ZkResult<String>

Device serial number.

Examples found in repository?
examples/device_info.rs (line 22)
8fn main() -> zkteco::ZkResult<()> {
9    let (ip, port) = parse_args();
10
11    let mut zk = Zk::builder(ip)
12        .port(port)
13        .timeout(Duration::from_secs(10))
14        // Many devices live on networks that block ICMP; skip the ping probe.
15        .omit_ping(true)
16        .build();
17
18    zk.connect()?;
19    println!("connected: {zk}");
20
21    println!("firmware:    {}", zk.get_firmware_version()?);
22    println!("serial:      {}", zk.get_serialnumber()?);
23    println!("platform:    {}", zk.get_platform()?);
24    println!("device name: {}", zk.get_device_name()?);
25    println!("mac:         {}", zk.get_mac().unwrap_or_default());
26    println!("time:        {}", zk.get_time()?);
27
28    let sizes = zk.read_sizes()?;
29    println!("sizes:       {sizes:?}");
30
31    zk.disconnect()?;
32    Ok(())
33}
Source

pub fn get_platform(&mut self) -> ZkResult<String>

Platform name.

Examples found in repository?
examples/device_info.rs (line 23)
8fn main() -> zkteco::ZkResult<()> {
9    let (ip, port) = parse_args();
10
11    let mut zk = Zk::builder(ip)
12        .port(port)
13        .timeout(Duration::from_secs(10))
14        // Many devices live on networks that block ICMP; skip the ping probe.
15        .omit_ping(true)
16        .build();
17
18    zk.connect()?;
19    println!("connected: {zk}");
20
21    println!("firmware:    {}", zk.get_firmware_version()?);
22    println!("serial:      {}", zk.get_serialnumber()?);
23    println!("platform:    {}", zk.get_platform()?);
24    println!("device name: {}", zk.get_device_name()?);
25    println!("mac:         {}", zk.get_mac().unwrap_or_default());
26    println!("time:        {}", zk.get_time()?);
27
28    let sizes = zk.read_sizes()?;
29    println!("sizes:       {sizes:?}");
30
31    zk.disconnect()?;
32    Ok(())
33}
Source

pub fn get_mac(&mut self) -> ZkResult<String>

MAC address.

Examples found in repository?
examples/device_info.rs (line 25)
8fn main() -> zkteco::ZkResult<()> {
9    let (ip, port) = parse_args();
10
11    let mut zk = Zk::builder(ip)
12        .port(port)
13        .timeout(Duration::from_secs(10))
14        // Many devices live on networks that block ICMP; skip the ping probe.
15        .omit_ping(true)
16        .build();
17
18    zk.connect()?;
19    println!("connected: {zk}");
20
21    println!("firmware:    {}", zk.get_firmware_version()?);
22    println!("serial:      {}", zk.get_serialnumber()?);
23    println!("platform:    {}", zk.get_platform()?);
24    println!("device name: {}", zk.get_device_name()?);
25    println!("mac:         {}", zk.get_mac().unwrap_or_default());
26    println!("time:        {}", zk.get_time()?);
27
28    let sizes = zk.read_sizes()?;
29    println!("sizes:       {sizes:?}");
30
31    zk.disconnect()?;
32    Ok(())
33}
Source

pub fn get_device_name(&mut self) -> ZkResult<String>

Device name (empty string if unavailable).

Examples found in repository?
examples/device_info.rs (line 24)
8fn main() -> zkteco::ZkResult<()> {
9    let (ip, port) = parse_args();
10
11    let mut zk = Zk::builder(ip)
12        .port(port)
13        .timeout(Duration::from_secs(10))
14        // Many devices live on networks that block ICMP; skip the ping probe.
15        .omit_ping(true)
16        .build();
17
18    zk.connect()?;
19    println!("connected: {zk}");
20
21    println!("firmware:    {}", zk.get_firmware_version()?);
22    println!("serial:      {}", zk.get_serialnumber()?);
23    println!("platform:    {}", zk.get_platform()?);
24    println!("device name: {}", zk.get_device_name()?);
25    println!("mac:         {}", zk.get_mac().unwrap_or_default());
26    println!("time:        {}", zk.get_time()?);
27
28    let sizes = zk.read_sizes()?;
29    println!("sizes:       {sizes:?}");
30
31    zk.disconnect()?;
32    Ok(())
33}
Source

pub fn get_face_version(&mut self) -> ZkResult<Option<u32>>

Face-engine version (0 if none, None if the option is missing).

Source

pub fn get_fp_version(&mut self) -> ZkResult<u32>

Fingerprint algorithm version.

Source

pub fn get_network_params(&mut self) -> ZkResult<NetworkParams>

Read network parameters (IP / mask / gateway).

Source

pub fn get_pin_width(&mut self) -> ZkResult<u8>

Configured user-id (PIN) width in characters.

Source

pub fn read_sizes(&mut self) -> ZkResult<DeviceSizes>

Read device memory / record counters into DeviceSizes (also cached on self, see sizes).

Examples found in repository?
examples/device_info.rs (line 28)
8fn main() -> zkteco::ZkResult<()> {
9    let (ip, port) = parse_args();
10
11    let mut zk = Zk::builder(ip)
12        .port(port)
13        .timeout(Duration::from_secs(10))
14        // Many devices live on networks that block ICMP; skip the ping probe.
15        .omit_ping(true)
16        .build();
17
18    zk.connect()?;
19    println!("connected: {zk}");
20
21    println!("firmware:    {}", zk.get_firmware_version()?);
22    println!("serial:      {}", zk.get_serialnumber()?);
23    println!("platform:    {}", zk.get_platform()?);
24    println!("device name: {}", zk.get_device_name()?);
25    println!("mac:         {}", zk.get_mac().unwrap_or_default());
26    println!("time:        {}", zk.get_time()?);
27
28    let sizes = zk.read_sizes()?;
29    println!("sizes:       {sizes:?}");
30
31    zk.disconnect()?;
32    Ok(())
33}
Source

pub fn get_time(&mut self) -> ZkResult<NaiveDateTime>

Read the device clock.

Examples found in repository?
examples/device_info.rs (line 26)
8fn main() -> zkteco::ZkResult<()> {
9    let (ip, port) = parse_args();
10
11    let mut zk = Zk::builder(ip)
12        .port(port)
13        .timeout(Duration::from_secs(10))
14        // Many devices live on networks that block ICMP; skip the ping probe.
15        .omit_ping(true)
16        .build();
17
18    zk.connect()?;
19    println!("connected: {zk}");
20
21    println!("firmware:    {}", zk.get_firmware_version()?);
22    println!("serial:      {}", zk.get_serialnumber()?);
23    println!("platform:    {}", zk.get_platform()?);
24    println!("device name: {}", zk.get_device_name()?);
25    println!("mac:         {}", zk.get_mac().unwrap_or_default());
26    println!("time:        {}", zk.get_time()?);
27
28    let sizes = zk.read_sizes()?;
29    println!("sizes:       {sizes:?}");
30
31    zk.disconnect()?;
32    Ok(())
33}
Source

pub fn set_time(&mut self, timestamp: NaiveDateTime) -> ZkResult<()>

Set the device clock.

Source

pub fn restart(&mut self) -> ZkResult<()>

Restart the device (ends the session).

Source

pub fn poweroff(&mut self) -> ZkResult<()>

Power the device off (ends the session).

Source

pub fn refresh_data(&mut self) -> ZkResult<()>

Refresh the device’s internal data after writes.

Source

pub fn free_data(&mut self) -> ZkResult<()>

Clear the device’s open data buffer.

Source

pub fn test_voice(&mut self, index: u32) -> ZkResult<bool>

Play a built-in voice prompt / beep by index (see the device manual for the index table). Returns true if accepted.

Source

pub fn unlock(&mut self, seconds: u32) -> ZkResult<()>

Unlock the door for seconds seconds.

Source

pub fn get_lock_state(&mut self) -> ZkResult<bool>

Query the door/lock state. Returns true if the device acknowledges.

Source

pub fn write_lcd(&mut self, line_number: i16, text: &str) -> ZkResult<()>

Write text to a line of the device LCD.

Source

pub fn clear_lcd(&mut self) -> ZkResult<()>

Clear the device LCD.

Source

pub fn reg_event(&mut self, flags: u32) -> ZkResult<()>

Register for real-time events (bitmask of EF_*).

Source

pub fn cancel_capture(&mut self) -> ZkResult<bool>

Cancel an in-progress fingerprint capture.

Source

pub fn verify_user(&mut self) -> ZkResult<()>

Enter verify state (used around enroll / live capture).

Source

pub fn set_sdk_build_1(&mut self) -> ZkResult<bool>

Enable SDK build mode 1 (some devices need this before bulk reads).

Source

pub fn get_users(&mut self) -> ZkResult<Vec<User>>

Read all enrolled users.

Examples found in repository?
examples/get_users.rs (line 22)
8fn main() -> zkteco::ZkResult<()> {
9    let mut args = std::env::args().skip(1);
10    let ip = args.next().expect("usage: get_users <ip> [port]");
11    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
12
13    let mut zk = Zk::builder(ip)
14        .port(port)
15        .timeout(Duration::from_secs(10))
16        .omit_ping(true)
17        .build();
18
19    zk.connect()?;
20    // Disable user interaction while we read in bulk, then restore it.
21    zk.disable_device()?;
22    let users = zk.get_users()?;
23    zk.enable_device()?;
24    zk.disconnect()?;
25
26    println!("{} users", users.len());
27    for u in users {
28        println!(
29            "  uid={:<4} id={:<10} name={:<20} priv={} card={}",
30            u.uid, u.user_id, u.name, u.privilege, u.card
31        );
32    }
33    Ok(())
34}
More examples
Hide additional examples
examples/set_delete_user.rs (line 25)
10fn main() -> zkteco::ZkResult<()> {
11    let mut args = std::env::args().skip(1);
12    let ip = args.next().expect("usage: set_delete_user <ip> [port]");
13    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
14
15    let mut zk = Zk::builder(ip)
16        .port(port)
17        .timeout(Duration::from_secs(10))
18        .omit_ping(true)
19        .build();
20
21    zk.connect()?;
22    zk.disable_device()?;
23
24    // Populate next_uid / next_user_id by reading current users first.
25    let _ = zk.get_users()?;
26
27    // uid = 0 asks the crate to assign the next free uid / user_id.
28    let user = User::new(0, "Test User", USER_DEFAULT, "1234", "", "", 0);
29    zk.set_user(&user)?;
30    println!("created a user; uid counter now {}", zk.next_uid());
31
32    // Delete by user_id (uid = 0 triggers a lookup).
33    let created = zk.get_users()?;
34    if let Some(last) = created.iter().max_by_key(|u| u.uid) {
35        println!("deleting uid={} id={}", last.uid, last.user_id);
36        zk.delete_user(last.uid, &last.user_id)?;
37    }
38
39    zk.enable_device()?;
40    zk.disconnect()?;
41    Ok(())
42}
Source

pub fn set_user(&mut self, user: &User) -> ZkResult<()>

Create or update a user.

If user.uid is 0, the next free uid / user-id is assigned (call get_users first so the counters are populated).

Examples found in repository?
examples/set_delete_user.rs (line 29)
10fn main() -> zkteco::ZkResult<()> {
11    let mut args = std::env::args().skip(1);
12    let ip = args.next().expect("usage: set_delete_user <ip> [port]");
13    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
14
15    let mut zk = Zk::builder(ip)
16        .port(port)
17        .timeout(Duration::from_secs(10))
18        .omit_ping(true)
19        .build();
20
21    zk.connect()?;
22    zk.disable_device()?;
23
24    // Populate next_uid / next_user_id by reading current users first.
25    let _ = zk.get_users()?;
26
27    // uid = 0 asks the crate to assign the next free uid / user_id.
28    let user = User::new(0, "Test User", USER_DEFAULT, "1234", "", "", 0);
29    zk.set_user(&user)?;
30    println!("created a user; uid counter now {}", zk.next_uid());
31
32    // Delete by user_id (uid = 0 triggers a lookup).
33    let created = zk.get_users()?;
34    if let Some(last) = created.iter().max_by_key(|u| u.uid) {
35        println!("deleting uid={} id={}", last.uid, last.user_id);
36        zk.delete_user(last.uid, &last.user_id)?;
37    }
38
39    zk.enable_device()?;
40    zk.disconnect()?;
41    Ok(())
42}
Source

pub fn delete_user(&mut self, uid: u16, user_id: &str) -> ZkResult<()>

Delete a user by internal uid. If uid is 0, resolves it from user_id (which requires a get_users lookup).

Examples found in repository?
examples/set_delete_user.rs (line 36)
10fn main() -> zkteco::ZkResult<()> {
11    let mut args = std::env::args().skip(1);
12    let ip = args.next().expect("usage: set_delete_user <ip> [port]");
13    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
14
15    let mut zk = Zk::builder(ip)
16        .port(port)
17        .timeout(Duration::from_secs(10))
18        .omit_ping(true)
19        .build();
20
21    zk.connect()?;
22    zk.disable_device()?;
23
24    // Populate next_uid / next_user_id by reading current users first.
25    let _ = zk.get_users()?;
26
27    // uid = 0 asks the crate to assign the next free uid / user_id.
28    let user = User::new(0, "Test User", USER_DEFAULT, "1234", "", "", 0);
29    zk.set_user(&user)?;
30    println!("created a user; uid counter now {}", zk.next_uid());
31
32    // Delete by user_id (uid = 0 triggers a lookup).
33    let created = zk.get_users()?;
34    if let Some(last) = created.iter().max_by_key(|u| u.uid) {
35        println!("deleting uid={} id={}", last.uid, last.user_id);
36        zk.delete_user(last.uid, &last.user_id)?;
37    }
38
39    zk.enable_device()?;
40    zk.disconnect()?;
41    Ok(())
42}
Source

pub fn clear_data(&mut self) -> ZkResult<()>

Clear ALL data on the device (users, attendance, templates).

Source

pub fn get_attendance(&mut self) -> ZkResult<Vec<Attendance>>

Read all attendance records.

Examples found in repository?
examples/get_attendance.rs (line 21)
8fn main() -> zkteco::ZkResult<()> {
9    let mut args = std::env::args().skip(1);
10    let ip = args.next().expect("usage: get_attendance <ip> [port]");
11    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
12
13    let mut zk = Zk::builder(ip)
14        .port(port)
15        .timeout(Duration::from_secs(15))
16        .omit_ping(true)
17        .build();
18
19    zk.connect()?;
20    zk.disable_device()?;
21    let logs = zk.get_attendance()?;
22    zk.enable_device()?;
23    zk.disconnect()?;
24
25    println!("{} records", logs.len());
26    for a in logs {
27        println!(
28            "  {} user={} status={} {}",
29            a.timestamp,
30            a.user_id,
31            a.status,
32            a.punch_label()
33        );
34    }
35    Ok(())
36}
Source

pub fn clear_attendance(&mut self) -> ZkResult<()>

Clear all attendance records.

Source

pub fn get_templates(&mut self) -> ZkResult<Vec<Finger>>

Read all fingerprint templates.

Source

pub fn get_user_template( &mut self, uid: u16, finger_id: u8, ) -> ZkResult<Option<Finger>>

Fetch a single fingerprint template for (uid, finger_id).

Source

pub fn delete_user_template( &mut self, uid: u16, finger_id: u8, user_id: &str, ) -> ZkResult<bool>

Delete a single template. If uid is 0 it is resolved from user_id.

Source

pub fn enroll_user( &mut self, uid: u16, finger_id: u8, user_id: &str, ) -> ZkResult<bool>

Interactively enroll a fingerprint for an existing user.

This puts the device into enrollment mode; the person must press their finger on the sensor (typically three times). Returns true if a template was captured. If user_id is empty it is resolved from uid.

Note: this blocks while waiting for the person to interact with the device (the read timeout is temporarily raised to 60s, matching pyzk).

Source

pub fn save_user_template( &mut self, user: &User, fingers: &[Finger], ) -> ZkResult<()>

Save a user together with their fingerprint templates (high-rate upload).

Source

pub fn save_user_templates( &mut self, items: &[(User, Vec<Finger>)], ) -> ZkResult<()>

Save multiple users and their templates in a single buffered upload.

(pyzk’s HR_save_usertemplates.)

Source

pub fn live_capture( &mut self, poll_timeout: Duration, ) -> ZkResult<LiveCapture<'_>>

Start capturing attendance punches in real time.

Returns a LiveCapture iterator. Each next() yields:

  • Some(Ok(Some(att))) — a punch,
  • Some(Ok(None)) — a timeout “tick” (lets you poll the stop flag),
  • Some(Err(_)) — a fatal error,
  • None — the capture was stopped.

poll_timeout controls how often a tick is produced.

Examples found in repository?
examples/live_capture.rs (line 23)
9fn main() -> zkteco::ZkResult<()> {
10    let mut args = std::env::args().skip(1);
11    let ip = args.next().expect("usage: live_capture <ip> [port]");
12    let port: u16 = args.next().and_then(|p| p.parse().ok()).unwrap_or(4370);
13
14    let mut zk = Zk::builder(ip)
15        .port(port)
16        .timeout(Duration::from_secs(30))
17        .omit_ping(true)
18        .build();
19
20    zk.connect()?;
21    println!("listening for punches (Ctrl-C to stop)...");
22
23    let mut capture = zk.live_capture(Duration::from_secs(10))?;
24
25    // Stop the loop on Ctrl-C by flipping the shared stop flag.
26    let stop = capture.stop_handle();
27    ctrlc_set(move || stop.store(true, Ordering::SeqCst));
28
29    for event in &mut capture {
30        match event? {
31            Some(att) => println!("punch: {att}"),
32            None => println!("(tick — no punch in the last interval)"),
33        }
34    }
35    println!("stopped.");
36    Ok(())
37}

Trait Implementations§

Source§

impl Display for Zk

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl Freeze for Zk

§

impl RefUnwindSafe for Zk

§

impl Send for Zk

§

impl Sync for Zk

§

impl Unpin for Zk

§

impl UnsafeUnpin for Zk

§

impl UnwindSafe for Zk

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.