phaserunner 0.1.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 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: []