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.
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.3
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-05-27 00:00:00.000000000 Z
10
+ date: 2025-09-26 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: bytes