openc3 6.8.1 → 6.9.1

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.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/bin/openc3cli +5 -5
  4. data/data/config/command_modifiers.yaml +9 -1
  5. data/data/config/screen.yaml +1 -1
  6. data/lib/openc3/accessors/json_accessor.rb +5 -5
  7. data/lib/openc3/api/interface_api.rb +71 -4
  8. data/lib/openc3/api/router_api.rb +98 -8
  9. data/lib/openc3/api/stash_api.rb +3 -3
  10. data/lib/openc3/api/tlm_api.rb +1 -1
  11. data/lib/openc3/bridge/bridge_config.rb +1 -1
  12. data/lib/openc3/interfaces/file_interface.rb +18 -0
  13. data/lib/openc3/interfaces/http_client_interface.rb +11 -0
  14. data/lib/openc3/interfaces/http_server_interface.rb +8 -0
  15. data/lib/openc3/interfaces/interface.rb +90 -21
  16. data/lib/openc3/interfaces/mqtt_interface.rb +19 -0
  17. data/lib/openc3/interfaces/mqtt_stream_interface.rb +20 -0
  18. data/lib/openc3/interfaces/protocols/burst_protocol.rb +16 -0
  19. data/lib/openc3/interfaces/protocols/cmd_response_protocol.rb +18 -0
  20. data/lib/openc3/interfaces/protocols/crc_protocol.rb +19 -0
  21. data/lib/openc3/interfaces/protocols/fixed_protocol.rb +17 -1
  22. data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +14 -0
  23. data/lib/openc3/interfaces/protocols/length_protocol.rb +25 -1
  24. data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +16 -3
  25. data/lib/openc3/interfaces/protocols/protocol.rb +79 -1
  26. data/lib/openc3/interfaces/protocols/slip_protocol.rb +23 -0
  27. data/lib/openc3/interfaces/protocols/template_protocol.rb +38 -0
  28. data/lib/openc3/interfaces/protocols/terminated_protocol.rb +14 -1
  29. data/lib/openc3/interfaces/serial_interface.rb +14 -0
  30. data/lib/openc3/interfaces/simulated_target_interface.rb +1 -1
  31. data/lib/openc3/interfaces/tcpip_client_interface.rb +16 -2
  32. data/lib/openc3/interfaces/tcpip_server_interface.rb +11 -1
  33. data/lib/openc3/interfaces/udp_interface.rb +14 -0
  34. data/lib/openc3/io/json_api_object.rb +1 -1
  35. data/lib/openc3/io/json_drb.rb +1 -1
  36. data/lib/openc3/io/json_drb_object.rb +1 -1
  37. data/lib/openc3/io/json_rpc.rb +5 -4
  38. data/lib/openc3/logs/packet_log_reader.rb +1 -1
  39. data/lib/openc3/logs/packet_log_writer.rb +6 -6
  40. data/lib/openc3/microservices/decom_microservice.rb +5 -1
  41. data/lib/openc3/microservices/interface_microservice.rb +103 -38
  42. data/lib/openc3/microservices/microservice.rb +4 -4
  43. data/lib/openc3/microservices/queue_microservice.rb +14 -21
  44. data/lib/openc3/microservices/reducer_microservice.rb +1 -1
  45. data/lib/openc3/microservices/router_microservice.rb +28 -25
  46. data/lib/openc3/models/activity_model.rb +18 -17
  47. data/lib/openc3/models/cvt_model.rb +12 -9
  48. data/lib/openc3/models/interface_model.rb +70 -12
  49. data/lib/openc3/models/metadata_model.rb +2 -2
  50. data/lib/openc3/models/microservice_model.rb +1 -1
  51. data/lib/openc3/models/microservice_status_model.rb +2 -2
  52. data/lib/openc3/models/model.rb +4 -4
  53. data/lib/openc3/models/note_model.rb +2 -2
  54. data/lib/openc3/models/plugin_model.rb +9 -4
  55. data/lib/openc3/models/queue_model.rb +25 -25
  56. data/lib/openc3/models/reaction_model.rb +6 -6
  57. data/lib/openc3/models/script_engine_model.rb +1 -1
  58. data/lib/openc3/models/script_status_model.rb +3 -3
  59. data/lib/openc3/models/sorted_model.rb +5 -5
  60. data/lib/openc3/models/target_model.rb +11 -11
  61. data/lib/openc3/models/timeline_model.rb +2 -2
  62. data/lib/openc3/models/tool_model.rb +1 -1
  63. data/lib/openc3/models/trigger_group_model.rb +3 -3
  64. data/lib/openc3/models/trigger_model.rb +6 -6
  65. data/lib/openc3/models/widget_model.rb +1 -1
  66. data/lib/openc3/operators/operator.rb +2 -2
  67. data/lib/openc3/packets/json_packet.rb +1 -1
  68. data/lib/openc3/packets/packet.rb +1 -1
  69. data/lib/openc3/script/calendar.rb +2 -2
  70. data/lib/openc3/script/metadata.rb +4 -4
  71. data/lib/openc3/script/queue.rb +13 -5
  72. data/lib/openc3/script/script_runner.rb +9 -9
  73. data/lib/openc3/script/storage.rb +1 -1
  74. data/lib/openc3/script/tables.rb +2 -2
  75. data/lib/openc3/script/web_socket_api.rb +7 -7
  76. data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +0 -12
  77. data/lib/openc3/tools/table_manager/table_manager_core.rb +1 -1
  78. data/lib/openc3/topics/command_decom_topic.rb +3 -3
  79. data/lib/openc3/topics/command_topic.rb +1 -1
  80. data/lib/openc3/topics/interface_topic.rb +45 -5
  81. data/lib/openc3/topics/limits_event_topic.rb +8 -8
  82. data/lib/openc3/topics/router_topic.rb +42 -3
  83. data/lib/openc3/topics/system_events_topic.rb +1 -1
  84. data/lib/openc3/topics/telemetry_decom_topic.rb +1 -1
  85. data/lib/openc3/utilities/authentication.rb +1 -1
  86. data/lib/openc3/utilities/cosmos_rails_formatter.rb +2 -3
  87. data/lib/openc3/utilities/local_mode.rb +8 -8
  88. data/lib/openc3/utilities/logger.rb +3 -3
  89. data/lib/openc3/utilities/running_script.rb +7 -8
  90. data/lib/openc3/version.rb +5 -5
  91. data/templates/plugin/README.md +3 -3
  92. data/templates/plugin/Rakefile +3 -3
  93. data/templates/plugin/plugin.gemspec +1 -0
  94. data/templates/tool_angular/.gitignore +1 -1
  95. data/templates/tool_angular/package.json +2 -48
  96. data/templates/tool_react/.gitignore +1 -2
  97. data/templates/tool_react/package.json +1 -51
  98. data/templates/tool_svelte/.gitignore +1 -2
  99. data/templates/tool_svelte/package.json +1 -49
  100. data/templates/tool_vue/package.json +3 -36
  101. data/templates/widget/Rakefile +1 -1
  102. data/templates/widget/package.json +2 -28
  103. metadata +9 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c5c9572654acef44ab63e67ad9a7b52aa251ea68ec7b71ab334ee808b11fc775
4
- data.tar.gz: 7e8d5cbe0502c419fe1302e248356ce353f2dfaad2137261c526a154c4d48d7a
3
+ metadata.gz: 83838350c2ec54b5fcd1b6108f42fe9d7f45fd24f6de04fb7c5c98855251b9b9
4
+ data.tar.gz: c1b89314a5af6f7740857228d01c0ab9e2b2e03e59c209b0e646fefb4f281425
5
5
  SHA512:
6
- metadata.gz: 10c253d0b643320ae6cb2cc5f435179a45aee18ba4fa232c058eb1517b417a1d379805c97db8ef0afebb4520694c30b7be6b6bed23cc05ec1bb7e9f6d190347c
7
- data.tar.gz: 54fb43c3cb643213da37343e0bbef903ea070574b168a6451832d3097682c0ab6ae9371b6afc7a5f7d61a474b773cd0c787b0aceeca3a768fbfe6676f4da1e6f
6
+ metadata.gz: 35be666ae0ea4d134fa6c7d54d79ee323e5d878918c25706d17514b1db8b28b6ca05c6c0f175426f285227e6fd16d6b90ccbf21316c71057aaaf958660a7c8a7
7
+ data.tar.gz: 3c0f703c797d6fbd1be90d526a91ac94a06ec6d9ad042e3ea1212da4c73557be6e4634be73ca49f17c8277f7b7052154e0283b0a994f84f91cf96422811155ac
data/Gemfile CHANGED
@@ -6,7 +6,7 @@ gemspec :name => 'openc3'
6
6
 
7
7
  # Include the rails gems for the convenience of custom microservice plugins
8
8
  gem 'bootsnap', '>= 1.9.3', require: false
9
- gem 'rack-cors', '~> 2.0'
9
+ gem 'rack-cors', '~> 3.0'
10
10
  gem 'rails', '~> 7.2.0'
11
11
  gem 'tzinfo-data'
12
12
  gem 'ruby-termios', '>= 1.0'
data/bin/openc3cli CHANGED
@@ -152,7 +152,7 @@ def xtce_converter(args)
152
152
  elsif options[:plugin] && options[:output]
153
153
  begin
154
154
  variables = nil
155
- variables = JSON.parse(File.read(options[:variables]), :allow_nan => true, :create_additions => true) if options[:variables]
155
+ variables = JSON.parse(File.read(options[:variables]), allow_nan: true, create_additions: true) if options[:variables]
156
156
  puts "Installing #{File.basename(options[:plugin])}"
157
157
  plugin_hash = OpenC3::PluginModel.install_phase1(options[:plugin], existing_variables: variables, scope: 'DEFAULT', validate_only: true)
158
158
  plugin_hash['variables']['xtce_output'] = options[:output]
@@ -204,7 +204,7 @@ def validate_plugin(plugin_file_path, scope:, variables_file: nil)
204
204
  OpenC3::Logger.level = OpenC3::Logger::DEBUG
205
205
  scope ||= 'DEFAULT'
206
206
  variables = nil
207
- variables = JSON.parse(File.read(variables_file), :allow_nan => true, :create_additions => true) if variables_file
207
+ variables = JSON.parse(File.read(variables_file), allow_nan: true, create_additions: true) if variables_file
208
208
  puts "Installing #{File.basename(plugin_file_path)}"
209
209
  plugin_hash = OpenC3::PluginModel.install_phase1(plugin_file_path, existing_variables: variables, scope: scope, validate_only: true)
210
210
  OpenC3::PluginModel.install_phase2(plugin_hash, scope: scope, validate_only: true,
@@ -358,7 +358,7 @@ def load_plugin(plugin_file_path, scope:, plugin_hash_file: nil, force: false, v
358
358
  if plugin_hash_file
359
359
  # Admin Create / Edit / or Upgrade Plugin
360
360
  OpenC3::PluginModel.install_phase1(plugin_file_path, existing_variables: existing_variables, scope: scope)
361
- plugin_hash = JSON.parse(File.read(plugin_hash_file), :allow_nan => true, :create_additions => true)
361
+ plugin_hash = JSON.parse(File.read(plugin_hash_file), allow_nan: true, create_additions: true)
362
362
  else
363
363
  # Init or Command Line openc3cli load with no plugin_hash_file
364
364
  file_full_name = File.basename(plugin_file_path, ".gem")
@@ -415,7 +415,7 @@ def load_plugin(plugin_file_path, scope:, plugin_hash_file: nil, force: false, v
415
415
  # Outside Cluster
416
416
  require 'openc3/script'
417
417
  if plugin_hash_file
418
- plugin_hash = JSON.parse(File.read(plugin_hash_file), :allow_nan => true, :create_additions => true)
418
+ plugin_hash = JSON.parse(File.read(plugin_hash_file), allow_nan: true, create_additions: true)
419
419
  else
420
420
  plugin_hash = plugin_install_phase1(plugin_file_path, scope: scope)
421
421
  end
@@ -983,7 +983,7 @@ if not ARGV[0].nil? # argument(s) given
983
983
  get_redis_keys()
984
984
  when 'hget'
985
985
  redis = Redis.new(url: $redis_url, username: ENV['OPENC3_REDIS_USERNAME'], password: ENV['OPENC3_REDIS_PASSWORD'])
986
- puts JSON.parse(redis.hget(ARGV[2], ARGV[3]), :allow_nan => true, :create_additions => true)
986
+ puts JSON.parse(redis.hget(ARGV[2], ARGV[3]), allow_nan: true, create_additions: true)
987
987
  else
988
988
  puts "Unknown redis task: #{ARGV[1]}\n"
989
989
  puts "Valid redis tasks: keys, hget"
@@ -289,16 +289,20 @@ VALIDATOR:
289
289
  return [false, "TGT PKT ITEM is 0"]
290
290
  end
291
291
  @cmd_acpt_cnt = tlm("TGT PKT CMD_ACPT_CNT")
292
+ # Return true to indicate Success, false to indicate Failure,
293
+ # and nil to indicate Unknown. The second value is the optional message.
292
294
  return [true, nil]
293
295
  end
294
296
  def post_check(packet)
295
297
  wait_check("TGT PKT CMD_ACPT_CNT > #{@cmd_acpt_cnt}", 10)
298
+ # Return true to indicate Success, false to indicate Failure,
299
+ # and nil to indicate Unknown. The second value is the optional message.
296
300
  return [true, nil]
297
301
  end
298
302
  end
299
303
 
300
304
  python_example: |
301
- VALIDATOR custom_validator.rb
305
+ VALIDATOR custom_validator.py
302
306
 
303
307
  Defined in custom_validator.py:
304
308
 
@@ -313,9 +317,13 @@ VALIDATOR:
313
317
  if tlm("TGT PKT ITEM") == 0:
314
318
  return [False, "TGT PKT ITEM is 0"]
315
319
  self.cmd_acpt_cnt = tlm("INST HEALTH_STATUS CMD_ACPT_CNT")
320
+ # Return true to indicate Success, false to indicate Failure,
321
+ # and nil to indicate Unknown. The second value is the optional message.
316
322
  return [True, None]
317
323
 
318
324
  def post_check(self, command):
319
325
  wait_check(f"INST HEALTH_STATUS CMD_ACPT_CNT > {self.cmd_acpt_cnt}", 10)
326
+ # Return true to indicate Success, false to indicate Failure,
327
+ # and nil to indicate Unknown. The second value is the optional message.
320
328
  return [True, None]
321
329
  since: 5.19.0
@@ -19,7 +19,7 @@ SCREEN:
19
19
  description: Number of seconds between screen updates
20
20
  values: '[0-9]*\.?[0-9]+'
21
21
  example: |
22
- SCREEN AUTO AUTO 1.0 FIXED
22
+ SCREEN AUTO AUTO 1.0
23
23
  END:
24
24
  summary: Indicates the close of a layout widget
25
25
  description: All layout widgets must be closed to properly identify where they
@@ -43,7 +43,7 @@ module OpenC3
43
43
 
44
44
  # Convert to ruby objects
45
45
  if String === buffer
46
- decoded = JSON.parse(buffer, :allow_nan => true, :create_additions => true)
46
+ decoded = JSON.parse(buffer, allow_nan: true, create_additions: true)
47
47
  else
48
48
  decoded = buffer
49
49
  end
@@ -53,7 +53,7 @@ module OpenC3
53
53
 
54
54
  # Update buffer
55
55
  if String === buffer
56
- buffer.replace(JSON.generate(decoded.as_json, :allow_nan => true))
56
+ buffer.replace(JSON.generate(decoded.as_json, allow_nan: true))
57
57
  end
58
58
 
59
59
  return value
@@ -62,7 +62,7 @@ module OpenC3
62
62
  def self.read_items(items, buffer)
63
63
  # Prevent JsonPath from decoding every call
64
64
  if String === buffer
65
- decoded = JSON.parse(buffer, :allow_nan => true, :create_additions => true)
65
+ decoded = JSON.parse(buffer, allow_nan: true, create_additions: true)
66
66
  else
67
67
  decoded = buffer
68
68
  end
@@ -75,7 +75,7 @@ module OpenC3
75
75
 
76
76
  # Convert to ruby objects
77
77
  if String === buffer
78
- decoded = JSON.parse(buffer, :allow_nan => true)
78
+ decoded = JSON.parse(buffer, allow_nan: true)
79
79
  else
80
80
  decoded = buffer
81
81
  end
@@ -86,7 +86,7 @@ module OpenC3
86
86
 
87
87
  # Update buffer
88
88
  if String === buffer
89
- buffer.replace(JSON.generate(decoded, :allow_nan => true))
89
+ buffer.replace(JSON.generate(decoded, allow_nan: true))
90
90
  end
91
91
 
92
92
  return values
@@ -14,7 +14,7 @@
14
14
  # GNU Affero General Public License for more details.
15
15
 
16
16
  # Modified by OpenC3, Inc.
17
- # All changes Copyright 2022, OpenC3, Inc.
17
+ # All changes Copyright 2025, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
20
  # This file may also be used under the terms of a commercial license
@@ -36,8 +36,12 @@ module OpenC3
36
36
  'stop_raw_logging_interface',
37
37
  'get_all_interface_info',
38
38
  'map_target_to_interface',
39
+ 'unmap_target_from_interface',
39
40
  'interface_cmd',
40
- 'interface_protocol_cmd'
41
+ 'interface_protocol_cmd',
42
+ 'interface_target_enable',
43
+ 'interface_target_disable',
44
+ 'interface_details'
41
45
  ])
42
46
 
43
47
  # Get information about an interface
@@ -138,19 +142,43 @@ module OpenC3
138
142
  def map_target_to_interface(target_name, interface_name, cmd_only: false, tlm_only: false, unmap_old: true, manual: false, scope: $openc3_scope, token: $openc3_token)
139
143
  # TODO: Check if they have command authority for the targets mapped to this interface
140
144
  authorize(permission: 'system_set', interface_name: interface_name, manual: manual, scope: scope, token: token)
141
- new_interface = InterfaceModel.get_model(name: interface_name, scope: scope)
145
+ interface = InterfaceModel.get_model(name: interface_name, scope: scope)
142
146
  if Array === target_name
143
147
  target_names = target_name
144
148
  else
145
149
  target_names = [target_name]
146
150
  end
147
151
  target_names.each do |name|
148
- new_interface.map_target(name, cmd_only: cmd_only, tlm_only: tlm_only, unmap_old: unmap_old)
152
+ interface.map_target(name, cmd_only: cmd_only, tlm_only: tlm_only, unmap_old: unmap_old)
149
153
  Logger.info("Target #{name} mapped to Interface #{interface_name}", scope: scope)
150
154
  end
151
155
  nil
152
156
  end
153
157
 
158
+ # Removes association of a target and all its commands and telemetry with a particular
159
+ # interface. No commands will go out over and no telemetry be received
160
+ # from that interface for the target.
161
+ #
162
+ # @param target_name [String/Array] The name of the target(s)
163
+ # @param interface_name (see #connect_interface)
164
+ def unmap_target_from_interface(target_name, interface_name, cmd_only: false, tlm_only: false, manual: false, scope: $openc3_scope, token: $openc3_token)
165
+ # TODO: Check if they have command authority for the targets mapped to this interface
166
+ authorize(permission: 'system_set', interface_name: interface_name, manual: manual, scope: scope, token: token)
167
+ interface = InterfaceModel.get_model(name: interface_name, scope: scope)
168
+ raise "Interface '#{interface_name}' does not exist" unless interface
169
+
170
+ if Array === target_name
171
+ target_names = target_name
172
+ else
173
+ target_names = [target_name]
174
+ end
175
+ target_names.each do |name|
176
+ interface.unmap_target(name, cmd_only: cmd_only, tlm_only: tlm_only)
177
+ Logger.info("Target #{name} unmapped from Interface #{interface_name}", scope: scope)
178
+ end
179
+ nil
180
+ end
181
+
154
182
  def interface_cmd(interface_name, cmd_name, *cmd_params, manual: false, scope: $openc3_scope, token: $openc3_token)
155
183
  # TODO: Check if they have command authority for the targets mapped to this interface
156
184
  authorize(permission: 'system_set', interface_name: interface_name, manual: manual, scope: scope, token: token)
@@ -162,5 +190,44 @@ module OpenC3
162
190
  authorize(permission: 'system_set', interface_name: interface_name, manual: manual, scope: scope, token: token)
163
191
  InterfaceTopic.protocol_cmd(interface_name, cmd_name, *cmd_params, read_write: read_write, index: index, scope: scope)
164
192
  end
193
+
194
+ def interface_target_enable(interface_name, target_name, cmd_only: false, tlm_only: false, manual: false, scope: $openc3_scope, token: $openc3_token)
195
+ authorize(permission: 'system_set', interface_name: interface_name, manual: manual, scope: scope, token: token)
196
+ interface = InterfaceModel.get_model(name: interface_name, scope: scope)
197
+ if cmd_only and tlm_only
198
+ cmd_only = false
199
+ tlm_only = false
200
+ end
201
+ if not tlm_only
202
+ interface.cmd_target_enabled[target_name.upcase] = true
203
+ end
204
+ if not cmd_only
205
+ interface.tlm_target_enabled[target_name.upcase] = true
206
+ end
207
+ interface.update
208
+ InterfaceTopic.interface_target_enable(interface_name, target_name, cmd_only: cmd_only, tlm_only: tlm_only, scope: scope)
209
+ end
210
+
211
+ def interface_target_disable(interface_name, target_name, cmd_only: false, tlm_only: false, manual: false, scope: $openc3_scope, token: $openc3_token)
212
+ authorize(permission: 'system_set', interface_name: interface_name, manual: manual, scope: scope, token: token)
213
+ interface = InterfaceModel.get_model(name: interface_name, scope: scope)
214
+ if cmd_only and tlm_only
215
+ cmd_only = false
216
+ tlm_only = false
217
+ end
218
+ if not tlm_only
219
+ interface.cmd_target_enabled[target_name.upcase] = false
220
+ end
221
+ if not cmd_only
222
+ interface.tlm_target_enabled[target_name.upcase] = false
223
+ end
224
+ interface.update
225
+ InterfaceTopic.interface_target_disable(interface_name, target_name, cmd_only: cmd_only, tlm_only: tlm_only, scope: scope)
226
+ end
227
+
228
+ def interface_details(interface_name, manual: false, scope: $openc3_scope, token: $openc3_token)
229
+ authorize(permission: 'system', interface_name: interface_name, manual: manual, scope: scope, token: token)
230
+ InterfaceTopic.interface_details(interface_name, scope: scope)
231
+ end
165
232
  end
166
233
  end
@@ -14,7 +14,7 @@
14
14
  # GNU Affero General Public License for more details.
15
15
 
16
16
  # Modified by OpenC3, Inc.
17
- # All changes Copyright 2022, OpenC3, Inc.
17
+ # All changes Copyright 2025, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
20
  # This file may also be used under the terms of a commercial license
@@ -36,7 +36,12 @@ module OpenC3
36
36
  'stop_raw_logging_router',
37
37
  'get_all_router_info',
38
38
  'router_cmd',
39
- 'router_protocol_cmd'
39
+ 'router_protocol_cmd',
40
+ 'map_target_to_router',
41
+ 'unmap_target_from_router',
42
+ 'router_target_enable',
43
+ 'router_target_disable',
44
+ 'router_details'
40
45
  ])
41
46
 
42
47
  # Get information about a router
@@ -62,7 +67,7 @@ module OpenC3
62
67
  # @param router_name [String] Name of router
63
68
  # @param router_params [Array] Optional parameters to pass to the router
64
69
  def connect_router(router_name, *router_params, manual: false, scope: $openc3_scope, token: $openc3_token)
65
- # TODO: Check if they have command authority for the targets mapped to this interface
70
+ # TODO: Check if they have command authority for the targets mapped to this router
66
71
  authorize(permission: 'system_set', router_name: router_name, manual: manual, scope: scope, token: token)
67
72
  RouterTopic.connect_router(router_name, *router_params, scope: scope)
68
73
  end
@@ -71,7 +76,7 @@ module OpenC3
71
76
  #
72
77
  # @param router_name [String] Name of router
73
78
  def disconnect_router(router_name, manual: false, scope: $openc3_scope, token: $openc3_token)
74
- # TODO: Check if they have command authority for the targets mapped to this interface
79
+ # TODO: Check if they have command authority for the targets mapped to this router
75
80
  authorize(permission: 'system_set', router_name: router_name, manual: manual, scope: scope, token: token)
76
81
  RouterTopic.disconnect_router(router_name, scope: scope)
77
82
  end
@@ -80,7 +85,7 @@ module OpenC3
80
85
  #
81
86
  # @param router_name [String] The name of the router
82
87
  def start_raw_logging_router(router_name = 'ALL', manual: false, scope: $openc3_scope, token: $openc3_token)
83
- # TODO: Check if they have command authority for the targets mapped to this interface
88
+ # TODO: Check if they have command authority for the targets mapped to this router
84
89
  authorize(permission: 'system_set', router_name: router_name, manual: manual, scope: scope, token: token)
85
90
  if router_name == 'ALL'
86
91
  get_router_names().each do |router_name|
@@ -95,7 +100,7 @@ module OpenC3
95
100
  #
96
101
  # @param router_name [String] The name of the router
97
102
  def stop_raw_logging_router(router_name = 'ALL', manual: false, scope: $openc3_scope, token: $openc3_token)
98
- # TODO: Check if they have command authority for the targets mapped to this interface
103
+ # TODO: Check if they have command authority for the targets mapped to this router
99
104
  authorize(permission: 'system_set', router_name: router_name, manual: manual, scope: scope, token: token)
100
105
  if router_name == 'ALL'
101
106
  get_router_names().each do |router_name|
@@ -124,15 +129,100 @@ module OpenC3
124
129
  end
125
130
 
126
131
  def router_cmd(router_name, cmd_name, *cmd_params, manual: false, scope: $openc3_scope, token: $openc3_token)
127
- # TODO: Check if they have command authority for the targets mapped to this interface
132
+ # TODO: Check if they have command authority for the targets mapped to this router
128
133
  authorize(permission: 'system_set', router_name: router_name, manual: manual, scope: scope, token: token)
129
134
  RouterTopic.router_cmd(router_name, cmd_name, *cmd_params, scope: scope)
130
135
  end
131
136
 
132
137
  def router_protocol_cmd(router_name, cmd_name, *cmd_params, read_write: :READ_WRITE, index: -1, manual: false, scope: $openc3_scope, token: $openc3_token)
133
- # TODO: Check if they have command authority for the targets mapped to this interface
138
+ # TODO: Check if they have command authority for the targets mapped to this router
134
139
  authorize(permission: 'system_set', router_name: router_name, manual: manual, scope: scope, token: token)
135
140
  RouterTopic.protocol_cmd(router_name, cmd_name, *cmd_params, read_write: read_write, index: index, scope: scope)
136
141
  end
142
+
143
+ # Associates a target and all its commands and telemetry with a particular
144
+ # router.
145
+ #
146
+ # @param target_name [String/Array] The name of the target(s)
147
+ # @param router_name (see #connect_router)
148
+ def map_target_to_router(target_name, router_name, cmd_only: false, tlm_only: false, unmap_old: true, manual: false, scope: $openc3_scope, token: $openc3_token)
149
+ # TODO: Check if they have command authority for the targets mapped to this router
150
+ authorize(permission: 'system_set', router_name: router_name, manual: manual, scope: scope, token: token)
151
+ router = RouterModel.get_model(name: router_name, scope: scope)
152
+ raise "Router '#{router_name}' does not exist" unless router
153
+
154
+ if Array === target_name
155
+ target_names = target_name
156
+ else
157
+ target_names = [target_name]
158
+ end
159
+ target_names.each do |name|
160
+ router.map_target(name, cmd_only: cmd_only, tlm_only: tlm_only, unmap_old: unmap_old)
161
+ Logger.info("Target #{name} mapped to Router #{router_name}", scope: scope)
162
+ end
163
+ nil
164
+ end
165
+
166
+ # Removes association of a target and all its commands and telemetry with a particular
167
+ # router.
168
+ #
169
+ # @param target_name [String/Array] The name of the target(s)
170
+ # @param router_name (see #connect_router)
171
+ def unmap_target_from_router(target_name, router_name, cmd_only: false, tlm_only: false, manual: false, scope: $openc3_scope, token: $openc3_token)
172
+ # TODO: Check if they have command authority for the targets mapped to this router
173
+ authorize(permission: 'system_set', router_name: router_name, manual: manual, scope: scope, token: token)
174
+ router = RouterModel.get_model(name: router_name, scope: scope)
175
+ raise "Router '#{router_name}' does not exist" unless router
176
+
177
+ if Array === target_name
178
+ target_names = target_name
179
+ else
180
+ target_names = [target_name]
181
+ end
182
+ target_names.each do |name|
183
+ router.unmap_target(name, cmd_only: cmd_only, tlm_only: tlm_only)
184
+ Logger.info("Target #{name} unmapped from Router #{router_name}", scope: scope)
185
+ end
186
+ nil
187
+ end
188
+
189
+ def router_target_enable(router_name, target_name, cmd_only: false, tlm_only: false, manual: false, scope: $openc3_scope, token: $openc3_token)
190
+ authorize(permission: 'system_set', router_name: router_name, manual: manual, scope: scope, token: token)
191
+ router = RouterModel.get_model(name: router_name, scope: scope)
192
+ if cmd_only and tlm_only
193
+ cmd_only = false
194
+ tlm_only = false
195
+ end
196
+ if not tlm_only
197
+ router.cmd_target_enabled[target_name.upcase] = true
198
+ end
199
+ if not cmd_only
200
+ router.tlm_target_enabled[target_name.upcase] = true
201
+ end
202
+ router.update
203
+ RouterTopic.router_target_enable(router_name, target_name, cmd_only: cmd_only, tlm_only: tlm_only, scope: scope)
204
+ end
205
+
206
+ def router_target_disable(router_name, target_name, cmd_only: false, tlm_only: false, manual: false, scope: $openc3_scope, token: $openc3_token)
207
+ authorize(permission: 'system_set', router_name: router_name, manual: manual, scope: scope, token: token)
208
+ router = RouterModel.get_model(name: router_name, scope: scope)
209
+ if cmd_only and tlm_only
210
+ cmd_only = false
211
+ tlm_only = false
212
+ end
213
+ if not tlm_only
214
+ router.cmd_target_enabled[target_name.upcase] = false
215
+ end
216
+ if not cmd_only
217
+ router.tlm_target_enabled[target_name.upcase] = false
218
+ end
219
+ router.update
220
+ RouterTopic.router_target_disable(router_name, target_name, cmd_only: cmd_only, tlm_only: tlm_only, scope: scope)
221
+ end
222
+
223
+ def router_details(router_name, manual: false, scope: $openc3_scope, token: $openc3_token)
224
+ authorize(permission: 'system', router_name: router_name, manual: manual, scope: scope, token: token)
225
+ RouterTopic.router_details(router_name, scope: scope)
226
+ end
137
227
  end
138
228
  end
@@ -31,14 +31,14 @@ module OpenC3
31
31
 
32
32
  def stash_set(key, value, manual: false, scope: $openc3_scope, token: $openc3_token)
33
33
  authorize(permission: 'script_run', manual: manual, scope: scope, token: token)
34
- StashModel.set( {name: key, value: JSON.generate(value.as_json(:allow_nan => true)) }, scope: scope)
34
+ StashModel.set( {name: key, value: JSON.generate(value.as_json, allow_nan: true) }, scope: scope)
35
35
  end
36
36
 
37
37
  def stash_get(key, manual: false, scope: $openc3_scope, token: $openc3_token)
38
38
  authorize(permission: 'script_view', manual: manual, scope: scope, token: token)
39
39
  result = StashModel.get(name: key, scope: scope)
40
40
  if result
41
- JSON.parse(result['value'], :allow_nan => true, :create_additions => true)
41
+ JSON.parse(result['value'], allow_nan: true, create_additions: true)
42
42
  else
43
43
  nil
44
44
  end
@@ -46,7 +46,7 @@ module OpenC3
46
46
 
47
47
  def stash_all(manual: false, scope: $openc3_scope, token: $openc3_token)
48
48
  authorize(permission: 'script_view', manual: manual, scope: scope, token: token)
49
- StashModel.all(scope: scope).transform_values { |hash| JSON.parse(hash["value"], :allow_nan => true, :create_additions => true) }
49
+ StashModel.all(scope: scope).transform_values { |hash| JSON.parse(hash["value"], allow_nan: true, create_additions: true) }
50
50
  end
51
51
 
52
52
  def stash_keys(manual: false, scope: $openc3_scope, token: $openc3_token)
@@ -486,7 +486,7 @@ module OpenC3
486
486
  xread.each do |topic, data|
487
487
  data.each do |id, msg_hash|
488
488
  lookup[topic] = id # save the new ID
489
- json_hash = JSON.parse(msg_hash['json_data'], :allow_nan => true, :create_additions => true)
489
+ json_hash = JSON.parse(msg_hash['json_data'], allow_nan: true, create_additions: true)
490
490
  msg_hash.delete('json_data')
491
491
  packets << msg_hash.merge(json_hash)
492
492
  end
@@ -153,7 +153,7 @@ module OpenC3
153
153
  current_interface_or_router.reconnect_delay = Float(params[0])
154
154
 
155
155
  when 'LOG_STREAM', 'LOG_RAW'
156
- parser.verify_num_parameters(0, nil, "#{keyword} <Log Stream Class File (optional)> <Log Stream Parameters (optional)>")
156
+ parser.verify_num_parameters(0, nil, "#{keyword} <Log Stream Parameters (optional)>")
157
157
  current_interface_or_router.stream_log_pair = StreamLogPair.new(current_interface_or_router.name, params)
158
158
  current_interface_or_router.start_raw_logging
159
159
 
@@ -222,5 +222,23 @@ module OpenC3
222
222
  end
223
223
  end
224
224
  end
225
+
226
+ def details
227
+ result = super()
228
+ result['command_write_folder'] = @command_write_folder
229
+ result['telemetry_read_folder'] = @telemetry_read_folder
230
+ result['telemetry_archive_folder'] = @telemetry_archive_folder
231
+ result['file_read_size'] = @file_read_size
232
+ result['stored'] = @stored
233
+ result['filename'] = @filename
234
+ result['extension'] = @extension
235
+ result['label'] = @label
236
+ result['queue_length'] = @queue.length
237
+ result['polling'] = @polling
238
+ result['recursive'] = @recursive
239
+ result['throttle'] = @throttle
240
+ result['discard_file_header_bytes'] = @discard_file_header_bytes
241
+ return result
242
+ end
225
243
  end
226
244
  end
@@ -234,5 +234,16 @@ module OpenC3
234
234
  packet.extra = extra
235
235
  return packet
236
236
  end
237
+
238
+ def details
239
+ result = super()
240
+ result['url'] = @url
241
+ result['write_timeout'] = @write_timeout
242
+ result['read_timeout'] = @read_timeout
243
+ result['connect_timeout'] = @connect_timeout
244
+ result['include_request_in_response'] = @include_request_in_response
245
+ result['request_queue_length'] = @request_queue.length
246
+ return result
247
+ end
237
248
  end
238
249
  end
@@ -188,5 +188,13 @@ module OpenC3
188
188
  def convert_packet_to_data(_packet)
189
189
  raise "Commands cannot be sent to HttpServerInterface"
190
190
  end
191
+
192
+ def details
193
+ result = super()
194
+ result['listen_address'] = @listen_address
195
+ result['port'] = @port
196
+ result['request_queue_length'] = @request_queue.length
197
+ return result
198
+ end
191
199
  end
192
200
  end