gembird-backend 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
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
18
+ .DS_Store
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/.travis.yml ADDED
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - jruby-18mode
7
+ - jruby-19mode
8
+ - rbx-18mode
9
+ - rbx-19mode
10
+ - ruby-head
11
+ - jruby-head
12
+ - ree
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in gembird-web.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,6 @@
1
+ # rspec
2
+ guard 'rspec', :version => 2 do
3
+ watch(%r{^spec/.+_spec\.rb$})
4
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
5
+ watch('spec/spec_helper.rb') { "spec" }
6
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Jens Bissinger
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # GembirdBackend
2
+
3
+ This is a wrapper to provide ruby API for `sispmctl` script.
4
+
5
+ More info at the [sispmctl project page](http://sispmctl.sourceforge.net/).
6
+
7
+ [![Travis-CI Build Status](https://secure.travis-ci.org/dpree/gembird-backend.png)](https://secure.travis-ci.org/dpree/gembird-backend)
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem gembird-backend
14
+
15
+ And then execute:
16
+
17
+ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ gem install gembird-backend
22
+
23
+ ## Usage
24
+
25
+ **List all connected devices**
26
+
27
+ require 'gembird-backend'
28
+
29
+ GembirdBackend.devices
30
+ # => [{:number=>"0",
31
+ # :usb_device=>"001",
32
+ # :usb_bus=>"004",
33
+ # :type=>"4-socket SiS-PM",
34
+ # :serial=>"02:01:48:af:e0"}]
35
+
36
+ require 'gembird-backend'
37
+
38
+ **Check the status of the sockets for every connected device**
39
+
40
+ require 'gembird-backend'
41
+ GembirdBackend.socket
42
+ # => [{:number=>"0",
43
+ # :usb_device => "003",
44
+ # :sockets=>{"1"=>"on",
45
+ # "2"=>"off",
46
+ # "3"=>"on",
47
+ # "4"=>"off"}}]
48
+
49
+ ## Contributing
50
+
51
+ 1. Fork it
52
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
53
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
54
+ 4. Push to the branch (`git push origin my-new-feature`)
55
+ 5. Create new Pull Request
56
+
57
+ ## License
58
+
59
+ see LICENSE file
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/gembird-backend/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Jens Bissinger"]
6
+ gem.email = ["mail@jens-bissinger.de"]
7
+ gem.description = %q{Wrapper around sispmctl script}
8
+ gem.summary = %q{Provides an API to control Gembird USB power strips}
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "gembird-backend"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = GembirdBackend::VERSION
17
+
18
+ gem.add_development_dependency "rspec"
19
+ gem.add_development_dependency "guard-rspec"
20
+ gem.add_development_dependency "yard"
21
+ gem.add_development_dependency "rake"
22
+
23
+ end
@@ -0,0 +1,54 @@
1
+ require "logger"
2
+ require File.join(File.dirname(__FILE__), "gembird-backend/scanner")
3
+ require File.join(File.dirname(__FILE__), "gembird-backend/parser")
4
+ require File.join(File.dirname(__FILE__), "gembird-backend/command")
5
+ require File.join(File.dirname(__FILE__), "gembird-backend/retry")
6
+ module GembirdBackend
7
+ # when error occurs
8
+ class ExecutionError < StandardError; end
9
+
10
+ class << self
11
+ def logger
12
+ @logger ||= Logger.new(open('/dev/null', "w+"))
13
+ end
14
+
15
+ def parse result
16
+ @parser ||= GembirdBackend::Parser.new
17
+ @parser.parse result
18
+ end
19
+
20
+ def command
21
+ @command ||= GembirdBackend::Command.new
22
+ end
23
+
24
+ def try &block
25
+ @retry ||= GembirdBackend::Retry.new
26
+ @retry.try &block
27
+ end
28
+
29
+ # @see GembirdBackend::Command#devices
30
+ def devices
31
+ try { parse command.devices }
32
+ end
33
+
34
+ # @see GembirdBackend::Command#on!
35
+ def on! socket='all', options={}
36
+ try { parse command.on! socket, options }
37
+ end
38
+
39
+ # @see GembirdBackend::Command#off!
40
+ def off! socket='all', options={}
41
+ try { parse command.off! socket, options }
42
+ end
43
+
44
+ # @see GembirdBackend::Command#toggle!
45
+ def toggle! socket='all', options={}
46
+ try { parse command.toggle! socket, options }
47
+ end
48
+
49
+ # @see GembirdBackend::Command#status
50
+ def status socket='all', options={}
51
+ try { parse command.status socket, options }
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,78 @@
1
+ module GembirdBackend
2
+ class Command
3
+ BIN = 'sispmctl' # the sispmctl binary
4
+
5
+ # set dry to true for testing purposes
6
+ attr_reader :dry
7
+ def initialize dry=false
8
+ @dry = dry
9
+ end
10
+
11
+ def call action, argument = nil, options = {}
12
+ args = []
13
+ if device = options[:device]
14
+ # serial or number
15
+ args << (device.to_s.include?(":") ? "-D" : "-d")
16
+ args << device
17
+ end
18
+ args << (argument ? [action, argument] : action)
19
+ command = build args
20
+ dry ? command : exec(command)
21
+ end
22
+
23
+ def build *options
24
+ [BIN, options].flatten.join ' '
25
+ end
26
+
27
+ def exec command
28
+ `#{command}`
29
+ end
30
+
31
+ # scans for devices
32
+ # @return [Array<Hash>] devices
33
+ # @example return
34
+ # [{:number=>"0",
35
+ # :usb_device=>"001",
36
+ # :usb_bus=>"004",
37
+ # :type=>"4-socket SiS-PM",
38
+ # :serial=>"02:01:48:af:e0"}]
39
+ def devices
40
+ call '-s'
41
+ end
42
+
43
+ # switch a socket on
44
+ # @return [Array<Hash>] devices
45
+ # @see #status example return values
46
+ def on! socket='all', options={}
47
+ call '-o', socket, options
48
+ end
49
+
50
+ # switch a socket off
51
+ # @return [Array<Hash>] devices
52
+ # @see #status example return values
53
+ def off! socket='all', options={}
54
+ call '-f', socket, options
55
+ end
56
+
57
+ # toggle a socket
58
+ # @return [Array<Hash>] devices
59
+ # @see #status example return values
60
+ def toggle! socket='all', options={}
61
+ call '-t', socket, options
62
+ end
63
+
64
+ # get the status of a socket
65
+ # @return [Array<Hash>] devices
66
+ # @example return
67
+ # [{:number=>"0",
68
+ # :usb_device => "003",
69
+ # :sockets=>{"1"=>"on",
70
+ # "2"=>"off",
71
+ # "3"=>"on",
72
+ # "4"=>"off"}}]
73
+ # :sockets=>{"1"=>"on", "2"=>"off", "3"=>"on", "4"=>"off"}}]
74
+ def status socket='all', options={}
75
+ call '-g', socket, options
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,34 @@
1
+ module GembirdBackend
2
+ class Parser
3
+ # @param [String] result
4
+ # @return [Array] stack of parsed result
5
+ def parse result
6
+ tokens = GembirdBackend::Scanner.new.scan result
7
+ stack = []
8
+ tokens.each do |token, *args|
9
+ case token
10
+ when :begin_device
11
+ stack << {}
12
+ stack.last[:number] = args.first.first
13
+ when :device_type
14
+ stack.last[:type] = args.first.first
15
+ when :device_serial
16
+ stack.last[:serial] = args.first.first
17
+ when :usb_info
18
+ stack.last[:usb_device] = args.first
19
+ stack.last[:usb_bus] = args.last
20
+ when :accessing_device
21
+ stack << {}
22
+ stack.last[:number] = args.first
23
+ stack.last[:usb_device] = args.last
24
+ when :socket_status
25
+ stack.last[:sockets] ||= {}
26
+ stack.last[:sockets][args.first] = args.last
27
+ when :error
28
+ raise GembirdBackend::ExecutionError, args.first
29
+ end
30
+ end
31
+ stack
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,30 @@
1
+ module GembirdBackend
2
+ class Retry
3
+ attr_reader :delay
4
+ def initialize(delay = true)
5
+ @delay = delay
6
+ end
7
+
8
+ # try to make a successful call
9
+ # retry n times in case of error
10
+ # @param [Fixnum] n
11
+ def try(n = 3, &block)
12
+ try = lambda do
13
+ begin
14
+ block.call
15
+ rescue ExecutionError => e
16
+ GembirdBackend.logger.warn "retrying... #{e}"
17
+ nil
18
+ end
19
+ end
20
+ sleep_time = 0
21
+ n.times do
22
+ result = try.call
23
+ return result if result
24
+ sleep (2 ** sleep_time) if delay
25
+ sleep_time += 1
26
+ end
27
+ nil
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,44 @@
1
+ module GembirdBackend
2
+ class Scanner
3
+ # @param [String] result
4
+ # @return [Array] tokens
5
+ def scan result
6
+ tokens = []
7
+ result.split("\n").each do |line|
8
+
9
+ ### socket
10
+ if matched = line.match(/^Accessing Gembird #(.+) USB device (.+)$/)
11
+ device_number, usb_device = *matched.captures
12
+ tokens << [:accessing_device, device_number, usb_device]
13
+ elsif matched = line.match(/outlet.+?(\d+).+?(on|off)/)
14
+ socket_number, status = *matched.captures
15
+ tokens << [:socket_status, socket_number, status]
16
+
17
+ ### device
18
+ elsif matched = line.match(/^Gembird #(.+)$/)
19
+ device_number = *matched.captures
20
+ tokens << [:begin_device, device_number]
21
+ elsif matched = line.match(/device type:\s+(.+)/)
22
+ device_type = *matched.captures
23
+ tokens << [:device_type, device_type]
24
+ elsif matched = line.match(/serial number:\s+(.+)/)
25
+ device_serial = *matched.captures
26
+ tokens << [:device_serial, device_serial]
27
+ elsif matched = line.match(/USB information:\s+bus (.+), device (.+)/)
28
+ usb_bus, usb_device = *matched.captures
29
+ tokens << [:usb_info, usb_device, usb_bus]
30
+
31
+ ### error
32
+ elsif line =~ /error/i || line =~ /Check USB connections/
33
+ tokens << [:error, result]
34
+ elsif line =~ /Invalid number or given device not found/ ||
35
+ line =~ /No device with serial number/
36
+ tokens << [:device_not_found]
37
+ else
38
+ # noop
39
+ end
40
+ end
41
+ tokens
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,3 @@
1
+ module GembirdBackend
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,2 @@
1
+ Invalid number or given device not found.
2
+ Terminating
@@ -0,0 +1,4 @@
1
+ Gembird #0
2
+ USB information: bus 004, device 001
3
+ device type: 4-socket SiS-PM
4
+ serial number: 02:01:48:af:e0
@@ -0,0 +1 @@
1
+ No GEMBIRD SiS-PM found. Check USB connections, please!
@@ -0,0 +1,5 @@
1
+ Accessing Gembird #0 USB device 003
2
+ Status of outlet 1: off
3
+ Error performing requested action
4
+ Libusb error string: Operation timed out
5
+ Terminating
@@ -0,0 +1,5 @@
1
+ Accessing Gembird #0 USB device 003
2
+ Status of outlet 1: on
3
+ Status of outlet 2: off
4
+ Status of outlet 3: on
5
+ Status of outlet 4: off
@@ -0,0 +1,2 @@
1
+ No device with serial number foobar123 found.
2
+ Terminating
@@ -0,0 +1,70 @@
1
+ require "spec_helper"
2
+
3
+ describe GembirdBackend::Command do
4
+ before :each do
5
+ @command = GembirdBackend::Command.new(true)
6
+ end
7
+
8
+ it 'builds empty command' do
9
+ @command.build.should == 'sispmctl'
10
+ end
11
+
12
+ it 'builds any command' do
13
+ @command.build('foo', 'bar').should == 'sispmctl foo bar'
14
+ end
15
+
16
+ describe '#devices' do
17
+ it 'scans all' do
18
+ @command.devices.should == 'sispmctl -s'
19
+ end
20
+ end
21
+
22
+ describe '#status' do
23
+ it 'retrieves all' do
24
+ @command.status.should == 'sispmctl -g all'
25
+ end
26
+ it 'retrieves single' do
27
+ @command.status(1).should == 'sispmctl -g 1'
28
+ end
29
+ it 'retrieves single for device' do
30
+ @command.status(1, :device=>"aa:bb").should == 'sispmctl -D aa:bb -g 1'
31
+ end
32
+ end
33
+
34
+ describe '#on!' do
35
+ it 'switches all on' do
36
+ @command.on!.should == 'sispmctl -o all'
37
+ end
38
+ it 'switches single on' do
39
+ @command.on!(1).should == 'sispmctl -o 1'
40
+ end
41
+ it 'switches single for device' do
42
+ @command.on!(1, :device=>"123").should == 'sispmctl -d 123 -o 1'
43
+ end
44
+ end
45
+
46
+ describe '#off!' do
47
+ it 'switches all off' do
48
+ @command.off!.should == 'sispmctl -f all'
49
+ end
50
+ it 'switches single off' do
51
+ @command.off!(1).should == 'sispmctl -f 1'
52
+ end
53
+ it 'switches single for device off' do
54
+ @command.off!(1, :device=>1).should == 'sispmctl -d 1 -f 1'
55
+ end
56
+ end
57
+
58
+ describe '#toggle!' do
59
+ it 'toggles all' do
60
+ @command.toggle!.should == 'sispmctl -t all'
61
+ end
62
+ it 'toggles single' do
63
+ @command.toggle!(1).should == 'sispmctl -t 1'
64
+ end
65
+ it 'toggles single for device' do
66
+ @command.toggle!(1, :device=>1).should == 'sispmctl -d 1 -t 1'
67
+ end
68
+ end
69
+ end
70
+
@@ -0,0 +1,31 @@
1
+ require "spec_helper"
2
+
3
+ describe GembirdBackend::Parser do
4
+ before :each do
5
+ @parser = GembirdBackend::Parser.new
6
+ end
7
+
8
+ it 'lists all devices' do
9
+ @parser.parse(command_result('devices.txt')).should == \
10
+ [{:number=>"0", :usb_device=>"001", :usb_bus=>"004",
11
+ :type=>"4-socket SiS-PM", :serial=>"02:01:48:af:e0"}]
12
+ end
13
+
14
+ it 'lists all sockets' do
15
+ @parser.parse(command_result('socket-status.txt')).should == \
16
+ [{:number=>"0", :usb_device => "003",
17
+ :sockets=>{"1"=>"on", "2"=>"off", "3"=>"on", "4"=>"off"}}]
18
+ end
19
+
20
+ it 'detects error' do
21
+ lambda do
22
+ @parser.parse(command_result('socket-status-error.txt'))
23
+ end.should raise_error(GembirdBackend::ExecutionError)
24
+ end
25
+
26
+ it 'detects connection loss' do
27
+ lambda do
28
+ @parser.parse(command_result('no-connection.txt'))
29
+ end.should raise_error(GembirdBackend::ExecutionError)
30
+ end
31
+ end
@@ -0,0 +1,27 @@
1
+ require "spec_helper"
2
+
3
+ describe GembirdBackend do
4
+ before :each do
5
+ GembirdBackend.instance_variable_set('@retry', GembirdBackend::Retry.new(false))
6
+ class CommandMock < GembirdBackend::Command
7
+ attr_accessor :exec_count
8
+ def exec command
9
+ self.exec_count ||= 0
10
+ self.exec_count += 1
11
+ case command
12
+ when /-g/
13
+ command_result('socket-status.txt')
14
+ else
15
+ command_result('socket-status-error.txt')
16
+ end
17
+ end
18
+ end
19
+ @mock = CommandMock.new
20
+ GembirdBackend.instance_variable_set("@command", @mock)
21
+ end
22
+
23
+ it 'should try 3 times' do
24
+ GembirdBackend.on!.should be_nil
25
+ @mock.exec_count.should == 3
26
+ end
27
+ end
@@ -0,0 +1,14 @@
1
+ require File.join(File.dirname(__FILE__), "../lib/gembird-backend")
2
+ RSpec.configure do |config|
3
+ config.treat_symbols_as_metadata_keys_with_true_values = true
4
+ config.run_all_when_everything_filtered = true
5
+ config.filter_run :focus
6
+ end
7
+
8
+ def assets(*path)
9
+ File.join(File.dirname(__FILE__), "assets", *path)
10
+ end
11
+
12
+ def command_result(file)
13
+ File.read assets "sispmctl", file
14
+ end
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gembird-backend
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Jens Bissinger
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-04-01 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :development
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: guard-rspec
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :development
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: yard
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :development
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: rake
50
+ prerelease: false
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ type: :development
58
+ version_requirements: *id004
59
+ description: Wrapper around sispmctl script
60
+ email:
61
+ - mail@jens-bissinger.de
62
+ executables: []
63
+
64
+ extensions: []
65
+
66
+ extra_rdoc_files: []
67
+
68
+ files:
69
+ - .gitignore
70
+ - .rspec
71
+ - .travis.yml
72
+ - Gemfile
73
+ - Guardfile
74
+ - LICENSE
75
+ - README.md
76
+ - Rakefile
77
+ - gembird-backend.gemspec
78
+ - lib/gembird-backend.rb
79
+ - lib/gembird-backend/command.rb
80
+ - lib/gembird-backend/parser.rb
81
+ - lib/gembird-backend/retry.rb
82
+ - lib/gembird-backend/scanner.rb
83
+ - lib/gembird-backend/version.rb
84
+ - spec/assets/sispmctl/device-not-found.txt
85
+ - spec/assets/sispmctl/devices.txt
86
+ - spec/assets/sispmctl/no-connection.txt
87
+ - spec/assets/sispmctl/socket-status-error.txt
88
+ - spec/assets/sispmctl/socket-status.txt
89
+ - spec/assets/sispmctl/wrong-serial.txt
90
+ - spec/lib/gembird-backend/command_spec.rb
91
+ - spec/lib/gembird-backend/parser_spec.rb
92
+ - spec/lib/gembird-backend_spec.rb
93
+ - spec/spec_helper.rb
94
+ homepage: ""
95
+ licenses: []
96
+
97
+ post_install_message:
98
+ rdoc_options: []
99
+
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: "0"
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: "0"
114
+ requirements: []
115
+
116
+ rubyforge_project:
117
+ rubygems_version: 1.8.15
118
+ signing_key:
119
+ specification_version: 3
120
+ summary: Provides an API to control Gembird USB power strips
121
+ test_files:
122
+ - spec/assets/sispmctl/device-not-found.txt
123
+ - spec/assets/sispmctl/devices.txt
124
+ - spec/assets/sispmctl/no-connection.txt
125
+ - spec/assets/sispmctl/socket-status-error.txt
126
+ - spec/assets/sispmctl/socket-status.txt
127
+ - spec/assets/sispmctl/wrong-serial.txt
128
+ - spec/lib/gembird-backend/command_spec.rb
129
+ - spec/lib/gembird-backend/parser_spec.rb
130
+ - spec/lib/gembird-backend_spec.rb
131
+ - spec/spec_helper.rb
132
+ has_rdoc: