openc3 6.9.1 → 6.9.2
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 +4 -4
- data/bin/openc3cli +289 -0
- data/lib/openc3/interfaces.rb +6 -4
- data/lib/openc3/microservices/interface_microservice.rb +9 -5
- data/lib/openc3/microservices/queue_microservice.rb +14 -6
- data/lib/openc3/models/plugin_model.rb +63 -6
- data/lib/openc3/models/reaction_model.rb +1 -1
- data/lib/openc3/models/target_model.rb +7 -3
- data/lib/openc3/models/trigger_model.rb +1 -1
- data/lib/openc3/script/script.rb +1 -1
- data/lib/openc3/system/system.rb +3 -3
- data/lib/openc3/utilities/authentication.rb +25 -6
- data/lib/openc3/utilities/cli_generator.rb +347 -3
- data/lib/openc3/version.rb +5 -5
- data/templates/command_validator/command_validator.py +49 -0
- data/templates/command_validator/command_validator.rb +54 -0
- data/templates/tool_angular/package.json +48 -2
- data/templates/tool_react/package.json +51 -1
- data/templates/tool_svelte/package.json +48 -1
- data/templates/tool_vue/package.json +36 -3
- data/templates/widget/package.json +28 -2
- metadata +5 -5
- data/templates/tool_vue/.browserslistrc +0 -16
- data/templates/widget/.browserslistrc +0 -16
data/lib/openc3/script/script.rb
CHANGED
|
@@ -232,7 +232,7 @@ module OpenC3
|
|
|
232
232
|
raise "initialize_offline_access only valid in COSMOS Enterprise. OPENC3_KEYCLOAK_URL environment variable must be set."
|
|
233
233
|
end
|
|
234
234
|
auth = OpenC3KeycloakAuthentication.new(keycloak_url)
|
|
235
|
-
auth.token(include_bearer: true, openid_scope: 'openid
|
|
235
|
+
auth.token(include_bearer: true, openid_scope: 'openid offline_access')
|
|
236
236
|
set_offline_access(auth.refresh_token)
|
|
237
237
|
end
|
|
238
238
|
|
data/lib/openc3/system/system.rb
CHANGED
|
@@ -95,11 +95,11 @@ module OpenC3
|
|
|
95
95
|
bucket_key = "#{scope}/target_archives/#{target_name}/#{target_name}_current.zip"
|
|
96
96
|
Logger.info("Retrieving #{bucket_key} from targets bucket")
|
|
97
97
|
bucket.get_object(bucket: ENV['OPENC3_CONFIG_BUCKET'], key: bucket_key, path: zip_path)
|
|
98
|
+
targets_path = "#{base_dir}/targets"
|
|
99
|
+
FileUtils.mkdir_p(targets_path)
|
|
98
100
|
Zip::File.open(zip_path) do |zip_file|
|
|
99
101
|
zip_file.each do |entry|
|
|
100
|
-
|
|
101
|
-
FileUtils.mkdir_p(File.dirname(path))
|
|
102
|
-
zip_file.extract(entry, path) unless File.exist?(path)
|
|
102
|
+
zip_file.extract(entry.name, destination_directory: targets_path)
|
|
103
103
|
end
|
|
104
104
|
end
|
|
105
105
|
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
require 'openc3/version'
|
|
24
24
|
require 'openc3/io/json_drb'
|
|
25
25
|
require 'faraday'
|
|
26
|
+
require 'uri'
|
|
26
27
|
|
|
27
28
|
module OpenC3
|
|
28
29
|
# Basic exception for known errors
|
|
@@ -112,9 +113,13 @@ module OpenC3
|
|
|
112
113
|
client_id = ENV['OPENC3_API_CLIENT'] || 'api'
|
|
113
114
|
if ENV['OPENC3_API_USER'] and ENV['OPENC3_API_PASSWORD']
|
|
114
115
|
# Username and password
|
|
115
|
-
data =
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
data = {
|
|
117
|
+
'username' => ENV['OPENC3_API_USER'],
|
|
118
|
+
'password' => ENV['OPENC3_API_PASSWORD'],
|
|
119
|
+
'client_id' => client_id,
|
|
120
|
+
'grant_type' => 'password',
|
|
121
|
+
'scope' => openid_scope
|
|
122
|
+
}
|
|
118
123
|
headers = {
|
|
119
124
|
'Content-Type' => 'application/x-www-form-urlencoded',
|
|
120
125
|
'User-Agent' => "OpenC3KeycloakAuthorization / #{OPENC3_VERSION} (ruby/openc3/lib/utilities/authentication)",
|
|
@@ -134,7 +139,11 @@ module OpenC3
|
|
|
134
139
|
# Refresh the token and save token to instance
|
|
135
140
|
def _refresh_token(current_time)
|
|
136
141
|
client_id = ENV['OPENC3_API_CLIENT'] || 'api'
|
|
137
|
-
data =
|
|
142
|
+
data = {
|
|
143
|
+
'client_id' => client_id,
|
|
144
|
+
'refresh_token' => @refresh_token,
|
|
145
|
+
'grant_type' => 'refresh_token'
|
|
146
|
+
}
|
|
138
147
|
headers = {
|
|
139
148
|
'Content-Type' => 'application/x-www-form-urlencoded',
|
|
140
149
|
'User-Agent' => "OpenC3KeycloakAuthorization / #{OPENC3_VERSION} (ruby/openc3/lib/utilities/authentication)",
|
|
@@ -150,11 +159,21 @@ module OpenC3
|
|
|
150
159
|
def _make_request(headers, data)
|
|
151
160
|
realm = ENV['OPENC3_KEYCLOAK_REALM'] || 'openc3'
|
|
152
161
|
uri = URI("#{@url}/realms/#{realm}/protocol/openid-connect/token")
|
|
153
|
-
|
|
162
|
+
# Obfuscate password and refresh token in logs unless debug mode is enabled
|
|
163
|
+
if JsonDRb.debug?
|
|
164
|
+
log_data = data.inspect
|
|
165
|
+
else
|
|
166
|
+
# Create a copy of the hash with sensitive values obfuscated
|
|
167
|
+
log_data = data.dup
|
|
168
|
+
log_data['password'] = '***' if log_data.key?('password')
|
|
169
|
+
log_data['refresh_token'] = '***' if log_data.key?('refresh_token')
|
|
170
|
+
log_data = log_data.inspect
|
|
171
|
+
end
|
|
172
|
+
@log[0] = "request uri: #{uri} header: #{headers} body: #{log_data}"
|
|
154
173
|
STDOUT.puts @log[0] if JsonDRb.debug?
|
|
155
174
|
saved_verbose = $VERBOSE; $VERBOSE = nil
|
|
156
175
|
begin
|
|
157
|
-
resp = @http.post(uri, data, headers)
|
|
176
|
+
resp = @http.post(uri, URI.encode_www_form(data), headers)
|
|
158
177
|
ensure
|
|
159
178
|
$VERBOSE = saved_verbose
|
|
160
179
|
end
|
|
@@ -18,15 +18,55 @@
|
|
|
18
18
|
|
|
19
19
|
module OpenC3
|
|
20
20
|
class CliGenerator
|
|
21
|
-
GENERATORS = %w(plugin target microservice widget conversion processor limits_response tool tool_vue tool_angular tool_react tool_svelte)
|
|
21
|
+
GENERATORS = %w(plugin target microservice widget conversion processor limits_response tool tool_vue tool_angular tool_react tool_svelte command_validator)
|
|
22
22
|
TEMPLATES_DIR = "#{File.dirname(__FILE__)}/../../../templates"
|
|
23
23
|
|
|
24
24
|
# Called by openc3cli with ARGV[1..-1]
|
|
25
25
|
def self.generate(args)
|
|
26
|
+
if args[0].nil? || args[0] == '--help' || args[0] == '-h'
|
|
27
|
+
puts "Usage: cli generate GENERATOR [ARGS...] (--ruby or --python)"
|
|
28
|
+
puts ""
|
|
29
|
+
puts "Generate COSMOS components from templates"
|
|
30
|
+
puts ""
|
|
31
|
+
puts "Available Generators:"
|
|
32
|
+
puts " plugin Create a new COSMOS plugin"
|
|
33
|
+
puts " target Create a new target within a plugin"
|
|
34
|
+
puts " microservice Create a new microservice within a plugin"
|
|
35
|
+
puts " widget Create a new custom widget"
|
|
36
|
+
puts " conversion Create a new conversion class for a target"
|
|
37
|
+
puts " processor Create a new processor for a target"
|
|
38
|
+
puts " limits_response Create a new limits response for a target"
|
|
39
|
+
puts " command_validator Create a new command validator for a target"
|
|
40
|
+
puts " tool Create a new tool (Vue.js by default)"
|
|
41
|
+
puts " tool_vue Create a new Vue.js tool"
|
|
42
|
+
puts " tool_angular Create a new Angular tool"
|
|
43
|
+
puts " tool_react Create a new React tool"
|
|
44
|
+
puts " tool_svelte Create a new Svelte tool"
|
|
45
|
+
puts ""
|
|
46
|
+
puts "Run 'cli generate GENERATOR --help' for detailed help on each generator."
|
|
47
|
+
puts ""
|
|
48
|
+
puts "Options:"
|
|
49
|
+
puts " --ruby Generate Ruby code (or set OPENC3_LANGUAGE=ruby)"
|
|
50
|
+
puts " --python Generate Python code (or set OPENC3_LANGUAGE=python)"
|
|
51
|
+
puts " -h, --help Show this help message"
|
|
52
|
+
puts ""
|
|
53
|
+
puts "Examples:"
|
|
54
|
+
puts " cli generate plugin MyPlugin --ruby"
|
|
55
|
+
puts " cli generate target EXAMPLE --python"
|
|
56
|
+
puts " cli generate widget SuperdataWidget --ruby"
|
|
57
|
+
puts " cli generate conversion EXAMPLE STATUS --ruby"
|
|
58
|
+
puts ""
|
|
59
|
+
puts "Documentation:"
|
|
60
|
+
puts " https://docs.openc3.com/docs/development/developing"
|
|
61
|
+
exit(args[0].nil? ? 1 : 0)
|
|
62
|
+
end
|
|
26
63
|
unless GENERATORS.include?(args[0])
|
|
27
64
|
abort("Unknown generator '#{args[0]}'. Valid generators: #{GENERATORS.join(', ')}")
|
|
28
65
|
end
|
|
29
|
-
|
|
66
|
+
# Skip argument validation if user is requesting help
|
|
67
|
+
unless args[1] == '--help' || args[1] == '-h'
|
|
68
|
+
check_args(args)
|
|
69
|
+
end
|
|
30
70
|
send("generate_#{args[0].to_s.downcase.gsub('-', '_')}", args)
|
|
31
71
|
end
|
|
32
72
|
|
|
@@ -79,6 +119,29 @@ module OpenC3
|
|
|
79
119
|
end
|
|
80
120
|
|
|
81
121
|
def self.generate_plugin(args)
|
|
122
|
+
if args[1].nil? || args[1] == '--help' || args[1] == '-h'
|
|
123
|
+
puts "Usage: cli generate plugin NAME (--ruby or --python)"
|
|
124
|
+
puts ""
|
|
125
|
+
puts "Generate a new COSMOS plugin"
|
|
126
|
+
puts ""
|
|
127
|
+
puts "Arguments:"
|
|
128
|
+
puts " NAME Name of the plugin (required)"
|
|
129
|
+
puts " Will be prefixed with 'openc3-cosmos-'"
|
|
130
|
+
puts " Spaces, underscores, and hyphens will be converted to hyphens"
|
|
131
|
+
puts ""
|
|
132
|
+
puts "Options:"
|
|
133
|
+
puts " --ruby Generate Ruby plugin (or set OPENC3_LANGUAGE=ruby)"
|
|
134
|
+
puts " --python Generate Python plugin (or set OPENC3_LANGUAGE=python)"
|
|
135
|
+
puts " -h, --help Show this help message"
|
|
136
|
+
puts ""
|
|
137
|
+
puts "Example:"
|
|
138
|
+
puts " cli generate plugin demo --ruby"
|
|
139
|
+
puts " Creates: openc3-cosmos-demo/"
|
|
140
|
+
puts ""
|
|
141
|
+
puts "Documentation:"
|
|
142
|
+
puts " https://docs.openc3.com/docs/configuration/plugins"
|
|
143
|
+
exit(args[1].nil? ? 1 : 0)
|
|
144
|
+
end
|
|
82
145
|
if args.length < 2 or args.length > 3
|
|
83
146
|
abort("Usage: cli generate #{args[0]} <NAME> (--ruby or --python)")
|
|
84
147
|
end
|
|
@@ -102,6 +165,30 @@ module OpenC3
|
|
|
102
165
|
end
|
|
103
166
|
|
|
104
167
|
def self.generate_target(args)
|
|
168
|
+
if args[1].nil? || args[1] == '--help' || args[1] == '-h'
|
|
169
|
+
puts "Usage: cli generate target NAME (--ruby or --python)"
|
|
170
|
+
puts ""
|
|
171
|
+
puts "Generate a new target within an existing plugin"
|
|
172
|
+
puts ""
|
|
173
|
+
puts "Arguments:"
|
|
174
|
+
puts " NAME Name of the target (required)"
|
|
175
|
+
puts " Will be uppercased and underscores/hyphens converted to underscores"
|
|
176
|
+
puts ""
|
|
177
|
+
puts "Options:"
|
|
178
|
+
puts " --ruby Generate Ruby target (or set OPENC3_LANGUAGE=ruby)"
|
|
179
|
+
puts " --python Generate Python target (or set OPENC3_LANGUAGE=python)"
|
|
180
|
+
puts " -h, --help Show this help message"
|
|
181
|
+
puts ""
|
|
182
|
+
puts "Example:"
|
|
183
|
+
puts " cli generate target EXAMPLE --ruby"
|
|
184
|
+
puts " Creates: targets/EXAMPLE/"
|
|
185
|
+
puts ""
|
|
186
|
+
puts "Note: Must be run from within an existing plugin directory"
|
|
187
|
+
puts ""
|
|
188
|
+
puts "Documentation:"
|
|
189
|
+
puts " https://docs.openc3.com/docs/configuration/target"
|
|
190
|
+
exit(args[1].nil? ? 1 : 0)
|
|
191
|
+
end
|
|
105
192
|
if args.length < 2 or args.length > 3
|
|
106
193
|
abort("Usage: cli generate #{args[0]} <NAME> (--ruby or --python)")
|
|
107
194
|
end
|
|
@@ -133,7 +220,17 @@ module OpenC3
|
|
|
133
220
|
end
|
|
134
221
|
gemspec_filename = Dir['*.gemspec'][0]
|
|
135
222
|
gemspec = File.read(gemspec_filename)
|
|
136
|
-
gemspec.gsub!(
|
|
223
|
+
gemspec.gsub!(/s\.files = Dir\.glob.*\n/) do |match|
|
|
224
|
+
<<RUBY
|
|
225
|
+
# Prefer pyproject.toml over requirements.txt
|
|
226
|
+
python_dep_file = if File.exist?('pyproject.toml')
|
|
227
|
+
'pyproject.toml'
|
|
228
|
+
else
|
|
229
|
+
'requirements.txt'
|
|
230
|
+
end
|
|
231
|
+
s.files = Dir.glob("{targets,lib,tools,microservices}/**/*") + %w(Rakefile README.md LICENSE.txt plugin.txt) + [python_dep_file]
|
|
232
|
+
RUBY
|
|
233
|
+
end
|
|
137
234
|
File.write(gemspec_filename, gemspec)
|
|
138
235
|
|
|
139
236
|
target_txt_filename = "targets/#{target_name}/target.txt"
|
|
@@ -164,6 +261,30 @@ module OpenC3
|
|
|
164
261
|
end
|
|
165
262
|
|
|
166
263
|
def self.generate_microservice(args)
|
|
264
|
+
if args[1].nil? || args[1] == '--help' || args[1] == '-h'
|
|
265
|
+
puts "Usage: cli generate microservice NAME (--ruby or --python)"
|
|
266
|
+
puts ""
|
|
267
|
+
puts "Generate a new microservice within an existing plugin"
|
|
268
|
+
puts ""
|
|
269
|
+
puts "Arguments:"
|
|
270
|
+
puts " NAME Name of the microservice (required)"
|
|
271
|
+
puts " Will be uppercased and underscores/hyphens converted to underscores"
|
|
272
|
+
puts ""
|
|
273
|
+
puts "Options:"
|
|
274
|
+
puts " --ruby Generate Ruby microservice (or set OPENC3_LANGUAGE=ruby)"
|
|
275
|
+
puts " --python Generate Python microservice (or set OPENC3_LANGUAGE=python)"
|
|
276
|
+
puts " -h, --help Show this help message"
|
|
277
|
+
puts ""
|
|
278
|
+
puts "Example:"
|
|
279
|
+
puts " cli generate microservice DATA_PROCESSOR --ruby"
|
|
280
|
+
puts " Creates: microservices/DATA_PROCESSOR/"
|
|
281
|
+
puts ""
|
|
282
|
+
puts "Note: Must be run from within an existing plugin directory"
|
|
283
|
+
puts ""
|
|
284
|
+
puts "Documentation:"
|
|
285
|
+
puts " https://docs.openc3.com/docs/configuration/plugins#microservices"
|
|
286
|
+
exit(args[1].nil? ? 1 : 0)
|
|
287
|
+
end
|
|
167
288
|
if args.length < 2 or args.length > 3
|
|
168
289
|
abort("Usage: cli generate #{args[0]} <NAME> (--ruby or --python)")
|
|
169
290
|
end
|
|
@@ -203,6 +324,31 @@ module OpenC3
|
|
|
203
324
|
end
|
|
204
325
|
|
|
205
326
|
def self.generate_widget(args)
|
|
327
|
+
if args[1].nil? || args[1] == '--help' || args[1] == '-h'
|
|
328
|
+
puts "Usage: cli generate widget NAME (--ruby or --python)"
|
|
329
|
+
puts ""
|
|
330
|
+
puts "Generate a new custom Vue.js widget within an existing plugin"
|
|
331
|
+
puts ""
|
|
332
|
+
puts "Arguments:"
|
|
333
|
+
puts " NAME Name of the widget (required)"
|
|
334
|
+
puts " Must be CapitalCase ending with 'Widget'"
|
|
335
|
+
puts " Example: SuperdataWidget, StatusWidget"
|
|
336
|
+
puts ""
|
|
337
|
+
puts "Options:"
|
|
338
|
+
puts " --ruby Generate Ruby plugin (or set OPENC3_LANGUAGE=ruby)"
|
|
339
|
+
puts " --python Generate Python plugin (or set OPENC3_LANGUAGE=python)"
|
|
340
|
+
puts " -h, --help Show this help message"
|
|
341
|
+
puts ""
|
|
342
|
+
puts "Example:"
|
|
343
|
+
puts " cli generate widget SuperdataWidget --ruby"
|
|
344
|
+
puts " Creates: src/SuperdataWidget.vue"
|
|
345
|
+
puts ""
|
|
346
|
+
puts "Note: Must be run from within an existing plugin directory"
|
|
347
|
+
puts ""
|
|
348
|
+
puts "Documentation:"
|
|
349
|
+
puts " https://docs.openc3.com/docs/guides/custom-widgets"
|
|
350
|
+
exit(args[1].nil? ? 1 : 0)
|
|
351
|
+
end
|
|
206
352
|
if args.length < 2 or args.length > 3
|
|
207
353
|
abort("Usage: cli generate #{args[0]} <SuperdataWidget> (--ruby or --python)")
|
|
208
354
|
end
|
|
@@ -249,6 +395,75 @@ module OpenC3
|
|
|
249
395
|
end
|
|
250
396
|
|
|
251
397
|
def self.generate_tool(args)
|
|
398
|
+
if args[1].nil? || args[1] == '--help' || args[1] == '-h'
|
|
399
|
+
tool_type = args[0].to_s.downcase.gsub('-', '_')
|
|
400
|
+
|
|
401
|
+
# Specific help for tool variants
|
|
402
|
+
if tool_type != 'tool'
|
|
403
|
+
framework = case tool_type
|
|
404
|
+
when 'tool_vue' then 'Vue.js'
|
|
405
|
+
when 'tool_react' then 'React'
|
|
406
|
+
when 'tool_angular' then 'Angular'
|
|
407
|
+
when 'tool_svelte' then 'Svelte'
|
|
408
|
+
else 'Custom'
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
puts "Usage: cli generate #{args[0]} 'TOOL NAME' (--ruby or --python)"
|
|
412
|
+
puts ""
|
|
413
|
+
puts "Generate a new #{framework} tool within an existing plugin"
|
|
414
|
+
puts ""
|
|
415
|
+
puts "Arguments:"
|
|
416
|
+
puts " TOOL NAME Display name of the tool (required, can include spaces)"
|
|
417
|
+
puts " Will be converted to lowercase without spaces for directory name"
|
|
418
|
+
puts ""
|
|
419
|
+
puts "Options:"
|
|
420
|
+
puts " --ruby Generate Ruby plugin (or set OPENC3_LANGUAGE=ruby)"
|
|
421
|
+
puts " --python Generate Python plugin (or set OPENC3_LANGUAGE=python)"
|
|
422
|
+
puts " -h, --help Show this help message"
|
|
423
|
+
puts ""
|
|
424
|
+
puts "Example:"
|
|
425
|
+
puts " cli generate #{args[0]} 'Data Viewer' --ruby"
|
|
426
|
+
puts " Creates: tools/dataviewer/ (#{framework}-based)"
|
|
427
|
+
puts ""
|
|
428
|
+
puts "Note: Must be run from within an existing plugin directory"
|
|
429
|
+
puts " For other tool types, see: cli generate tool --help"
|
|
430
|
+
puts ""
|
|
431
|
+
puts "Documentation:"
|
|
432
|
+
puts " https://docs.openc3.com/docs/guides/custom-tools"
|
|
433
|
+
exit(args[1].nil? ? 1 : 0)
|
|
434
|
+
else
|
|
435
|
+
# Generic help showing all types
|
|
436
|
+
puts "Usage: cli generate #{args[0]} 'TOOL NAME' (--ruby or --python)"
|
|
437
|
+
puts ""
|
|
438
|
+
puts "Generate a new custom tool within an existing plugin"
|
|
439
|
+
puts ""
|
|
440
|
+
puts "Arguments:"
|
|
441
|
+
puts " TOOL NAME Display name of the tool (required, can include spaces)"
|
|
442
|
+
puts " Will be converted to lowercase without spaces for directory name"
|
|
443
|
+
puts ""
|
|
444
|
+
puts "Options:"
|
|
445
|
+
puts " --ruby Generate Ruby plugin (or set OPENC3_LANGUAGE=ruby)"
|
|
446
|
+
puts " --python Generate Python plugin (or set OPENC3_LANGUAGE=python)"
|
|
447
|
+
puts " -h, --help Show this help message"
|
|
448
|
+
puts ""
|
|
449
|
+
puts "Tool Types:"
|
|
450
|
+
puts " tool Generate Vue.js tool (default)"
|
|
451
|
+
puts " tool_vue Generate Vue.js tool"
|
|
452
|
+
puts " tool_angular Generate Angular tool"
|
|
453
|
+
puts " tool_react Generate React tool"
|
|
454
|
+
puts " tool_svelte Generate Svelte tool"
|
|
455
|
+
puts ""
|
|
456
|
+
puts "Example:"
|
|
457
|
+
puts " cli generate tool 'Data Viewer' --ruby"
|
|
458
|
+
puts " Creates: tools/dataviewer/"
|
|
459
|
+
puts ""
|
|
460
|
+
puts "Note: Must be run from within an existing plugin directory"
|
|
461
|
+
puts ""
|
|
462
|
+
puts "Documentation:"
|
|
463
|
+
puts " https://docs.openc3.com/docs/guides/custom-tools"
|
|
464
|
+
exit(args[1].nil? ? 1 : 0)
|
|
465
|
+
end
|
|
466
|
+
end
|
|
252
467
|
if args.length < 2 or args.length > 3
|
|
253
468
|
abort("Usage: cli generate #{args[0]} 'Tool Name' (--ruby or --python)")
|
|
254
469
|
end
|
|
@@ -300,6 +515,31 @@ module OpenC3
|
|
|
300
515
|
self.singleton_class.send(:alias_method, :generate_tool_svelte, :generate_tool)
|
|
301
516
|
|
|
302
517
|
def self.generate_conversion(args)
|
|
518
|
+
if args[1].nil? || args[2].nil? || args[1] == '--help' || args[1] == '-h'
|
|
519
|
+
puts "Usage: cli generate conversion TARGET NAME (--ruby or --python)"
|
|
520
|
+
puts ""
|
|
521
|
+
puts "Generate a new conversion class for an existing target"
|
|
522
|
+
puts ""
|
|
523
|
+
puts "Arguments:"
|
|
524
|
+
puts " TARGET Target name (required, must exist)"
|
|
525
|
+
puts " NAME Conversion name (required)"
|
|
526
|
+
puts " Will be uppercased with '_CONVERSION' suffix"
|
|
527
|
+
puts ""
|
|
528
|
+
puts "Options:"
|
|
529
|
+
puts " --ruby Generate Ruby conversion (or set OPENC3_LANGUAGE=ruby)"
|
|
530
|
+
puts " --python Generate Python conversion (or set OPENC3_LANGUAGE=python)"
|
|
531
|
+
puts " -h, --help Show this help message"
|
|
532
|
+
puts ""
|
|
533
|
+
puts "Example:"
|
|
534
|
+
puts " cli generate conversion EXAMPLE STATUS --ruby"
|
|
535
|
+
puts " Creates: targets/EXAMPLE/lib/status_conversion.rb"
|
|
536
|
+
puts ""
|
|
537
|
+
puts "Note: Must be run from within an existing plugin directory"
|
|
538
|
+
puts ""
|
|
539
|
+
puts "Documentation:"
|
|
540
|
+
puts " https://docs.openc3.com/docs/configuration/telemetry#read_conversion"
|
|
541
|
+
exit(args[1].nil? || args[2].nil? ? 1 : 0)
|
|
542
|
+
end
|
|
303
543
|
if args.length < 3 or args.length > 4
|
|
304
544
|
abort("Usage: cli generate conversion <TARGET> <NAME> (--ruby or --python)")
|
|
305
545
|
end
|
|
@@ -329,6 +569,31 @@ module OpenC3
|
|
|
329
569
|
end
|
|
330
570
|
|
|
331
571
|
def self.generate_processor(args)
|
|
572
|
+
if args[1].nil? || args[2].nil? || args[1] == '--help' || args[1] == '-h'
|
|
573
|
+
puts "Usage: cli generate processor TARGET NAME (--ruby or --python)"
|
|
574
|
+
puts ""
|
|
575
|
+
puts "Generate a new processor for an existing target"
|
|
576
|
+
puts ""
|
|
577
|
+
puts "Arguments:"
|
|
578
|
+
puts " TARGET Target name (required, must exist)"
|
|
579
|
+
puts " NAME Processor name (required)"
|
|
580
|
+
puts " Will be uppercased with '_PROCESSOR' suffix"
|
|
581
|
+
puts ""
|
|
582
|
+
puts "Options:"
|
|
583
|
+
puts " --ruby Generate Ruby processor (or set OPENC3_LANGUAGE=ruby)"
|
|
584
|
+
puts " --python Generate Python processor (or set OPENC3_LANGUAGE=python)"
|
|
585
|
+
puts " -h, --help Show this help message"
|
|
586
|
+
puts ""
|
|
587
|
+
puts "Example:"
|
|
588
|
+
puts " cli generate processor EXAMPLE DATA --ruby"
|
|
589
|
+
puts " Creates: targets/EXAMPLE/lib/data_processor.rb"
|
|
590
|
+
puts ""
|
|
591
|
+
puts "Note: Must be run from within an existing plugin directory"
|
|
592
|
+
puts ""
|
|
593
|
+
puts "Documentation:"
|
|
594
|
+
puts " https://docs.openc3.com/docs/configuration/telemetry#processor"
|
|
595
|
+
exit(args[1].nil? || args[2].nil? ? 1 : 0)
|
|
596
|
+
end
|
|
332
597
|
if args.length < 3 or args.length > 4
|
|
333
598
|
abort("Usage: cli generate processor <TARGET> <NAME> (--ruby or --python)")
|
|
334
599
|
end
|
|
@@ -358,6 +623,31 @@ module OpenC3
|
|
|
358
623
|
end
|
|
359
624
|
|
|
360
625
|
def self.generate_limits_response(args)
|
|
626
|
+
if args[1].nil? || args[2].nil? || args[1] == '--help' || args[1] == '-h'
|
|
627
|
+
puts "Usage: cli generate limits_response TARGET NAME (--ruby or --python)"
|
|
628
|
+
puts ""
|
|
629
|
+
puts "Generate a new limits response for an existing target"
|
|
630
|
+
puts ""
|
|
631
|
+
puts "Arguments:"
|
|
632
|
+
puts " TARGET Target name (required, must exist)"
|
|
633
|
+
puts " NAME Limits response name (required)"
|
|
634
|
+
puts " Will be uppercased with '_LIMITS_RESPONSE' suffix"
|
|
635
|
+
puts ""
|
|
636
|
+
puts "Options:"
|
|
637
|
+
puts " --ruby Generate Ruby limits response (or set OPENC3_LANGUAGE=ruby)"
|
|
638
|
+
puts " --python Generate Python limits response (or set OPENC3_LANGUAGE=python)"
|
|
639
|
+
puts " -h, --help Show this help message"
|
|
640
|
+
puts ""
|
|
641
|
+
puts "Example:"
|
|
642
|
+
puts " cli generate limits_response EXAMPLE CUSTOM --ruby"
|
|
643
|
+
puts " Creates: targets/EXAMPLE/lib/custom_limits_response.rb"
|
|
644
|
+
puts ""
|
|
645
|
+
puts "Note: Must be run from within an existing plugin directory"
|
|
646
|
+
puts ""
|
|
647
|
+
puts "Documentation:"
|
|
648
|
+
puts " https://docs.openc3.com/docs/configuration/telemetry#limits_response"
|
|
649
|
+
exit(args[1].nil? || args[2].nil? ? 1 : 0)
|
|
650
|
+
end
|
|
361
651
|
if args.length < 3 or args.length > 4
|
|
362
652
|
abort("Usage: cli generate limits_response <TARGET> <NAME> (--ruby or --python)")
|
|
363
653
|
end
|
|
@@ -385,5 +675,59 @@ module OpenC3
|
|
|
385
675
|
puts " LIMITS_RESPONSE #{response_basename}"
|
|
386
676
|
return response_name
|
|
387
677
|
end
|
|
678
|
+
|
|
679
|
+
def self.generate_command_validator(args)
|
|
680
|
+
if args[1].nil? || args[2].nil? || args[1] == '--help' || args[1] == '-h'
|
|
681
|
+
puts "Usage: cli generate command_validator TARGET NAME (--ruby or --python)"
|
|
682
|
+
puts ""
|
|
683
|
+
puts "Generate a new command validator for an existing target"
|
|
684
|
+
puts ""
|
|
685
|
+
puts "Arguments:"
|
|
686
|
+
puts " TARGET Target name (required, must exist)"
|
|
687
|
+
puts " NAME Command validator name (required)"
|
|
688
|
+
puts " Will be uppercased with '_COMMAND_VALIDATOR' suffix"
|
|
689
|
+
puts ""
|
|
690
|
+
puts "Options:"
|
|
691
|
+
puts " --ruby Generate Ruby command validator (or set OPENC3_LANGUAGE=ruby)"
|
|
692
|
+
puts " --python Generate Python command validator (or set OPENC3_LANGUAGE=python)"
|
|
693
|
+
puts " -h, --help Show this help message"
|
|
694
|
+
puts ""
|
|
695
|
+
puts "Example:"
|
|
696
|
+
puts " cli generate command_validator EXAMPLE RANGE --ruby"
|
|
697
|
+
puts " Creates: targets/EXAMPLE/lib/range_command_validator.rb"
|
|
698
|
+
puts ""
|
|
699
|
+
puts "Note: Must be run from within an existing plugin directory"
|
|
700
|
+
puts ""
|
|
701
|
+
puts "Documentation:"
|
|
702
|
+
puts " https://docs.openc3.com/docs/configuration/command#validator"
|
|
703
|
+
exit(args[1].nil? || args[2].nil? ? 1 : 0)
|
|
704
|
+
end
|
|
705
|
+
if args.length < 3 or args.length > 4
|
|
706
|
+
abort("Usage: cli generate command_validator <TARGET> <NAME> (--ruby or --python)")
|
|
707
|
+
end
|
|
708
|
+
|
|
709
|
+
# Create the local variables
|
|
710
|
+
target_name = args[1].upcase
|
|
711
|
+
unless File.exist?("targets/#{target_name}")
|
|
712
|
+
abort("Target '#{target_name}' does not exist! Command validators must be created for existing targets.")
|
|
713
|
+
end
|
|
714
|
+
validator_name = "#{args[2].upcase.gsub(/_+|-+/, '_')}_COMMAND_VALIDATOR"
|
|
715
|
+
validator_basename = "#{validator_name.downcase}.#{@@language}"
|
|
716
|
+
validator_class = validator_basename.filename_to_class_name # NOSONAR
|
|
717
|
+
validator_filename = "targets/#{target_name}/lib/#{validator_basename}"
|
|
718
|
+
if File.exist?(validator_filename)
|
|
719
|
+
abort("Command validator #{validator_filename} already exists!")
|
|
720
|
+
end
|
|
721
|
+
|
|
722
|
+
process_template("#{TEMPLATES_DIR}/command_validator", binding) do |filename|
|
|
723
|
+
filename.sub!("command_validator.#{@@language}", validator_filename)
|
|
724
|
+
false
|
|
725
|
+
end
|
|
726
|
+
|
|
727
|
+
puts "Command validator #{validator_filename} successfully generated!"
|
|
728
|
+
puts "To use the command validator add the following to a command:"
|
|
729
|
+
puts " VALIDATOR #{validator_basename}"
|
|
730
|
+
return validator_name
|
|
731
|
+
end
|
|
388
732
|
end
|
|
389
733
|
end
|
data/lib/openc3/version.rb
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# encoding: ascii-8bit
|
|
2
2
|
|
|
3
|
-
OPENC3_VERSION = '6.9.
|
|
3
|
+
OPENC3_VERSION = '6.9.2'
|
|
4
4
|
module OpenC3
|
|
5
5
|
module Version
|
|
6
6
|
MAJOR = '6'
|
|
7
7
|
MINOR = '9'
|
|
8
|
-
PATCH = '
|
|
8
|
+
PATCH = '2'
|
|
9
9
|
OTHER = ''
|
|
10
|
-
BUILD = '
|
|
10
|
+
BUILD = '0b659342611ec28c5dac351032c18442820977a3'
|
|
11
11
|
end
|
|
12
|
-
VERSION = '6.9.
|
|
13
|
-
GEM_VERSION = '6.9.
|
|
12
|
+
VERSION = '6.9.2'
|
|
13
|
+
GEM_VERSION = '6.9.2'
|
|
14
14
|
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from openc3.packets.command_validator import CommandValidator
|
|
2
|
+
# Using the OpenC3 API requires the following imports:
|
|
3
|
+
# from openc3.api import wait_check
|
|
4
|
+
|
|
5
|
+
# Custom command validator class
|
|
6
|
+
# See https://docs.openc3.com/docs/configuration/command
|
|
7
|
+
class <%= validator_class %>(CommandValidator):
|
|
8
|
+
def __init__(self, *args):
|
|
9
|
+
super().__init__()
|
|
10
|
+
self.args = args
|
|
11
|
+
|
|
12
|
+
# Called before a command is sent
|
|
13
|
+
# @param command [dict] The command dictionary containing all the command details
|
|
14
|
+
# @return [list] First element is True/False/None for success/failure/unknown,
|
|
15
|
+
# second element is an optional message string
|
|
16
|
+
def pre_check(self, command):
|
|
17
|
+
# Add your pre-command validation logic here
|
|
18
|
+
# Example:
|
|
19
|
+
# target_name = command['target_name']
|
|
20
|
+
# command_name = command['cmd_name']
|
|
21
|
+
# params = command['cmd_params']
|
|
22
|
+
# self.count = tlm("TARGET PACKET COUNT")
|
|
23
|
+
#
|
|
24
|
+
# if some_condition:
|
|
25
|
+
# return [False, "Command validation failed: reason"]
|
|
26
|
+
|
|
27
|
+
# Return True to indicate Success, False to indicate Failure,
|
|
28
|
+
# and None to indicate Unknown. The second value is the optional message.
|
|
29
|
+
return [True, None]
|
|
30
|
+
|
|
31
|
+
# Called after a command is sent
|
|
32
|
+
# @param command [dict] The command dictionary containing all the command details
|
|
33
|
+
# @return [list] First element is True/False/None for success/failure/unknown,
|
|
34
|
+
# second element is an optional message string
|
|
35
|
+
def post_check(self, command):
|
|
36
|
+
# Add your post-command validation logic here
|
|
37
|
+
# Example:
|
|
38
|
+
# Use the OpenC3 API to check telemetry or wait for responses
|
|
39
|
+
# wait_check("TARGET PACKET ITEM == 'EXPECTED'", 5) # Wait up to 5 seconds
|
|
40
|
+
# wait_check(f"TARGET PACKET COUNT > {self.count}", 5) # Wait up to 5 seconds
|
|
41
|
+
#
|
|
42
|
+
# if some_condition:
|
|
43
|
+
# return [False, "Post-command validation failed: reason"]
|
|
44
|
+
#
|
|
45
|
+
# Wait for telemetry
|
|
46
|
+
|
|
47
|
+
# Return True to indicate Success, False to indicate Failure,
|
|
48
|
+
# and None to indicate Unknown. The second value is the optional message.
|
|
49
|
+
return [True, None]
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
require 'openc3/packets/command_validator'
|
|
3
|
+
|
|
4
|
+
module OpenC3
|
|
5
|
+
# Custom command validator class
|
|
6
|
+
# See https://docs.openc3.com/docs/configuration/command
|
|
7
|
+
class <%= validator_class %> < CommandValidator
|
|
8
|
+
def initialize(*args)
|
|
9
|
+
super()
|
|
10
|
+
@args = args
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Called before a command is sent
|
|
14
|
+
# @param command [Hash] The command hash containing all the command details
|
|
15
|
+
# @return [Array<Boolean, String>] First element is true/false/nil for success/failure/unknown,
|
|
16
|
+
# second element is an optional message string
|
|
17
|
+
def pre_check(command)
|
|
18
|
+
# Add your pre-command validation logic here
|
|
19
|
+
# Example:
|
|
20
|
+
# target_name = command['target_name']
|
|
21
|
+
# command_name = command['cmd_name']
|
|
22
|
+
# params = command['cmd_params']
|
|
23
|
+
# @count = tlm("TARGET PACKET COUNT")
|
|
24
|
+
#
|
|
25
|
+
# if some_condition
|
|
26
|
+
# return [false, "Command validation failed: reason"]
|
|
27
|
+
# end
|
|
28
|
+
|
|
29
|
+
# Return true to indicate Success, false to indicate Failure,
|
|
30
|
+
# and nil to indicate Unknown. The second value is the optional message.
|
|
31
|
+
return [true, nil]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Called after a command is sent
|
|
35
|
+
# @param command [Hash] The command hash containing all the command details
|
|
36
|
+
# @return [Array<Boolean, String>] First element is true/false/nil for success/failure/unknown,
|
|
37
|
+
# second element is an optional message string
|
|
38
|
+
def post_check(command)
|
|
39
|
+
# Add your post-command validation logic here
|
|
40
|
+
# Example:
|
|
41
|
+
# Use the OpenC3 API to check telemetry or wait for responses
|
|
42
|
+
# wait_check("TARGET PACKET ITEM == 'EXPECTED'", 5) # Wait up to 5 seconds
|
|
43
|
+
# wait_check("TARGET PACKET COUNT > #{@count}", 5) # Wait up to 5 seconds
|
|
44
|
+
#
|
|
45
|
+
# if some_condition
|
|
46
|
+
# return [false, "Post-command validation failed: reason"]
|
|
47
|
+
# end
|
|
48
|
+
|
|
49
|
+
# Return true to indicate Success, false to indicate Failure,
|
|
50
|
+
# and nil to indicate Unknown. The second value is the optional message.
|
|
51
|
+
return [true, nil]
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|