rbzk 0.1.3 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +304 -254
- data/lib/rbzk/cli/commands.rb +337 -55
- data/lib/rbzk/finger.rb +12 -1
- data/lib/rbzk/user.rb +34 -0
- data/lib/rbzk/version.rb +1 -1
- data/lib/rbzk/zk.rb +204 -0
- metadata +2 -2
data/lib/rbzk/zk.rb
CHANGED
@@ -348,6 +348,166 @@ module RBZK
|
|
348
348
|
end
|
349
349
|
end
|
350
350
|
|
351
|
+
# Unlock the door
|
352
|
+
# @param time [Integer] define delay in seconds
|
353
|
+
# @return [Boolean] true if successful, raises exception otherwise
|
354
|
+
def unlock(time = 3)
|
355
|
+
command_string = [time * 10].pack('L<')
|
356
|
+
response = self.send_command(CMD_UNLOCK, command_string)
|
357
|
+
|
358
|
+
if response && response[:status]
|
359
|
+
true
|
360
|
+
else
|
361
|
+
raise RBZK::ZKErrorResponse, "Can't open door"
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
# Get the lock state
|
366
|
+
# @return [Boolean] true if door is open, false otherwise
|
367
|
+
def get_lock_state
|
368
|
+
response = self.send_command(CMD_DOORSTATE_RRQ)
|
369
|
+
|
370
|
+
if response && response[:status]
|
371
|
+
true
|
372
|
+
else
|
373
|
+
false
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
# Write text to LCD
|
378
|
+
# @param line_number [Integer] line number
|
379
|
+
# @param text [String] text to write
|
380
|
+
# @return [Boolean] true if successful, raises exception otherwise
|
381
|
+
def write_lcd(line_number, text)
|
382
|
+
command_string = [line_number, 0].pack('s<c') + ' ' + text.encode(@encoding, invalid: :replace, undef: :replace)
|
383
|
+
response = self.send_command(CMD_WRITE_LCD, command_string)
|
384
|
+
|
385
|
+
if response && response[:status]
|
386
|
+
true
|
387
|
+
else
|
388
|
+
raise RBZK::ZKErrorResponse, "Can't write lcd"
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
# Clear LCD
|
393
|
+
# @return [Boolean] true if successful, raises exception otherwise
|
394
|
+
def clear_lcd
|
395
|
+
response = self.send_command(CMD_CLEAR_LCD)
|
396
|
+
|
397
|
+
if response && response[:status]
|
398
|
+
true
|
399
|
+
else
|
400
|
+
raise RBZK::ZKErrorResponse, "Can't clear lcd"
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
# Refresh the device data
|
405
|
+
# @return [Boolean] true if successful, raises exception otherwise
|
406
|
+
def refresh_data
|
407
|
+
response = self.send_command(CMD_REFRESHDATA)
|
408
|
+
|
409
|
+
if response && response[:status]
|
410
|
+
true
|
411
|
+
else
|
412
|
+
raise RBZK::ZKErrorResponse, "Can't refresh data"
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
# Create or update user by uid
|
417
|
+
# @param uid [Integer] user ID that are generated from device
|
418
|
+
# @param name [String] name of the user
|
419
|
+
# @param privilege [Integer] user privilege level (default or admin)
|
420
|
+
# @param password [String] user password
|
421
|
+
# @param group_id [String] group ID
|
422
|
+
# @param user_id [String] your own user ID
|
423
|
+
# @param card [Integer] card number
|
424
|
+
# @return [Boolean] true if successful, raises exception otherwise
|
425
|
+
def set_user(uid: nil, name: '', privilege: 0, password: '', group_id: '', user_id: '', card: 0)
|
426
|
+
# If uid is not provided, use next_uid
|
427
|
+
if uid.nil?
|
428
|
+
uid = @next_uid
|
429
|
+
if user_id.empty?
|
430
|
+
user_id = @next_user_id
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
# If user_id is not provided, use uid as string
|
435
|
+
if user_id.empty?
|
436
|
+
user_id = uid.to_s # ZK6 needs uid2 == uid
|
437
|
+
end
|
438
|
+
|
439
|
+
# Validate privilege
|
440
|
+
if privilege != USER_DEFAULT && privilege != USER_ADMIN
|
441
|
+
privilege = USER_DEFAULT
|
442
|
+
end
|
443
|
+
privilege = privilege.to_i
|
444
|
+
|
445
|
+
# Create command string based on user_packet_size
|
446
|
+
if @user_packet_size == 28 # firmware == 6
|
447
|
+
group_id = 0 if group_id.empty?
|
448
|
+
|
449
|
+
begin
|
450
|
+
command_string = [uid, privilege].pack('S<C') +
|
451
|
+
password.encode(@encoding, invalid: :replace, undef: :replace).ljust(5, "\x00")[0...5] +
|
452
|
+
name.encode(@encoding, invalid: :replace, undef: :replace).ljust(8, "\x00")[0...8] +
|
453
|
+
[card.to_i, 0, group_id.to_i, 0, user_id.to_i].pack('L<CS<S<L<')
|
454
|
+
rescue => e
|
455
|
+
if @verbose
|
456
|
+
puts "Error packing user: #{e.message}"
|
457
|
+
end
|
458
|
+
raise RBZK::ZKErrorResponse, "Can't pack user"
|
459
|
+
end
|
460
|
+
else
|
461
|
+
# For other firmware versions
|
462
|
+
name_pad = name.encode(@encoding, invalid: :replace, undef: :replace).ljust(24, "\x00")[0...24]
|
463
|
+
card_str = [card.to_i].pack('L<')[0...4]
|
464
|
+
command_string = [uid, privilege].pack('S<C') +
|
465
|
+
password.encode(@encoding, invalid: :replace, undef: :replace).ljust(8, "\x00")[0...8] +
|
466
|
+
name_pad +
|
467
|
+
card_str + "\x00" +
|
468
|
+
group_id.encode(@encoding, invalid: :replace, undef: :replace).ljust(7, "\x00")[0...7] +
|
469
|
+
"\x00" +
|
470
|
+
user_id.encode(@encoding, invalid: :replace, undef: :replace).ljust(24, "\x00")[0...24]
|
471
|
+
end
|
472
|
+
|
473
|
+
# Send command
|
474
|
+
response = self.send_command(CMD_USER_WRQ, command_string, 1024)
|
475
|
+
|
476
|
+
if response && response[:status]
|
477
|
+
# Update next_uid and next_user_id if necessary
|
478
|
+
self.refresh_data
|
479
|
+
if @next_uid == uid
|
480
|
+
@next_uid += 1
|
481
|
+
end
|
482
|
+
if @next_user_id == user_id
|
483
|
+
@next_user_id = @next_uid.to_s
|
484
|
+
end
|
485
|
+
true
|
486
|
+
else
|
487
|
+
raise RBZK::ZKErrorResponse, "Can't set user"
|
488
|
+
end
|
489
|
+
end
|
490
|
+
|
491
|
+
# Delete user by uid
|
492
|
+
# @param uid [Integer] user ID that are generated from device
|
493
|
+
# @return [Boolean] true if successful, raises exception otherwise
|
494
|
+
def delete_user(uid: 0)
|
495
|
+
# Send command
|
496
|
+
command_string = [uid].pack('S<')
|
497
|
+
response = self.send_command(CMD_DELETE_USER, command_string)
|
498
|
+
|
499
|
+
if response && response[:status]
|
500
|
+
self.refresh_data
|
501
|
+
# Update next_uid if necessary
|
502
|
+
if uid == (@next_uid - 1)
|
503
|
+
@next_uid = uid
|
504
|
+
end
|
505
|
+
true
|
506
|
+
else
|
507
|
+
raise RBZK::ZKErrorResponse, "Can't delete user"
|
508
|
+
end
|
509
|
+
end
|
510
|
+
|
351
511
|
# Helper method to read data with buffer (ZK6: 1503)
|
352
512
|
def read_with_buffer(command, fct = 0, ext = 0)
|
353
513
|
|
@@ -717,6 +877,50 @@ module RBZK
|
|
717
877
|
end
|
718
878
|
end
|
719
879
|
|
880
|
+
# Send data with buffer
|
881
|
+
# @param buffer [String] data to send
|
882
|
+
# @return [Boolean] true if successful, raises exception otherwise
|
883
|
+
def send_with_buffer(buffer)
|
884
|
+
max_chunk = 1024
|
885
|
+
size = buffer.size
|
886
|
+
self.free_data
|
887
|
+
|
888
|
+
command = CMD_PREPARE_DATA
|
889
|
+
command_string = [size].pack('L<')
|
890
|
+
response = self.send_command(command, command_string)
|
891
|
+
|
892
|
+
if !response || !response[:status]
|
893
|
+
raise RBZK::ZKErrorResponse, "Can't prepare data"
|
894
|
+
end
|
895
|
+
|
896
|
+
remain = size % max_chunk
|
897
|
+
packets = (size - remain) / max_chunk
|
898
|
+
start = 0
|
899
|
+
|
900
|
+
packets.times do
|
901
|
+
send_chunk(buffer[start, max_chunk])
|
902
|
+
start += max_chunk
|
903
|
+
end
|
904
|
+
|
905
|
+
send_chunk(buffer[start, remain]) if remain > 0
|
906
|
+
|
907
|
+
true
|
908
|
+
end
|
909
|
+
|
910
|
+
# Send a chunk of data
|
911
|
+
# @param command_string [String] data to send
|
912
|
+
# @return [Boolean] true if successful, raises exception otherwise
|
913
|
+
def send_chunk(command_string)
|
914
|
+
command = CMD_DATA
|
915
|
+
response = self.send_command(command, command_string)
|
916
|
+
|
917
|
+
if response && response[:status]
|
918
|
+
true
|
919
|
+
else
|
920
|
+
raise RBZK::ZKErrorResponse, "Can't send chunk"
|
921
|
+
end
|
922
|
+
end
|
923
|
+
|
720
924
|
# Helper method to read a chunk of data
|
721
925
|
def read_chunk(start, size)
|
722
926
|
if @verbose
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbzk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Khaled AbuShqear
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-09-26 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: bytes
|