openc3 5.1.1 → 5.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/bin/openc3cli +48 -9
  3. data/data/config/interface_modifiers.yaml +14 -0
  4. data/data/config/parameter_modifiers.yaml +5 -3
  5. data/data/config/screen.yaml +12 -8
  6. data/data/config/target.yaml +33 -0
  7. data/ext/openc3/ext/config_parser/config_parser.c +66 -63
  8. data/ext/openc3/ext/packet/packet.c +1 -4
  9. data/lib/openc3/api/README.md +5 -0
  10. data/lib/openc3/api/api.rb +3 -1
  11. data/lib/openc3/api/cmd_api.rb +43 -112
  12. data/lib/openc3/api/interface_api.rb +3 -3
  13. data/lib/openc3/api/offline_access_api.rb +78 -0
  14. data/lib/openc3/api/settings_api.rb +3 -1
  15. data/lib/openc3/api/stash_api.rb +63 -0
  16. data/lib/openc3/api/target_api.rb +4 -5
  17. data/lib/openc3/config/config_parser.rb +47 -47
  18. data/lib/openc3/interfaces/interface.rb +11 -1
  19. data/lib/openc3/interfaces/protocols/burst_protocol.rb +30 -16
  20. data/lib/openc3/interfaces/protocols/fixed_protocol.rb +8 -2
  21. data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +2 -2
  22. data/lib/openc3/interfaces/protocols/override_protocol.rb +2 -2
  23. data/lib/openc3/interfaces/tcpip_server_interface.rb +3 -1
  24. data/lib/openc3/io/json_api_object.rb +30 -9
  25. data/lib/openc3/io/json_drb.rb +6 -1
  26. data/lib/openc3/io/json_drb_object.rb +18 -9
  27. data/lib/openc3/io/json_rpc.rb +5 -3
  28. data/lib/openc3/logs/buffered_packet_log_writer.rb +1 -1
  29. data/lib/openc3/logs/log_writer.rb +8 -2
  30. data/lib/openc3/microservices/cleanup_microservice.rb +3 -3
  31. data/lib/openc3/microservices/decom_microservice.rb +8 -8
  32. data/lib/openc3/microservices/interface_microservice.rb +86 -71
  33. data/lib/openc3/microservices/log_microservice.rb +5 -3
  34. data/lib/openc3/microservices/microservice.rb +18 -14
  35. data/lib/openc3/microservices/multi_microservice.rb +62 -0
  36. data/lib/openc3/microservices/periodic_microservice.rb +58 -0
  37. data/lib/openc3/microservices/reaction_microservice.rb +61 -47
  38. data/lib/openc3/microservices/reducer_microservice.rb +64 -40
  39. data/lib/openc3/microservices/router_microservice.rb +4 -4
  40. data/lib/openc3/microservices/text_log_microservice.rb +2 -2
  41. data/lib/openc3/microservices/timeline_microservice.rb +44 -30
  42. data/lib/openc3/microservices/trigger_group_microservice.rb +39 -36
  43. data/lib/openc3/migrations/20221202214600_add_target_names.rb +30 -0
  44. data/lib/openc3/migrations/20221210174900_convert_to_multi.rb +65 -0
  45. data/lib/openc3/models/cvt_model.rb +1 -1
  46. data/lib/openc3/models/gem_model.rb +24 -20
  47. data/lib/openc3/models/interface_model.rb +69 -35
  48. data/lib/openc3/models/metadata_model.rb +1 -1
  49. data/lib/openc3/models/microservice_model.rb +7 -24
  50. data/lib/openc3/models/migration_model.rb +52 -0
  51. data/lib/openc3/models/model.rb +2 -7
  52. data/lib/openc3/models/note_model.rb +1 -1
  53. data/lib/openc3/models/offline_access_model.rb +55 -0
  54. data/lib/openc3/models/plugin_model.rb +12 -3
  55. data/lib/openc3/models/reaction_model.rb +6 -2
  56. data/lib/openc3/models/scope_model.rb +89 -13
  57. data/lib/openc3/models/settings_model.rb +1 -1
  58. data/lib/openc3/models/stash_model.rb +53 -0
  59. data/lib/openc3/models/target_model.rb +301 -130
  60. data/lib/openc3/models/tool_model.rb +1 -12
  61. data/lib/openc3/models/widget_model.rb +1 -6
  62. data/lib/openc3/operators/microservice_operator.rb +45 -6
  63. data/lib/openc3/operators/operator.rb +27 -5
  64. data/lib/openc3/packets/commands.rb +1 -25
  65. data/lib/openc3/packets/limits.rb +0 -75
  66. data/lib/openc3/packets/packet.rb +0 -28
  67. data/lib/openc3/packets/packet_item.rb +23 -0
  68. data/lib/openc3/packets/packet_item_limits.rb +2 -2
  69. data/lib/openc3/packets/parsers/state_parser.rb +10 -6
  70. data/lib/openc3/packets/telemetry.rb +1 -45
  71. data/lib/openc3/script/commands.rb +41 -71
  72. data/lib/openc3/script/extract.rb +15 -1
  73. data/lib/openc3/script/{calendar.rb → metadata.rb} +42 -17
  74. data/lib/openc3/script/script.rb +13 -5
  75. data/lib/openc3/script/storage.rb +3 -1
  76. data/lib/openc3/system/system.rb +19 -17
  77. data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +4 -4
  78. data/lib/openc3/top_level.rb +3 -3
  79. data/lib/openc3/topics/command_decom_topic.rb +2 -2
  80. data/lib/openc3/topics/command_topic.rb +7 -6
  81. data/lib/openc3/topics/interface_topic.rb +2 -2
  82. data/lib/openc3/topics/router_topic.rb +1 -1
  83. data/lib/openc3/topics/telemetry_topic.rb +2 -1
  84. data/lib/openc3/utilities/authentication.rb +35 -14
  85. data/lib/openc3/utilities/aws_bucket.rb +4 -3
  86. data/lib/openc3/utilities/bucket.rb +4 -2
  87. data/lib/openc3/utilities/bucket_file_cache.rb +3 -8
  88. data/lib/openc3/utilities/bucket_utilities.rb +77 -15
  89. data/lib/openc3/utilities/local_mode.rb +12 -9
  90. data/lib/openc3/utilities/logger.rb +17 -9
  91. data/lib/openc3/utilities/message_log.rb +6 -5
  92. data/lib/openc3/utilities/migration.rb +22 -0
  93. data/lib/openc3/utilities/store_autoload.rb +7 -5
  94. data/lib/openc3/utilities/target_file.rb +9 -7
  95. data/lib/openc3/version.rb +6 -6
  96. data/lib/openc3.rb +2 -1
  97. metadata +14 -3
@@ -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/packets/packet'
@@ -30,8 +30,7 @@ module OpenC3
30
30
  private
31
31
 
32
32
  # Format the command like it appears in a script
33
- # TODO: Make this output alternative syntax if any binary data
34
- def _cmd_string(target_name, cmd_name, cmd_params, raw, scope: $openc3_scope)
33
+ def _cmd_string(target_name, cmd_name, cmd_params, raw)
35
34
  output_string = $disconnect ? 'DISCONNECT: ' : ''
36
35
  if raw
37
36
  output_string += 'cmd_raw("'
@@ -68,7 +67,7 @@ module OpenC3
68
67
 
69
68
  # Log any warnings about disabling checks and log the command itself
70
69
  # NOTE: This is a helper method and should not be called directly
71
- def _log_cmd(target_name, cmd_name, cmd_params, raw, no_range, no_hazardous, scope: $openc3_scope)
70
+ def _log_cmd(target_name, cmd_name, cmd_params, raw, no_range, no_hazardous)
72
71
  if no_range
73
72
  Logger.warn "Command #{target_name} #{cmd_name} being sent ignoring range checks"
74
73
  end
@@ -94,6 +93,7 @@ module OpenC3
94
93
  # Invalid number of arguments
95
94
  raise "ERROR: Invalid number of arguments (#{args.length}) passed to #{cmd}()"
96
95
  end
96
+
97
97
  # Get the command and validate the parameters
98
98
  command = $api_server.get_command(target_name, cmd_name, scope: scope)
99
99
  cmd_params.each do |param_name, param_value|
@@ -106,16 +106,10 @@ module OpenC3
106
106
  end
107
107
 
108
108
  # Send the command and log the results
109
+ # This method signature has to include the keyword params present in cmd_api.rb cmd_implementation()
109
110
  # NOTE: This is a helper method and should not be called directly
110
- def _cmd(cmd, cmd_no_hazardous, *args, **kw_args)
111
- if kw_args[:scope]
112
- scope = kw_args[:scope]
113
- kw_args.delete(:scope)
114
- else
115
- scope = $openc3_scope
116
- end
117
- args << kw_args if kw_args.length > 0
118
-
111
+ def _cmd(cmd, cmd_no_hazardous, *args, scope: $openc3_scope, token: $openc3_token, timeout: nil, **kwargs)
112
+ extract_string_kwargs_to_args(args, kwargs)
119
113
  raw = cmd.include?('raw')
120
114
  no_range = cmd.include?('no_range') || cmd.include?('no_checks')
121
115
  no_hazardous = cmd.include?('no_hazardous') || cmd.include?('no_checks')
@@ -124,88 +118,64 @@ module OpenC3
124
118
  _cmd_disconnect(cmd, raw, no_range, no_hazardous, *args, scope: scope)
125
119
  else
126
120
  begin
127
- target_name, cmd_name, cmd_params = $api_server.method_missing(cmd, *args, scope: scope)
128
- _log_cmd(target_name, cmd_name, cmd_params, raw, no_range, no_hazardous, scope: scope)
121
+ target_name, cmd_name, cmd_params = $api_server.method_missing(cmd, *args, scope: scope, token: token, timeout: timeout)
122
+ _log_cmd(target_name, cmd_name, cmd_params, raw, no_range, no_hazardous)
129
123
  rescue HazardousError => e
130
124
  # This opens a prompt at which point they can cancel and stop the script
131
125
  # or say Yes and send the command. Thus we don't care about the return value.
132
126
  prompt_for_hazardous(e.target_name, e.cmd_name, e.hazardous_description)
133
- target_name, cmd_name, cmd_params = $api_server.method_missing(cmd_no_hazardous, *args, scope: scope)
134
- _log_cmd(target_name, cmd_name, cmd_params, raw, no_range, no_hazardous, scope: scope)
127
+ target_name, cmd_name, cmd_params = $api_server.method_missing(cmd_no_hazardous, *args, scope: scope, token: token, timeout: timeout)
128
+ _log_cmd(target_name, cmd_name, cmd_params, raw, no_range, no_hazardous)
135
129
  end
136
130
  end
137
131
  end
138
132
 
139
- # Send a command to the specified target
133
+ # The following methods send a command to the specified target. The equivalent
134
+ # 'raw' version does not perform command parameter conversions
135
+ #
140
136
  # Usage:
141
137
  # cmd(target_name, cmd_name, cmd_params = {})
142
138
  # or
143
139
  # cmd('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
144
- def cmd(*args, **kw_args)
145
- _cmd('cmd', 'cmd_no_hazardous_check', *args, **kw_args)
140
+ def cmd(*args, **kwargs)
141
+ _cmd('cmd', 'cmd_no_hazardous_check', *args, **kwargs)
142
+ end
143
+ def cmd_raw(*args, **kwargs)
144
+ _cmd('cmd_raw', 'cmd_raw_no_hazardous_check', *args, **kwargs)
146
145
  end
147
146
 
148
147
  # Send a command to the specified target without range checking parameters
149
- # Usage:
150
- # cmd_no_range_check(target_name, cmd_name, cmd_params = {})
151
- # or
152
- # cmd_no_range_check('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
153
- def cmd_no_range_check(*args, **kw_args)
154
- _cmd('cmd_no_range_check', 'cmd_no_checks', *args, **kw_args)
148
+ def cmd_no_range_check(*args, **kwargs)
149
+ _cmd('cmd_no_range_check', 'cmd_no_checks', *args, **kwargs)
155
150
  end
156
-
157
- # Send a command to the specified target without hazardous checks
158
- # Usage:
159
- # cmd_no_hazardous_check(target_name, cmd_name, cmd_params = {})
160
- # or
161
- # cmd_no_hazardous_check('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
162
- def cmd_no_hazardous_check(*args, **kw_args)
163
- _cmd('cmd_no_hazardous_check', nil, *args, **kw_args)
151
+ def cmd_raw_no_range_check(*args, **kwargs)
152
+ _cmd('cmd_raw_no_range_check', 'cmd_raw_no_checks', *args, **kwargs)
164
153
  end
165
154
 
166
- # Send a command to the specified target without range checking or hazardous checks
167
- # Usage:
168
- # cmd_no_checks(target_name, cmd_name, cmd_params = {})
169
- # or
170
- # cmd_no_checks('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
171
- def cmd_no_checks(*args, **kw_args)
172
- _cmd('cmd_no_checks', nil, *args, **kw_args)
155
+ # Send a command to the specified target without hazardous checks
156
+ def cmd_no_hazardous_check(*args, **kwargs)
157
+ _cmd('cmd_no_hazardous_check', nil, *args, **kwargs)
173
158
  end
174
-
175
- # Send a command to the specified target without running conversions
176
- # Usage:
177
- # cmd_raw(target_name, cmd_name, cmd_params = {})
178
- # or
179
- # cmd_raw('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
180
- def cmd_raw(*args, **kw_args)
181
- _cmd('cmd_raw', 'cmd_raw_no_hazardous_check', *args, **kw_args)
159
+ def cmd_raw_no_hazardous_check(*args, **kwargs)
160
+ _cmd('cmd_raw_no_hazardous_check', nil, *args, **kwargs)
182
161
  end
183
162
 
184
- # Send a command to the specified target without range checking parameters or running conversions
185
- # Usage:
186
- # cmd_raw_no_range_check(target_name, cmd_name, cmd_params = {})
187
- # or
188
- # cmd_raw_no_range_check('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
189
- def cmd_raw_no_range_check(*args, **kw_args)
190
- _cmd('cmd_raw_no_range_check', 'cmd_raw_no_checks', *args, **kw_args)
163
+ # Send a command to the specified target without range checking or hazardous checks
164
+ def cmd_no_checks(*args, **kwargs)
165
+ _cmd('cmd_no_checks', nil, *args, **kwargs)
191
166
  end
192
-
193
- # Send a command to the specified target without hazardous checks or running conversions
194
- # Usage:
195
- # cmd_raw_no_hazardous_check(target_name, cmd_name, cmd_params = {})
196
- # or
197
- # cmd_raw_no_hazardous_check('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
198
- def cmd_raw_no_hazardous_check(*args, **kw_args)
199
- _cmd('cmd_raw_no_hazardous_check', nil, *args, **kw_args)
167
+ def cmd_raw_no_checks(*args, **kwargs)
168
+ _cmd('cmd_raw_no_checks', nil, *args, **kwargs)
200
169
  end
201
170
 
202
- # Send a command to the specified target without range checking or hazardous checks or running conversions
203
- # Usage:
204
- # cmd_raw_no_checks(target_name, cmd_name, cmd_params = {})
205
- # or
206
- # cmd_raw_no_checks('target_name cmd_name with cmd_param1 value1, cmd_param2 value2')
207
- def cmd_raw_no_checks(*args, **kw_args)
208
- _cmd('cmd_raw_no_checks', nil, *args, **kw_args)
171
+ # Returns whether the specified command is hazardous
172
+ #
173
+ # Accepts two different calling styles:
174
+ # get_cmd_hazardous("TGT CMD with PARAM1 val, PARAM2 val")
175
+ # get_cmd_hazardous('TGT','CMD',{'PARAM1'=>val,'PARAM2'=>val})
176
+ def get_cmd_hazardous(*args, **kwargs)
177
+ extract_string_kwargs_to_args(args, kwargs)
178
+ $api_server.get_cmd_hazardous(*args)
209
179
  end
210
180
 
211
181
  # Sends raw data through an interface from a file
@@ -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/utilities/store'
@@ -28,6 +28,20 @@ module OpenC3
28
28
 
29
29
  private
30
30
 
31
+ # Pulls all string keyword arguments into the args array. Raises on any symbol keyword arguments.
32
+ # Thus this method should only be called after you already filter out any symbol keyword arguments.
33
+ def extract_string_kwargs_to_args(args, kwargs)
34
+ # Split keywords into string keywords (part of our API, e.g. "PARAM" => 123) and
35
+ # symbol keywords which are meant for the internal methods, e.g. scope:, token:, timeout:
36
+ # If the user tries to pass symbol keywords then that is an error
37
+ str, sym = kwargs.partition {|k, v| k.is_a?(String) }.map(&:to_h)
38
+ unless sym.empty?
39
+ raise ArgumentError, "Unknown symbol keyword(s): #{sym.keys.join(', ')}. "\
40
+ "COSMOS command parameters must be passed as strings: \"#{sym.to_a[0][0].to_s}\" => ..."
41
+ end
42
+ args << str unless str.empty?
43
+ end
44
+
31
45
  def add_cmd_parameter(keyword, value, packet, cmd_params)
32
46
  quotes_removed = value.remove_quotes
33
47
  if value == quotes_removed
@@ -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/script/extract'
@@ -29,64 +29,89 @@ module OpenC3
29
29
 
30
30
  private
31
31
 
32
- # Gets the current metadata
32
+ # Gets all the metadata
33
33
  #
34
34
  # @return The result of the method call.
35
- def get_metadata(scope: $openc3_scope)
36
- response = $api_server.request('get', "/openc3-api/metadata/latest", scope: scope)
35
+ def metadata_all(limit: 100, scope: $openc3_scope)
36
+ response = $api_server.request('get', "/openc3-api/metadata", query: { limit: limit }, scope: scope)
37
37
  # Non-existant just returns nil
38
38
  return nil if response.nil? || response.code != 200
39
39
  return JSON.parse(response.body, :allow_nan => true, :create_additions => true)
40
40
  end
41
+ alias all_metadata metadata_all
41
42
 
42
- # Sets the metadata
43
+ # Gets metadata, default is latest if start is nil
44
+ #
45
+ # @return The result of the method call.
46
+ def metadata_get(start: nil, scope: $openc3_scope)
47
+ if start
48
+ response = $api_server.request('get', "/openc3-api/metadata/#{start}", scope: scope)
49
+ else
50
+ response = $api_server.request('get', "/openc3-api/metadata/latest", scope: scope)
51
+ end
52
+ # Non-existant just returns nil
53
+ return nil if response.nil? || response.code != 200
54
+ return JSON.parse(response.body, :allow_nan => true, :create_additions => true)
55
+ end
56
+ alias get_metadata metadata_get
57
+
58
+ # Create a new metadata entry at the given start time or now if no start given
43
59
  #
44
60
  # @param metadata [Hash<Symbol, Variable>] A hash of metadata
61
+ # @param start [Integer] Metadata time value as integer seconds from epoch
45
62
  # @param color [String] Events color to show on Calendar tool, if nil will be blue
46
- # @param start [Time] Metadata time value, if nil will be current time
47
63
  # @return The result of the method call.
48
- def set_metadata(metadata, color: nil, start: nil, scope: $openc3_scope)
64
+ def metadata_set(metadata, start: nil, color: nil, scope: $openc3_scope)
49
65
  unless metadata.is_a?(Hash)
50
66
  raise "metadata must be a Hash: #{metadata} is a #{metadata.class}"
51
67
  end
52
- color = color.nil? ? '#003784' : color
68
+ color = '#003784' unless color
53
69
  data = { color: color, metadata: metadata }
54
70
  data[:start] = start.iso8601 unless start.nil?
55
71
  response = $api_server.request('post', '/openc3-api/metadata', data: data, json: true, scope: scope)
56
- if response.nil? || response.code != 201
57
- raise "Failed to set_metadata"
72
+ if response.nil?
73
+ raise "Failed to set metadata due to #{response.code}"
74
+ elsif response.code == 409
75
+ raise "Metadata overlaps existing metadata. Did you metadata_set within 1s of another?"
76
+ elsif response.code != 201
77
+ raise "Failed to set metadata due to #{response.code}"
58
78
  end
59
79
  return JSON.parse(response.body, :allow_nan => true, :create_additions => true)
60
80
  end
81
+ alias set_metadata metadata_set
61
82
 
62
- # Updates the metadata
83
+ # Updates existing metadata. If no start is given, updates latest metadata.
63
84
  #
64
85
  # @param metadata [Hash<Symbol, Variable>] A hash of metadata
65
- # @param color [String] Events color to show on Calendar tool, if nil will be blue
66
86
  # @param start [Integer] Metadata time value as integer seconds from epoch
87
+ # @param color [String] Events color to show on Calendar tool, if nil will be blue
67
88
  # @return The result of the method call.
68
- def update_metadata(metadata, color: nil, start: nil, scope: $openc3_scope)
89
+ def metadata_update(metadata, start: nil, color: nil, scope: $openc3_scope)
69
90
  unless metadata.is_a?(Hash)
70
91
  raise "metadata must be a Hash: #{metadata} is a #{metadata.class}"
71
92
  end
72
- color = color.nil? ? '#003784' : color
73
- if start == nil
93
+ if start.nil? # No start so grab latest
74
94
  existing = get_metadata()
75
95
  start = existing['start']
96
+ color = existing['color'] unless color
76
97
  metadata = existing['metadata'].merge(metadata)
98
+ else
99
+ color = '#003784' unless color
77
100
  end
78
101
  data = { :color => color, :metadata => metadata }
79
102
  data[:start] = Time.at(start).iso8601
80
103
  response = $api_server.request('put', "/openc3-api/metadata/#{start}", data: data, json: true, scope: scope)
81
104
  if response.nil? || response.code != 200
82
- raise "Failed to update_metadata"
105
+ raise "Failed to update metadata"
83
106
  end
84
107
  return JSON.parse(response.body, :allow_nan => true, :create_additions => true)
85
108
  end
109
+ alias update_metadata metadata_update
86
110
 
87
111
  # Requests the metadata from the user for a target
88
- def input_metadata(*args, **kwargs)
112
+ def metadata_input(*args, **kwargs)
89
113
  raise StandardError "can only be used in Script Runner"
90
114
  end
115
+ alias input_metadata metadata_input
91
116
  end
92
117
  end
@@ -24,7 +24,7 @@ require 'openc3'
24
24
  require 'openc3/api/api'
25
25
  require 'openc3/io/json_drb_object'
26
26
  require 'openc3/script/api_shared'
27
- require 'openc3/script/calendar'
27
+ require 'openc3/script/metadata'
28
28
  require 'openc3/script/commands'
29
29
  require 'openc3/script/telemetry'
30
30
  require 'openc3/script/limits'
@@ -199,8 +199,12 @@ module OpenC3
199
199
 
200
200
  # generate the auth object
201
201
  def generate_auth
202
- if ENV['OPENC3_API_USER'].nil?
203
- return OpenC3Authentication.new()
202
+ if ENV['OPENC3_API_TOKEN'].nil? and ENV['OPENC3_API_USER'].nil?
203
+ if ENV['OPENC3_API_PASSWORD'] || ENV['OPENC3_SERVICE_PASSWORD']
204
+ return OpenC3Authentication.new()
205
+ else
206
+ return nil
207
+ end
204
208
  else
205
209
  return OpenC3KeycloakAuthentication.new(ENV['OPENC3_KEYCLOAK_URL'])
206
210
  end
@@ -265,8 +269,12 @@ module OpenC3
265
269
 
266
270
  # generate the auth object
267
271
  def generate_auth
268
- if ENV['OPENC3_API_USER'].nil?
269
- return OpenC3Authentication.new()
272
+ if ENV['OPENC3_API_TOKEN'].nil? and ENV['OPENC3_API_USER'].nil?
273
+ if ENV['OPENC3_API_PASSWORD'] || ENV['OPENC3_SERVICE_PASSWORD']
274
+ return OpenC3Authentication.new()
275
+ else
276
+ return nil
277
+ end
270
278
  else
271
279
  return OpenC3KeycloakAuthentication.new(ENV['OPENC3_KEYCLOAK_URL'])
272
280
  end
@@ -17,12 +17,14 @@
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 'tempfile'
24
24
  require 'net/http'
25
25
 
26
+ ENV['OPENC3_CLOUD'] ||= 'local'
27
+
26
28
  module OpenC3
27
29
  module Script
28
30
  private
@@ -72,26 +72,28 @@ module OpenC3
72
72
  end
73
73
 
74
74
  def self.setup_targets(target_names, base_dir, scope:)
75
- FileUtils.mkdir_p("#{base_dir}/targets")
76
- bucket = Bucket.getClient()
77
- target_names.each do |target_name|
78
- # Retrieve bucket/targets/target_name/target_id.zip
79
- zip_path = "#{base_dir}/targets/#{target_name}_current.zip"
80
- FileUtils.mkdir_p(File.dirname(zip_path))
81
- bucket_key = "#{scope}/target_archives/#{target_name}/#{target_name}_current.zip"
82
- Logger.info("Retrieving #{bucket_key} from targets bucket")
83
- bucket.get_object(bucket: ENV['OPENC3_CONFIG_BUCKET'], key: bucket_key, path: zip_path)
84
- Zip::File.open(zip_path) do |zip_file|
85
- zip_file.each do |entry|
86
- path = File.join("#{base_dir}/targets", entry.name)
87
- FileUtils.mkdir_p(File.dirname(path))
88
- zip_file.extract(entry, path) unless File.exist?(path)
75
+ if @@instance.nil?
76
+ FileUtils.mkdir_p("#{base_dir}/targets")
77
+ bucket = Bucket.getClient()
78
+ target_names.each do |target_name|
79
+ # Retrieve bucket/targets/target_name/target_id.zip
80
+ zip_path = "#{base_dir}/targets/#{target_name}_current.zip"
81
+ FileUtils.mkdir_p(File.dirname(zip_path))
82
+ bucket_key = "#{scope}/target_archives/#{target_name}/#{target_name}_current.zip"
83
+ Logger.info("Retrieving #{bucket_key} from targets bucket")
84
+ bucket.get_object(bucket: ENV['OPENC3_CONFIG_BUCKET'], key: bucket_key, path: zip_path)
85
+ Zip::File.open(zip_path) do |zip_file|
86
+ zip_file.each do |entry|
87
+ path = File.join("#{base_dir}/targets", entry.name)
88
+ FileUtils.mkdir_p(File.dirname(path))
89
+ zip_file.extract(entry, path) unless File.exist?(path)
90
+ end
89
91
  end
90
92
  end
91
- end
92
93
 
93
- # Build System from targets
94
- System.instance(target_names, "#{base_dir}/targets")
94
+ # Build System from targets
95
+ System.instance(target_names, "#{base_dir}/targets")
96
+ end
95
97
  end
96
98
 
97
99
  # Get the singleton instance of System
@@ -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
  module OpenC3
@@ -153,7 +153,7 @@ module OpenC3
153
153
  def handle_packet(packet)
154
154
  if packet.stored
155
155
  # Stored telemetry does not update the current value table
156
- identified_packet = System.telemetry.identify_and_define_packet(packet, @interface.target_names)
156
+ identified_packet = System.telemetry.identify_and_define_packet(packet, @interface.tlm_target_names)
157
157
  else
158
158
  # Identify and update packet
159
159
  if packet.identified?
@@ -169,12 +169,12 @@ module OpenC3
169
169
  packet.target_name = nil
170
170
  packet.packet_name = nil
171
171
  identified_packet = System.telemetry.identify!(packet.buffer,
172
- @interface.target_names)
172
+ @interface.tlm_target_names)
173
173
  end
174
174
  else
175
175
  # Packet needs to be identified
176
176
  identified_packet = System.telemetry.identify!(packet.buffer,
177
- @interface.target_names)
177
+ @interface.tlm_target_names)
178
178
  end
179
179
  end
180
180
 
@@ -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
  # This file contains top level functions in the OpenC3 namespace
@@ -354,7 +354,7 @@ module OpenC3
354
354
  def self.catch_fatal_exception
355
355
  yield
356
356
  rescue Exception => error
357
- unless error.class == SystemExit or error.class == Interrupt
357
+ unless SystemExit === error or SignalException === error
358
358
  Logger.level = Logger::FATAL
359
359
  OpenC3.handle_fatal_exception(error, false)
360
360
  end
@@ -366,7 +366,7 @@ module OpenC3
366
366
  # @param error [Exception] The exception to handle
367
367
  # @param try_gui [Boolean] Whether to try and create a GUI exception popup
368
368
  def self.handle_fatal_exception(error, try_gui = true)
369
- unless error.class == SystemExit or error.class == Interrupt
369
+ unless SystemExit === error or SignalException === error
370
370
  $openc3_fatal_exception = error
371
371
  self.write_exception_file(error)
372
372
  Logger.level = Logger::FATAL
@@ -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/topics/topic'
@@ -30,7 +30,7 @@ module OpenC3
30
30
 
31
31
  def self.write_packet(packet, scope:)
32
32
  topic = "#{scope}__DECOMCMD__{#{packet.target_name}}__#{packet.packet_name}"
33
- msg_hash = { time: packet.received_time.to_nsec_from_epoch,
33
+ msg_hash = { time: packet.packet_time.to_nsec_from_epoch,
34
34
  target_name: packet.target_name,
35
35
  packet_name: packet.packet_name,
36
36
  stored: packet.stored.to_s,
@@ -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/topics/topic'
@@ -29,7 +29,8 @@ module OpenC3
29
29
 
30
30
  def self.write_packet(packet, scope:)
31
31
  topic = "#{scope}__COMMAND__{#{packet.target_name}}__#{packet.packet_name}"
32
- msg_hash = { time: packet.received_time.to_nsec_from_epoch,
32
+ msg_hash = { time: packet.packet_time.to_nsec_from_epoch,
33
+ received_time: packet.received_time.to_nsec_from_epoch,
33
34
  target_name: packet.target_name,
34
35
  packet_name: packet.packet_name,
35
36
  received_count: packet.received_count,
@@ -39,7 +40,8 @@ module OpenC3
39
40
  end
40
41
 
41
42
  # @param command [Hash] Command hash structure read to be written to a topic
42
- def self.send_command(command, scope:)
43
+ def self.send_command(command, timeout: COMMAND_ACK_TIMEOUT_S, scope:)
44
+ timeout = COMMAND_ACK_TIMEOUT_S unless timeout
43
45
  ack_topic = "{#{scope}__ACKCMD}TARGET__#{command['target_name']}"
44
46
  Topic.update_topic_offsets([ack_topic])
45
47
  # Save the existing cmd_params Hash and JSON generate before writing to the topic
@@ -47,9 +49,8 @@ module OpenC3
47
49
  command['cmd_params'] = JSON.generate(command['cmd_params'].as_json(:allow_nan => true))
48
50
  OpenC3.inject_context(command)
49
51
  cmd_id = Topic.write_topic("{#{scope}__CMD}TARGET__#{command['target_name']}", command, '*', 100)
50
- # TODO: This timeout is fine for most but can we get the write_timeout from the interface here?
51
52
  time = Time.now
52
- while (Time.now - time) < COMMAND_ACK_TIMEOUT_S
53
+ while (Time.now - time) < timeout
53
54
  Topic.read_topics([ack_topic]) do |topic, msg_id, msg_hash, redis|
54
55
  if msg_hash["id"] == cmd_id
55
56
  if msg_hash["result"] == "SUCCESS"
@@ -63,7 +64,7 @@ module OpenC3
63
64
  end
64
65
  end
65
66
  end
66
- raise "Timeout waiting for cmd ack"
67
+ raise "Timeout of #{timeout}s waiting for cmd ack"
67
68
  end
68
69
 
69
70
  ###########################################################################
@@ -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/topics/topic'
@@ -29,7 +29,7 @@ module OpenC3
29
29
  def self.topics(interface, scope:)
30
30
  topics = []
31
31
  topics << "{#{scope}__CMD}INTERFACE__#{interface.name}"
32
- interface.target_names.each do |target_name|
32
+ interface.cmd_target_names.each do |target_name|
33
33
  topics << "{#{scope}__CMD}TARGET__#{target_name}"
34
34
  end
35
35
  topics
@@ -29,7 +29,7 @@ module OpenC3
29
29
  def self.topics(router, scope:)
30
30
  topics = []
31
31
  topics << "{#{scope}__CMD}ROUTER__#{router.name}"
32
- router.target_names.each do |target_name|
32
+ router.tlm_target_names.each do |target_name|
33
33
  System.telemetry.packets(target_name).each do |packet_name, packet|
34
34
  topics << "#{scope}__TELEMETRY__{#{packet.target_name}}__#{packet.packet_name}"
35
35
  end
@@ -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/topics/topic'
@@ -27,6 +27,7 @@ module OpenC3
27
27
  def self.write_packet(packet, scope:)
28
28
  msg_hash = {
29
29
  :time => packet.packet_time.to_nsec_from_epoch,
30
+ :received_time => packet.received_time.to_nsec_from_epoch,
30
31
  :stored => packet.stored.to_s,
31
32
  :target_name => packet.target_name,
32
33
  :packet_name => packet.packet_name,