phaserunner 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 87c1d0249d18a43fb7e048a536af0bc908ab5dbe
4
+ data.tar.gz: 2bb48bc573a75916c5e2b2429474c5168f44b092
5
+ SHA512:
6
+ metadata.gz: 708604d673edf3de8125d7fc87ee1bf546b2827c911a7deecee69948ac741ec917ca73270d578e0c5b5571c6519387fe9445091f40d4fc75fffa56ddaadce8ae
7
+ data.tar.gz: 077551a923681d39bf69c82440ba29f21f105ba8426b611546e07aa4ecd226721164b6e8d0903ef4f2b4e37ed311afed2e879353ab9368af6d0f05cf77a79a3e
data/.gitignore ADDED
@@ -0,0 +1,39 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+ /html/
13
+
14
+ # Used by dotenv library to load environment variables.
15
+ # .env
16
+
17
+
18
+ ## Documentation cache and generated files:
19
+ /.yardoc/
20
+ /_yardoc/
21
+ /doc/
22
+ /rdoc/
23
+
24
+ ## Environment normalization:
25
+ /.bundle/
26
+ /vendor/bundle
27
+ /lib/bundler/man/
28
+
29
+ # for a library or gem, you might want to ignore these files since the code is
30
+ # intended to run in multiple environments; otherwise, check them in:
31
+ Gemfile.lock
32
+ .ruby-version
33
+ .ruby-gemset
34
+
35
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
36
+ .rvmrc
37
+
38
+ *.csv
39
+ *.log
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/README.rdoc ADDED
@@ -0,0 +1,36 @@
1
+ == NAME
2
+ phaserunner - Read values from the Grin PhaseRunner Controller for logging
3
+
4
+ == SYNOPSIS
5
+ phaserunner [global options] command [command options] [arguments...]
6
+
7
+ == VERSION
8
+ 0.1.0
9
+
10
+ == GLOBAL OPTIONS
11
+ -t, --tty=arg - Serial (USB) device (default: /dev/ttyUSB0)
12
+ -b, --baudrate=arg - Serial port baudrate (default: 115200)
13
+ -s, --slave_id=arg - Modbus slave ID (default: 1)
14
+ -d, --dictionary_file=arg - Path to json file that contains Grin Modbus Dictionary (default: /Users/rberger/.rvm/gems/ruby-2.4.1/gems/asi_bod-0.1.4/BODm.json)
15
+ -l, --loop=arg - Loop the command n times (default: 10)
16
+ --version - Display the program version
17
+ --help - Show this message
18
+
19
+ == COMMANDS
20
+ help - Shows a list of commands or help for one command
21
+ read_register - Read a single or multiple adjacent registers from and address
22
+ log - Logs a range plus bulk sparse set of registers with multiple addresses to stdout and file
23
+
24
+ === NAME
25
+ log - Logs a range plus bulk sparse set of registers with multiple addresses to stdout and file
26
+
27
+ === SYNOPSIS
28
+ phaserunner [global options] log [command options]
29
+
30
+ === DESCRIPTION
31
+ Logs interesting Phaserunner registers to stdout and a CSV file. File name in the form: phaserunner.#{Time.now.strftime('%Y-%m-%d_%H-%M-%S')}.csv
32
+
33
+ === COMMAND OPTIONS
34
+ -q, --[no-]quiet - Do not output to stdout
35
+
36
+ :include:phaserunner.rdoc
data/Rakefile ADDED
@@ -0,0 +1,44 @@
1
+ require 'rake/clean'
2
+ require 'rubygems'
3
+ require 'rubygems/package_task'
4
+ require 'rdoc/task'
5
+ require 'cucumber'
6
+ require 'cucumber/rake/task'
7
+ Rake::RDocTask.new do |rd|
8
+ rd.main = "README.rdoc"
9
+ rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
10
+ rd.title = 'Your application title'
11
+ end
12
+
13
+ spec = eval(File.read('phaserunner.gemspec'))
14
+
15
+ Gem::PackageTask.new(spec) do |pkg|
16
+ end
17
+ CUKE_RESULTS = 'results.html'
18
+ CLEAN << CUKE_RESULTS
19
+ desc 'Run features'
20
+ Cucumber::Rake::Task.new(:features) do |t|
21
+ opts = "features --format html -o #{CUKE_RESULTS} --format progress -x"
22
+ opts += " --tags #{ENV['TAGS']}" if ENV['TAGS']
23
+ t.cucumber_opts = opts
24
+ t.fork = false
25
+ end
26
+
27
+ desc 'Run features tagged as work-in-progress (@wip)'
28
+ Cucumber::Rake::Task.new('features:wip') do |t|
29
+ tag_opts = ' --tags ~@pending'
30
+ tag_opts = ' --tags @wip'
31
+ t.cucumber_opts = "features --format html -o #{CUKE_RESULTS} --format pretty -x -s#{tag_opts}"
32
+ t.fork = false
33
+ end
34
+
35
+ task :cucumber => :features
36
+ task 'cucumber:wip' => 'features:wip'
37
+ task :wip => 'features:wip'
38
+ require 'rake/testtask'
39
+ Rake::TestTask.new do |t|
40
+ t.libs << "test"
41
+ t.test_files = FileList['test/*_test.rb']
42
+ end
43
+
44
+ task :default => [:test,:features]
data/exe/phaserunner ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require 'phaserunner'
3
+
4
+ cli = Phaserunner::Cli.new
5
+ cli.main
@@ -0,0 +1,7 @@
1
+ require 'phaserunner/gli_patch.rb'
2
+ require 'phaserunner/version.rb'
3
+ require 'phaserunner/main.rb'
4
+ require 'phaserunner/modbus.rb'
5
+
6
+ # Add requires for other files you add to your project here, so
7
+ # you just need to require this one file in your bin file
@@ -0,0 +1,13 @@
1
+ # Work around a bug with the RdocDocumentListener
2
+ # Fix rdoc formatter #201
3
+ # https://github.com/davetron5000/gli/pull/201#issuecomment-195385509
4
+ require 'gli'
5
+ module RdocDocumentListenerAppFix
6
+ def initialize(_global_options,_options,_arguments,app)
7
+ super
8
+ @app = app
9
+ end
10
+ end
11
+ class GLI::Commands::RdocDocumentListener
12
+ prepend RdocDocumentListenerAppFix
13
+ end
@@ -0,0 +1,122 @@
1
+ require 'gli'
2
+ require 'json'
3
+ require 'pp'
4
+
5
+ module Phaserunner
6
+
7
+ class Cli
8
+ attr_reader :modbus
9
+ attr_reader :dict
10
+ attr_reader :loop
11
+ attr_reader :phaserunnerOutFd
12
+
13
+ include GLI::App
14
+
15
+ def main
16
+ program_desc 'Read values from the Grin PhaseRunner Controller for logging'
17
+
18
+ version Phaserunner::VERSION
19
+
20
+ subcommand_option_handling :normal
21
+ arguments :strict
22
+ sort_help :manually
23
+
24
+ desc 'Serial (USB) device'
25
+ default_value '/dev/ttyUSB0'
26
+ arg 'tty'
27
+ flag [:t, :tty]
28
+
29
+ desc 'Serial port baudrate'
30
+ default_value 115200
31
+ arg 'baudrate'
32
+ flag [:b, :baudrate]
33
+
34
+ desc 'Modbus slave ID'
35
+ default_value 1
36
+ arg 'slave_id'
37
+ flag [:s, :slave_id]
38
+
39
+ desc 'Path to json file that contains Grin Modbus Dictionary'
40
+ default_value Modbus.default_file_path
41
+ arg 'dictionary_file'
42
+ flag [:d, :dictionary_file]
43
+
44
+ desc 'Loop the command n times'
45
+ default_value 10
46
+ arg 'loop', :optional
47
+ flag [:l, :loop], type: Integer
48
+ # flag [:l, :loop], :desc => 'Loop the command n times', :type => Integer
49
+
50
+ desc 'Read a single or multiple adjacent registers from and address'
51
+ arg_name 'register_address'
52
+ command :read_register do |read_register|
53
+ read_register.desc 'Number of registers to read starting at the Arg Address'
54
+ read_register.default_value 1
55
+ read_register.flag [:c, :count]
56
+
57
+ read_register.arg 'address'
58
+ read_register.action do |global_options, options, args|
59
+ address = args[0].to_i
60
+ count = args[1].to_i
61
+ node = dict[address]
62
+ puts modbus.range_address_header(address, count).join(",")
63
+ (0..loop).each do |i|
64
+ puts modbus.read_raw_range(address, count).join(",")
65
+ end
66
+ end
67
+ end
68
+
69
+ desc 'Logs a range plus bulk sparse set of registers with multiple addresses to stdout and file'
70
+ long_desc %q(Logs interesting Phaserunner registers to stdout and a CSV file. File name in the form: phaserunner.#{Time.now.strftime('%Y-%m-%d_%H-%M-%S')}.csv)
71
+ command :log do |log|
72
+ log.desc 'Do not output to stdout'
73
+ log.switch [:q, :quiet]
74
+ log.action do |global_options, options, args|
75
+ quiet = options[:quiet]
76
+ start_address = 258
77
+ count = 12
78
+ misc_addresses =[277,334]
79
+ header = modbus.bulk_log_header(start_address, count, misc_addresses)
80
+ data = modbus.bulk_log_data(start_address, count, misc_addresses)
81
+
82
+ hdr = %Q(Timestamp,#{header.join(",")})
83
+ puts hdr if not quiet
84
+ phaserunnerOutFd.puts hdr
85
+
86
+ (0..loop).each do |i|
87
+ str = %Q(#{Time.now.utc.round(10).iso8601(6)},#{data.join(",")})
88
+ puts str if not quiet
89
+ phaserunnerOutFd.puts str
90
+ sleep 0.2
91
+ end
92
+ end
93
+ end
94
+
95
+ pre do |global, command, options, args|
96
+ # Pre logic here
97
+ # Return true to proceed; false to abort and not call the
98
+ # chosen command
99
+ # Use skips_pre before a command to skip this block
100
+ # on that command only
101
+ @modbus = Modbus.new(global)
102
+ @dict = @modbus.dict
103
+ @loop = global[:loop]
104
+ @phaserunnerOutFd = File.open("phaserunner.#{Time.now.strftime('%Y-%m-%d_%H-%M-%S')}.csv", 'w')
105
+ end
106
+
107
+ post do |global,command,options,args|
108
+ # Post logic here
109
+ # Use skips_post before a command to skip this
110
+ # block on that command only
111
+ end
112
+
113
+ on_error do |exception|
114
+ # Error logic here
115
+ # return false to skip default error handling
116
+ true
117
+ end
118
+
119
+ exit run(ARGV)
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,92 @@
1
+ require 'rmodbus'
2
+ require 'json'
3
+ require 'asi_bod'
4
+
5
+ module Phaserunner
6
+ # Methods for communicating with the Modbus interface to the Phaserunner
7
+ class Modbus
8
+ # Contains the Grin Phaesrunner Modbus Dictionary
9
+ # @params [Hash<Integer, Hash>] dict The Dictionary with a key for each register address
10
+ # @option dict [String] :name Name of the register
11
+ # @option dict [Integer] :address Address of register
12
+ # @option dict [Integer] :accessLevel Access Level of register
13
+ # @option dict [Boolean] :read If the register can be read
14
+ # @option dict [Boolean] :write If the register can be written
15
+ # @option dict [Boolean] :saved If the register has been saved
16
+ # @option dict [Integer,Float,String] :scale How to scale the raw value
17
+ # @option dict [String] :units The units for the value
18
+ # @option dict [Stirng] :type Further info on how to interpret the value
19
+ attr_reader :dict
20
+
21
+ # Returns the path to the default BODm.json file
22
+ def self.default_file_path
23
+ AsiBod::Bod.default_file_path
24
+ end
25
+
26
+ # New Modbus
27
+ # Converts the opts hash into Class Instance Variables (attr_readers)
28
+ # Reads the JSON Grin Phaserunner Modbus Dictionary into a Hash
29
+ # @params opts [Hash] comes from the CLI
30
+ def initialize(opts)
31
+ # Converts each key of the opts hash from the CLI into individual class attr_readers.
32
+ # So they are now available to the rest of this Class as instance variables.
33
+ # The key of the hash becomes the name of the instance variable.
34
+ # They are available to all the methods of this class
35
+ # See https://stackoverflow.com/a/7527916/38841
36
+ opts.each_pair do |name, value|
37
+ self.class.send(:attr_accessor, name)
38
+ instance_variable_set("@#{name}", value)
39
+ end
40
+
41
+ @bod = AsiBod::Bod.new(bod_file: dictionary_file)
42
+ @dict = @bod.hash_data
43
+ end
44
+
45
+ def read_raw_range(start_address, count)
46
+ #puts("Reading from #{dict[start_address][:name]} scale: #{dict[start_address][:scale]} units: #{dict[start_address][:units]}")
47
+ cl = ::ModBus::RTUClient.new(tty, baudrate)
48
+ cl.with_slave(slave_id) do |slave|
49
+ slave.read_holding_registers(start_address, count)
50
+ end
51
+ end
52
+
53
+ def range_address_header(start_address, count)
54
+ end_address = start_address + count
55
+ (start_address...end_address).map do |address|
56
+ "#{dict[address][:name]} (#{dict[address][:units]})"
57
+ end
58
+ end
59
+
60
+ def read_addresses(addresses)
61
+ addresses.map do |address|
62
+ read_raw_range(address, 1)
63
+ end
64
+ end
65
+
66
+ def bulk_addresses_header(addresses)
67
+ addresses.map do |address|
68
+ "#{dict[address][:name]} (#{dict[address][:units]})"
69
+ end
70
+ end
71
+
72
+ # More optimized data fetch. Gets an address range + misc individual addresses
73
+ # @param start_address [Integer] Initial address of the range
74
+ # @param count [Integer] Count of addresses in range
75
+ # @param misc_addresses [Array<Integer>] List of misc individual addresses
76
+ # @return [Array<Integer>] List of the register values in the order requested
77
+ def bulk_log_data(start_address, count, misc_addresses)
78
+ read_raw_range(start_address, count) + read_addresses(misc_addresses)
79
+ end
80
+
81
+ # Get the headers for the bulk_log data
82
+ # @param start_address [Integer] Initial address of the range
83
+ # @param count [Integer] Count of addresses in range
84
+ # @param misc_addresses [Array<Integer>] List of misc individual addresses
85
+ # @return [Array<String>] Array of the headers
86
+ def bulk_log_header(start_address, count, misc_addresses)
87
+ range_address_header(start_address, count) +
88
+ bulk_addresses_header(misc_addresses)
89
+ end
90
+ end
91
+ end
92
+
@@ -0,0 +1,3 @@
1
+ module Phaserunner
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,39 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "phaserunner/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "phaserunner"
8
+ spec.version = Phaserunner::VERSION
9
+ spec.authors = ["Robert J. Berger"]
10
+ spec.email = ["rberger@ibd.com"]
11
+
12
+ spec.summary = %q{Read values from the Grin PhaseRunner Controller for logging}
13
+ spec.description = %q{Read values from the Grin PhaseRunner Controller via Modbus RTU suitable for logging}
14
+ spec.homepage = "https://github.com/rberger/phaserunner"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = 'exe'
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ['lib']
23
+
24
+ spec.has_rdoc = true
25
+ spec.extra_rdoc_files = ['README.rdoc', 'phaserunner.rdoc']
26
+ spec.rdoc_options << '--title' << 'phaserunner' << '--main' << 'README.rdoc' << '-ri'
27
+
28
+ spec.add_runtime_dependency 'gli', '~> 2.17'
29
+ spec.add_runtime_dependency 'rmodbus', '~> 1.3'
30
+ spec.add_runtime_dependency 'serialport', '~> 1.3'
31
+ spec.add_runtime_dependency 'asi_bod', '~> 0.1.3'
32
+
33
+ spec.add_development_dependency 'bundler', '~> 1.16'
34
+ spec.add_development_dependency 'rake', '~> 10.0'
35
+ spec.add_development_dependency 'rspec', '~> 3.0'
36
+ spec.add_development_dependency 'rdoc'
37
+ spec.add_development_dependency 'aruba', '~> 0.14'
38
+ spec.add_development_dependency 'yard', '~> 0.9'
39
+ end
data/phaserunner.rdoc ADDED
@@ -0,0 +1,83 @@
1
+ == phaserunner - Read values from the Grin PhaseRunner Controller for logging
2
+
3
+ v0.1.0
4
+
5
+ === Global Options
6
+ === -b|--baudrate arg
7
+
8
+ Serial port baudrate
9
+
10
+ [Default Value] 115200
11
+
12
+
13
+ === -d|--dictionary_file arg
14
+
15
+ Path to json file that contains Grin Modbus Dictionary
16
+
17
+ [Default Value] /Users/rberger/.rvm/gems/ruby-2.4.1/gems/asi_bod-0.1.4/BODm.json
18
+
19
+
20
+ === -l|--loop arg
21
+
22
+ Loop the command n times
23
+
24
+ [Default Value] 10
25
+
26
+
27
+ === -s|--slave_id arg
28
+
29
+ Modbus slave ID
30
+
31
+ [Default Value] 1
32
+
33
+
34
+ === -t|--tty arg
35
+
36
+ Serial (USB) device
37
+
38
+ [Default Value] /dev/ttyUSB0
39
+
40
+
41
+ === --help
42
+ Show this message
43
+
44
+
45
+
46
+ === --version
47
+ Display the program version
48
+
49
+
50
+
51
+ === Commands
52
+ ==== Command: <tt>help command</tt>
53
+ Shows a list of commands or help for one command
54
+
55
+ Gets help for the application or its commands. Can also list the commands in a way helpful to creating a bash-style completion function
56
+ ===== Options
57
+ ===== -c
58
+ List commands one per line, to assist with shell completion
59
+
60
+
61
+
62
+ ==== Command: <tt>log </tt>
63
+ Logs a range plus bulk sparse set of registers with multiple addresses to stdout and file
64
+
65
+ Logs interesting Phaserunner registers to stdout and a CSV file. File name in the form: phaserunner.#{Time.now.strftime('%Y-%m-%d_%H-%M-%S')}.csv
66
+ ===== Options
67
+ ===== -q|--[no-]quiet
68
+ Do not output to stdout
69
+
70
+
71
+
72
+ ==== Command: <tt>read_register register_address</tt>
73
+ Read a single or multiple adjacent registers from and address
74
+
75
+
76
+ ===== Options
77
+ ===== -c|--count arg
78
+
79
+ Number of registers to read starting at the Arg Address
80
+
81
+ [Default Value] 1
82
+
83
+
data/todo.md ADDED
@@ -0,0 +1,40 @@
1
+ ## Things to measure
2
+ * 258 Reading from Faults
3
+ * 262, Motor Current, Motor peak current
4
+ * 265, battery voltage, 32, Volts
5
+ * 266, Battery Current, Measured battery amperage
6
+ * 270, Throttle Voltage, Filtered throttle voltage, 4096
7
+ * 277, warnings, bit vector,
8
+ * 281 DSP Core Temperature
9
+
10
+ ## Maybe:
11
+ * 260, vehicle speed, 256, km/hr
12
+ * 268, battery power, 1, Watts
13
+ * 269, last fault, bit vector,
14
+ * 273, raw controller temperature sensor voltage, 4096, Volts
15
+ * 277, warnings, bit vector,
16
+ * 328, instantaneous pedal speed, 64, RPM
17
+ * 334, motor input power, 1, W
18
+
19
+ ## One of:
20
+ * 263, Motor RPM, Motor speed , 1
21
+ * 311, Wheel RPM (Speed Sensor Based), Calculated wheel speed based on wheel speed sensor, 16
22
+ * 312, Wheel RPM (Motor Based), Calculated wheel speed based on motor pole pairs, 16
23
+ * 313, Measured Wheel RPM, Measured wheel speed, 16
24
+
25
+
26
+ ## DO
27
+ * 258 Reading from Faults
28
+ * 259, Controller Temperature, Base plate temperature, 1, deg Celsius
29
+ * 260, vehicle speed, 256, km/hr, 256, Km/hour
30
+ * 262, Motor Current, Motor peak current, 32, Amps
31
+ * 263, Motor RPM, Motor speed , 1, RPM
32
+ * 264, Motor Speed, Motor speed, 40.96, % of rated rpm
33
+ * 265, battery voltage, 32, Volts
34
+ * 266, Battery Current, Measured battery amperage, 32, Amps
35
+ * 267, Battery State of Charge, Remaining battery capacity, 32, %
36
+ * 268, Battery Power, Calculated battery output power, 1, Watts
37
+ * 269, Last Fault
38
+ * 270, Throttle Voltage, Filtered throttle voltage, 4096, Volts
39
+ * 277, warnings, bit vector,
40
+ * 334, motor input power, 1, W
metadata ADDED
@@ -0,0 +1,206 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: phaserunner
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Robert J. Berger
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-01-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: gli
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.17'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.17'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rmodbus
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: serialport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: asi_bod
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.1.3
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.1.3
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.16'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.16'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '10.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '10.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '3.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '3.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rdoc
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: aruba
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.14'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.14'
139
+ - !ruby/object:Gem::Dependency
140
+ name: yard
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '0.9'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '0.9'
153
+ description: Read values from the Grin PhaseRunner Controller via Modbus RTU suitable
154
+ for logging
155
+ email:
156
+ - rberger@ibd.com
157
+ executables:
158
+ - phaserunner
159
+ extensions: []
160
+ extra_rdoc_files:
161
+ - README.rdoc
162
+ - phaserunner.rdoc
163
+ files:
164
+ - ".gitignore"
165
+ - Gemfile
166
+ - README.rdoc
167
+ - Rakefile
168
+ - exe/phaserunner
169
+ - lib/phaserunner.rb
170
+ - lib/phaserunner/gli_patch.rb
171
+ - lib/phaserunner/main.rb
172
+ - lib/phaserunner/modbus.rb
173
+ - lib/phaserunner/version.rb
174
+ - phaserunner.gemspec
175
+ - phaserunner.rdoc
176
+ - todo.md
177
+ homepage: https://github.com/rberger/phaserunner
178
+ licenses:
179
+ - MIT
180
+ metadata: {}
181
+ post_install_message:
182
+ rdoc_options:
183
+ - "--title"
184
+ - phaserunner
185
+ - "--main"
186
+ - README.rdoc
187
+ - "-ri"
188
+ require_paths:
189
+ - lib
190
+ required_ruby_version: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ required_rubygems_version: !ruby/object:Gem::Requirement
196
+ requirements:
197
+ - - ">="
198
+ - !ruby/object:Gem::Version
199
+ version: '0'
200
+ requirements: []
201
+ rubyforge_project:
202
+ rubygems_version: 2.6.14
203
+ signing_key:
204
+ specification_version: 4
205
+ summary: Read values from the Grin PhaseRunner Controller for logging
206
+ test_files: []