openc3 5.1.1 → 5.2.0

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 (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,