apiotics_factory 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/License +9 -0
- data/bin/apiotics_factory +3 -0
- data/lib/apiotics_factory/clear_credentials.rb +25 -0
- data/lib/apiotics_factory/configuration.rb +30 -0
- data/lib/apiotics_factory/generator.rb +133 -0
- data/lib/apiotics_factory/my_command.rb +15 -0
- data/lib/apiotics_factory/portal.rb +33 -0
- data/lib/apiotics_factory/publish.rb +83 -0
- data/lib/apiotics_factory/underscore.rb +11 -0
- data/lib/apiotics_factory/version.rb +3 -0
- data/lib/apiotics_factory.rb +28 -0
- data/lib/templates/apiotics_driver.rb.erb +244 -0
- data/lib/templates/apiotics_interfaces.rb.erb +33 -0
- data/lib/templates/config.json.erb +172 -0
- data/lib/templates/exec.rb.erb +8 -0
- data/lib/templates/grove_pi/grove_pi.rb +270 -0
- data/lib/templates/grove_pi/i2c/device/acm1602ni.rb +19 -0
- data/lib/templates/grove_pi/i2c/device/adt7410.rb +149 -0
- data/lib/templates/grove_pi/i2c/device/aqm0802.rb +70 -0
- data/lib/templates/grove_pi/i2c/device/bmp180.rb +207 -0
- data/lib/templates/grove_pi/i2c/device/d6t-44l.rb +52 -0
- data/lib/templates/grove_pi/i2c/device/hd44780.rb +172 -0
- data/lib/templates/grove_pi/i2c/device/hdc1000.rb +42 -0
- data/lib/templates/grove_pi/i2c/device/mpl115a2.rb +38 -0
- data/lib/templates/grove_pi/i2c/driver/gpio.rb +213 -0
- data/lib/templates/grove_pi/i2c/driver/i2c-dev.rb +60 -0
- data/lib/templates/grove_pi/i2c/driver.rb +28 -0
- data/lib/templates/grove_pi/i2c/i2c.rb +45 -0
- metadata +114 -0
@@ -0,0 +1,213 @@
|
|
1
|
+
require_relative "../../i2c"
|
2
|
+
require_relative "../../i2c/driver"
|
3
|
+
=begin
|
4
|
+
Generic software I2C Driver based on /sys/class/gpio.
|
5
|
+
THIS MODULE WORKS WITH VERY SLOW SPEED ABOUT JUST 1kHz (normaly 100kHz).
|
6
|
+
=end
|
7
|
+
|
8
|
+
class I2CDevice::Driver::GPIO < I2CDevice::Driver::Base
|
9
|
+
@@DEBUG = false
|
10
|
+
|
11
|
+
def self.export(pin) #:nodoc:
|
12
|
+
File.open("/sys/class/gpio/export", "w") do |f|
|
13
|
+
f.syswrite(pin)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.unexport(pin) #:nodoc:
|
18
|
+
File.open("/sys/class/gpio/unexport", "w") do |f|
|
19
|
+
f.syswrite(pin)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.direction(pin, direction) #:nodoc:
|
24
|
+
# [:in, :out, :high, :low].include?(direction) or raise "direction must be :in, :out, :high or :low"
|
25
|
+
File.open("/sys/class/gpio/gpio#{pin}/direction", "w") do |f|
|
26
|
+
f.syswrite(direction)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.read(pin) #:nodoc:
|
31
|
+
File.open("/sys/class/gpio/gpio#{pin}/value", "r") do |f|
|
32
|
+
f.sysread(1).to_i
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.write(pin, val) #:nodoc:
|
37
|
+
File.open("/sys/class/gpio/gpio#{pin}/value", "w") do |f|
|
38
|
+
f.syswrite(val ? "1" : "0")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.finalizer(ports) #:nodoc:
|
43
|
+
proc do
|
44
|
+
ports.each do |pin|
|
45
|
+
GPIO.unexport(pin)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Pin-number of SDA
|
51
|
+
attr_reader :sda
|
52
|
+
# Pin-number of SCL
|
53
|
+
attr_reader :scl
|
54
|
+
# Clock speed in kHz
|
55
|
+
attr_reader :speed
|
56
|
+
|
57
|
+
# <tt>opts[:sda]</tt> :: [Integer] Pin-number of SDA
|
58
|
+
# <tt>opts[:scl]</tt> :: [Integer] Pin-number of SCL
|
59
|
+
# <tt>[ opts[:speed] = 1 ]</tt> :: [Integer] Clock speed in kHz
|
60
|
+
def initialize(opts={})
|
61
|
+
@sda = opts[:sda] or raise "opts[:sda] = [gpio pin number] is required"
|
62
|
+
@scl = opts[:scl] or raise "opts[:scl] = [gpio pin number] is required"
|
63
|
+
@speed = opts[:speed] || 1 # kHz but insane
|
64
|
+
@clock = 1.0 / (@speed * 1000)
|
65
|
+
|
66
|
+
begin
|
67
|
+
GPIO.export(@sda)
|
68
|
+
GPIO.export(@scl)
|
69
|
+
rescue Errno::EBUSY => e
|
70
|
+
end
|
71
|
+
ObjectSpace.define_finalizer(self, self.class.finalizer([@scl, @sda]))
|
72
|
+
begin
|
73
|
+
GPIO.direction(@sda, :high)
|
74
|
+
GPIO.direction(@scl, :high)
|
75
|
+
GPIO.direction(@sda, :in)
|
76
|
+
GPIO.direction(@scl, :in)
|
77
|
+
rescue Errno::EACCES => e # writing to gpio after export is failed in a while
|
78
|
+
retry
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Interface of I2CDevice::Driver
|
83
|
+
def i2cget(address, param, length=1)
|
84
|
+
ret = ""
|
85
|
+
start_condition
|
86
|
+
unless write( (address << 1) + 0)
|
87
|
+
raise I2CDevice::I2CIOError, "Unknown slave device (address:#{address})"
|
88
|
+
end
|
89
|
+
write(param)
|
90
|
+
stop_condition # AVR stucked with SCL low without this (Does not AVR support Sr condition?)
|
91
|
+
start_condition
|
92
|
+
unless write( (address << 1) + 1)
|
93
|
+
raise I2CDevice::I2CIOError, "Unknown slave device (address:#{address})"
|
94
|
+
end
|
95
|
+
length.times do |n|
|
96
|
+
ret << read(n != length - 1).chr
|
97
|
+
end
|
98
|
+
ret
|
99
|
+
ensure
|
100
|
+
stop_condition
|
101
|
+
end
|
102
|
+
|
103
|
+
# Interface of I2CDevice::Driver
|
104
|
+
def i2cset(address, *data)
|
105
|
+
sent = 0
|
106
|
+
start_condition
|
107
|
+
unless write( (address << 1) + 0)
|
108
|
+
raise I2CDevice::I2CIOError, "Unknown slave device (address:#{address})"
|
109
|
+
end
|
110
|
+
data.each do |c|
|
111
|
+
unless write(c)
|
112
|
+
break
|
113
|
+
end
|
114
|
+
sent += 1
|
115
|
+
end
|
116
|
+
sent
|
117
|
+
ensure
|
118
|
+
stop_condition
|
119
|
+
end
|
120
|
+
|
121
|
+
private
|
122
|
+
|
123
|
+
# Send start condition (or repeated start condition)
|
124
|
+
# raise I2CDevice::I2CBUSBusy if SCL line is low
|
125
|
+
def start_condition
|
126
|
+
p :start_condition if @@DEBUG
|
127
|
+
sleep @clock
|
128
|
+
GPIO.direction(@sda, :in)
|
129
|
+
GPIO.direction(@scl, :in)
|
130
|
+
if GPIO.read(@scl) == 0
|
131
|
+
raise I2CDevice::I2CBUSBusy, "BUS is busy"
|
132
|
+
end
|
133
|
+
|
134
|
+
sleep @clock / 2
|
135
|
+
GPIO.direction(@scl, :high)
|
136
|
+
sleep @clock / 2
|
137
|
+
GPIO.direction(@sda, :low)
|
138
|
+
sleep @clock
|
139
|
+
end
|
140
|
+
|
141
|
+
# Send stop condition.
|
142
|
+
def stop_condition
|
143
|
+
p :stop_condition if @@DEBUG
|
144
|
+
GPIO.direction(@scl, :low)
|
145
|
+
sleep @clock / 2
|
146
|
+
GPIO.direction(@sda, :low)
|
147
|
+
sleep @clock / 2
|
148
|
+
GPIO.direction(@scl, :in)
|
149
|
+
sleep @clock / 2
|
150
|
+
GPIO.direction(@sda, :in)
|
151
|
+
sleep @clock / 2
|
152
|
+
end
|
153
|
+
|
154
|
+
# Write one _byte_ to BUS.
|
155
|
+
def write(byte)
|
156
|
+
p [:write, byte] if @@DEBUG
|
157
|
+
GPIO.direction(@scl, :low)
|
158
|
+
sleep @clock
|
159
|
+
|
160
|
+
7.downto(0) do |n|
|
161
|
+
GPIO.direction(@sda, byte[n] == 1 ? :high : :low)
|
162
|
+
GPIO.direction(@scl, :in)
|
163
|
+
until GPIO.read(@scl) == 1
|
164
|
+
# clock streching
|
165
|
+
sleep @clock
|
166
|
+
end
|
167
|
+
sleep @clock
|
168
|
+
GPIO.direction(@scl, :low)
|
169
|
+
GPIO.write(@sda, false)
|
170
|
+
sleep @clock
|
171
|
+
end
|
172
|
+
|
173
|
+
GPIO.direction(@sda, :in)
|
174
|
+
GPIO.direction(@scl, :in)
|
175
|
+
sleep @clock / 2
|
176
|
+
ack = GPIO.read(@sda) == 0
|
177
|
+
sleep @clock / 2
|
178
|
+
while GPIO.read(@scl) == 0
|
179
|
+
sleep @clock
|
180
|
+
end
|
181
|
+
GPIO.direction(@scl, :low)
|
182
|
+
ack
|
183
|
+
end
|
184
|
+
|
185
|
+
# Read one byte from BUS.
|
186
|
+
# <tt>ack</tt> :: [true|flase] Send ack for this read.
|
187
|
+
# Returns :: [Integer] Byte
|
188
|
+
def read(ack=true)
|
189
|
+
p [:read, ack] if @@DEBUG
|
190
|
+
ret = 0
|
191
|
+
|
192
|
+
GPIO.direction(@scl, :low)
|
193
|
+
sleep @clock
|
194
|
+
GPIO.direction(@sda, :in)
|
195
|
+
|
196
|
+
8.times do
|
197
|
+
GPIO.direction(@scl, :in)
|
198
|
+
sleep @clock / 2
|
199
|
+
ret = (ret << 1) | GPIO.read(@sda)
|
200
|
+
sleep @clock / 2
|
201
|
+
GPIO.direction(@scl, :low)
|
202
|
+
sleep @clock
|
203
|
+
end
|
204
|
+
|
205
|
+
GPIO.direction(@sda, ack ? :low : :high)
|
206
|
+
|
207
|
+
GPIO.write(@scl, true)
|
208
|
+
sleep @clock
|
209
|
+
GPIO.write(@scl, false)
|
210
|
+
sleep @clock
|
211
|
+
ret
|
212
|
+
end
|
213
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require_relative "../../i2c"
|
2
|
+
require_relative "../../i2c/driver"
|
3
|
+
|
4
|
+
class I2CDevice::Driver::I2CDev < I2CDevice::Driver::Base
|
5
|
+
# ioctl command
|
6
|
+
# Ref. https://www.kernel.org/pub/linux/kernel/people/marcelo/linux-2.4/include/linux/i2c.h
|
7
|
+
I2C_RETRIES = 0x0701
|
8
|
+
I2C_TIMEOUT = 0x0702
|
9
|
+
I2C_SLAVE = 0x0703
|
10
|
+
I2C_SLAVE_FORCE = 0x0706
|
11
|
+
I2C_TENBIT = 0x0704
|
12
|
+
I2C_FUNCS = 0x0705
|
13
|
+
I2C_RDWR = 0x0707
|
14
|
+
I2C_SMBUS = 0x0720
|
15
|
+
I2C_UDELAY = 0x0705
|
16
|
+
I2C_MDELAY = 0x0706
|
17
|
+
|
18
|
+
# This depends on /dev/i2c-* (i2c-dev) feature on Linux. You may load i2c-dev kernel module.
|
19
|
+
# <tt>path</tt> :: [String] Path to /dev/i2c-* file.
|
20
|
+
# <tt>force</tt> :: [Boolean] Force the driver to read or set values even if the device is in use.
|
21
|
+
# This is dangerous, as it can seriously confuse the kernel driver in question.
|
22
|
+
# It can also cause i2cget and i2cset to writ to the wrong register.
|
23
|
+
# Use at your own risk and only if you know what you're doing.
|
24
|
+
#
|
25
|
+
# If _path_ is not specified, this method use <tt>Dir.glob("/dev/i2c-*").last</tt> for _path_
|
26
|
+
def initialize(path=nil, force=false)
|
27
|
+
if path.nil?
|
28
|
+
path = Dir.glob("/dev/i2c-*").sort.last
|
29
|
+
end
|
30
|
+
|
31
|
+
unless File.exist?(path)
|
32
|
+
raise I2CDevice::I2CIOError, "/dev/i2c-0 is required"
|
33
|
+
end
|
34
|
+
|
35
|
+
@path = path
|
36
|
+
@slave_command = force ? I2C_SLAVE_FORCE : I2C_SLAVE
|
37
|
+
end
|
38
|
+
|
39
|
+
# Interface of I2CDevice::Driver
|
40
|
+
def i2cget(address, param, length)
|
41
|
+
i2c = File.open(@path, "r+")
|
42
|
+
i2c.ioctl(@slave_command, address)
|
43
|
+
i2c.syswrite(param.chr) unless param.nil?
|
44
|
+
ret = i2c.sysread(length)
|
45
|
+
i2c.close
|
46
|
+
ret
|
47
|
+
rescue Errno::EIO => e
|
48
|
+
raise I2CDevice::I2CIOError, e.message
|
49
|
+
end
|
50
|
+
|
51
|
+
# Interface of I2CDevice::Driver
|
52
|
+
def i2cset(address, *data)
|
53
|
+
i2c = File.open(@path, "r+")
|
54
|
+
i2c.ioctl(@slave_command, address)
|
55
|
+
i2c.syswrite(data.pack("C*"))
|
56
|
+
i2c.close
|
57
|
+
rescue Errno::EIO => e
|
58
|
+
raise I2CDevice::I2CIOError, e.message
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative "../i2c"
|
4
|
+
|
5
|
+
module I2CDevice::Driver
|
6
|
+
# Abstract class for I2CDevice::Driver
|
7
|
+
class Base
|
8
|
+
include I2CDevice::Driver
|
9
|
+
end
|
10
|
+
|
11
|
+
# Low-level method for i2cget
|
12
|
+
# Driver must implement this.
|
13
|
+
# <tt>address</tt> :: [Integer] 7-bit slave address without r/w bit. MSB is always 0.
|
14
|
+
# <tt>data</tt> :: [Array[Integer]] Writing bytes array.
|
15
|
+
# Returns :: [String] Wrote bytes
|
16
|
+
def i2cget(address, param, length=1)
|
17
|
+
raise NotImplementedError
|
18
|
+
end
|
19
|
+
|
20
|
+
# Low-level method for i2cset
|
21
|
+
# Driver must implement this.
|
22
|
+
# <tt>address</tt> :: [Integer] 7-bit slave address without r/w bit. MSB is always 0.
|
23
|
+
# <tt>data</tt> :: [Array[Integer]] Writing bytes array.
|
24
|
+
# Returns :: [String] Wrote bytes
|
25
|
+
def i2cset(address, *data)
|
26
|
+
raise NotImplementedError
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# Generic abstract class for I2C manipulation.
|
2
|
+
class I2CDevice
|
3
|
+
VERSION = "0.0.6"
|
4
|
+
|
5
|
+
# Super class of all of this library.
|
6
|
+
class I2CException < Exception; end
|
7
|
+
class I2CIOError < I2CException; end
|
8
|
+
class I2CBUSBusy < I2CIOError; end
|
9
|
+
|
10
|
+
# Slave address
|
11
|
+
attr_accessor :address
|
12
|
+
|
13
|
+
# <tt>args[:address]</tt> :: [Integer] 7-bit slave address without r/w bit. MSB is always 0.
|
14
|
+
# <tt>args[:driver]</tt> :: [I2CDevice::Driver::I2CDev] Instance of driver class
|
15
|
+
def initialize(args={})
|
16
|
+
if args[:driver].nil?
|
17
|
+
require "i2c/driver/i2c-dev"
|
18
|
+
args[:driver] = I2CDevice::Driver::I2CDev.new
|
19
|
+
end
|
20
|
+
|
21
|
+
@driver = args[:driver]
|
22
|
+
@address = args[:address] or raise I2CException, "args[:address] required"
|
23
|
+
end
|
24
|
+
|
25
|
+
# This method read data from slave with following process:
|
26
|
+
#
|
27
|
+
# 1. Write `param` to slave
|
28
|
+
# 2. re-start
|
29
|
+
# 3. Read data until NACK or `length`
|
30
|
+
#
|
31
|
+
# <tt>param</tt> :: [Integer] First writing byte. Typically, this is slave memory address.
|
32
|
+
# <tt>length=1</tt> :: [Integer] Read bytes length
|
33
|
+
# Returns :: [String] Bytes
|
34
|
+
def i2cget(param, length=1)
|
35
|
+
@driver.i2cget(@address, param, length)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Write _data_ to slave.
|
39
|
+
# <tt>data</tt> :: [Array[Integer]] Writing bytes array.
|
40
|
+
# Returns :: [String] Wrote bytes
|
41
|
+
def i2cset(*data)
|
42
|
+
@driver.i2cset(@address, *data)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: apiotics_factory
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Apiotics
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-05-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: thor
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.20'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.20'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: httparty
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.14'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.14'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rest-client
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.0'
|
55
|
+
description: A gem to quickly create stub drivers for Apiotics devices.
|
56
|
+
email: info@apiotics.com
|
57
|
+
executables:
|
58
|
+
- apiotics_factory
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- License
|
63
|
+
- bin/apiotics_factory
|
64
|
+
- lib/apiotics_factory.rb
|
65
|
+
- lib/apiotics_factory/clear_credentials.rb
|
66
|
+
- lib/apiotics_factory/configuration.rb
|
67
|
+
- lib/apiotics_factory/generator.rb
|
68
|
+
- lib/apiotics_factory/my_command.rb
|
69
|
+
- lib/apiotics_factory/portal.rb
|
70
|
+
- lib/apiotics_factory/publish.rb
|
71
|
+
- lib/apiotics_factory/underscore.rb
|
72
|
+
- lib/apiotics_factory/version.rb
|
73
|
+
- lib/templates/apiotics_driver.rb.erb
|
74
|
+
- lib/templates/apiotics_interfaces.rb.erb
|
75
|
+
- lib/templates/config.json.erb
|
76
|
+
- lib/templates/exec.rb.erb
|
77
|
+
- lib/templates/grove_pi/grove_pi.rb
|
78
|
+
- lib/templates/grove_pi/i2c/device/acm1602ni.rb
|
79
|
+
- lib/templates/grove_pi/i2c/device/adt7410.rb
|
80
|
+
- lib/templates/grove_pi/i2c/device/aqm0802.rb
|
81
|
+
- lib/templates/grove_pi/i2c/device/bmp180.rb
|
82
|
+
- lib/templates/grove_pi/i2c/device/d6t-44l.rb
|
83
|
+
- lib/templates/grove_pi/i2c/device/hd44780.rb
|
84
|
+
- lib/templates/grove_pi/i2c/device/hdc1000.rb
|
85
|
+
- lib/templates/grove_pi/i2c/device/mpl115a2.rb
|
86
|
+
- lib/templates/grove_pi/i2c/driver.rb
|
87
|
+
- lib/templates/grove_pi/i2c/driver/gpio.rb
|
88
|
+
- lib/templates/grove_pi/i2c/driver/i2c-dev.rb
|
89
|
+
- lib/templates/grove_pi/i2c/i2c.rb
|
90
|
+
homepage: https://www.apiotics.com
|
91
|
+
licenses:
|
92
|
+
- Apiotics Factory License
|
93
|
+
metadata: {}
|
94
|
+
post_install_message:
|
95
|
+
rdoc_options: []
|
96
|
+
require_paths:
|
97
|
+
- lib
|
98
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
requirements: []
|
109
|
+
rubyforge_project:
|
110
|
+
rubygems_version: 2.2.2
|
111
|
+
signing_key:
|
112
|
+
specification_version: 4
|
113
|
+
summary: A Gem To Generate Apiotics Drivers
|
114
|
+
test_files: []
|