openc3 5.1.1 → 5.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/openc3cli +48 -9
- data/data/config/interface_modifiers.yaml +14 -0
- data/data/config/parameter_modifiers.yaml +5 -3
- data/data/config/screen.yaml +12 -8
- data/data/config/target.yaml +33 -0
- data/ext/openc3/ext/config_parser/config_parser.c +66 -63
- data/ext/openc3/ext/packet/packet.c +1 -4
- data/lib/openc3/api/README.md +5 -0
- data/lib/openc3/api/api.rb +3 -1
- data/lib/openc3/api/cmd_api.rb +43 -112
- data/lib/openc3/api/interface_api.rb +3 -3
- data/lib/openc3/api/offline_access_api.rb +78 -0
- data/lib/openc3/api/settings_api.rb +3 -1
- data/lib/openc3/api/stash_api.rb +63 -0
- data/lib/openc3/api/target_api.rb +4 -5
- data/lib/openc3/config/config_parser.rb +47 -47
- data/lib/openc3/interfaces/interface.rb +11 -1
- data/lib/openc3/interfaces/protocols/burst_protocol.rb +30 -16
- data/lib/openc3/interfaces/protocols/fixed_protocol.rb +8 -2
- data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +2 -2
- data/lib/openc3/interfaces/protocols/override_protocol.rb +2 -2
- data/lib/openc3/interfaces/tcpip_server_interface.rb +3 -1
- data/lib/openc3/io/json_api_object.rb +30 -9
- data/lib/openc3/io/json_drb.rb +6 -1
- data/lib/openc3/io/json_drb_object.rb +18 -9
- data/lib/openc3/io/json_rpc.rb +5 -3
- data/lib/openc3/logs/buffered_packet_log_writer.rb +1 -1
- data/lib/openc3/logs/log_writer.rb +8 -2
- data/lib/openc3/microservices/cleanup_microservice.rb +3 -3
- data/lib/openc3/microservices/decom_microservice.rb +8 -8
- data/lib/openc3/microservices/interface_microservice.rb +86 -71
- data/lib/openc3/microservices/log_microservice.rb +5 -3
- data/lib/openc3/microservices/microservice.rb +18 -14
- data/lib/openc3/microservices/multi_microservice.rb +62 -0
- data/lib/openc3/microservices/periodic_microservice.rb +58 -0
- data/lib/openc3/microservices/reaction_microservice.rb +61 -47
- data/lib/openc3/microservices/reducer_microservice.rb +64 -40
- data/lib/openc3/microservices/router_microservice.rb +4 -4
- data/lib/openc3/microservices/text_log_microservice.rb +2 -2
- data/lib/openc3/microservices/timeline_microservice.rb +44 -30
- data/lib/openc3/microservices/trigger_group_microservice.rb +39 -36
- data/lib/openc3/migrations/20221202214600_add_target_names.rb +30 -0
- data/lib/openc3/migrations/20221210174900_convert_to_multi.rb +65 -0
- data/lib/openc3/models/cvt_model.rb +1 -1
- data/lib/openc3/models/gem_model.rb +24 -20
- data/lib/openc3/models/interface_model.rb +69 -35
- data/lib/openc3/models/metadata_model.rb +1 -1
- data/lib/openc3/models/microservice_model.rb +7 -24
- data/lib/openc3/models/migration_model.rb +52 -0
- data/lib/openc3/models/model.rb +2 -7
- data/lib/openc3/models/note_model.rb +1 -1
- data/lib/openc3/models/offline_access_model.rb +55 -0
- data/lib/openc3/models/plugin_model.rb +12 -3
- data/lib/openc3/models/reaction_model.rb +6 -2
- data/lib/openc3/models/scope_model.rb +89 -13
- data/lib/openc3/models/settings_model.rb +1 -1
- data/lib/openc3/models/stash_model.rb +53 -0
- data/lib/openc3/models/target_model.rb +301 -130
- data/lib/openc3/models/tool_model.rb +1 -12
- data/lib/openc3/models/widget_model.rb +1 -6
- data/lib/openc3/operators/microservice_operator.rb +45 -6
- data/lib/openc3/operators/operator.rb +27 -5
- data/lib/openc3/packets/commands.rb +1 -25
- data/lib/openc3/packets/limits.rb +0 -75
- data/lib/openc3/packets/packet.rb +0 -28
- data/lib/openc3/packets/packet_item.rb +23 -0
- data/lib/openc3/packets/packet_item_limits.rb +2 -2
- data/lib/openc3/packets/parsers/state_parser.rb +10 -6
- data/lib/openc3/packets/telemetry.rb +1 -45
- data/lib/openc3/script/commands.rb +41 -71
- data/lib/openc3/script/extract.rb +15 -1
- data/lib/openc3/script/{calendar.rb → metadata.rb} +42 -17
- data/lib/openc3/script/script.rb +13 -5
- data/lib/openc3/script/storage.rb +3 -1
- data/lib/openc3/system/system.rb +19 -17
- data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +4 -4
- data/lib/openc3/top_level.rb +3 -3
- data/lib/openc3/topics/command_decom_topic.rb +2 -2
- data/lib/openc3/topics/command_topic.rb +7 -6
- data/lib/openc3/topics/interface_topic.rb +2 -2
- data/lib/openc3/topics/router_topic.rb +1 -1
- data/lib/openc3/topics/telemetry_topic.rb +2 -1
- data/lib/openc3/utilities/authentication.rb +35 -14
- data/lib/openc3/utilities/aws_bucket.rb +4 -3
- data/lib/openc3/utilities/bucket.rb +4 -2
- data/lib/openc3/utilities/bucket_file_cache.rb +3 -8
- data/lib/openc3/utilities/bucket_utilities.rb +77 -15
- data/lib/openc3/utilities/local_mode.rb +12 -9
- data/lib/openc3/utilities/logger.rb +17 -9
- data/lib/openc3/utilities/message_log.rb +6 -5
- data/lib/openc3/utilities/migration.rb +22 -0
- data/lib/openc3/utilities/store_autoload.rb +7 -5
- data/lib/openc3/utilities/target_file.rb +9 -7
- data/lib/openc3/version.rb +6 -6
- data/lib/openc3.rb +2 -1
- 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
|
-
|
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
|
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, **
|
111
|
-
|
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
|
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
|
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
|
-
#
|
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, **
|
145
|
-
_cmd('cmd', 'cmd_no_hazardous_check', *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
|
-
|
150
|
-
|
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
|
-
|
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
|
167
|
-
|
168
|
-
|
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
|
-
|
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
|
185
|
-
|
186
|
-
|
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
|
-
|
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
|
-
#
|
203
|
-
#
|
204
|
-
#
|
205
|
-
#
|
206
|
-
#
|
207
|
-
def
|
208
|
-
|
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
|
32
|
+
# Gets all the metadata
|
33
33
|
#
|
34
34
|
# @return The result of the method call.
|
35
|
-
def
|
36
|
-
response = $api_server.request('get', "/openc3-api/metadata
|
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
|
-
#
|
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
|
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 =
|
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?
|
57
|
-
raise "Failed to
|
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
|
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
|
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
|
-
|
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
|
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
|
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
|
data/lib/openc3/script/script.rb
CHANGED
@@ -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/
|
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
|
-
|
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
|
-
|
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
|
data/lib/openc3/system/system.rb
CHANGED
@@ -72,26 +72,28 @@ module OpenC3
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def self.setup_targets(target_names, base_dir, scope:)
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
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
|
-
|
94
|
-
|
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.
|
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.
|
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.
|
177
|
+
@interface.tlm_target_names)
|
178
178
|
end
|
179
179
|
end
|
180
180
|
|
data/lib/openc3/top_level.rb
CHANGED
@@ -17,7 +17,7 @@
|
|
17
17
|
# All changes Copyright 2022, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
19
|
#
|
20
|
-
# This file may also be used under the terms of a commercial license
|
20
|
+
# This file may also be used under the terms of a commercial license
|
21
21
|
# if purchased from OpenC3, Inc.
|
22
22
|
|
23
23
|
# 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
|
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
|
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.
|
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.
|
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) <
|
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.
|
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.
|
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,
|