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