alien 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZjlhN2ZjMjUyYzgxYzE4NzAyYjdjNDEwMWJlMmYyNzQ5NDYwZDQ2NQ==
5
+ data.tar.gz: !binary |-
6
+ Njc2NjNkMGJkOTBhNmQ2YzY0OTQ5ODk1NzMyYWI2NjY1OTk1NjFjOA==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ MjViNGZmYTIwNzk1NTY0YzFhZDE0NGJiOGE5YWVmY2NhNmUyYTlmYmFjNDY3
10
+ ZjhjZDFlOGViNzYyNjdlMjMyMmY3Yjg4YTBhYzlkODMwZmVkZDVhZWEyM2Qx
11
+ NTAxYWVjYWRjZjJmYzAyZDIwMjNiOTU1NGEzNzQ2NjhlYWE0OGI=
12
+ data.tar.gz: !binary |-
13
+ MDM3NDg2MjIzMDI4MDRlMmQ5YjA5N2IyNDcyN2EyZGQxZDA1NjJkN2Y4NjQ0
14
+ MGFmYzExY2FkNDkwYmIzOTJhMjgxODU3YTA4OWRiMDgzOGM3ZDliZmRhNGZm
15
+ MDdmYmRkZTI5NzUyMjQ0NGJlZTNlMDNiZDA1NDgwNmQyOWJlZjk=
@@ -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 alien.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,29 @@
1
+ Copyright (c) 2009, Alien Technology Corporation
2
+ Copyright (c) 2014, Artur Rodrigues
3
+ All rights reserved
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+ 1. Redistributions of source code must retain the above copyright
8
+ notice, this list of conditions and the following disclaimer.
9
+ 2. Redistributions in binary form must reproduce the above copyright
10
+ notice, this list of conditions and the following disclaimer in the
11
+ documentation and/or other materials provided with the distribution.
12
+ 3. All advertising materials mentioning features or use of this software
13
+ must display the following acknowledgement:
14
+ This product includes software developed by the <organization>.
15
+ 4. Neither the name of the <organization> nor the
16
+ names of its contributors may be used to endorse or promote products
17
+ derived from this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL ALIEN TECHNOLOGY CORPORATION OR ITS CONTRIBUTORS
23
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,48 @@
1
+ # Alien
2
+
3
+ Interface to Alien Technology ARCA enabled readers, patched to be compatible with Ruby 1.9.3
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'alien'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+
21
+ ```bash
22
+ $ gem install alien
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ Fetching the taglist
28
+
29
+ ```ruby
30
+ require 'alien'
31
+
32
+ r = Alien::AlienReader.new
33
+ r.open('150.164.9.34')
34
+ taglist_string = r.taglist
35
+ lines = taglist_string.split "\r\n"
36
+ tl = Array.new
37
+ lines.each { |line| tl.push Alien::AlienTag.new(line) }
38
+ puts tl
39
+ r.close
40
+ ```
41
+
42
+ ## Contributing
43
+
44
+ 1. Fork it ( http://github.com/<my-github-username>/alien/fork )
45
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
46
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
47
+ 4. Push to the branch (`git push origin my-new-feature`)
48
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'alien/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "alien"
8
+ spec.version = Alien::VERSION
9
+ spec.authors = ["Artur Rodrigues"]
10
+ spec.email = ["arturhoo@gmail.com"]
11
+ spec.summary = %q{Interface to Alien Technology ARCA enabled readers.}
12
+ spec.description = %q{Ruby interface to Alien Technology ARCA enabled readers.}
13
+ spec.homepage = ""
14
+ spec.license = "BSD"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake"
23
+ end
@@ -0,0 +1,11 @@
1
+ require "alien/version"
2
+ require "alien/alienblocktimer"
3
+ require "alien/alienconfig"
4
+ require "alien/alienconnection"
5
+ require "alien/alienreader"
6
+ require "alien/alientag"
7
+ require "alien/alientaglist"
8
+
9
+ module Alien
10
+ # Your code goes here...
11
+ end
@@ -0,0 +1,113 @@
1
+ =begin rdoc
2
+ =Alien Ruby RFID Library
3
+ ==alienblocktimer.rb
4
+
5
+ A tiny little class to help me time code blocks. Ruby has a 'profiler' library that is
6
+ much more powerful, but I've found this handy for quick timing checks.
7
+
8
+ Returns elapsed time for an operation and an optional description.
9
+
10
+
11
+ Example 1):
12
+
13
+ You can just create the timer in place and use it.
14
+
15
+ puts AlienBlockTimer.new("Time for this block: "){
16
+ ... Some lengthy operation in the block ...
17
+ }
18
+
19
+ Results in:
20
+
21
+ Time for this block: 0.123
22
+
23
+
24
+ Example 2):
25
+
26
+ Alternatively, create an instance and use it later.
27
+
28
+ t=AlienBlockTimer.new("")
29
+
30
+ puts t.measure("Time for this block: "){
31
+ ... Some lengthy operation in the block ...
32
+ }
33
+
34
+ ...or...
35
+
36
+ t.measure("Time for this other block: "){
37
+ ... Some lengthy operation in the block ...
38
+ }
39
+
40
+ puts t
41
+
42
+ Example 3):
43
+
44
+ You can also use the class to make a series of elapsed time measurements.
45
+
46
+ puts "Starting measurment..."
47
+
48
+ t.start
49
+
50
+ (code here...)
51
+
52
+ puts "So far: #{t.elapsed}"
53
+
54
+ (more code...)
55
+
56
+ puts "Done!: #{t.elapsed}"
57
+
58
+
59
+
60
+ Copyright 2007 Alien Technology Corporation. All rights reserved.
61
+ =end
62
+
63
+ #A class to measure the execution time for blocks of code.
64
+ module Alien
65
+ class AlienBlockTimer
66
+
67
+
68
+ #Setup the timer and pass in an optional description. If there is an associated block with the
69
+ #call, execute a timing measurment.
70
+ def initialize (description="",&block)
71
+ @t1=Time.now
72
+ @measurement = "Timer initialized."
73
+ unless block.nil?
74
+ measure(description){yield}
75
+ end
76
+ end
77
+
78
+
79
+ #Measure the execution time for an asscociated code block.
80
+ def measure(description="", &block)
81
+
82
+ start
83
+
84
+ unless block.nil?
85
+ yield
86
+ @measurement = description + elapsed.to_s
87
+ else
88
+ #Error message Haiku. :)
89
+ @measurement = "No block to measure. Your timer waits patiently. Give him one to use."
90
+ end
91
+
92
+ end
93
+
94
+ #Grab a start time
95
+ def start
96
+ @t1=Time.now
97
+ end
98
+
99
+ #The time since we called start or since the class was initialized.
100
+ def elapsed
101
+ Time.now - @t1
102
+ end
103
+
104
+ def inspect
105
+ @measurement
106
+ end
107
+
108
+ def to_s
109
+ @measurement
110
+ end
111
+
112
+ end
113
+ end
@@ -0,0 +1,69 @@
1
+ =begin rdoc
2
+ =Alien Ruby RFID Library
3
+ ==alienconfig.rb
4
+
5
+ A class to load/save application configuration data in a simple text file.
6
+
7
+ Minimal error handling.
8
+
9
+ Configuration parameters are maintained as a hash.
10
+
11
+ Copyright 2008, Alien Technology Corporation. All rights reserved.
12
+ =end
13
+
14
+ module Alien
15
+ class AlienConfig < Hash
16
+
17
+ def initialize(fn)
18
+ super(nil)
19
+ load(fn)
20
+ end
21
+
22
+ private
23
+ # Open a file and read out the configuration parameters. Save into a hash structure.
24
+ # Blank lines and comment lines, beginning with '#' are ignored.
25
+ def load(fn)
26
+ if File.file?(fn)
27
+ begin
28
+ File.open(fn).each do |line|
29
+ #peel off terminators/leading spaces, etc.
30
+ line.strip!
31
+
32
+ #ignore comment lines...
33
+ if (line[0..0]!="#")
34
+ keyval = line.split("=") # split on equal sign
35
+
36
+ #ignore blank lines
37
+ if keyval.size>0
38
+ key = keyval[0].strip
39
+ value = keyval[1].strip
40
+ self[key] = value
41
+ end
42
+ end
43
+ end
44
+ rescue
45
+ raise "Error: trouble loading data from file: #{fn}.\nDetails: #{$!}"
46
+ end
47
+ else
48
+ raise "Error: cannot find configuration file: #{fn}.\nDetails: File not found."
49
+ end
50
+ end
51
+
52
+ #Save the hash data to a file.
53
+ def save(fn)
54
+ begin
55
+ File.open(fn,"w") do |file|
56
+ output = ""
57
+ self.each do |key, value|
58
+ output << key.to_s + "=" + value.to_s + "\r\n"
59
+ end
60
+
61
+ file.print output
62
+ file.close
63
+ end
64
+ rescue
65
+ raise "Error: trouble saving configuration file: #{fn}.\nDetails: #{$!}"
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,186 @@
1
+ =begin rdoc
2
+ =Alien Ruby RFID Library
3
+ ==alienconnection.rb
4
+
5
+ A simple class to handle the basics of socket communication with RFID readers from Alien Technology Corporation.
6
+
7
+ Copyright 2008, Alien Technology Corporation. All rights reserved.
8
+ =end
9
+
10
+ require 'socket'
11
+ require 'timeout'
12
+
13
+ # Handles socket communication w/an Alien RFID Reader.
14
+ module Alien
15
+ class AlienConnection
16
+
17
+ attr_accessor :raise_errors
18
+
19
+ def initialize
20
+ @connected = false
21
+ @raise_errors = true
22
+ end
23
+
24
+ # Returns the connected status of this AlienReader.
25
+ def connected
26
+ return @connected
27
+ end
28
+
29
+
30
+ # Read from the open socket until a null character is found.
31
+ # Strips off the trailing \r\n from the response
32
+ def receive(opts={})
33
+ timeout = opts.fetch(:timeout, 40).to_i
34
+ wait_for_null = opts.fetch(:wait_for_null, true)
35
+
36
+ s = ""
37
+
38
+ # Wait for data to become available on the socket
39
+ res = select([@sock], nil, nil, timeout)
40
+ if (res == nil)
41
+ raise "Timeout waiting for reader response." if @raise_errors
42
+ end
43
+
44
+ if (wait_for_null)
45
+ # Some readers don't put a null on the end of the 'call back later' message.
46
+ # Check for 'later' to know when to punt on the read.
47
+ begin
48
+ timeout(timeout) {
49
+ char = @sock.recv(1)
50
+ while (char != "\0")
51
+ s << char
52
+ char = @sock.recv(1)
53
+ end
54
+ }
55
+ rescue Timeout::Error
56
+ raise "Timeout waiting for reader response." if @raise_errors
57
+ end
58
+
59
+ s.strip!
60
+
61
+ if s.include? "Error"
62
+ raise s if @raise_errors
63
+ end
64
+
65
+ # If this is a response to a Quit command, the reader will close the socket.
66
+ # If there is an active connection, the reader will reject our attempt to connect.
67
+ # Either way, we're not connected anymore...
68
+ if (s.include? "Goodbye!")
69
+ close(false)
70
+ end
71
+
72
+ return s
73
+ else
74
+ # Simply try to read up to 1 kB and return it
75
+ return @sock.recv(1024)
76
+ end
77
+ end
78
+
79
+
80
+ # Send a message over an open socket (Alien terse msg format to suppress prompts on reply)
81
+ def send (msg="")
82
+ if @connected
83
+ @sock.write "\1#{msg}\r\n" # leading \1 for terse reply
84
+ end
85
+ end
86
+
87
+
88
+ # Send a message over an open socket and wait for a reply
89
+ def sendreceive(msg="", opts={})
90
+ timeout = opts.fetch(:timeout, 40)
91
+ wait_for_null = opts.fetch(:wait_for_null, true)
92
+
93
+ begin
94
+ if @connected
95
+ send(msg)
96
+ receive(:timeout=>timeout, :wait_for_null=>wait_for_null)
97
+ else
98
+ raise "Not connected to reader."
99
+ end
100
+ rescue
101
+ err = "Error in alienconnection:\nTried to send:\"#{msg}\"\nand got:\n\"" + String($!) +"\""
102
+ raise err
103
+ end
104
+ end
105
+
106
+
107
+ # Try to open a socket connection to the reader.
108
+ def connect(ipaddress='localhost', port=23)
109
+ @connected = false
110
+
111
+ #connect to a reader and grab the welcome message...
112
+ begin
113
+ timeout(3) {
114
+ @sock = TCPSocket.new(ipaddress, port)
115
+ }
116
+
117
+ s = receive() #Grab the welcome message
118
+ if s.include?("later.") #Reader is busy. Please call back later.
119
+ raise "Trouble Connecting to #{ipaddress}. (Someone else is talking to the reader.)"
120
+ end
121
+ @connected = true
122
+ rescue RuntimeError
123
+ raise
124
+ rescue Timeout::Error, Errno::ETIMEDOUT
125
+ raise "Trouble Connecting to #{ipaddress}. (No reader at this IP?)"
126
+ rescue Errno::ECONNREFUSED
127
+ raise "Trouble Connecting to #{ipaddress}. (Connection refused.)"
128
+ end
129
+
130
+ return @connected
131
+ end
132
+
133
+
134
+ private
135
+ # Login to the reader on an open socket connection. Call connect first.
136
+ def login (username="alien", password="password")
137
+ if @connected
138
+ begin
139
+ @sock.write "#{username}\r\n"
140
+ receive()
141
+ @sock.write "#{password}\r\n"
142
+ s = receive()
143
+
144
+ if s.include? "Error:"
145
+ err_msg = s.scan(/(Error: )(.*)/).flatten[1]
146
+ close()
147
+ raise "Trouble logging in. " << err_msg
148
+ @connected = false
149
+ end
150
+ rescue
151
+ raise
152
+ end
153
+ end
154
+
155
+ return @connected
156
+ end
157
+
158
+ public
159
+ # Execute both the connect and login methods in one call.
160
+ def open(ipaddress="localhost", port=23, username="alien", password="password")
161
+ connect(ipaddress,port)
162
+
163
+ if @connected
164
+ login(username,password)
165
+ end
166
+
167
+ return @connected
168
+ end
169
+
170
+
171
+ # Close the socket.
172
+ def close(send_quit=true)
173
+ if @connected
174
+ if send_quit
175
+ @sock.write("quit\r\n")
176
+ sleep 1
177
+ end
178
+ @sock.close()
179
+ end
180
+
181
+ @connected = false
182
+ return true
183
+ end
184
+
185
+ end #class AlienConnection
186
+ end
@@ -0,0 +1,169 @@
1
+ =begin rdoc
2
+ =Alien Ruby RFID Library
3
+ ==alienreader.rb
4
+
5
+ AlienReader is a fairly lightweight class that inherits from AlienConnection. It provides methods that map attributes to reader functions like readername, readertype, etc, and exposes the execute method to send/receive an arbitrary command to the reader.
6
+
7
+ This class uses a metaprogramming hack to dynamically build methods for many of the simple reader attributes from a file. This is a pretty flexible way to create the class and avoid lots of repetitive coding.
8
+
9
+
10
+ Copyright 2008, Alien Technology Corporation. All rights reserved.
11
+ =end
12
+
13
+ require File.join(File.dirname(__FILE__), 'alienconnection')
14
+ require File.join(File.dirname(__FILE__), 'alientaglist')
15
+
16
+ module Alien
17
+ class AlienReader< AlienConnection
18
+ @@methods_needed = true
19
+
20
+ #call the AlienConnection initializer and build lots of the Getters/Setters from a reader methods file. Default value for the methods file will be the file, readermethods.txt found in the same directory as this file, alienreader.rb.
21
+ def initialize(methodsfile=File.join(File.dirname(__FILE__) , "readermethods.dat"))
22
+ super()
23
+ if @@methods_needed
24
+ build_methods(methodsfile)
25
+ end
26
+ end
27
+
28
+ #execute a sendreceive and pull off the 'y' payload for messages that
29
+ #return with an 'x = y' style reply
30
+ private
31
+ def execute (cmd)
32
+ s = sendreceive(cmd)
33
+ if s.include? '='
34
+ return s.split('=')[1].strip!
35
+ else
36
+ return s
37
+ end
38
+ end
39
+
40
+ def add_get(cmd)
41
+ method_name = cmd.to_sym
42
+ self.class.instance_eval {
43
+ send :define_method, method_name do |*val|
44
+ if val.nil? || val.to_s.size==0
45
+ execute("#{cmd}?")
46
+ else
47
+ puts "sending val"
48
+ execute("#{cmd} [#{val.join}]?")
49
+ end
50
+ end
51
+ }
52
+ end
53
+
54
+ def add_set(cmd)
55
+ method_name = (cmd+"=").to_sym
56
+ self.class.instance_eval {
57
+ send :define_method, method_name do |*val|
58
+ execute("#{cmd}=#{val.join}")
59
+ end
60
+ }
61
+ end
62
+
63
+ def add_do(cmd)
64
+ method_name = cmd.to_sym
65
+ self.class.instance_eval {
66
+ send :define_method, method_name do |*val|
67
+ if val.nil? || val.to_s.size==0
68
+ sendreceive("#{cmd}")
69
+ else
70
+ sendreceive("#{cmd} #{val.join}")
71
+ end
72
+ end
73
+ }
74
+ end
75
+
76
+ def add_do_set(cmd)
77
+ method_name = cmd.to_sym
78
+ self.class.instance_eval {
79
+ send :define_method, method_name do |*val|
80
+ if val.nil? || val.to_s.size==0
81
+ execute("#{cmd}")
82
+ else
83
+ execute("#{cmd}=#{val.join}")
84
+ end
85
+ end
86
+ }
87
+ end
88
+
89
+ def add_getset(cmd)
90
+ add_get(cmd)
91
+ add_set(cmd)
92
+ end
93
+
94
+ #Build lots of the simple get/set methods supported by the class from a configuration file...
95
+ private
96
+ def build_methods(fn)
97
+ #puts "building methods from: #{fn}"
98
+ #open the file and read out the methods to be supported
99
+ if File.file?(fn)
100
+ File.open(fn).each do |line|
101
+ #puts line
102
+ #ignore comment lines...
103
+ if (line[0..0]!="#")
104
+ dat = line.split
105
+
106
+ #ignore blank lines
107
+ if dat.size>0
108
+ method_name = dat[0].strip
109
+ use = dat[1].strip
110
+
111
+ #puts "Method: #{dat[0]} Use: #{dat[1]}"
112
+ case dat[1].downcase
113
+ when "getset"
114
+ add_getset(dat[0])
115
+ when "get"
116
+ add_get(dat[0])
117
+ when "set"
118
+ add_set(dat[0])
119
+ when "do"
120
+ add_do(dat[0])
121
+ when "doset"
122
+ add_do_set(dat[0])
123
+ end
124
+ end
125
+ end
126
+ end
127
+ @@methods_needed = false
128
+ else
129
+ raise "Error: cannot find method definition file: #{fn}."
130
+ end
131
+ end
132
+
133
+ public
134
+ # Makes the reader blink its LEDs.
135
+ #
136
+ # _blinkled_ is a more complicated function call than an attribute.
137
+ # We just put the method in here rather than try to generate it dynamically.
138
+ def blinkled (state1, state2, duration, count)
139
+ execute('blinkled=' + state1.to_s + ' ' + state2.to_s + ' ' + duration.to_s + ' ' +count.to_s)
140
+ end
141
+
142
+ # Returns the state of the reader's external inputs
143
+ def gpio
144
+ execute('externalinput?')
145
+ end
146
+
147
+ # Sets reader's external outputs
148
+ def gpio=(newvalue)
149
+ execute('externaloutput='+newvalue)
150
+ end
151
+
152
+ # Executes the Alien _UpgradeNow_ command. The _opts_ parameter correspondst to the standard
153
+ # values passed to the _UpgradeNow_ command. For example
154
+ # rdr.upgradenow("force http://server.ip/firmware")
155
+ def upgradenow(opts="")
156
+ sendreceive("upgradenow #{opts}", :timeout=>120)
157
+ end
158
+
159
+ # Implements the Alien _service_ command
160
+ def service(service_name ="all", command="status")
161
+ sendreceive("service #{service_name} #{command}")
162
+ end
163
+
164
+ def alien_tag_list
165
+ tl = AlienTagList.new(self.taglist)
166
+ return tl
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,165 @@
1
+ =begin rdoc
2
+ =Alien Ruby RFID Library
3
+ ==alientag.rb
4
+
5
+ A simple class to hold taglist data elements. Allows construction of Tag objects from taglist entries. (The format of strings handled by the 'create' method is assumed to be compatible with Alien's 'text' taglist format.)
6
+
7
+ Copyright 2007, Alien Technology Corporation. All rights reserved.
8
+ =end
9
+
10
+ require 'date'
11
+
12
+ module Alien
13
+ # A storage class for RFID tag data elements.
14
+ class AlienTag
15
+
16
+ #By mixing in Comparable we can easily sort arrays of tags.
17
+ include Comparable
18
+
19
+ attr_accessor :id # EPC code of the tag that was read
20
+ attr_accessor :ant # Antenna on which the last read was made
21
+ attr_accessor :count # Number of times the tag has been read since discovery
22
+ attr_accessor :disc # Time of discovery
23
+ attr_accessor :last # Time of latest read
24
+ attr_accessor :proto # Protocol used to read the tag. A bit map where Gen2 = 16.
25
+
26
+ attr_accessor :rssi
27
+ attr_accessor :speed
28
+ attr_accessor :freq #:nodoc:
29
+
30
+ # Populate the instance variables from a taglist entry string.
31
+ # The following field separators are supported in the taglist entry string:
32
+ # 'tag:', 'disc:', 'last:', 'count:', 'ant:', 'proto:', 'speed:', 'rssi:'
33
+ def initialize(taglist_entry)
34
+ @disc = @last = @last_last = 0
35
+ @ant = @count = @proto = @rssi = @speed = @freq = 0
36
+ @speed_smooth = @speed_last = 0
37
+ @pos_smooth = @pos_last = @pos_min = 0
38
+
39
+ create(taglist_entry)
40
+ end
41
+
42
+ # (*Deprecated*) Returns tag *id*.
43
+ #
44
+ # This method is for backward compatibility with an earlier version of this API.
45
+ # Use _id_ instead.
46
+ def tag
47
+ @id
48
+ end
49
+
50
+ # (*Deprecated*) Sets tag *id*.
51
+ #
52
+ # This method is for backward compatibility with an earlier version of this API.
53
+ # Use <i>id=</i> instead.
54
+ def tag=(val)
55
+ @id = val
56
+ end
57
+
58
+ # Return the contents of the tag object as a string (returns tag *id* as a string)
59
+ def inspect
60
+ @id.to_s
61
+ end
62
+
63
+ # The 'spaceship' operator allows us to compare tags for sorting, etc.
64
+ def <=>(s)
65
+ @id <=> s.id
66
+ end
67
+
68
+ # Returns a printable version of the tag object (returns tag *id* as a string)
69
+ def to_s
70
+ @id.to_s
71
+ end
72
+
73
+ # Try to parse a taglist entry into a set of Tag object variables.
74
+ #
75
+ # Uses a simple mapping from Alien 'text' format:
76
+ #
77
+ # Tag:0102 0304 0506 0708 0900 0A0B, Disc:2008/10/28 10:49:35, Last:2008/10/28 10:49:35, Count:1, Ant:3, Proto:2
78
+ #
79
+ # *rssi* and *speed* attributes are not included in the default text format.
80
+ # In order to have them parsed correctly the _TagListFormat_ must be set to _custom_ and
81
+ # the _TagListCustomFormat_ fields must be separated by the following text tokens:
82
+ #
83
+ # 'tag:', 'disc:', 'last:', 'count:', 'ant:', 'proto:', 'speed:', 'rssi:'
84
+ #
85
+ # For example:
86
+ #
87
+ # @rdr.taglistcustomformat("Tag:%i, Disc:${DATE1} ${TIME1}, Last:${DATE2} ${TIME2}, Count:${COUNT}, Ant:${TX}, Proto:${PROTO#}, Speed:${SPEED}, rssi:${RSSI})"
88
+ # @rdr.taglistformat("custom")
89
+ def create(taglist_entry)
90
+ @id = ""
91
+ return self if (taglist_entry=="(No Tags)")
92
+
93
+ tagline = taglist_entry.split("\r\n")[0]
94
+ tagbits = Hash.new("0")
95
+
96
+ tagline.split(", ").each do |keyval|
97
+ key, val = keyval.split(":", 2)
98
+ if key.nil?
99
+ raise "Trouble parsing taglist string. Text format expected. This string was: #{taglist_entry}"
100
+ end
101
+ tagbits[key.downcase] = val
102
+ end
103
+
104
+ if (!tagbits.empty?)
105
+ #zero length ids can cause funny behavior
106
+ if tagbits['tag'] != nil
107
+ @id = tagbits['tag']
108
+ end
109
+
110
+ @ant = tagbits['ant']
111
+ @count = tagbits['count']
112
+ @disc = tagbits['disc']
113
+ @last = DateTime.parse(tagbits['last'])
114
+ @last_last = @last
115
+ @proto = tagbits['proto']
116
+ @rssi = tagbits['rssi']
117
+ @freq = tagbits['freq']
118
+ @speed = tagbits['speed']
119
+ end
120
+ return self
121
+ end
122
+
123
+ # Updates an existing tag object from the new one by incrementing the *count* and setting the new *last* time
124
+ def update(new_tag)
125
+ # Copy the last timestamp and increment the counts
126
+ @last = new_tag.last
127
+ @count += new_tag.count
128
+ @last_last = @last
129
+ =begin
130
+ # Update the speed, smooth it, calculate distance
131
+ dt = (@last - @last_last) * 86400.0
132
+ smooth_coef = 5
133
+ smooth_factor = Math.exp(-smooth_coef*dt)
134
+ thresh_zero1 = -0.01 # Any speeds between these thresholds are considered 0
135
+ thresh_zero2 = +0.01
136
+ puts
137
+ #printf("\ndt=%0.000010f, smooth_factor(init)=%0.00005f\n", dt, smooth_factor)
138
+
139
+ # Update the speed, smooth out jitter
140
+ @speed = new_tag.speed
141
+ if @speed.to_f > thresh_zero1 && @speed.to_f < thresh_zero2
142
+ # @speed = 0
143
+ end
144
+
145
+ #printf("speed_smooth(initial)=%+0.003f\n", @speed_smooth)
146
+ @speed_smooth = @speed_smooth*smooth_factor + @speed.to_f*(1 - smooth_factor)
147
+ @pos_last = @pos_smooth
148
+ @pos_smooth += @speed_last * dt/1000
149
+ @speed_last = @speed_smooth
150
+
151
+ printf("speed=%+0.003f", @speed.to_s)
152
+ printf(", speed_smooth=%+0.003f", @speed_smooth.to_s)
153
+ printf(", pos=%+0.005f\n", @pos_smooth.to_s)
154
+
155
+ # Update new pos_min, if needed
156
+ @pos_min = @pos_smooth if (@pos_smooth < @pos_min)
157
+ printf("pos_last=%+0.5f, pos_min=%0.5f\n", @pos_last.to_s, @pos_min.to_s)
158
+ # If last position was the min and tag is moving away --> TopDeadCenter
159
+ if @pos_last == @pos_min && @pos_smooth > @pos_last
160
+ puts "********************************************"
161
+ end
162
+ =end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,65 @@
1
+ =begin rdoc
2
+ =Alien Ruby RFID Library
3
+ ==alientaglist.rb
4
+
5
+ A simple class to hold an array of taglist data elements.
6
+
7
+ (The format of strings handled by the build_tag method is assumed to be compatible with Alien's 'text' taglist format.)
8
+
9
+ Copyright 2008, Alien Technology Corporation. All rights reserved.
10
+ =end
11
+
12
+ #Takes a string returned from a Taglist function call and builds an array of tags.
13
+
14
+ module Alien
15
+ class AlienTagList < Array
16
+
17
+ def initialize(taglist_string="")
18
+ super()
19
+ string_to_taglist(taglist_string) if taglist_string != ""
20
+ end
21
+
22
+
23
+ # Takes a taglist string from a reader and appends it to the array.
24
+ def string_to_taglist(taglist_string)
25
+ lines = taglist_string.split("\r\n")
26
+
27
+ lines.each do |line|
28
+ if line != "(No Tags)"
29
+ add_tag(AlienTag.new(line))
30
+ end
31
+ end
32
+
33
+ return self
34
+ end
35
+
36
+ # Adds an AlienTag to the list.
37
+ def add_tag(t)
38
+ self.push(t)
39
+ return self
40
+ end
41
+
42
+ # A little regular expression scanner. Looks at the list of tags and returns a
43
+ # new taglist containing those tag IDs that match a regular expression filter.
44
+ def filter(filter)
45
+ tl = AlienTagList.new
46
+
47
+ self.each do |ele|
48
+ if ele.tag =~ filter
49
+ tl.add_tag(ele)
50
+ end
51
+ end
52
+
53
+ return tl
54
+ end
55
+
56
+ # A self-modifying version of filter_taglist.
57
+ # Excercise caution. Elements in the taglist array that do not match
58
+ # the regular expression are deleted.
59
+ def filter!(filter)
60
+ self.delete_if { |ele| !(ele.tag =~ filter)}
61
+ return self
62
+ end
63
+
64
+ end #class AlienTagList
65
+ end
@@ -0,0 +1,204 @@
1
+ #**************************************************************
2
+ #general commands
3
+ #**************************************************************
4
+ function getset
5
+ readername getset
6
+ readertype get
7
+ readerversion get
8
+ dspversion get
9
+ readernumber getset
10
+ baudrate getset
11
+ uptime get
12
+ username getset
13
+ maxantenna get
14
+ antennasequence getset
15
+ antennastatus get
16
+ rfattenuation getset
17
+ rflevel getset
18
+ rfmodulation getset
19
+ reboot do
20
+ factorysettings do
21
+ info get
22
+ save do
23
+ quit do
24
+ mydata getset
25
+
26
+ #**************************************************************
27
+ #network commands
28
+ #**************************************************************
29
+ macaddress get
30
+ dhcp getset
31
+ dhcptimeout getset
32
+ ipaddress getset
33
+ hostname getset
34
+ upgradeaddress getset
35
+ networkupgrade getset
36
+ gateway getset
37
+ netmask getset
38
+ dns getset
39
+ networktimeout getset
40
+ commandport getset
41
+ commandportlocal getset
42
+ heartbeataddress getset
43
+ heartbeatport getset
44
+ heartbeattime getset
45
+ heartbeatcount getset
46
+ heartbeatnow do
47
+ wwwport getset
48
+ acceptconnections getset
49
+ ping do
50
+
51
+ #**************************************************************
52
+ #time commands
53
+ #**************************************************************
54
+ timeserver getset
55
+ time getset
56
+ timezone getset
57
+
58
+ #**************************************************************
59
+ #taglist commands
60
+ #**************************************************************
61
+ persisttime getset
62
+ taglistformat getset
63
+ taglistantennacombine getset
64
+ taglistcustomformat getset
65
+ taglistmillis getset
66
+ streamheader getset
67
+ tagstreammode getset
68
+ tagstreamaddress getset
69
+ tagstreamkeepalivetime getset
70
+ tagstreamformat getset
71
+ tagstreamcustomformat getset
72
+ t do
73
+ taglist get
74
+ acquire do
75
+ tag get
76
+ clear do
77
+
78
+ #**************************************************************
79
+ #acquire commands
80
+ #**************************************************************
81
+ acquiremode getset
82
+ tagtype getset
83
+ acqmask getset
84
+ acqg2cycles getset
85
+ acqg2count getset
86
+ acqg2q getset
87
+ acqg2qmax getset
88
+ acqg2select getset
89
+ acqg2session getset
90
+ acqg2mask getset
91
+ acqg2maskaction getset
92
+ acqg2accesspwd getset
93
+ acqg2tagdata getset
94
+ acqg2target getset
95
+ speedfilter getset
96
+ rssifilter getset
97
+
98
+ #**************************************************************
99
+ #i/o commands
100
+ #**************************************************************
101
+ externalinput getset
102
+ externaloutput getset
103
+ invertexternalinput getset
104
+ invertexternaloutput getset
105
+ initexternaloutput getset
106
+ iotype getset
107
+ iolistformat getset
108
+ iolistcustomformat getset
109
+ iostreammode getset
110
+ iostreamaddress getset
111
+ iostreamkeepalivetime getset
112
+ iostreamformat getset
113
+ iostreamcustomformat getset
114
+
115
+ #*************************************************************
116
+ #automode commands
117
+ #**************************************************************
118
+ automode getset
119
+ autowaitoutput getset
120
+ autoworkoutput getset
121
+ autotrueoutput getset
122
+ autofalseoutput getset
123
+ autostarttrigger getset
124
+ autostoptrigger getset
125
+ autostoptimer getset
126
+ autostartpause getset
127
+ autostoppause getset
128
+ autotruepause getset
129
+ autofalsepause getset
130
+ autoaction getset
131
+ automodetriggernow do
132
+ automodereset do
133
+
134
+ #**************************************************************
135
+ #notify commands
136
+ #**************************************************************
137
+ notifyformat getset
138
+ notifyheader getset
139
+ notifyaddress getset
140
+ notifytime getset
141
+ notifytrigger getset
142
+ notifykeepalivetime getset
143
+ mailserver getset
144
+ mailfrom getset
145
+ notifymode getset
146
+ notifyretrycount getset
147
+ notifyretrypause getset
148
+ notifyqueuelimit getset
149
+ notifyinclude getset
150
+ notifynow do
151
+
152
+ #**************************************************************
153
+ #program commands
154
+ #**************************************************************
155
+ progdataunit getset
156
+ progprotocol getset
157
+ progantenna getset
158
+ progepcdata getset
159
+ progepcdatainc getset
160
+ progg2killpwd getset
161
+ progg2accesspwd getset
162
+ proguserdata getset
163
+ proguserdatainc getset
164
+ progg2locktype getset
165
+ progattempts getset
166
+ progsuccessformat getset
167
+ progalienimagemap getset
168
+ progalienimagensi getset
169
+
170
+ programepc doset
171
+ programuser doset
172
+ programaccesspwd doset
173
+ programkillpwd doset
174
+ programandlockepc doset
175
+ programandlockuser doset
176
+ programalienimage doset
177
+
178
+ erase do
179
+ g2write doset
180
+ g2read doset
181
+ g2erase doset
182
+
183
+ lockepc doset
184
+ lockuser doset
185
+ lockkillpwd doset
186
+ lockaccesspwd doset
187
+ unlockepc doset
188
+ unlockuser doset
189
+ unlockkillpwd doset
190
+ unlockaccesspwd doset
191
+
192
+ lockuserblocks doset
193
+ hidealienuserblocks doset
194
+
195
+ #**************************************************************
196
+ #experimental commands
197
+ #**************************************************************
198
+ automodetype getset
199
+ autoseektimer getset
200
+ autoseekpause getset
201
+ autoseekrflevel getset
202
+ lbt getset
203
+ lbtlimit getset
204
+ lbtvalue get
@@ -0,0 +1,3 @@
1
+ module Alien
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: alien
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Artur Rodrigues
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Ruby interface to Alien Technology ARCA enabled readers.
42
+ email:
43
+ - arturhoo@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - .gitignore
49
+ - Gemfile
50
+ - LICENSE
51
+ - README.md
52
+ - Rakefile
53
+ - alien.gemspec
54
+ - lib/alien.rb
55
+ - lib/alien/alienblocktimer.rb
56
+ - lib/alien/alienconfig.rb
57
+ - lib/alien/alienconnection.rb
58
+ - lib/alien/alienreader.rb
59
+ - lib/alien/alientag.rb
60
+ - lib/alien/alientaglist.rb
61
+ - lib/alien/readermethods.dat
62
+ - lib/alien/version.rb
63
+ homepage: ''
64
+ licenses:
65
+ - BSD
66
+ metadata: {}
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 2.2.1
84
+ signing_key:
85
+ specification_version: 4
86
+ summary: Interface to Alien Technology ARCA enabled readers.
87
+ test_files: []
88
+ has_rdoc: