rfid-usb-gom-sensor 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/bin/{rfid-usb-gom-sensor.rb → rfid-usb-gom-sensor} +2 -1
- data/lib/rfid-usb-gom-sensor/node.rb +139 -10
- data/spec/rfid-usb-gom-sensor/node_spec.rb +32 -15
- metadata +5 -5
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.2
|
@@ -6,7 +6,7 @@ require 'applix'
|
|
6
6
|
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
7
7
|
require 'rfid-usb-gom-sensor'
|
8
8
|
|
9
|
-
|
9
|
+
Thread.abort_on_exception = true
|
10
10
|
$stderr.sync = true
|
11
11
|
$stdout.sync = true
|
12
12
|
|
@@ -26,6 +26,7 @@ def main argv
|
|
26
26
|
end
|
27
27
|
sensor = RfidUsbGomSensor::Node.new daemon.service_path, options
|
28
28
|
sensor.preroll
|
29
|
+
daemon.background_loop(1.1) { sensor.push_active_tags_to_gom }
|
29
30
|
daemon.forever { sensor.detect }
|
30
31
|
|
31
32
|
rescue Usage => e
|
@@ -3,6 +3,74 @@ begin
|
|
3
3
|
rescue Exception
|
4
4
|
require 'serialport'
|
5
5
|
end
|
6
|
+
require 'monitor.rb'
|
7
|
+
|
8
|
+
module X
|
9
|
+
class Entry
|
10
|
+
attr_accessor :path, :name, :mtime
|
11
|
+
def initialize data = nil
|
12
|
+
@data = data
|
13
|
+
end
|
14
|
+
|
15
|
+
def mtime
|
16
|
+
@mtime ||= Time.parse @data["mtime"]
|
17
|
+
end
|
18
|
+
|
19
|
+
def path
|
20
|
+
@path ||= @data["uri"]
|
21
|
+
end
|
22
|
+
|
23
|
+
def name
|
24
|
+
@name ||= (path.split %r|[:/]|)[-1]
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
"name: #{name}\npath: #{path}\nmtime: #{mtime}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.find path, recurse = 0
|
32
|
+
json = (Gom::Remote.connection.read "#{path}.json")
|
33
|
+
clazz, key = /:/.match(path) ? [Attribute, "attribute"] : [Node, "node"]
|
34
|
+
a = clazz.new JSON.parse(json)[key]
|
35
|
+
a
|
36
|
+
=begin
|
37
|
+
json = (connection.read "#{path}.json")
|
38
|
+
(JSON.parse json)["node"]["entries"].select do |entry|
|
39
|
+
# 1. select attribute entries
|
40
|
+
entry.has_key? "attribute"
|
41
|
+
end.inject({}) do |h, a|
|
42
|
+
# 2. make it a key, value list
|
43
|
+
h[a["attribute"]["name"].to_sym] = a["attribute"]["value"]
|
44
|
+
h
|
45
|
+
end
|
46
|
+
=end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Attribute < Entry
|
51
|
+
attr_writer :value
|
52
|
+
def value
|
53
|
+
@value ||= @data["value"]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class Node < Entry
|
58
|
+
def entries
|
59
|
+
debugger if(defined? debugger)
|
60
|
+
@entries ||= @data["entries"].map do |entry|
|
61
|
+
if a = entry['attribute']
|
62
|
+
(Attribute.new a)
|
63
|
+
else
|
64
|
+
X::Entry.find entry['node']
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_s
|
70
|
+
"#{super.to_s}\n#{entries.inspect}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
6
74
|
|
7
75
|
module RfidUsbGomSensor
|
8
76
|
class Node < Gom::Remote::Entry
|
@@ -25,6 +93,18 @@ module RfidUsbGomSensor
|
|
25
93
|
|
26
94
|
@ip = connection.callback_server.host
|
27
95
|
@sp = SerialPort.new device, baudrate
|
96
|
+
|
97
|
+
@sensor_tags = {}.extend(MonitorMixin)
|
98
|
+
@gom_tags = find_tags
|
99
|
+
end
|
100
|
+
|
101
|
+
def find_tags
|
102
|
+
tag_node = X::Entry.find "#{@path}/tags"
|
103
|
+
#puts "-->#{tag_node.inspect}<---"
|
104
|
+
#puts "--->\n#{tag_node}\n<---"
|
105
|
+
tag_node.entries.inject({}) do |tags, node|
|
106
|
+
tags.update node.name => node.mtime
|
107
|
+
end
|
28
108
|
end
|
29
109
|
|
30
110
|
# reader commands
|
@@ -37,7 +117,7 @@ module RfidUsbGomSensor
|
|
37
117
|
#info = [0x02, 0x01, 0x47, 0x46, 0x03]
|
38
118
|
#info.each {|c| @sp.putc c.to_i}
|
39
119
|
@sp.puts GetInfo
|
40
|
-
2.times {@sp.getc}
|
120
|
+
2.times { @sp.getc}
|
41
121
|
print "Detected reader: "
|
42
122
|
37.times {putc(@sp.getc)}
|
43
123
|
print "\n"
|
@@ -50,17 +130,37 @@ module RfidUsbGomSensor
|
|
50
130
|
end
|
51
131
|
|
52
132
|
class << self
|
53
|
-
def
|
54
|
-
|
55
|
-
|
56
|
-
cc
|
133
|
+
def raise_broken_read cc, expected, buf
|
134
|
+
msg = "checksum missmatch: #{cc} != #{expected} -- #{buf.unpack 'H*'}"
|
135
|
+
raise BrokenRead, msg
|
57
136
|
end
|
58
137
|
|
138
|
+
# blk format:
|
139
|
+
#
|
140
|
+
# 0 STX 0x02
|
141
|
+
# 1 ADR 0x01
|
142
|
+
# 2 UID7 0xE0
|
143
|
+
# 3 UID6
|
144
|
+
# 4 UID5
|
145
|
+
# 5 UID4
|
146
|
+
# 6 UID3
|
147
|
+
# 7 UID2
|
148
|
+
# 8 UID1
|
149
|
+
# 9 UID0
|
150
|
+
# 10 ERR 0x00
|
151
|
+
# 11 BCC XOR[1..10]
|
152
|
+
# 12 ETX 0x03
|
153
|
+
#
|
59
154
|
def decode blk
|
60
155
|
#validate
|
61
156
|
rec = (blk.unpack 'c2Qc*')
|
62
|
-
|
63
|
-
|
157
|
+
id = rec[2]
|
158
|
+
rec[2] = "0x#{([id].pack 'Q').unpack 'H*'}"
|
159
|
+
expected = rec[4]
|
160
|
+
cc = (blk[1..10].unpack "C*").inject(0) {|cc, c| cc^c}
|
161
|
+
(cc == expected) or (raise_broken_read cc, expected, blk)
|
162
|
+
#checksum blk[1..10], rec[4]
|
163
|
+
#puts "-#{rec.inspect}-"
|
64
164
|
rec
|
65
165
|
end
|
66
166
|
end
|
@@ -68,7 +168,7 @@ module RfidUsbGomSensor
|
|
68
168
|
def detect
|
69
169
|
loop do
|
70
170
|
uid = next_tag
|
71
|
-
|
171
|
+
@sensor_tags.synchronize { @sensor_tags[uid] = Time.now }
|
72
172
|
end
|
73
173
|
rescue BrokenRead => e
|
74
174
|
(resync_from_broken_read e) and retry
|
@@ -76,6 +176,33 @@ module RfidUsbGomSensor
|
|
76
176
|
:stop # if (e.signm == "INT")
|
77
177
|
end
|
78
178
|
|
179
|
+
def push_active_tags_to_gom
|
180
|
+
active_tags = []
|
181
|
+
@sensor_tags.synchronize do
|
182
|
+
active_tags = @sensor_tags.keys
|
183
|
+
@sensor_tags.clear
|
184
|
+
end
|
185
|
+
#puts "active tags: #{active_tags.inspect}"
|
186
|
+
#connection.write "#{@path}/tags/#{uid}:sensor_ip", @ip
|
187
|
+
|
188
|
+
# 1. which gom tags are not longer active?
|
189
|
+
active_tags.each { |tag| @gom_tags.delete tag }
|
190
|
+
(to_be_deleted = @gom_tags.keys).each do |tag_id|
|
191
|
+
puts "disappeared: #{@path}/tags/#{tag_id}"
|
192
|
+
connection.destroy "#{@path}/tags/#{tag_id}"
|
193
|
+
end
|
194
|
+
@gom_tags.clear
|
195
|
+
|
196
|
+
# 2. active_tags becomes the new gom_tags
|
197
|
+
active_tags.each do |tag_id|
|
198
|
+
@gom_tags[tag_id] = Time.now
|
199
|
+
puts " active: #{@path}/tags/#{tag_id}"
|
200
|
+
connection.write "#{@path}/tags/#{tag_id}:sensor_ip", @ip
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
private
|
205
|
+
|
79
206
|
def resync_from_broken_read e
|
80
207
|
puts " !! broken read resync not yet implemented: #{e}"
|
81
208
|
raise e
|
@@ -86,6 +213,10 @@ module RfidUsbGomSensor
|
|
86
213
|
stx, adx, uid, err, bcc, etx = (Node.decode blk)
|
87
214
|
uid
|
88
215
|
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
__END__
|
89
220
|
|
90
221
|
def _detect
|
91
222
|
=begin
|
@@ -118,5 +249,3 @@ Format:
|
|
118
249
|
rescue SignalException => e
|
119
250
|
:stop # if (e.signm == "INT")
|
120
251
|
end
|
121
|
-
end
|
122
|
-
end
|
@@ -26,22 +26,39 @@ describe RfidUsbGomSensor::Node do
|
|
26
26
|
end
|
27
27
|
|
28
28
|
describe "with a node it" do
|
29
|
+
|
29
30
|
RFID_NODE = <<-JSON
|
31
|
+
{
|
32
|
+
"node": {
|
33
|
+
"uri": "/sensors/rfid-usb-reader",
|
34
|
+
"mtime": "2010-01-06T15:14:57+01:00",
|
35
|
+
"ctime": "2010-01-06T15:14:57+01:00",
|
36
|
+
"entries": [
|
30
37
|
{
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
38
|
+
"node": "/sensors/rfid-usb-reader/tags",
|
39
|
+
"mtime": "2009-12-31T13:00:39+01:00",
|
40
|
+
"ctime": "2009-12-31T13:00:39+01:00"
|
41
|
+
}
|
42
|
+
,
|
43
|
+
{ "attribute": {
|
44
|
+
"name": "daemon_ip",
|
45
|
+
"node": "/sensors/rfid-usb-reader",
|
46
|
+
"value": "127.0.0.1",
|
47
|
+
"type": "string",
|
48
|
+
"mtime": "2010-01-07T19:30:36+01:00",
|
49
|
+
"ctime": "2010-01-07T19:30:36+01:00"
|
50
|
+
} }
|
51
|
+
,
|
52
|
+
{ "attribute": {
|
53
|
+
"name": "device",
|
54
|
+
"node": "/sensors/rfid-usb-reader",
|
55
|
+
"value": "/dev/tty.SLAB_USBtoUART",
|
56
|
+
"type": "string",
|
57
|
+
"mtime": "2010-01-06T15:15:29+01:00",
|
58
|
+
"ctime": "2010-01-06T15:15:29+01:00"
|
59
|
+
} } ]
|
60
|
+
}
|
61
|
+
}
|
45
62
|
JSON
|
46
63
|
|
47
64
|
before :each do
|
@@ -51,7 +68,7 @@ describe RfidUsbGomSensor::Node do
|
|
51
68
|
end
|
52
69
|
|
53
70
|
it "should pull its config from GOM" do
|
54
|
-
@sensor.device.should == "/dev/
|
71
|
+
@sensor.device.should == "/dev/tty.SLAB_USBtoUART"
|
55
72
|
end
|
56
73
|
end
|
57
74
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rfid-usb-gom-sensor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- art+com/dirk luesebrink
|
@@ -9,8 +9,8 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
13
|
-
default_executable: rfid-usb-gom-sensor
|
12
|
+
date: 2010-01-08 00:00:00 +01:00
|
13
|
+
default_executable: rfid-usb-gom-sensor
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: toholio-serialport
|
@@ -45,7 +45,7 @@ dependencies:
|
|
45
45
|
description: "\n As an alternative to the gesture driven content selection on the wall\n guests may use an tablet-PC version of the content load application.\n After content selection the android handset must by adssociated with\n the selection for which the tablet PC has an USB RFID sensor installed.\n This gem now implements the RFID GOM sensor node mapping code which runs\n on the tablet PC.\n "
|
46
46
|
email: dirk.luesebrink@gmail.com
|
47
47
|
executables:
|
48
|
-
- rfid-usb-gom-sensor
|
48
|
+
- rfid-usb-gom-sensor
|
49
49
|
extensions: []
|
50
50
|
|
51
51
|
extra_rdoc_files:
|
@@ -58,7 +58,7 @@ files:
|
|
58
58
|
- README.mkd
|
59
59
|
- Rakefile
|
60
60
|
- VERSION
|
61
|
-
- bin/rfid-usb-gom-sensor
|
61
|
+
- bin/rfid-usb-gom-sensor
|
62
62
|
- lib/rfid-usb-gom-sensor.rb
|
63
63
|
- lib/rfid-usb-gom-sensor/node.rb
|
64
64
|
- lib/rfid_usb_reader.rb
|