asi_bod 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.rdoc +17 -2
- data/asi_bod.rdoc +1 -1
- data/lib/asi_bod/asi.rb +14 -4
- data/lib/asi_bod/bod.rb +9 -2
- data/lib/asi_bod/cli.rb +55 -43
- data/lib/asi_bod/dict.rb +20 -6
- data/lib/asi_bod/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0fffe6a70e746724e33292bea03778ae3c4ae4e7
|
4
|
+
data.tar.gz: 343e48434eb1a69e0e532891fc4fcc39649fd15a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed713a4e7cca0ceacd3cebb2eca07d40cc28347fc015b2bd7ff21f576a9bae87429e71862905f0d97285e94c458171ad582f2dcadc4518d017da2ee53f8eea5a
|
7
|
+
data.tar.gz: 29f643a1f59f09624aa728da6d8f8d38105c736913a13c750adf7bb9e9734484ff72cc7ae897b1809c9a0fbdf75414e8cc7fecbaf3c2adeccddb8c6cb7e9a56c
|
data/README.rdoc
CHANGED
@@ -5,6 +5,8 @@
|
|
5
5
|
== SYNOPSIS
|
6
6
|
asi_bod [global options] command [command options] [arguments...]
|
7
7
|
|
8
|
+
{<img src="https://badge.fury.io/rb/asi_bod.svg" alt="Gem Version" />}[https://badge.fury.io/rb/asi_bod]
|
9
|
+
|
8
10
|
== Overview
|
9
11
|
|
10
12
|
Tool to view, search and potentially merge the Grin Tech Phaserunner +BOD.json+
|
@@ -21,11 +23,24 @@ If you want to start with the original or another version of the +BOD.json+ or t
|
|
21
23
|
+ASIObjectDictionary.xml+ then you can override the defaults with the +-a,
|
22
24
|
--asi_file+ or +-b, --bod_file+ flags
|
23
25
|
|
26
|
+
== GLOBAL OPTIONS
|
27
|
+
-a, --asi_file=arg - Path to the ASIObjectDictionary XML file (default: /Users/rberger/odrive/IBD Google
|
28
|
+
Drive/Trike/bike-pi/asi_bod/ASIObjectDictionary.xml)
|
29
|
+
-b, --bod_file=arg - Path to the BOD JSON file (default: /Users/rberger/odrive/IBD Google
|
30
|
+
Drive/Trike/bike-pi/asi_bod/BODm.json)
|
31
|
+
--version - Display the program version
|
32
|
+
--[no-]address_view - View Address (default: enabled)
|
33
|
+
--[no-]name_view - View Name (default: enabled)
|
34
|
+
--[no-]description_view - View Description (default: enabled)
|
35
|
+
-s, --[no-]scale_view - View Scale
|
36
|
+
-u, --[no-]units_view - View Units
|
37
|
+
--help - Show this message
|
38
|
+
|
24
39
|
== COMMANDS
|
25
|
-
find - Find a node in one or both of the dictionaries
|
26
40
|
help - Shows a list of commands or help for one command
|
27
|
-
merge - Merge the Description from asi to bod
|
28
41
|
view - View the data
|
42
|
+
find - Find a node in one or both of the dictionaries
|
43
|
+
merge - Merge the Description from asi to bod
|
29
44
|
|
30
45
|
== Detailed Command Line Info
|
31
46
|
|
data/asi_bod.rdoc
CHANGED
data/lib/asi_bod/asi.rb
CHANGED
@@ -2,23 +2,33 @@
|
|
2
2
|
require 'nori'
|
3
3
|
|
4
4
|
module AsiBod
|
5
|
+
|
6
|
+
# Handle reading in ASI ObjectDictionary and doing operations on it
|
5
7
|
class Asi
|
6
8
|
attr_reader :nori
|
7
9
|
attr_reader :raw_data
|
8
10
|
attr_reader :array_data
|
9
11
|
attr_reader :hash_data
|
10
12
|
|
11
|
-
|
13
|
+
# Returns the path to the default ASIObjectDictionary.xml file
|
14
|
+
def self.default_file_path
|
15
|
+
File.expand_path('../../../ASIObjectDictionary.xml', __FILE__)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Asi.new reads in the source file for the ASIObjectDictionary and creates
|
19
|
+
# an internal Hash
|
20
|
+
# @param params [Hash]
|
21
|
+
def initialize(params = { asi_file: default_file_path })
|
12
22
|
@nori = Nori.new
|
13
|
-
@raw_data = @nori.parse(File.read(
|
14
|
-
@array_data = @raw_data[
|
23
|
+
@raw_data = @nori.parse(File.read(params[:asi_file]))
|
24
|
+
@array_data = @raw_data['InternalAppEntity']['Parameters'].first[1]
|
15
25
|
@hash_data = array_data_to_hash(@array_data)
|
16
26
|
end
|
17
27
|
|
18
28
|
# Convert the array of hashes to a hash with the address as primary key
|
19
29
|
def array_data_to_hash(array_data)
|
20
30
|
array_data.each_with_object({}) do |node, memo|
|
21
|
-
memo[node[
|
31
|
+
memo[node['Address'].to_i] = clean_node(node)
|
22
32
|
end
|
23
33
|
end
|
24
34
|
|
data/lib/asi_bod/bod.rb
CHANGED
@@ -1,11 +1,18 @@
|
|
1
1
|
require 'json'
|
2
2
|
|
3
3
|
module AsiBod
|
4
|
+
|
5
|
+
# Handle reading in Grin Tech BOD Json file and doing operations on it
|
4
6
|
class Bod
|
5
7
|
attr_reader :hash_data
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
+
# Returns the path to the default BODm.json file
|
10
|
+
def self.default_file_path
|
11
|
+
File.expand_path('../../../BODm.json', __FILE__)
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(params = { bod_file: default_file_path })
|
15
|
+
@json_data = JSON.parse(File.read(params[:bod_file]))
|
9
16
|
@hash_data = json_data_to_hash(@json_data)
|
10
17
|
end
|
11
18
|
|
data/lib/asi_bod/cli.rb
CHANGED
@@ -12,27 +12,28 @@ module AsiBod
|
|
12
12
|
|
13
13
|
GPARENT = GLI::Command::PARENT
|
14
14
|
|
15
|
-
KEY_ORDER = {address: 0,
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
15
|
+
KEY_ORDER = { address: 0,
|
16
|
+
name: 1,
|
17
|
+
description: 2,
|
18
|
+
scale: 3,
|
19
|
+
units: 4,
|
20
|
+
read: 5,
|
21
|
+
write: 6 }
|
22
22
|
|
23
23
|
def which_keys(options)
|
24
24
|
options.each_with_object([]) do |(k,v), memo|
|
25
|
-
if k.is_a?(String) && k.include?(
|
25
|
+
if k.is_a?(String) && k.include?('_view')
|
26
26
|
# Its a view key
|
27
27
|
next unless options[k]
|
28
28
|
# Strip off the '_view' and convert to a symbol
|
29
|
-
key = k[0..(k.index(
|
29
|
+
key = k[0..(k.index('_view') - 1)].to_sym
|
30
30
|
# Store them in KEY_ORDER
|
31
31
|
memo[KEY_ORDER[key]] = key
|
32
32
|
end
|
33
33
|
end.compact
|
34
34
|
end
|
35
35
|
|
36
|
+
# Main body. Does all the CLI processing and dispatching
|
36
37
|
def main
|
37
38
|
program_desc 'Manipulate and view the ASIObjectDictionary.xml and BOD.json files'
|
38
39
|
|
@@ -40,14 +41,15 @@ module AsiBod
|
|
40
41
|
|
41
42
|
subcommand_option_handling :normal
|
42
43
|
arguments :strict
|
44
|
+
sort_help :manually
|
43
45
|
|
44
46
|
desc 'Path to the ASIObjectDictionary XML file'
|
45
|
-
default_value
|
46
|
-
flag [:a
|
47
|
+
default_value Asi.default_file_path
|
48
|
+
flag [:a, :asi_file]
|
47
49
|
|
48
50
|
desc 'Path to the BOD JSON file'
|
49
|
-
default_value
|
50
|
-
flag [:b
|
51
|
+
default_value Bod.default_file_path
|
52
|
+
flag [:b, :bod_file]
|
51
53
|
|
52
54
|
desc 'View Address'
|
53
55
|
switch :address_view, default_value: true
|
@@ -66,27 +68,35 @@ module AsiBod
|
|
66
68
|
|
67
69
|
desc 'View the data'
|
68
70
|
command :view do |view|
|
69
|
-
view.desc
|
71
|
+
view.desc 'Pretty Print output of the simplified ASI ObjectDictionary as a hash'
|
70
72
|
view.command :asi do |view_asi|
|
71
|
-
view.desc
|
73
|
+
view.desc 'Output as Json instead of CSV'
|
72
74
|
view.switch [:j, :json]
|
73
75
|
|
74
|
-
view_asi.action do |global_options,options,args|
|
76
|
+
view_asi.action do |global_options, options, args|
|
75
77
|
if options[GPARENT][:json]
|
76
78
|
puts JSON.pretty_generate asi.hash_data
|
77
79
|
else
|
78
|
-
Dict.
|
80
|
+
Dict.specific_keys_per_node(
|
81
|
+
asi.hash_data,
|
82
|
+
which_keys(global_options)) do |address, node|
|
83
|
+
puts node
|
84
|
+
end
|
79
85
|
end
|
80
86
|
end
|
81
87
|
end
|
82
88
|
|
83
|
-
view.desc
|
89
|
+
view.desc 'Pretty Print output of the simplified BOD as a hash'
|
84
90
|
view.command :bod do |view_bod|
|
85
91
|
view_bod.action do |global_options,options,args|
|
86
92
|
if options[GPARENT][:json]
|
87
93
|
puts JSON.pretty_generate bod.hash_data
|
88
94
|
else
|
89
|
-
Dict.
|
95
|
+
Dict.specific_keys_per_node(
|
96
|
+
bod.hash_data,
|
97
|
+
which_keys(global_options)).each_pair do |address, node|
|
98
|
+
puts node
|
99
|
+
end
|
90
100
|
end
|
91
101
|
end
|
92
102
|
end
|
@@ -95,19 +105,19 @@ module AsiBod
|
|
95
105
|
|
96
106
|
desc 'Find a node in one or both of the dictionaries'
|
97
107
|
command :find do |find|
|
98
|
-
find.desc
|
99
|
-
find.switch [:a, :asi]
|
108
|
+
find.desc 'Search the asi dictionary'
|
109
|
+
find.switch [:a, :asi]
|
100
110
|
|
101
|
-
find.desc
|
111
|
+
find.desc 'Search the bod dictionary'
|
102
112
|
find.switch [:b, :bod]
|
103
113
|
|
104
|
-
find.desc
|
105
|
-
find.long_desc
|
106
|
-
|
107
|
-
|
114
|
+
find.desc 'Find by register address'
|
115
|
+
find.long_desc 'Find by register address. ' +
|
116
|
+
'Must select at least one of ' +
|
117
|
+
'asi or bod and specify search_term'
|
108
118
|
find.arg 'address'
|
109
119
|
find.command :by_address do |find_by_address|
|
110
|
-
find_by_address.action do |global_options,options,args|
|
120
|
+
find_by_address.action do |global_options, options, args|
|
111
121
|
address = args.first
|
112
122
|
# puts "find_by_address global_options #{global_options.inspect} options: #{options.inspect} args: #{args.inspect}"
|
113
123
|
puts "asi: => " +
|
@@ -119,27 +129,29 @@ module AsiBod
|
|
119
129
|
end
|
120
130
|
end
|
121
131
|
|
122
|
-
find.desc
|
123
|
-
find.long_desc
|
124
|
-
|
125
|
-
|
132
|
+
find.desc 'Find by the substring of a key'
|
133
|
+
find.long_desc 'Find by the substring of ' +
|
134
|
+
'a Must select at least one of ' +
|
135
|
+
'asi or bod and specify search_term'
|
126
136
|
find.arg 'node_key'
|
127
137
|
find.arg 'substring'
|
128
138
|
find.command :by_key_substring do |find_by_key_substring|
|
129
|
-
find_by_key_substring.action do |global_options,options,args|
|
139
|
+
find_by_key_substring.action do |global_options, options, args|
|
130
140
|
key = args[0].to_sym
|
131
141
|
substring = args[1]
|
132
142
|
if options[GPARENT][:asi]
|
133
143
|
puts "asi: key: #{key} substring: #{substring} => "
|
134
144
|
Dict.put_results(
|
135
145
|
Dict.find_by_key_substring(asi.hash_data, key, substring),
|
136
|
-
which_keys(global_options)
|
146
|
+
which_keys(global_options)
|
147
|
+
)
|
137
148
|
end
|
138
149
|
if options[GPARENT][:bod]
|
139
150
|
puts "bod: key: #{key} substring: #{substring} => "
|
140
151
|
Dict.put_results(
|
141
152
|
Dict.find_by_key_substring(bod.hash_data, key, substring),
|
142
|
-
which_keys(global_options)
|
153
|
+
which_keys(global_options)
|
154
|
+
)
|
143
155
|
end
|
144
156
|
end
|
145
157
|
end
|
@@ -154,26 +166,26 @@ module AsiBod
|
|
154
166
|
merge.switch [:j, :json]
|
155
167
|
merge.action do |global_options,options,args|
|
156
168
|
raw_result = Dict.merge(asi.hash_data, bod.hash_data)
|
157
|
-
if options[:json]
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
169
|
+
result = if options[:json]
|
170
|
+
JSON.pretty_generate raw_result
|
171
|
+
else
|
172
|
+
raw_result.pretty_inspect
|
173
|
+
end
|
162
174
|
puts result
|
163
175
|
end
|
164
176
|
end
|
165
177
|
|
166
|
-
pre do |global_options,command,options,args|
|
178
|
+
pre do |global_options, command, options, args|
|
167
179
|
# Pre logic here
|
168
180
|
# Return true to proceed; false to abort and not call the
|
169
181
|
# chosen command
|
170
182
|
# Use skips_pre before a command to skip this block
|
171
183
|
# on that command only
|
172
|
-
@asi = AsiBod::Asi.new(global_options
|
173
|
-
@bod = AsiBod::Bod.new(global_options
|
184
|
+
@asi = AsiBod::Asi.new(global_options)
|
185
|
+
@bod = AsiBod::Bod.new(global_options)
|
174
186
|
end
|
175
187
|
|
176
|
-
post do |global_options,command,options,args|
|
188
|
+
post do |global_options, command, options, args|
|
177
189
|
# Post logic here
|
178
190
|
# Use skips_post before a command to skip this
|
179
191
|
# block on that command only
|
data/lib/asi_bod/dict.rb
CHANGED
@@ -2,11 +2,19 @@ require 'pp'
|
|
2
2
|
|
3
3
|
module AsiBod
|
4
4
|
|
5
|
+
# Manipulate the unified Hash that can contain the data from
|
6
|
+
# ASIObjectDictionary or BOD
|
5
7
|
class Dict
|
6
|
-
|
8
|
+
# Find a node in the dict by the value of the specified key
|
9
|
+
# @params dict [Hash] The unified Hash of Hashes that represents the ASIObjectDictionary or BOD data
|
10
|
+
# @params key [Symbol] The Key that will be search against
|
11
|
+
# @params search_value [String, Symbol] The value to search for
|
12
|
+
# @params output_keys [Array] What keys of the node to return
|
13
|
+
# @return [Array<Hash>] Array of Dict nodes scoped by output_keys
|
14
|
+
def self.find_by_key_substring(dict, key, search_value, output_keys)
|
7
15
|
dict.each_with_object({}) do |(k, v), memo|
|
8
16
|
next if v[key].nil?
|
9
|
-
memo[k] = v if v[key].to_s.include?
|
17
|
+
memo[k] = node_line(v, output_keys) if v[key].to_s.include? search_value
|
10
18
|
end
|
11
19
|
end
|
12
20
|
|
@@ -21,17 +29,23 @@ module AsiBod
|
|
21
29
|
# with only the keys specified
|
22
30
|
# @param results [Hash] The subset of a full asi or bod Hash
|
23
31
|
# @param keys [Array] Optional array of keys to display
|
24
|
-
|
25
|
-
|
26
|
-
|
32
|
+
# @return [Hash<Symbol>,<Hash>] Hash of Hashes with each hash having specified keys
|
33
|
+
def self.specific_keys_per_node(dict, keys)
|
34
|
+
dict.each_with_object({}) do |(key, node), memo|
|
35
|
+
memo[key] = Dict.node_line(node, keys)
|
27
36
|
end
|
28
37
|
end
|
29
38
|
|
39
|
+
# Merge the descriptions from ASIObjectDictionary Hash of Hashes into BOD
|
40
|
+
# Hash of Hashes This is not used often. Allowed the creation of the
|
41
|
+
# BODm.json file which has the ASIObjectDictionary Descriptions merged in
|
42
|
+
# @param asi [Hash] The Hash of Hashes of the ASIObjectDictionary
|
43
|
+
# @param bod [Hash] The Hash of Hashes of the BOD
|
30
44
|
def self.merge(asi, bod)
|
31
45
|
bod.each_with_object({}) do |(address, node), memo|
|
32
46
|
memo[address] = node
|
33
47
|
if (asi[address][:description].nil? ||
|
34
|
-
asi[address][:description].include?(
|
48
|
+
asi[address][:description].include?('Reserved') rescue true)
|
35
49
|
memo[address][:description] = nil
|
36
50
|
end
|
37
51
|
memo[address][:description] = asi[address][:description]
|
data/lib/asi_bod/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asi_bod
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert J. Berger
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-01-
|
11
|
+
date: 2018-01-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|