omg-networked-rfid 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ec1fd8a964b3c137be3bb309649c672ceb72e2ac
4
+ data.tar.gz: 6cbd02116b67f6043c9b29f390a19ff2d55c1f8f
5
+ SHA512:
6
+ metadata.gz: fdc68017e05d5ce67196447f76418bb6f33868e84d89ac2e038da5180a14ab845546c36075b1256f8d78a0c0df3302487f91f5e095749e2e0c203f7a3f0c66d6
7
+ data.tar.gz: 3229ccd254962a9d419793df9b274ee972edcc1b996478ab8290d83062ed1abbb903a25aaa693ee901952eba0ec9b15f26166ad3736e764436f6e96bd16460bf
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in omg-networked-rfid.gemspec
4
+ gemspec
@@ -0,0 +1,72 @@
1
+ # Omg-Networked-Rfid
2
+
3
+ ## Installation
4
+
5
+ Add this line to your application's Gemfile:
6
+
7
+ gem 'omg-networked-rfid'
8
+
9
+ And then execute:
10
+
11
+ $ bundle
12
+
13
+ Or install it yourself as:
14
+
15
+ $ gem install omg-networked-rfid
16
+
17
+ ## Usage
18
+
19
+ It provides a few basic classes that you can use to read RFID cards remotely.
20
+
21
+ * ```NetworkedRFID::RFIDReaderRepository``` provides a repository for collective RFID reader polling.
22
+
23
+ * ```NetworkedRFID::RemoteRFIDReader``` gives you a networked reader you can later add the repository. It delegates card reader events to a higher level delegate.
24
+
25
+ * ```NetworkedRFID::CardApplicationDelegate``` one of the delegates that can process ```NetworkedRFID::RemoteRFIDReader``` events. It translates those low-level events into card application events, which are then delegated further to a delegate of your choice. Your delegate is required to support only one method: ```card_scanned(card_number)```.
26
+
27
+ ### Example
28
+
29
+ Here's how you can read your cards using RFID cardreader and output their
30
+ numbers to the console.
31
+
32
+ ```ruby
33
+ require "bundler"
34
+ Bundler.require
35
+
36
+ # Your sample upper-level delegate
37
+ class SampleCardProcessingDelegate
38
+
39
+ def card_scanned(card_number)
40
+ puts "Card has been scanned: #{card_number}"
41
+ end
42
+
43
+ end
44
+
45
+ # Make an instance of your delegate
46
+ card_processing_delegate = SampleCardProcessingDelegate.new
47
+
48
+ # Assign it to a message-level delegate
49
+ card_application_delegate = NetworkedRFID::CardApplicationDelegate.new
50
+ card_application_delegate.delegate = card_processing_delegate
51
+
52
+ # Create new RFID reader and add the message-level delegate to it
53
+ reader = NetworkedRFID::RemoteRFIDReader.new("192.168.1.100", 2000)
54
+ reader.delegate = card_application_delegate
55
+
56
+ # Finally add newly created RFID reader to the repository
57
+ repository = NetworkedRFID::RFIDReaderRepository.new
58
+ repository << reader
59
+
60
+ # Start main polling cycle
61
+ while true
62
+ repository.poll
63
+ end
64
+ ```
65
+
66
+ ## Contributing
67
+
68
+ 1. Fork it
69
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
70
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
71
+ 4. Push to the branch (`git push origin my-new-feature`)
72
+ 5. Create new Merge Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,43 @@
1
+ module NetworkedRFID
2
+
3
+ # Делегат, обрабатывающий события кардридера и преобразовывающий их в события
4
+ # прикладывания карты.
5
+ #
6
+ # События прикладывания карты обрабатываются методом +card_scanned(number)+
7
+ # делегата.
8
+ class CardApplicationDelegate
9
+
10
+ attr_accessor :delegate, :card_number
11
+
12
+ state_machine :state, :initial => :waiting do
13
+
14
+ event :rfid_read do
15
+ transition :waiting => :card_applied
16
+ transition :card_applied => :card_applied
17
+ end
18
+
19
+ event :poll_reply do
20
+ transition :card_applied => :waiting
21
+ end
22
+
23
+ state :waiting
24
+ state :card_applied
25
+
26
+ before_transition any => :card_applied do |object, transition|
27
+ throw :halt if object.card_number == transition.args.first.card_number
28
+ end
29
+
30
+ after_transition any => :card_applied do |object, transition|
31
+ object.card_number = transition.args.first.card_number
32
+ object.delegate.card_scanned(object.card_number)
33
+ end
34
+
35
+ after_transition :card_applied => :waiting do |object|
36
+ object.card_number = nil
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,37 @@
1
+ module NetworkedRFID
2
+
3
+ # Класс отдельного TCP/IP-ридера, отвечающий за его опрос и передачу событий
4
+ # делегату +delegate+.
5
+ #
6
+ # У делегата должны быть определены методы-обработчики низкоуровневых событий
7
+ # кард-ридера вроде +poll_reply+ и +rfid_read+.
8
+ class RemoteRFIDReader
9
+ POLL_PACKET = [ 0x02, 0xe0, 0x00, 0x98, 0x02,
10
+ 0x00, 0x01, 0x7b, 0x03 ].pack('C*')
11
+
12
+ attr_reader :ip, :port
13
+ attr_accessor :delegate
14
+
15
+ # Инициализирует ридер, делая его доступным по _ip_ на порту _port_.
16
+ def initialize(ip, port)
17
+ @ip = ip
18
+ @port = port
19
+ @delegate = delegate
20
+ end
21
+
22
+ # Отправлять запрос на опрос состояния ридера через _socket_.
23
+ def poll(socket)
24
+ socket.send POLL_PACKET, 0, ip, port
25
+ end
26
+
27
+ # Обрабатывает двоичный ответ _response_ от ридера и отправяет его
28
+ # делегату.
29
+ def process_response(response)
30
+ response = RFIDReply.read(response)
31
+ if delegate.respond_to?(response.type)
32
+ delegate.send(response.type, response.payload)
33
+ end
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,14 @@
1
+ module NetworkedRFID
2
+
3
+ # Ответ на запрос о состоянии, когда карта приложена к ридеру.
4
+ class RFIDCardReadReply < BinData::Record
5
+ skip length: 1
6
+ array :card_number_bytes, type: :uint8, initial_length: 7
7
+
8
+ # Номер приложенной карты.
9
+ def card_number
10
+ card_number_bytes.to_a.reverse.inject(0) { |number, byte| (number << 8) + byte }
11
+ end
12
+ end
13
+
14
+ end
@@ -0,0 +1,76 @@
1
+ module NetworkedRFID
2
+
3
+ protected
4
+
5
+ module ReaderControlMethods
6
+
7
+ class << self
8
+
9
+ def included(klass)
10
+ methods = {
11
+ beep: {
12
+ once: {
13
+ short: [ 0x02, 0xa0, 0x00, 0x26, 0x07, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x01, 0x85, 0x03 ],
14
+ long: [ 0x02, 0xe0, 0x00, 0x26, 0x07, 0x00, 0x04, 0x05, 0x00, 0x00, 0x00, 0x01, 0xc1, 0x03 ]
15
+ },
16
+ twice: [ 0x02, 0xe0, 0x00, 0x26, 0x07, 0x00, 0x04, 0x01, 0x00, 0x01, 0x01, 0x01, 0xc5, 0x03 ]
17
+ },
18
+ lights: {
19
+ off: [ 0x02, 0xb0, 0x00, 0x24, 0x02, 0x00, 0x00, 0x96, 0x03 ],
20
+ red_on: [ 0x02, 0xa0, 0x00, 0x24, 0x02, 0x00, 0x01, 0x87, 0x03 ],
21
+ green_on: [ 0x02, 0xb0, 0x00, 0x24, 0x02, 0x00, 0x02, 0x94, 0x03 ],
22
+ both_on: [ 0x02, 0xb0, 0x00, 0x24, 0x02, 0x00, 0x03, 0x94, 0x03 ]
23
+ }
24
+ }
25
+
26
+ mod = Module.new
27
+
28
+ load_methods methods, [ ] do |method, packet|
29
+ klass.send :define_method, method do |ip|
30
+ socket = UDPSocket.new
31
+ socket.send packet.pack("C*"), 0, ip, 2000
32
+ socket.recv 16
33
+ socket.close
34
+ end
35
+ end
36
+
37
+ klass.include(mod)
38
+
39
+ end
40
+
41
+ private
42
+
43
+ def load_methods(methods, path, &block)
44
+ methods.each do |key, value|
45
+ if value.kind_of?(Array)
46
+ yield (path + [ key ]).join("_"), value
47
+ else
48
+ load_methods(value, path + [ key ], &block)
49
+ end
50
+ end
51
+ end
52
+
53
+ end
54
+
55
+ end
56
+
57
+ public
58
+
59
+ # Синглтон-сервис, обеспечивающий отправку команд ридеру в одностороннем
60
+ # порядке.
61
+ #
62
+ # Позволяет отправлять команды на включение лампочек, пищание и др.
63
+ #
64
+ # Полный перечень методов:
65
+ # +RFIDControllerService.instance.public_methods(false)+
66
+ class RFIDControllerService
67
+
68
+ include ReaderControlMethods
69
+
70
+ def self.instance
71
+ @instance ||= new
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -0,0 +1,7 @@
1
+ module NetworkedRFID
2
+
3
+ # Пустой ответ на запрос о состоянии ридера.
4
+ class RFIDPollReply < BinData::Record
5
+ end
6
+
7
+ end
@@ -0,0 +1,41 @@
1
+ module NetworkedRFID
2
+
3
+ # Репозиторий всех ридеров, с которыми взаимодействует система.
4
+ class RFIDReaderRepository
5
+
6
+ # Опросить состояние ридеров и передать каждому полученный ответ
7
+ # на обработку.
8
+ def poll
9
+ readers.values.each do |reader|
10
+ reader.poll(socket)
11
+ end
12
+
13
+ while have_replies?
14
+ reply_packet = socket.recvfrom_nonblock(64)
15
+ readers[reply_packet[1][2].to_s].process_response reply_packet[0]
16
+ end
17
+ end
18
+
19
+ # Добавить ридер в репозиторий.
20
+ def <<(reader)
21
+ readers[reader.ip] = reader
22
+ end
23
+
24
+ protected
25
+
26
+ def have_replies?
27
+ result = IO.select([ socket ], nil, nil, 0.125)
28
+ !result.nil? && result[0].size > 0
29
+ end
30
+
31
+ def socket
32
+ @socket ||= UDPSocket.new
33
+ end
34
+
35
+ def readers
36
+ @readers ||= { }
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,27 @@
1
+ module NetworkedRFID
2
+
3
+ # Двоичная структура ответа на запрос о состоянии ридера.
4
+ class RFIDReply < BinData::Record
5
+ POLL_REPLY = 1
6
+ RFID_READ = 8
7
+
8
+ skip length: 3
9
+ uint8 :packet_type
10
+
11
+ choice :payload, :selection => ->{ packet_type } do
12
+ rfid_poll_reply 1
13
+ rfid_card_read_reply 8
14
+ rest :default
15
+ end
16
+
17
+ # Тип ответа.
18
+ def type
19
+ {
20
+ POLL_REPLY => :poll_reply,
21
+ RFID_READ => :rfid_read
22
+ }[packet_type]
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,10 @@
1
+ require "bindata"
2
+ require "state_machine"
3
+
4
+ require_relative "networked_rfid/card_application_delegate"
5
+ require_relative "networked_rfid/remote_rfid_reader"
6
+ require_relative "networked_rfid/rfid_card_read_reply"
7
+ require_relative "networked_rfid/rfid_poll_reply"
8
+ require_relative "networked_rfid/rfid_reader_repository"
9
+ require_relative "networked_rfid/rfid_reply"
10
+ require_relative "networked_rfid/rfid_controller_service"
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "omg-networked-rfid"
7
+ spec.version = "2.1.0"
8
+ spec.authors = ["Ivan Kasatenko"]
9
+ spec.email = ["sky.31338@gmail.com"]
10
+ spec.description = %q{Networked RFID support library}
11
+ spec.summary = %q{Library that gives a basic framework to support networked RFID CV5600 reader}
12
+ spec.homepage = ""
13
+ spec.license = "Commercial"
14
+
15
+ spec.files = `git ls-files`.split($/)
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency "bindata"
21
+ spec.add_dependency "state_machine"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: omg-networked-rfid
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ivan Kasatenko
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-01-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bindata
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: state_machine
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Networked RFID support library
70
+ email:
71
+ - sky.31338@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - Gemfile
78
+ - Gemfile.lock
79
+ - README.md
80
+ - Rakefile
81
+ - lib/networked_rfid/card_application_delegate.rb
82
+ - lib/networked_rfid/remote_rfid_reader.rb
83
+ - lib/networked_rfid/rfid_card_read_reply.rb
84
+ - lib/networked_rfid/rfid_controller_service.rb
85
+ - lib/networked_rfid/rfid_poll_reply.rb
86
+ - lib/networked_rfid/rfid_reader_repository.rb
87
+ - lib/networked_rfid/rfid_reply.rb
88
+ - lib/omg-networked-rfid.rb
89
+ - omg-networked-rfid.gemspec
90
+ - vendor/cache/bindata-1.6.0.gem
91
+ - vendor/cache/state_machine-1.2.0.gem
92
+ homepage: ''
93
+ licenses:
94
+ - Commercial
95
+ metadata: {}
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubyforge_project:
112
+ rubygems_version: 2.2.1
113
+ signing_key:
114
+ specification_version: 4
115
+ summary: Library that gives a basic framework to support networked RFID CV5600 reader
116
+ test_files: []