openc3 5.4.3.pre.beta0 → 5.5.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of openc3 might be problematic. Click here for more details.

Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/bin/openc3cli +58 -74
  3. data/data/config/item_modifiers.yaml +1 -1
  4. data/data/config/plugins.yaml +5 -0
  5. data/data/config/widgets.yaml +13 -11
  6. data/lib/openc3/api/cmd_api.rb +43 -17
  7. data/lib/openc3/api/tlm_api.rb +37 -4
  8. data/lib/openc3/bridge/bridge.rb +3 -3
  9. data/lib/openc3/bridge/bridge_config.rb +68 -20
  10. data/lib/openc3/interfaces/interface.rb +8 -0
  11. data/lib/openc3/microservices/decom_microservice.rb +0 -3
  12. data/lib/openc3/microservices/interface_microservice.rb +2 -0
  13. data/lib/openc3/microservices/reaction_microservice.rb +0 -1
  14. data/lib/openc3/models/cvt_model.rb +1 -2
  15. data/lib/openc3/models/metadata_model.rb +1 -1
  16. data/lib/openc3/models/microservice_model.rb +1 -1
  17. data/lib/openc3/models/note_model.rb +1 -1
  18. data/lib/openc3/models/plugin_model.rb +14 -7
  19. data/lib/openc3/models/timeline_model.rb +1 -1
  20. data/lib/openc3/models/trigger_group_model.rb +1 -1
  21. data/lib/openc3/packets/packet_item.rb +1 -1
  22. data/lib/openc3/script/script.rb +10 -0
  23. data/lib/openc3/script/storage.rb +5 -5
  24. data/lib/openc3/script/web_socket_api.rb +423 -0
  25. data/lib/openc3/streams/tcpip_client_stream.rb +1 -1
  26. data/lib/openc3/streams/web_socket_client_stream.rb +98 -0
  27. data/lib/openc3/tools/table_manager/table_manager_core.rb +1 -2
  28. data/lib/openc3/utilities/aws_bucket.rb +22 -4
  29. data/lib/openc3/utilities/bucket_file_cache.rb +3 -2
  30. data/lib/openc3/utilities/bucket_utilities.rb +1 -1
  31. data/lib/openc3/utilities/cli_generator.rb +210 -0
  32. data/lib/openc3/utilities/local_mode.rb +2 -2
  33. data/lib/openc3/utilities/target_file.rb +43 -32
  34. data/lib/openc3/version.rb +7 -7
  35. data/templates/conversion/conversion.rb +43 -0
  36. data/templates/limits_response/response.rb +51 -0
  37. data/templates/microservice/microservices/TEMPLATE/microservice.rb +62 -0
  38. data/templates/plugin/plugin.txt +1 -0
  39. metadata +49 -15
  40. data/templates/plugin-template/plugin.txt +0 -9
  41. /data/templates/{plugin-template → plugin}/LICENSE.txt +0 -0
  42. /data/templates/{plugin-template → plugin}/README.md +0 -0
  43. /data/templates/{plugin-template → plugin}/Rakefile +0 -0
  44. /data/templates/{plugin-template → plugin}/plugin.gemspec +0 -0
  45. /data/templates/{plugin-template → target}/targets/TARGET/cmd_tlm/cmd.txt +0 -0
  46. /data/templates/{plugin-template → target}/targets/TARGET/cmd_tlm/tlm.txt +0 -0
  47. /data/templates/{plugin-template → target}/targets/TARGET/lib/target.rb +0 -0
  48. /data/templates/{plugin-template → target}/targets/TARGET/procedures/procedure.rb +0 -0
  49. /data/templates/{plugin-template → target}/targets/TARGET/screens/status.txt +0 -0
  50. /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: 859879129f5646a4e8fd10a916e1e88859a7b5ed178fe2983f42df4e7e8c1a52
4
- data.tar.gz: 745a188c5e9277e0bb793207f383f85d6ec6d571d41d6115530f6f78bd671817
3
+ metadata.gz: 0a21cdfc706de17b576884e2d65593ed329ce736d12384ce0ab1880b3d5d7986
4
+ data.tar.gz: a1927adc509a3087157cfc5b35737f01796c7fe54a711dd7e750a56de14d7b17
5
5
  SHA512:
6
- metadata.gz: '0582ba269983955ae39c8d0c941666d2fcc65811416e3c1ae7026811fa00d9699ecffc09e195909f30cac3c8571f6b83889349fed9c96ec89c95091aff088a61'
7
- data.tar.gz: a9c9c554d6595cd7718dc58b1e2e07e0ff9a440cd6545674b47250a3542164a41d27bad1bf237c8c121f170dd04380eeaa125769abc9423c0de2e610578f9799
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...] # Create a OpenC3 plugin from existing COSMOS 4 targets"
58
- op.on("-a", "--all", " Move all COSMOS 4 targets into a single OpenC3 plugin") do
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 plugin PLUGIN_NAME # Generate a COSMOS plugin"
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
- bridge = OpenC3::Bridge.new(filename)
573
- begin
574
- while true
575
- sleep(1)
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
- client.create(ENV['OPENC3_CONFIG_BUCKET'])
641
- client.create(ENV['OPENC3_LOGS_BUCKET'])
642
- client.create(ENV['OPENC3_TOOLS_BUCKET'])
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'
@@ -52,7 +52,7 @@ READ_CONVERSION:
52
52
  @multiplier = multiplier.to_f
53
53
  end
54
54
  def call(value, packet, buffer)
55
- return value * multiplier
55
+ return value * @multiplier
56
56
  end
57
57
  end
58
58
  end
@@ -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) %>
@@ -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 a GIF image on the canvas
1310
+ summary: Displays an image on the canvas
1311
1311
  parameters:
1312
- - name: Image name
1312
+ - name: Image filename
1313
1313
  required: true
1314
- description: Name of a image file. The file must be located in the
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 a GIF image on the canvas that changes with a telemetry value
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: Filename Prefix
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 prefix part of the filename of the gif images (expected
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
@@ -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 packet_name [String] Name of the packet
153
+ # @param command_name [String] Name of the packet
149
154
  # @return [Hash] Command as a hash
150
- def get_command(target_name, packet_name, scope: $openc3_scope, token: $openc3_token)
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, packet_name, type: :CMD, scope: scope)
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 packet_name [String] Name of the packet
160
- # @param param_name [String] Name of the parameter
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, packet_name, param_name, scope: $openc3_scope, token: $openc3_token)
163
- authorize(permission: 'cmd_info', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
164
- TargetModel.packet_item(target_name, packet_name, param_name, type: :CMD, scope: scope)
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, params = extract_fields_from_cmd_text(args[0], scope: scope)
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
- params = {}
194
+ parameters = {}
185
195
  else
186
- params = args[2]
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 params.keys.include?(item['name']) && item['states']
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
- param_name = params[item['name']]
215
+ parameter_name = parameters[item['name']]
203
216
  # Remove quotes from string parameters
204
- param_name = param_name.gsub('"', '').gsub("'", '') if param_name.is_a?(String)
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 == param_name || hash['value'] == param_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 = args[0]
302
- cmd_name = args[1]
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
 
@@ -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, item_type = item.split('__')
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
 
@@ -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