openc3 5.5.0.pre.beta0 → 5.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/openc3cli +58 -74
- data/data/config/item_modifiers.yaml +1 -1
- data/data/config/plugins.yaml +5 -0
- data/data/config/widgets.yaml +13 -11
- data/lib/openc3/api/cmd_api.rb +43 -17
- data/lib/openc3/api/tlm_api.rb +37 -4
- data/lib/openc3/bridge/bridge.rb +3 -3
- data/lib/openc3/bridge/bridge_config.rb +68 -20
- data/lib/openc3/interfaces/interface.rb +8 -0
- data/lib/openc3/microservices/decom_microservice.rb +0 -3
- data/lib/openc3/microservices/interface_microservice.rb +2 -0
- data/lib/openc3/microservices/reaction_microservice.rb +0 -1
- data/lib/openc3/models/cvt_model.rb +1 -2
- data/lib/openc3/models/metadata_model.rb +1 -1
- data/lib/openc3/models/microservice_model.rb +1 -1
- data/lib/openc3/models/note_model.rb +1 -1
- data/lib/openc3/models/plugin_model.rb +14 -7
- data/lib/openc3/models/timeline_model.rb +1 -1
- data/lib/openc3/models/trigger_group_model.rb +1 -1
- data/lib/openc3/packets/packet_item.rb +1 -1
- data/lib/openc3/script/storage.rb +5 -5
- data/lib/openc3/streams/web_socket_client_stream.rb +0 -1
- data/lib/openc3/tools/table_manager/table_manager_core.rb +1 -2
- data/lib/openc3/utilities/aws_bucket.rb +22 -4
- data/lib/openc3/utilities/bucket_file_cache.rb +3 -2
- data/lib/openc3/utilities/bucket_utilities.rb +1 -1
- data/lib/openc3/utilities/cli_generator.rb +210 -0
- data/lib/openc3/utilities/local_mode.rb +2 -2
- data/lib/openc3/utilities/target_file.rb +43 -32
- data/lib/openc3/version.rb +5 -5
- data/templates/conversion/conversion.rb +43 -0
- data/templates/limits_response/response.rb +51 -0
- data/templates/microservice/microservices/TEMPLATE/microservice.rb +62 -0
- data/templates/plugin/plugin.txt +1 -0
- metadata +19 -15
- data/templates/plugin-template/plugin.txt +0 -9
- /data/templates/{plugin-template → plugin}/LICENSE.txt +0 -0
- /data/templates/{plugin-template → plugin}/README.md +0 -0
- /data/templates/{plugin-template → plugin}/Rakefile +0 -0
- /data/templates/{plugin-template → plugin}/plugin.gemspec +0 -0
- /data/templates/{plugin-template → target}/targets/TARGET/cmd_tlm/cmd.txt +0 -0
- /data/templates/{plugin-template → target}/targets/TARGET/cmd_tlm/tlm.txt +0 -0
- /data/templates/{plugin-template → target}/targets/TARGET/lib/target.rb +0 -0
- /data/templates/{plugin-template → target}/targets/TARGET/procedures/procedure.rb +0 -0
- /data/templates/{plugin-template → target}/targets/TARGET/screens/status.txt +0 -0
- /data/templates/{plugin-template → target}/targets/TARGET/target.txt +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a21cdfc706de17b576884e2d65593ed329ce736d12384ce0ab1880b3d5d7986
|
4
|
+
data.tar.gz: a1927adc509a3087157cfc5b35737f01796c7fe54a711dd7e750a56de14d7b17
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0dc0c6851d30a29b647ae243b7cb6bfcf641c8cea7a86b41277c677a02f60ce9558f5bb1d37255eb358e99d4670c67e5fa9fecbe422055b061df10ee167591fb
|
7
|
+
data.tar.gz: ed5c29f6c49930381ed2985e22736ec5ee2037774c60ec50d27e25afddd6ab90224d1012ff57ffa109402abe489abeafa78faf63e9111e65fa7689ec65222b3f
|
data/bin/openc3cli
CHANGED
@@ -26,6 +26,7 @@
|
|
26
26
|
require 'openc3'
|
27
27
|
require 'openc3/utilities/local_mode'
|
28
28
|
require 'openc3/utilities/bucket'
|
29
|
+
require 'openc3/utilities/cli_generator'
|
29
30
|
require 'openc3/models/scope_model'
|
30
31
|
require 'openc3/models/plugin_model'
|
31
32
|
require 'openc3/models/gem_model'
|
@@ -42,20 +43,17 @@ require 'json'
|
|
42
43
|
require 'redis'
|
43
44
|
require 'erb'
|
44
45
|
require 'pp'
|
45
|
-
# require 'psych' # Psych code is commented out
|
46
46
|
require "irb"
|
47
47
|
require "irb/completion"
|
48
48
|
|
49
49
|
$redis_url = "redis://#{ENV['OPENC3_REDIS_HOSTNAME']}:#{ENV['OPENC3_REDIS_PORT']}"
|
50
|
-
# Initialize the connection to the bucket library
|
51
|
-
OpenC3::Bucket.getClient()
|
52
50
|
|
53
51
|
# Build the OpenStruct and OptionParser here as constants so we can use in methods
|
54
52
|
MIGRATE_OPTIONS = OpenStruct.new
|
55
53
|
MIGRATE_OPTIONS.all = false
|
56
54
|
MIGRATE_PARSER = OptionParser.new do |op|
|
57
|
-
op.banner = "cli migrate PLUGIN [TGT1...]
|
58
|
-
op.on("-a", "--all", "
|
55
|
+
op.banner = "cli migrate PLUGIN [TGT1...] # Create a OpenC3 plugin from existing COSMOS 4 targets"
|
56
|
+
op.on("-a", "--all", " Move all COSMOS 4 targets into a single OpenC3 plugin") do
|
59
57
|
MIGRATE_OPTIONS.all = true
|
60
58
|
end
|
61
59
|
end
|
@@ -69,9 +67,10 @@ def print_usage
|
|
69
67
|
puts " cli irb # Runs irb in the local directory"
|
70
68
|
puts " cli validate /PATH/FILENAME.gem SCOPE variables.txt # Validate a COSMOS plugin gem file"
|
71
69
|
puts " cli load /PATH/FILENAME.gem SCOPE variables.txt # Loads a COSMOS plugin gem file"
|
72
|
-
puts " cli generate
|
70
|
+
puts " cli generate TYPE OPTIONS # Generate various COSMOS entities"
|
73
71
|
puts " #{MIGRATE_PARSER}"
|
74
72
|
puts " cli bridge CONFIG_FILENAME # Run COSMOS host bridge"
|
73
|
+
puts " cli bridgegem gem_name variable1=value1 variable2=value2 # Runs bridge using gem bridge.txt"
|
75
74
|
puts " cli bridgesetup CONFIG_FILENAME # Create a default config file"
|
76
75
|
puts " cli geminstall GEMFILENAME SCOPE # Install loaded gem to /gems"
|
77
76
|
puts " cli rubysloc # Counts Ruby SLOC recursively. Run with --help for more info."
|
@@ -80,55 +79,6 @@ def print_usage
|
|
80
79
|
puts ""
|
81
80
|
end
|
82
81
|
|
83
|
-
def generate(args)
|
84
|
-
case args[0]
|
85
|
-
when 'plugin'
|
86
|
-
if args.length != 2
|
87
|
-
abort("Usage: cli generate plugin <NAME>")
|
88
|
-
end
|
89
|
-
if args[1] =~ /\s/
|
90
|
-
abort("Plugin names can not have spaces!")
|
91
|
-
end
|
92
|
-
|
93
|
-
plugin = args[1].downcase.gsub(/_+|-+/, '-')
|
94
|
-
plugin_name = "openc3-cosmos-#{plugin}"
|
95
|
-
if File.exist?(plugin_name)
|
96
|
-
abort("Plugin #{plugin_name} already exists!")
|
97
|
-
end
|
98
|
-
FileUtils.mkdir(plugin_name)
|
99
|
-
Dir.chdir(plugin_name) # Change to the plugin path to make copying easier
|
100
|
-
|
101
|
-
# Grab the plugin template
|
102
|
-
template_dir = "#{File.dirname(__FILE__)}/../templates/plugin-template"
|
103
|
-
target_name = plugin.upcase.gsub('-', '_')
|
104
|
-
target_lib_filename = "#{target_name.downcase}.rb"
|
105
|
-
target_class = target_lib_filename.filename_to_class_name
|
106
|
-
target_object = target_name.downcase
|
107
|
-
b = binding
|
108
|
-
|
109
|
-
Dir.glob("#{template_dir}/**/*").each do |file|
|
110
|
-
base_name = file.sub("#{template_dir}/", '')
|
111
|
-
# Rename the template TARGET to our actual target named after the plugin
|
112
|
-
base_name.sub!("targets/TARGET", "targets/#{target_name}")
|
113
|
-
if File.directory?(file)
|
114
|
-
FileUtils.mkdir(base_name)
|
115
|
-
next
|
116
|
-
end
|
117
|
-
base_name.sub!("target.rb", target_lib_filename)
|
118
|
-
base_name.sub!("plugin.gemspec", "#{plugin_name}.gemspec")
|
119
|
-
output = ERB.new(File.read(file), trim_mode: "-").result(b)
|
120
|
-
File.open(base_name, 'w') do |file|
|
121
|
-
file.write output
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
puts "Plugin #{plugin_name} successfully generated!\n"
|
126
|
-
return target_name # This makes the migrate method easier
|
127
|
-
else # Unknown generator
|
128
|
-
abort("Unknown generator #{args[0]}")
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
82
|
def migrate(args)
|
133
83
|
MIGRATE_PARSER.parse!(args)
|
134
84
|
abort(MIGRATE_PARSER.to_s) if args.length == 0
|
@@ -151,7 +101,7 @@ def migrate(args)
|
|
151
101
|
# NOTE: generate does a chdir to be inside the plugin directory
|
152
102
|
###############################################################
|
153
103
|
plugin = args.shift
|
154
|
-
target_name = generate(['plugin', plugin])
|
104
|
+
target_name = OpenC3::CliGenerator.generate(['plugin', plugin])
|
155
105
|
# Delete target contents from the plugin framework (but keep directory)
|
156
106
|
FileUtils.rm_rf Dir.glob("targets/#{target_name}/*")
|
157
107
|
|
@@ -263,10 +213,6 @@ def xtce_converter(args)
|
|
263
213
|
puts e.backtrace
|
264
214
|
result = ERROR_CODE
|
265
215
|
ensure
|
266
|
-
# Uninstall not necessary because this is run against a temporary container
|
267
|
-
# name = Psych.safe_load(`gem spec #{options[:plugin]} name`).to_s
|
268
|
-
# version = Psych.safe_load(`gem spec #{options[:plugin]} version`, permitted_classes: [Gem::Version]).to_s
|
269
|
-
# Gem::Uninstaller.new(name, {:version => version, :force => true}).uninstall
|
270
216
|
exit(result)
|
271
217
|
end
|
272
218
|
else
|
@@ -318,10 +264,6 @@ rescue => e
|
|
318
264
|
puts "Error: #{e.message}"
|
319
265
|
result = ERROR_CODE
|
320
266
|
ensure
|
321
|
-
# Uninstall not necessary because this is run against a temporary container
|
322
|
-
# name = Psych.safe_load(`gem spec #{plugin_file_path} name`).to_s
|
323
|
-
# version = Psych.safe_load(`gem spec #{plugin_file_path} version`, permitted_classes: [Gem::Version]).to_s
|
324
|
-
# Gem::Uninstaller.new(name, {:version => version, :force => true}).uninstall
|
325
267
|
exit(result)
|
326
268
|
end
|
327
269
|
|
@@ -524,6 +466,26 @@ def run_migrations(folder)
|
|
524
466
|
end
|
525
467
|
end
|
526
468
|
|
469
|
+
def run_bridge(filename, params)
|
470
|
+
variables = {}
|
471
|
+
params.each do |param|
|
472
|
+
name, value = param.split('=')
|
473
|
+
if name and value
|
474
|
+
variables[name] = value
|
475
|
+
else
|
476
|
+
raise "Invalid variable passed to bridgegem (syntax name=value): #{param}"
|
477
|
+
end
|
478
|
+
end
|
479
|
+
bridge = OpenC3::Bridge.new(filename, variables)
|
480
|
+
begin
|
481
|
+
while true
|
482
|
+
sleep(1)
|
483
|
+
end
|
484
|
+
rescue Interrupt
|
485
|
+
exit(0)
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
527
489
|
if not ARGV[0].nil? # argument(s) given
|
528
490
|
|
529
491
|
# Handle each task
|
@@ -551,7 +513,7 @@ if not ARGV[0].nil? # argument(s) given
|
|
551
513
|
gem_install(ARGV[1], scope: ARGV[2])
|
552
514
|
|
553
515
|
when 'generate'
|
554
|
-
generate(ARGV[1..-1])
|
516
|
+
OpenC3::CliGenerator.generate(ARGV[1..-1])
|
555
517
|
|
556
518
|
when 'migrate'
|
557
519
|
migrate(ARGV[1..-1])
|
@@ -569,14 +531,34 @@ if not ARGV[0].nil? # argument(s) given
|
|
569
531
|
ENV['OPENC3_NO_STORE'] = '1'
|
570
532
|
filename = ARGV[1]
|
571
533
|
filename = 'bridge.txt' unless filename
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
534
|
+
params = ARGV[2..-1]
|
535
|
+
params = [] unless params
|
536
|
+
run_bridge(filename, params)
|
537
|
+
|
538
|
+
when 'bridgegem'
|
539
|
+
ENV['OPENC3_NO_STORE'] = '1'
|
540
|
+
filename = nil
|
541
|
+
gem_name = ARGV[1]
|
542
|
+
Gem::Specification.each do |s|
|
543
|
+
# This appears to return the newest version of each gem first,
|
544
|
+
# so its ok that we stop on the first time it is found
|
545
|
+
if s.name == gem_name
|
546
|
+
if Array === Gem.path
|
547
|
+
Gem.path.each do |gem_path|
|
548
|
+
filename = File.join(gem_path, 'gems', "#{s.name}-#{s.version}", 'bridge.txt')
|
549
|
+
puts "Trying #{filename}"
|
550
|
+
break if File.exist?(filename)
|
551
|
+
end
|
552
|
+
else
|
553
|
+
filename = File.join(Gem.path, 'gems', "#{s.name}-#{s.version}", 'bridge.txt')
|
554
|
+
end
|
555
|
+
raise "#{filename} not found" unless File.exist?(filename)
|
576
556
|
end
|
577
|
-
rescue Interrupt
|
578
|
-
exit(0)
|
579
557
|
end
|
558
|
+
raise "gem #{gem_name} not found" unless filename
|
559
|
+
params = ARGV[2..-1]
|
560
|
+
params = [] unless params
|
561
|
+
run_bridge(filename, params)
|
580
562
|
|
581
563
|
when 'bridgesetup'
|
582
564
|
ENV['OPENC3_NO_STORE'] = '1'
|
@@ -637,9 +619,11 @@ if not ARGV[0].nil? # argument(s) given
|
|
637
619
|
|
638
620
|
when 'initbuckets'
|
639
621
|
client = OpenC3::Bucket.getClient()
|
640
|
-
|
641
|
-
|
642
|
-
|
622
|
+
ENV.map do |key, value|
|
623
|
+
if key.match(/^OPENC3_(.+)_BUCKET$/) && !value.empty?
|
624
|
+
client.create(value)
|
625
|
+
end
|
626
|
+
end
|
643
627
|
client.ensure_public(ENV['OPENC3_TOOLS_BUCKET'])
|
644
628
|
|
645
629
|
when 'runmigrations'
|
data/data/config/plugins.yaml
CHANGED
@@ -13,6 +13,11 @@ VARIABLE:
|
|
13
13
|
required: true
|
14
14
|
description: Default value of the variable
|
15
15
|
values: .+
|
16
|
+
NEEDS_DEPENDENCIES:
|
17
|
+
summary: Indicates the plugin needs dependencies and sets the GEM_HOME environment variable
|
18
|
+
description: If the plugin has a top level lib folder or lists runtime dependencies in the gemspec,
|
19
|
+
NEEDS_DEPENDENCIES is effectively already set. Note that in Enterprise Edition, having
|
20
|
+
NEEDS_DEPENDENCIES adds the NFS volume mount to the Kuberentes pod.
|
16
21
|
INTERFACE:
|
17
22
|
modifiers:
|
18
23
|
<%= MetaConfigParser.load('interface_modifiers.yaml').to_meta_config_yaml(4) %>
|
data/data/config/widgets.yaml
CHANGED
@@ -1307,12 +1307,11 @@ CANVASLABELVALUE:
|
|
1307
1307
|
description: The type of the value to display. Default is CONVERTED.
|
1308
1308
|
values: <%= %w(RAW CONVERTED FORMATTED WITH_UNITS) %>
|
1309
1309
|
CANVASIMAGE:
|
1310
|
-
summary: Displays
|
1310
|
+
summary: Displays an image on the canvas
|
1311
1311
|
parameters:
|
1312
|
-
- name: Image
|
1312
|
+
- name: Image filename
|
1313
1313
|
required: true
|
1314
|
-
description: Name of a image file. The file must be
|
1315
|
-
<CONFIG>/data directory.
|
1314
|
+
description: Name of a image file. The file must be in the plugin's targets/TARGET/public directory.
|
1316
1315
|
values: .+
|
1317
1316
|
- name: X Position
|
1318
1317
|
required: true
|
@@ -1323,7 +1322,10 @@ CANVASIMAGE:
|
|
1323
1322
|
description: Y position of the upper-left corner of the image on the canvas
|
1324
1323
|
values: \d+
|
1325
1324
|
CANVASIMAGEVALUE:
|
1326
|
-
summary: Displays
|
1325
|
+
summary: Displays an image on the canvas that changes with a telemetry value
|
1326
|
+
description:
|
1327
|
+
Use various SETTING values to indicate which images should be displayed based on telemetry.
|
1328
|
+
For example, SETTING IMAGE CONNECTED "ground_on.png" 400 100. See the DEMO for a complete example.
|
1327
1329
|
parameters:
|
1328
1330
|
- name: Target name
|
1329
1331
|
required: true
|
@@ -1337,13 +1339,13 @@ CANVASIMAGEVALUE:
|
|
1337
1339
|
required: true
|
1338
1340
|
description: The item name
|
1339
1341
|
values: .+
|
1340
|
-
- name:
|
1342
|
+
- name: Value type
|
1343
|
+
required: true
|
1344
|
+
description: The type of the value to display
|
1345
|
+
values: <%= %w(RAW CONVERTED FORMATTED WITH_UNITS) %>
|
1346
|
+
- name: Image filename
|
1341
1347
|
required: true
|
1342
|
-
description: The
|
1343
|
-
to be in the <CONFIG>/data directory). The actual filenames will be this
|
1344
|
-
value plus the word 'on' or the word 'off' and '.gif'. For example, your
|
1345
|
-
prefix is 'ground' so the files 'groundon.gif' and 'groundoff.gif' will
|
1346
|
-
be searched for in the <CONFIG>/data directory.
|
1348
|
+
description: The default image to display. The file must be in the targets/TARGET/public directory.
|
1347
1349
|
values: .+
|
1348
1350
|
- name: X Position
|
1349
1351
|
required: true
|
data/lib/openc3/api/cmd_api.rb
CHANGED
@@ -99,6 +99,7 @@ module OpenC3
|
|
99
99
|
# @param interface_name [String] The interface to send the raw binary
|
100
100
|
# @param data [String] The raw binary data
|
101
101
|
def send_raw(interface_name, data, scope: $openc3_scope, token: $openc3_token)
|
102
|
+
interface_name = interface_name.upcase
|
102
103
|
authorize(permission: 'cmd_raw', interface_name: interface_name, scope: scope, token: token)
|
103
104
|
get_interface(interface_name, scope: scope, token: token) # Check to make sure the interface exists
|
104
105
|
InterfaceTopic.write_raw(interface_name, data, scope: scope)
|
@@ -110,6 +111,8 @@ module OpenC3
|
|
110
111
|
# @param command_name [String] Packet name of the command
|
111
112
|
# @return [Hash] command hash with last command buffer
|
112
113
|
def get_cmd_buffer(target_name, command_name, scope: $openc3_scope, token: $openc3_token)
|
114
|
+
target_name = target_name.upcase
|
115
|
+
command_name = command_name.upcase
|
113
116
|
authorize(permission: 'cmd_info', target_name: target_name, packet_name: command_name, scope: scope, token: token)
|
114
117
|
TargetModel.packet(target_name, command_name, type: :CMD, scope: scope)
|
115
118
|
topic = "#{scope}__COMMAND__{#{target_name}}__#{command_name}"
|
@@ -127,6 +130,7 @@ module OpenC3
|
|
127
130
|
# @param target_name [String] Name of the target
|
128
131
|
# @return [Array<Hash>] Array of all commands as a hash
|
129
132
|
def get_all_commands(target_name, scope: $openc3_scope, token: $openc3_token)
|
133
|
+
target_name = target_name.upcase
|
130
134
|
authorize(permission: 'cmd_info', target_name: target_name, scope: scope, token: token)
|
131
135
|
TargetModel.packets(target_name, type: :CMD, scope: scope)
|
132
136
|
end
|
@@ -137,6 +141,7 @@ module OpenC3
|
|
137
141
|
# @param target_name [String] Name of the target
|
138
142
|
# @return [Array<String>] Array of all command packet names
|
139
143
|
def get_all_command_names(target_name, scope: $openc3_scope, token: $openc3_token)
|
144
|
+
target_name = target_name.upcase
|
140
145
|
authorize(permission: 'cmd_info', target_name: target_name, scope: scope, token: token)
|
141
146
|
TargetModel.packet_names(target_name, type: :CMD, scope: scope)
|
142
147
|
end
|
@@ -145,23 +150,28 @@ module OpenC3
|
|
145
150
|
#
|
146
151
|
# @since 5.0.0
|
147
152
|
# @param target_name [String] Name of the target
|
148
|
-
# @param
|
153
|
+
# @param command_name [String] Name of the packet
|
149
154
|
# @return [Hash] Command as a hash
|
150
|
-
def get_command(target_name,
|
155
|
+
def get_command(target_name, command_name, scope: $openc3_scope, token: $openc3_token)
|
156
|
+
target_name = target_name.upcase
|
157
|
+
command_name = command_name.upcase
|
151
158
|
authorize(permission: 'cmd_info', target_name: target_name, scope: scope, token: token)
|
152
|
-
TargetModel.packet(target_name,
|
159
|
+
TargetModel.packet(target_name, command_name, type: :CMD, scope: scope)
|
153
160
|
end
|
154
161
|
|
155
162
|
# Returns a hash of the given command parameter
|
156
163
|
#
|
157
164
|
# @since 5.0.0
|
158
165
|
# @param target_name [String] Name of the target
|
159
|
-
# @param
|
160
|
-
# @param
|
166
|
+
# @param command_name [String] Name of the packet
|
167
|
+
# @param parameter_name [String] Name of the parameter
|
161
168
|
# @return [Hash] Command parameter as a hash
|
162
|
-
def get_parameter(target_name,
|
163
|
-
|
164
|
-
|
169
|
+
def get_parameter(target_name, command_name, parameter_name, scope: $openc3_scope, token: $openc3_token)
|
170
|
+
target_name = target_name.upcase
|
171
|
+
command_name = command_name.upcase
|
172
|
+
parameter_name = parameter_name.upcase
|
173
|
+
authorize(permission: 'cmd_info', target_name: target_name, packet_name: command_name, scope: scope, token: token)
|
174
|
+
TargetModel.packet_item(target_name, command_name, parameter_name, type: :CMD, scope: scope)
|
165
175
|
end
|
166
176
|
|
167
177
|
# Returns whether the specified command is hazardous
|
@@ -176,35 +186,38 @@ module OpenC3
|
|
176
186
|
extract_string_kwargs_to_args(args, kwargs)
|
177
187
|
case args.length
|
178
188
|
when 1
|
179
|
-
target_name, command_name,
|
189
|
+
target_name, command_name, parameters = extract_fields_from_cmd_text(args[0], scope: scope)
|
180
190
|
when 2, 3
|
181
191
|
target_name = args[0]
|
182
192
|
command_name = args[1]
|
183
193
|
if args.length == 2
|
184
|
-
|
194
|
+
parameters = {}
|
185
195
|
else
|
186
|
-
|
196
|
+
parameters = args[2]
|
187
197
|
end
|
188
198
|
else
|
189
199
|
# Invalid number of arguments
|
190
200
|
raise "ERROR: Invalid number of arguments (#{args.length}) passed to get_cmd_hazardous()"
|
191
201
|
end
|
202
|
+
target_name = target_name.upcase
|
203
|
+
command_name = command_name.upcase
|
204
|
+
parameters = parameters.transform_keys(&:upcase)
|
192
205
|
|
193
206
|
authorize(permission: 'cmd_info', target_name: target_name, packet_name: command_name, scope: scope, token: token)
|
194
207
|
packet = TargetModel.packet(target_name, command_name, type: :CMD, scope: scope)
|
195
208
|
return true if packet['hazardous']
|
196
209
|
|
197
210
|
packet['items'].each do |item|
|
198
|
-
next unless
|
211
|
+
next unless parameters.keys.include?(item['name']) && item['states']
|
199
212
|
|
200
213
|
# States are an array of the name followed by a hash of 'value' and sometimes 'hazardous'
|
201
214
|
item['states'].each do |name, hash|
|
202
|
-
|
215
|
+
parameter_name = parameters[item['name']]
|
203
216
|
# Remove quotes from string parameters
|
204
|
-
|
217
|
+
parameter_name = parameter_name.gsub('"', '').gsub("'", '') if parameter_name.is_a?(String)
|
205
218
|
# To be hazardous the state must be marked hazardous
|
206
219
|
# Check if either the state name or value matches the param passed
|
207
|
-
if hash['hazardous'] && (name ==
|
220
|
+
if hash['hazardous'] && (name == parameter_name || hash['value'] == parameter_name)
|
208
221
|
return true
|
209
222
|
end
|
210
223
|
end
|
@@ -222,6 +235,9 @@ module OpenC3
|
|
222
235
|
# one of {Packet::VALUE_TYPES}
|
223
236
|
# @return [Varies] value
|
224
237
|
def get_cmd_value(target_name, command_name, parameter_name, value_type = :CONVERTED, scope: $openc3_scope, token: $openc3_token)
|
238
|
+
target_name = target_name.upcase
|
239
|
+
command_name = command_name.upcase
|
240
|
+
parameter_name = parameter_name.upcase
|
225
241
|
authorize(permission: 'cmd_info', target_name: target_name, packet_name: command_name, scope: scope, token: token)
|
226
242
|
CommandDecomTopic.get_cmd_item(target_name, command_name, parameter_name, type: value_type, scope: scope)
|
227
243
|
end
|
@@ -236,12 +252,15 @@ module OpenC3
|
|
236
252
|
def get_cmd_time(target_name = nil, command_name = nil, scope: $openc3_scope, token: $openc3_token)
|
237
253
|
authorize(permission: 'cmd_info', target_name: target_name, packet_name: command_name, scope: scope, token: token)
|
238
254
|
if target_name and command_name
|
255
|
+
target_name = target_name.upcase
|
256
|
+
command_name = command_name.upcase
|
239
257
|
time = CommandDecomTopic.get_cmd_item(target_name, command_name, 'RECEIVED_TIMESECONDS', type: :CONVERTED, scope: scope)
|
240
258
|
[target_name, command_name, time.to_i, ((time.to_f - time.to_i) * 1_000_000).to_i]
|
241
259
|
else
|
242
260
|
if target_name.nil?
|
243
261
|
targets = TargetModel.names(scope: scope)
|
244
262
|
else
|
263
|
+
target_name = target_name.upcase
|
245
264
|
targets = [target_name]
|
246
265
|
end
|
247
266
|
targets.each do |target_name|
|
@@ -268,6 +287,8 @@ module OpenC3
|
|
268
287
|
# @param command_name [String] Packet name of the command
|
269
288
|
# @return [Numeric] Transmit count for the command
|
270
289
|
def get_cmd_cnt(target_name, command_name, scope: $openc3_scope, token: $openc3_token)
|
290
|
+
target_name = target_name.upcase
|
291
|
+
command_name = command_name.upcase
|
271
292
|
authorize(permission: 'system', target_name: target_name, packet_name: command_name, scope: scope, token: token)
|
272
293
|
TargetModel.packet(target_name, command_name, type: :CMD, scope: scope)
|
273
294
|
Topic.get_cnt("#{scope}__COMMAND__{#{target_name}}__#{command_name}")
|
@@ -281,6 +302,8 @@ module OpenC3
|
|
281
302
|
authorize(permission: 'system', scope: scope, token: token)
|
282
303
|
counts = []
|
283
304
|
target_commands.each do |target_name, command_name|
|
305
|
+
target_name = target_name.upcase
|
306
|
+
command_name = command_name.upcase
|
284
307
|
counts << Topic.get_cnt("#{scope}__COMMAND__{#{target_name}}__#{command_name}")
|
285
308
|
end
|
286
309
|
counts
|
@@ -298,8 +321,8 @@ module OpenC3
|
|
298
321
|
when 1
|
299
322
|
target_name, cmd_name, cmd_params = extract_fields_from_cmd_text(args[0], scope: scope)
|
300
323
|
when 2, 3
|
301
|
-
target_name
|
302
|
-
cmd_name
|
324
|
+
target_name = args[0]
|
325
|
+
cmd_name = args[1]
|
303
326
|
if args.length == 2
|
304
327
|
cmd_params = {}
|
305
328
|
else
|
@@ -309,6 +332,9 @@ module OpenC3
|
|
309
332
|
# Invalid number of arguments
|
310
333
|
raise "ERROR: Invalid number of arguments (#{args.length}) passed to #{method_name}()"
|
311
334
|
end
|
335
|
+
target_name = target_name.upcase
|
336
|
+
cmd_name = cmd_name.upcase
|
337
|
+
cmd_params = cmd_params.transform_keys(&:upcase)
|
312
338
|
authorize(permission: 'cmd', target_name: target_name, packet_name: cmd_name, scope: scope, token: token)
|
313
339
|
packet = TargetModel.packet(target_name, cmd_name, type: :CMD, scope: scope)
|
314
340
|
|
data/lib/openc3/api/tlm_api.rb
CHANGED
@@ -120,11 +120,14 @@ module OpenC3
|
|
120
120
|
def inject_tlm(target_name, packet_name, item_hash = nil, type: :CONVERTED, scope: $openc3_scope, token: $openc3_token)
|
121
121
|
authorize(permission: 'tlm_set', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
|
122
122
|
type = type.to_s.intern
|
123
|
+
target_name = target_name.upcase
|
124
|
+
packet_name = packet_name.upcase
|
123
125
|
unless CvtModel::VALUE_TYPES.include?(type)
|
124
126
|
raise "Unknown type '#{type}' for #{target_name} #{packet_name}"
|
125
127
|
end
|
126
128
|
|
127
129
|
if item_hash
|
130
|
+
item_hash = item_hash.transform_keys(&:upcase)
|
128
131
|
# Check that the items exist ... exceptions are raised if not
|
129
132
|
TargetModel.packet_items(target_name, packet_name, item_hash.keys, scope: scope)
|
130
133
|
else
|
@@ -201,6 +204,8 @@ module OpenC3
|
|
201
204
|
# @param packet_name [String] Name of the packet
|
202
205
|
# @return [Hash] telemetry hash with last telemetry buffer
|
203
206
|
def get_tlm_buffer(target_name, packet_name, scope: $openc3_scope, token: $openc3_token)
|
207
|
+
target_name = target_name.upcase
|
208
|
+
packet_name = packet_name.upcase
|
204
209
|
authorize(permission: 'tlm', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
|
205
210
|
TargetModel.packet(target_name, packet_name, scope: scope)
|
206
211
|
topic = "#{scope}__TELEMETRY__{#{target_name}}__#{packet_name}"
|
@@ -222,11 +227,13 @@ module OpenC3
|
|
222
227
|
# of [item name, item value, item limits state] where the item limits
|
223
228
|
# state can be one of {OpenC3::Limits::LIMITS_STATES}
|
224
229
|
def get_tlm_packet(target_name, packet_name, stale_time: 30, type: :CONVERTED, scope: $openc3_scope, token: $openc3_token)
|
230
|
+
target_name = target_name.upcase
|
231
|
+
packet_name = packet_name.upcase
|
225
232
|
authorize(permission: 'tlm', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
|
226
233
|
packet = TargetModel.packet(target_name, packet_name, scope: scope)
|
227
234
|
t = _validate_tlm_type(type)
|
228
235
|
raise ArgumentError, "Unknown type '#{type}' for #{target_name} #{packet_name}" if t.nil?
|
229
|
-
items = packet['items'].map { | item | item['name'] }
|
236
|
+
items = packet['items'].map { | item | item['name'].upcase }
|
230
237
|
cvt_items = items.map { | item | "#{target_name}__#{packet_name}__#{item}__#{type}" }
|
231
238
|
current_values = CvtModel.get_tlm_values(cvt_items, stale_time: stale_time, scope: scope)
|
232
239
|
items.zip(current_values).map { | item , values | [item, values[0], values[1]]}
|
@@ -246,13 +253,18 @@ module OpenC3
|
|
246
253
|
if !items.is_a?(Array) || !items[0].is_a?(String)
|
247
254
|
raise ArgumentError, "items must be array of strings: ['TGT__PKT__ITEM__TYPE', ...]"
|
248
255
|
end
|
249
|
-
|
250
256
|
items.each_with_index do |item, index|
|
251
|
-
target_name, packet_name, item_name,
|
257
|
+
target_name, packet_name, item_name, value_type = item.split('__')
|
258
|
+
raise ArgumentError, "items must be formatted as TGT__PKT__ITEM__TYPE" if target_name.nil? || packet_name.nil? || item_name.nil? || value_type.nil?
|
259
|
+
target_name = target_name.upcase
|
260
|
+
packet_name = packet_name.upcase
|
261
|
+
item_name = item_name.upcase
|
262
|
+
value_type = value_type.upcase
|
252
263
|
if packet_name == 'LATEST'
|
253
264
|
_, packet_name, _ = tlm_process_args([target_name, packet_name, item_name], 'get_tlm_values', scope: scope) # Figure out which packet is LATEST
|
254
|
-
items[index] = "#{target_name}__#{packet_name}__#{item_name}__#{item_type}" # Replace LATEST with the real packet name
|
255
265
|
end
|
266
|
+
# Change packet_name in case of LATEST and ensure upcase
|
267
|
+
items[index] = "#{target_name}__#{packet_name}__#{item_name}__#{value_type}"
|
256
268
|
authorize(permission: 'tlm', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
|
257
269
|
end
|
258
270
|
CvtModel.get_tlm_values(items, stale_time: stale_time, scope: scope)
|
@@ -264,6 +276,7 @@ module OpenC3
|
|
264
276
|
# @param target_name [String] Name of the target
|
265
277
|
# @return [Array<Hash>] Array of all telemetry packet hashes
|
266
278
|
def get_all_telemetry(target_name, scope: $openc3_scope, token: $openc3_token)
|
279
|
+
target_name = target_name.upcase
|
267
280
|
authorize(permission: 'tlm', target_name: target_name, scope: scope, token: token)
|
268
281
|
TargetModel.packets(target_name, type: :TLM, scope: scope)
|
269
282
|
end
|
@@ -274,6 +287,7 @@ module OpenC3
|
|
274
287
|
# @param target_name [String] Name of the target
|
275
288
|
# @return [Array<String>] Array of all telemetry packet names
|
276
289
|
def get_all_telemetry_names(target_name, scope: $openc3_scope, token: $openc3_token)
|
290
|
+
target_name = target_name.upcase
|
277
291
|
authorize(permission: 'cmd_info', target_name: target_name, scope: scope, token: token)
|
278
292
|
TargetModel.packet_names(target_name, type: :TLM, scope: scope)
|
279
293
|
end
|
@@ -285,6 +299,8 @@ module OpenC3
|
|
285
299
|
# @param packet_name [String] Name of the packet
|
286
300
|
# @return [Hash] Telemetry packet hash
|
287
301
|
def get_telemetry(target_name, packet_name, scope: $openc3_scope, token: $openc3_token)
|
302
|
+
target_name = target_name.upcase
|
303
|
+
packet_name = packet_name.upcase
|
288
304
|
authorize(permission: 'tlm', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
|
289
305
|
TargetModel.packet(target_name, packet_name, scope: scope)
|
290
306
|
end
|
@@ -297,6 +313,9 @@ module OpenC3
|
|
297
313
|
# @param item_name [String] Name of the packet
|
298
314
|
# @return [Hash] Telemetry packet item hash
|
299
315
|
def get_item(target_name, packet_name, item_name, scope: $openc3_scope, token: $openc3_token)
|
316
|
+
target_name = target_name.upcase
|
317
|
+
packet_name = packet_name.upcase
|
318
|
+
item_name = item_name.upcase
|
300
319
|
authorize(permission: 'tlm', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
|
301
320
|
TargetModel.packet_item(target_name, packet_name, item_name, scope: scope)
|
302
321
|
end
|
@@ -316,6 +335,8 @@ module OpenC3
|
|
316
335
|
|
317
336
|
result = {}
|
318
337
|
packets.each do |target_name, packet_name|
|
338
|
+
target_name = target_name.upcase
|
339
|
+
packet_name = packet_name.upcase
|
319
340
|
authorize(permission: 'tlm', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
|
320
341
|
topic = "#{scope}__DECOM__{#{target_name}}__#{packet_name}"
|
321
342
|
id, _ = Topic.get_newest_message(topic)
|
@@ -356,6 +377,8 @@ module OpenC3
|
|
356
377
|
# @param packet_name [String] Name of the packet
|
357
378
|
# @return [Numeric] Receive count for the telemetry packet
|
358
379
|
def get_tlm_cnt(target_name, packet_name, scope: $openc3_scope, token: $openc3_token)
|
380
|
+
target_name = target_name.upcase
|
381
|
+
packet_name = packet_name.upcase
|
359
382
|
authorize(permission: 'system', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
|
360
383
|
TargetModel.packet(target_name, packet_name, scope: scope)
|
361
384
|
Topic.get_cnt("#{scope}__TELEMETRY__{#{target_name}}__#{packet_name}")
|
@@ -369,6 +392,8 @@ module OpenC3
|
|
369
392
|
authorize(permission: 'system', scope: scope, token: token)
|
370
393
|
counts = []
|
371
394
|
target_packets.each do |target_name, packet_name|
|
395
|
+
target_name = target_name.upcase
|
396
|
+
packet_name = packet_name.upcase
|
372
397
|
counts << Topic.get_cnt("#{scope}__TELEMETRY__{#{target_name}}__#{packet_name}")
|
373
398
|
end
|
374
399
|
counts
|
@@ -380,6 +405,8 @@ module OpenC3
|
|
380
405
|
# @param packet_name [String] Packet name
|
381
406
|
# @return [Array<String>] All of the ignored telemetry items for a packet.
|
382
407
|
def get_packet_derived_items(target_name, packet_name, scope: $openc3_scope, token: $openc3_token)
|
408
|
+
target_name = target_name.upcase
|
409
|
+
packet_name = packet_name.upcase
|
383
410
|
authorize(permission: 'tlm', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
|
384
411
|
packet = TargetModel.packet(target_name, packet_name, scope: scope)
|
385
412
|
return packet['items'].select { |item| item['data_type'] == 'DERIVED' }.map { |item| item['name'] }
|
@@ -413,6 +440,9 @@ module OpenC3
|
|
413
440
|
# Invalid number of arguments
|
414
441
|
raise "ERROR: Invalid number of arguments (#{args.length}) passed to #{method_name}()"
|
415
442
|
end
|
443
|
+
target_name = target_name.upcase
|
444
|
+
packet_name = packet_name.upcase
|
445
|
+
item_name = item_name.upcase
|
416
446
|
if packet_name == 'LATEST'
|
417
447
|
latest = -1
|
418
448
|
TargetModel.packets(target_name, scope: scope).each do |packet|
|
@@ -449,6 +479,9 @@ module OpenC3
|
|
449
479
|
# Invalid number of arguments
|
450
480
|
raise "ERROR: Invalid number of arguments (#{args.length}) passed to #{method_name}()"
|
451
481
|
end
|
482
|
+
target_name = target_name.upcase
|
483
|
+
packet_name = packet_name.upcase
|
484
|
+
item_name = item_name.upcase
|
452
485
|
# Determine if this item exists, it will raise appropriate errors if not
|
453
486
|
TargetModel.packet_item(target_name, packet_name, item_name, scope: scope)
|
454
487
|
|
data/lib/openc3/bridge/bridge.rb
CHANGED
@@ -17,7 +17,7 @@
|
|
17
17
|
# All changes Copyright 2022, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
19
|
#
|
20
|
-
# This file may also be used under the terms of a commercial license
|
20
|
+
# This file may also be used under the terms of a commercial license
|
21
21
|
# if purchased from OpenC3, Inc.
|
22
22
|
|
23
23
|
require 'openc3'
|
@@ -27,8 +27,8 @@ require 'openc3/bridge/bridge_router_thread'
|
|
27
27
|
|
28
28
|
module OpenC3
|
29
29
|
class Bridge
|
30
|
-
def initialize(filename)
|
31
|
-
@config = BridgeConfig.new(filename)
|
30
|
+
def initialize(filename, existing_variables = {})
|
31
|
+
@config = BridgeConfig.new(filename, existing_variables)
|
32
32
|
@threads = []
|
33
33
|
|
34
34
|
# Start Interface Threads
|