wifly 0.0.5 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -0
- data/README.md +3 -5
- data/lib/wifly.rb +1 -0
- data/lib/wifly/calculations.rb +3 -3
- data/lib/wifly/connection.rb +39 -15
- data/lib/wifly/control.rb +13 -8
- data/lib/wifly/version.rb +1 -1
- data/spec/calculations_spec.rb +2 -0
- data/spec/connection_spec.rb +6 -7
- data/spec/control_spec.rb +4 -4
- data/spec/integration_spec.rb +24 -0
- data/spec/spec_helper.rb +4 -0
- metadata +6 -4
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# Wifly
|
2
2
|
|
3
|
-
This Ruby gem can be used to talk to a [WiFly RN-XV](http://www.rovingnetworks.com/products/RN171XV) device at a specified address. The gem has no dependencies other than the socket libraries that ship with any Ruby installation.
|
4
|
-
* Unexpected output from the WiFly could cause the client to deadlock on a socket read, or could cause corrupt data in subsequent reads. I've tried to find the variants of output that I'm concerned with in my project; however, you might find some edge cases I haven't covered. In that case, pull requests are welcome.
|
5
|
-
* The version of the firmware must be passed into the client so that the size of the response strings can be predicted.
|
3
|
+
This Ruby gem can be used to talk to a [WiFly RN-XV](http://www.rovingnetworks.com/products/RN171XV) device at a specified address. The gem has no dependencies other than the socket libraries that ship with any Ruby installation.
|
6
4
|
|
7
5
|
## Installation
|
8
6
|
|
@@ -19,9 +17,9 @@ Or install it yourself as:
|
|
19
17
|
$ gem install wifly
|
20
18
|
|
21
19
|
## Usage
|
22
|
-
Create a client by passing in the host
|
20
|
+
Create a client by passing in the host and port
|
23
21
|
|
24
|
-
control = Wifly::Control.new('192.168.1.45', 2000
|
22
|
+
control = Wifly::Control.new('192.168.1.45', 2000)
|
25
23
|
|
26
24
|
Read the high pins:
|
27
25
|
|
data/lib/wifly.rb
CHANGED
data/lib/wifly/calculations.rb
CHANGED
@@ -5,9 +5,9 @@ module Wifly
|
|
5
5
|
# into an array of pins that are high
|
6
6
|
#
|
7
7
|
def parse_io(hex_str)
|
8
|
-
|
9
|
-
binary_string = hex_str
|
10
|
-
binary_string.reverse.
|
8
|
+
# use sprintf to pad with 0's to 16 bits
|
9
|
+
binary_string = "%016b" % hex_str.hex.to_i
|
10
|
+
binary_string.reverse.chars.each_with_index.map do |value, pin|
|
11
11
|
pin if value == "1"
|
12
12
|
end.compact
|
13
13
|
end
|
data/lib/wifly/connection.rb
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
module Wifly
|
2
2
|
class Connection
|
3
|
-
attr_accessor :address, :port
|
3
|
+
attr_accessor :address, :port
|
4
4
|
|
5
5
|
##
|
6
6
|
# address => the hostname or IP address of the wifly device
|
7
7
|
# port => the port for communicating with the wifly
|
8
|
-
|
9
|
-
def initialize(address, port, version)
|
8
|
+
def initialize(address, port)
|
10
9
|
self.address = address
|
11
10
|
self.port = port
|
12
|
-
self.version = version
|
13
11
|
end
|
14
12
|
|
15
13
|
##
|
@@ -19,18 +17,15 @@ module Wifly
|
|
19
17
|
# The wifly will echo back the command (with carriage return)
|
20
18
|
# along with another CRLF and the command prompt string.
|
21
19
|
# Something like "lites\r\r\n<2.32> "
|
22
|
-
# Since the string has a predictable length, we can do a blocking read.
|
23
20
|
#
|
24
|
-
def send_command(str
|
21
|
+
def send_command(str)
|
25
22
|
str += "\r"
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
rescue Errno::EPIPE # connection closed on the client end
|
30
|
-
initialize_socket
|
31
|
-
retry
|
23
|
+
write(socket, str) # the write is blocking
|
24
|
+
sleep(0.2)
|
25
|
+
read(socket).gsub(prompt,'')
|
32
26
|
end
|
33
27
|
|
28
|
+
|
34
29
|
def close
|
35
30
|
socket.close
|
36
31
|
end
|
@@ -40,14 +35,43 @@ module Wifly
|
|
40
35
|
end
|
41
36
|
|
42
37
|
private
|
38
|
+
|
39
|
+
def read(sock)
|
40
|
+
result = ''
|
41
|
+
begin
|
42
|
+
result = sock.read_nonblock(1024)
|
43
|
+
# connection lost somehow
|
44
|
+
rescue Errno::ECONNRESET, Errno::EPIPE, IOError
|
45
|
+
initialize_socket
|
46
|
+
read(socket)
|
47
|
+
# No more data on socket
|
48
|
+
rescue Errno::EAGAIN
|
49
|
+
retry
|
50
|
+
rescue EOFError => e
|
51
|
+
# ain't nothin left on socket.
|
52
|
+
end
|
53
|
+
result.strip
|
54
|
+
end
|
55
|
+
|
56
|
+
def write(sock, str)
|
57
|
+
begin
|
58
|
+
sock.write(str)
|
59
|
+
rescue Errno::EPIPE, IOError
|
60
|
+
initialize_socket
|
61
|
+
write(socket, str)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
43
65
|
def prompt
|
44
|
-
|
66
|
+
# 2.32
|
67
|
+
# 3.2.23
|
68
|
+
/<[0-9]{1,}\.[0-9]{1,}(\.[0-9]{1,})?>/
|
45
69
|
end
|
46
70
|
|
47
71
|
def initialize_socket
|
48
72
|
sock = Socket.tcp(address, port)
|
49
|
-
|
50
|
-
|
73
|
+
write(sock, COMMAND_MODE) # enter command mode
|
74
|
+
read(sock) # read off the response
|
51
75
|
sock
|
52
76
|
end
|
53
77
|
end
|
data/lib/wifly/control.rb
CHANGED
@@ -7,12 +7,11 @@ module Wifly
|
|
7
7
|
##
|
8
8
|
# address - the hostname or IP address
|
9
9
|
# port - defaults to 2000
|
10
|
-
# version - the firmware version (a string)
|
11
10
|
# connection - the object to use for talking to the wifly. Responds to "send_command."
|
12
11
|
# Defaults to Wifly::Connection.
|
13
12
|
#
|
14
|
-
def initialize(address, port,
|
15
|
-
self.connection = connection || Connection.new(address, port
|
13
|
+
def initialize(address, port, connection=nil)
|
14
|
+
self.connection = connection || Connection.new(address, port)
|
16
15
|
end
|
17
16
|
|
18
17
|
##
|
@@ -27,7 +26,7 @@ module Wifly
|
|
27
26
|
#
|
28
27
|
def set_high(pin)
|
29
28
|
hex = pin_to_hex(pin)
|
30
|
-
connection.send_command "set sys output #{hex} #{hex}"
|
29
|
+
connection.send_command "set sys output #{hex} #{hex}"
|
31
30
|
end
|
32
31
|
|
33
32
|
##
|
@@ -35,7 +34,7 @@ module Wifly
|
|
35
34
|
#
|
36
35
|
def set_low(pin)
|
37
36
|
hex = pin_to_hex(pin)
|
38
|
-
connection.send_command "set sys output 0x00 #{hex}"
|
37
|
+
connection.send_command "set sys output 0x00 #{hex}"
|
39
38
|
end
|
40
39
|
|
41
40
|
##
|
@@ -52,6 +51,13 @@ module Wifly
|
|
52
51
|
parse_io(read_io)
|
53
52
|
end
|
54
53
|
|
54
|
+
##
|
55
|
+
# Close the connection.
|
56
|
+
#
|
57
|
+
def close
|
58
|
+
connection.close
|
59
|
+
end
|
60
|
+
|
55
61
|
private
|
56
62
|
|
57
63
|
##
|
@@ -60,9 +66,8 @@ module Wifly
|
|
60
66
|
def read_io
|
61
67
|
cmd = "show io\r"
|
62
68
|
|
63
|
-
#
|
64
|
-
|
65
|
-
str = connection.send_command("show io", "8d08\r\n".length)
|
69
|
+
# result is something like 'show io\r\r\n8d08'
|
70
|
+
str = connection.send_command "show io"
|
66
71
|
|
67
72
|
# Return only the middle part, which is the io state
|
68
73
|
str.gsub(cmd,'').strip
|
data/lib/wifly/version.rb
CHANGED
data/spec/calculations_spec.rb
CHANGED
data/spec/connection_spec.rb
CHANGED
@@ -13,12 +13,12 @@ class Wifly::TestServer
|
|
13
13
|
@client.close
|
14
14
|
end
|
15
15
|
|
16
|
-
def receive_command(command
|
16
|
+
def receive_command(command)
|
17
17
|
@client = @socket.accept
|
18
18
|
|
19
19
|
@client.write(Wifly::HELLO)
|
20
20
|
@client.read((command + "\r").length)
|
21
|
-
@client.write(command + "\r\r\n<
|
21
|
+
@client.write(command + "\r\r\n<2.32> ")
|
22
22
|
@client.close
|
23
23
|
end
|
24
24
|
end
|
@@ -28,17 +28,16 @@ describe Wifly::Connection do
|
|
28
28
|
@server = Wifly::TestServer.new(2000)
|
29
29
|
end
|
30
30
|
it 'should set stuff on initialize' do
|
31
|
-
connection = Wifly::Connection.new('localhost', 2000
|
31
|
+
connection = Wifly::Connection.new('localhost', 2000)
|
32
32
|
connection.address.should eq('localhost')
|
33
33
|
connection.port.should eq(2000)
|
34
|
-
connection.version.should eq('2.3.13')
|
35
34
|
end
|
36
35
|
|
37
36
|
it 'should enter command mode' do
|
38
37
|
t = Thread.new do
|
39
38
|
@server.simple_connect
|
40
39
|
end
|
41
|
-
connection = Wifly::Connection.new('localhost', 2000
|
40
|
+
connection = Wifly::Connection.new('localhost', 2000)
|
42
41
|
connection.socket
|
43
42
|
t.join
|
44
43
|
@server.input.should eq(Wifly::COMMAND_MODE)
|
@@ -47,9 +46,9 @@ describe Wifly::Connection do
|
|
47
46
|
|
48
47
|
it 'should send commands correctly' do
|
49
48
|
t = Thread.new do
|
50
|
-
@server.receive_command("lites"
|
49
|
+
@server.receive_command("lites")
|
51
50
|
end
|
52
|
-
connection = Wifly::Connection.new('localhost', 2000
|
51
|
+
connection = Wifly::Connection.new('localhost', 2000)
|
53
52
|
|
54
53
|
result = connection.send_command("lites")
|
55
54
|
t.join
|
data/spec/control_spec.rb
CHANGED
@@ -2,9 +2,9 @@ require 'spec_helper'
|
|
2
2
|
describe Wifly::Control do
|
3
3
|
it 'should set high and low' do
|
4
4
|
connection = double('connection')
|
5
|
-
connection.should_receive(:send_command).with("set sys output 0x20 0x20"
|
6
|
-
connection.should_receive(:send_command).with("set sys output 0x00 0x20"
|
7
|
-
control = Wifly::Control.new('localhost', 2000,
|
5
|
+
connection.should_receive(:send_command).with("set sys output 0x20 0x20")
|
6
|
+
connection.should_receive(:send_command).with("set sys output 0x00 0x20")
|
7
|
+
control = Wifly::Control.new('localhost', 2000, connection)
|
8
8
|
control.set_high(5)
|
9
9
|
control.set_low(5)
|
10
10
|
end
|
@@ -12,7 +12,7 @@ describe Wifly::Control do
|
|
12
12
|
it 'should get high pins' do
|
13
13
|
connection = double('connection')
|
14
14
|
connection.should_receive(:send_command).exactly(2).times.and_return("show io\r\r\n8d08\r\n")
|
15
|
-
control = Wifly::Control.new('localhost', 2000,
|
15
|
+
control = Wifly::Control.new('localhost', 2000, connection)
|
16
16
|
|
17
17
|
control.read_pin(8).should eq(1)
|
18
18
|
control.read_pin(7).should eq(0)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
#
|
3
|
+
# This test excercizes pretty much most of the control methods
|
4
|
+
# on an actual WiFly. Supplying the WIFLY_IP as an environment
|
5
|
+
# variable activates this test.
|
6
|
+
# That means you should have the WiFly connected to a network
|
7
|
+
# accessible by the computer running this test.
|
8
|
+
#
|
9
|
+
if WIFLY_IP
|
10
|
+
describe Wifly do
|
11
|
+
it 'should really work' do
|
12
|
+
2.times do
|
13
|
+
control=Wifly::Control.new(WIFLY_IP, 2000)
|
14
|
+
5.times do |n|
|
15
|
+
control.set_high(7)
|
16
|
+
control.read_pin(7).should eq(1)
|
17
|
+
control.set_low(7)
|
18
|
+
control.read_pin(7).should eq(0)
|
19
|
+
end
|
20
|
+
control.close
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -5,6 +5,10 @@
|
|
5
5
|
#
|
6
6
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
7
|
require 'wifly'
|
8
|
+
require 'pry'
|
9
|
+
|
10
|
+
# If you set WIFLY_IP, a special "real" test will run against your WiFly.
|
11
|
+
WIFLY_IP = ENV['WIFLY_IP'] || nil
|
8
12
|
|
9
13
|
RSpec.configure do |config|
|
10
14
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wifly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-02-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -96,6 +96,7 @@ files:
|
|
96
96
|
- spec/calculations_spec.rb
|
97
97
|
- spec/connection_spec.rb
|
98
98
|
- spec/control_spec.rb
|
99
|
+
- spec/integration_spec.rb
|
99
100
|
- spec/spec_helper.rb
|
100
101
|
- wifly.gemspec
|
101
102
|
homepage: ''
|
@@ -113,7 +114,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
113
114
|
version: '0'
|
114
115
|
segments:
|
115
116
|
- 0
|
116
|
-
hash:
|
117
|
+
hash: 17962621
|
117
118
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
119
|
none: false
|
119
120
|
requirements:
|
@@ -122,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
123
|
version: '0'
|
123
124
|
segments:
|
124
125
|
- 0
|
125
|
-
hash:
|
126
|
+
hash: 17962621
|
126
127
|
requirements: []
|
127
128
|
rubyforge_project:
|
128
129
|
rubygems_version: 1.8.25
|
@@ -133,4 +134,5 @@ test_files:
|
|
133
134
|
- spec/calculations_spec.rb
|
134
135
|
- spec/connection_spec.rb
|
135
136
|
- spec/control_spec.rb
|
137
|
+
- spec/integration_spec.rb
|
136
138
|
- spec/spec_helper.rb
|