openc3 5.12.0 → 5.13.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of openc3 might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/bin/openc3cli +3 -3
- data/data/config/graph_settings.yaml +1 -1
- data/data/config/item_modifiers.yaml +1 -2
- data/data/config/parameter_modifiers.yaml +13 -14
- data/data/config/screen.yaml +1 -2
- data/data/config/target_config.yaml +2 -6
- data/lib/openc3/api/cmd_api.rb +99 -35
- data/lib/openc3/api/tlm_api.rb +63 -24
- data/lib/openc3/interfaces/mqtt_interface.rb +11 -9
- data/lib/openc3/interfaces/mqtt_stream_interface.rb +78 -0
- data/lib/openc3/logs/packet_log_reader.rb +2 -2
- data/lib/openc3/logs/text_log_writer.rb +3 -2
- data/lib/openc3/microservices/trigger_group_microservice.rb +2 -1
- data/lib/openc3/models/plugin_model.rb +38 -4
- data/lib/openc3/packets/json_packet.rb +46 -15
- data/lib/openc3/packets/packet_config.rb +2 -1
- data/lib/openc3/packets/parsers/xtce_parser.rb +5 -1
- data/lib/openc3/script/api_shared.rb +31 -31
- data/lib/openc3/script/commands.rb +18 -12
- data/lib/openc3/script/limits.rb +1 -1
- data/lib/openc3/script/storage.rb +4 -4
- data/lib/openc3/script/web_socket_api.rb +2 -2
- data/lib/openc3/streams/mqtt_stream.rb +109 -0
- data/lib/openc3/utilities/cli_generator.rb +33 -20
- data/lib/openc3/utilities/local_mode.rb +2 -2
- data/lib/openc3/utilities/logger.rb +17 -16
- data/lib/openc3/utilities/process_manager.rb +1 -1
- data/lib/openc3/version.rb +5 -5
- data/templates/conversion/conversion.py +28 -0
- data/templates/conversion/conversion.rb +1 -18
- data/templates/limits_response/response.py +37 -0
- data/templates/limits_response/response.rb +0 -17
- data/templates/microservice/microservices/TEMPLATE/microservice.py +54 -0
- data/templates/microservice/microservices/TEMPLATE/microservice.rb +0 -7
- data/templates/plugin/.gitignore +1 -0
- data/templates/target/targets/TARGET/lib/target.py +9 -0
- data/templates/target/targets/TARGET/procedures/procedure.py +3 -0
- data/templates/tool_angular/package.json +20 -19
- data/templates/tool_angular/yarn.lock +2222 -3212
- data/templates/tool_react/package.json +12 -12
- data/templates/tool_react/yarn.lock +586 -521
- data/templates/tool_svelte/package.json +11 -10
- data/templates/tool_svelte/src/services/openc3-api.js +17 -22
- data/templates/tool_svelte/yarn.lock +600 -516
- data/templates/tool_vue/package.json +10 -9
- data/templates/tool_vue/yarn.lock +113 -41
- data/templates/widget/package.json +9 -8
- data/templates/widget/yarn.lock +96 -35
- metadata +26 -4
@@ -0,0 +1,78 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
# Copyright 2023 OpenC3, Inc.
|
4
|
+
# All Rights Reserved.
|
5
|
+
#
|
6
|
+
# This program is free software; you can modify and/or redistribute it
|
7
|
+
# under the terms of the GNU Affero General Public License
|
8
|
+
# as published by the Free Software Foundation; version 3 with
|
9
|
+
# attribution addendums as found in the LICENSE.txt
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# This file may also be used under the terms of a commercial license
|
17
|
+
# if purchased from OpenC3, Inc.
|
18
|
+
|
19
|
+
require 'openc3/interfaces/stream_interface'
|
20
|
+
require 'openc3/streams/mqtt_stream'
|
21
|
+
|
22
|
+
module OpenC3
|
23
|
+
class MqttStreamInterface < StreamInterface
|
24
|
+
# @param hostname [String] MQTT server to connect to
|
25
|
+
# @param port [Integer] MQTT port
|
26
|
+
# @param ssl [Boolean] Use SSL true/false
|
27
|
+
def initialize(hostname, port = 1883, ssl = false, write_topic = nil, read_topic = nil, protocol_type = nil, *protocol_args)
|
28
|
+
super(protocol_type, protocol_args)
|
29
|
+
@hostname = hostname
|
30
|
+
@port = Integer(port)
|
31
|
+
@ssl = ConfigParser.handle_true_false(ssl)
|
32
|
+
@write_topic = ConfigParser.handle_nil(write_topic)
|
33
|
+
@read_topic = ConfigParser.handle_nil(read_topic)
|
34
|
+
@username = nil
|
35
|
+
@password = nil
|
36
|
+
@cert = nil
|
37
|
+
@key = nil
|
38
|
+
@ca_file = nil
|
39
|
+
end
|
40
|
+
|
41
|
+
# Creates a new {SerialStream} using the parameters passed in the constructor
|
42
|
+
def connect
|
43
|
+
@stream = MqttStream.new(@hostname, @port, @ssl, @write_topic, @read_topic)
|
44
|
+
@stream.username = @username if @username
|
45
|
+
@stream.password = @password if @password
|
46
|
+
@stream.cert = @cert if @cert
|
47
|
+
@stream.key = @key if @key
|
48
|
+
@stream.ca_file = @ca_file if @ca_file
|
49
|
+
super()
|
50
|
+
end
|
51
|
+
|
52
|
+
# Supported Options
|
53
|
+
# USERNAME - Username for Mqtt Server
|
54
|
+
# PASSWORD - Password for Mqtt Server
|
55
|
+
# CERT - Public Key for Client Cert Auth
|
56
|
+
# KEY - Private Key for Client Cert Auth
|
57
|
+
# CA_FILE - Certificate Authority for Client Cert Auth
|
58
|
+
# (see Interface#set_option)
|
59
|
+
def set_option(option_name, option_values)
|
60
|
+
super(option_name, option_values)
|
61
|
+
case option_name.upcase
|
62
|
+
when 'USERNAME'
|
63
|
+
@username = option_values[0]
|
64
|
+
when 'PASSWORD'
|
65
|
+
@password = option_values[0]
|
66
|
+
when 'CERT'
|
67
|
+
@cert = option_values[0]
|
68
|
+
when 'KEY'
|
69
|
+
@key = option_values[0]
|
70
|
+
when 'CA_FILE'
|
71
|
+
# CA_FILE must be given as a file
|
72
|
+
@ca_file = Tempfile.new('ca_file')
|
73
|
+
@ca_file.write(option_values[0])
|
74
|
+
@ca_file.close
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -298,12 +298,12 @@ module OpenC3
|
|
298
298
|
next_offset = 12
|
299
299
|
received_time_nsec_since_epoch = time_nsec_since_epoch
|
300
300
|
if includes_received_time
|
301
|
-
received_time_nsec_since_epoch = entry[next_offset..(next_offset + OPENC3_RECEIVED_TIME_FIXED_SIZE - 1)].unpack(OPENC3_RECEIVED_TIME_PACK_DIRECTIVE)
|
301
|
+
received_time_nsec_since_epoch = entry[next_offset..(next_offset + OPENC3_RECEIVED_TIME_FIXED_SIZE - 1)].unpack(OPENC3_RECEIVED_TIME_PACK_DIRECTIVE)[0]
|
302
302
|
next_offset += OPENC3_RECEIVED_TIME_FIXED_SIZE
|
303
303
|
end
|
304
304
|
extra = nil
|
305
305
|
if includes_extra
|
306
|
-
extra_length = entry[next_offset..(next_offset + OPENC3_EXTRA_LENGTH_FIXED_SIZE - 1)].unpack(OPENC3_EXTRA_LENGTH_PACK_DIRECTIVE)
|
306
|
+
extra_length = entry[next_offset..(next_offset + OPENC3_EXTRA_LENGTH_FIXED_SIZE - 1)].unpack(OPENC3_EXTRA_LENGTH_PACK_DIRECTIVE)[0]
|
307
307
|
next_offset += OPENC3_EXTRA_LENGTH_FIXED_SIZE
|
308
308
|
extra_encoded = entry[next_offset..(next_offset + extra_length - 1)]
|
309
309
|
next_offset += extra_length
|
@@ -78,8 +78,9 @@ module OpenC3
|
|
78
78
|
begin
|
79
79
|
# Need to write the OFFSET_MARKER for each packet
|
80
80
|
@last_offsets.each do |redis_topic, last_offset|
|
81
|
-
time = Time.now
|
82
|
-
|
81
|
+
time = Time.now.utc
|
82
|
+
# timestamp iso8601 with 6 decimal places to match the python output format
|
83
|
+
data = { time: time.to_nsec_from_epoch, '@timestamp' => time.iso8601(6), level: 'INFO', "microservice_name" => Logger.microservice_name, "container_name" => @container_name, "last_offset" => last_offset, "redis_topic" => redis_topic, "type" => "offset" }
|
83
84
|
write_entry(time.to_nsec_from_epoch, data.as_json(allow_nan: true).to_json(allow_nan: true)) if @file
|
84
85
|
end
|
85
86
|
|
@@ -333,7 +333,8 @@ module OpenC3
|
|
333
333
|
)
|
334
334
|
return nil if packet.nil?
|
335
335
|
_, limit = packet.read_with_limits_state(operand[ITEM_TYPE], operand[ITEM_VALUE_TYPE].intern)
|
336
|
-
|
336
|
+
# Convert limit symbol to string since we'll be comparing with strings
|
337
|
+
return limit.to_s
|
337
338
|
end
|
338
339
|
|
339
340
|
# extract the value outlined in the operand to get the packet item value
|
@@ -296,10 +296,15 @@ module OpenC3
|
|
296
296
|
|
297
297
|
# Undeploy all models associated with this plugin
|
298
298
|
def undeploy
|
299
|
+
errors = []
|
299
300
|
microservice_count = 0
|
300
301
|
microservices = MicroserviceModel.find_all_by_plugin(plugin: @name, scope: @scope)
|
301
302
|
microservices.each do |name, model_instance|
|
302
|
-
|
303
|
+
begin
|
304
|
+
model_instance.destroy
|
305
|
+
rescue Exception => error
|
306
|
+
errors << error
|
307
|
+
end
|
303
308
|
microservice_count += 1
|
304
309
|
end
|
305
310
|
# Wait for the operator to wake up and remove the microservice processes
|
@@ -308,15 +313,44 @@ module OpenC3
|
|
308
313
|
# Save TargetModel for last as it has the most to cleanup
|
309
314
|
[InterfaceModel, RouterModel, ToolModel, WidgetModel, TargetModel].each do |model|
|
310
315
|
model.find_all_by_plugin(plugin: @name, scope: @scope).each do |name, model_instance|
|
311
|
-
|
316
|
+
begin
|
317
|
+
model_instance.destroy
|
318
|
+
rescue Exception => error
|
319
|
+
errors << error
|
320
|
+
end
|
312
321
|
end
|
313
322
|
end
|
314
323
|
# Cleanup Redis stuff that might have been left by microservices
|
315
324
|
microservices.each do |name, model_instance|
|
316
|
-
|
325
|
+
begin
|
326
|
+
model_instance.cleanup
|
327
|
+
rescue Exception => error
|
328
|
+
errors << error
|
329
|
+
end
|
330
|
+
end
|
331
|
+
# Raise all the errors at once
|
332
|
+
if errors.length > 0
|
333
|
+
message = ''
|
334
|
+
errors.each do |error|
|
335
|
+
message += "\n#{error.formatted}\n"
|
336
|
+
end
|
337
|
+
raise message
|
317
338
|
end
|
318
339
|
rescue Exception => error
|
319
|
-
Logger.error("Error undeploying plugin model #{@name} in scope #{@scope} due to #{error}")
|
340
|
+
Logger.error("Error undeploying plugin model #{@name} in scope #{@scope} due to: #{error}")
|
341
|
+
ensure
|
342
|
+
# Double check everything is gone
|
343
|
+
found = []
|
344
|
+
[MicroserviceModel, InterfaceModel, RouterModel, ToolModel, WidgetModel, TargetModel].each do |model|
|
345
|
+
model.find_all_by_plugin(plugin: @name, scope: @scope).each do |name, model_instance|
|
346
|
+
found << model_instance
|
347
|
+
end
|
348
|
+
end
|
349
|
+
if found.length > 0
|
350
|
+
# If undeploy failed we need to not move forward with anything else
|
351
|
+
Logger.error("Error undeploying plugin model #{@name} in scope #{@scope} due to: Plugin submodels still exist after undeploy = #{found.length}")
|
352
|
+
raise "Plugin #{@name} submodels still exist after undeploy = #{found.length}"
|
353
|
+
end
|
320
354
|
end
|
321
355
|
|
322
356
|
# Reinstall
|
@@ -65,66 +65,97 @@ module OpenC3
|
|
65
65
|
# @param name [String] Name of the item to read - Should already by upcase
|
66
66
|
# @param value_type (see #read_item)
|
67
67
|
def read(name, value_type = :CONVERTED, reduced_type = nil)
|
68
|
+
value = nil
|
69
|
+
array_index = nil
|
70
|
+
if name[-1] == ']'
|
71
|
+
open_bracket_index = name.index('[')
|
72
|
+
if open_bracket_index
|
73
|
+
array_index = name[(open_bracket_index + 1)..-2].to_i
|
74
|
+
name = name[0..(open_bracket_index - 1)]
|
75
|
+
end
|
76
|
+
end
|
68
77
|
if reduced_type
|
69
78
|
raise "Reduced types only support RAW or CONVERTED value types: #{value_type} unsupported" if value_type == :WITH_UNITS or value_type == :FORMATTED
|
70
79
|
if value_type == :CONVERTED
|
71
80
|
case reduced_type
|
72
81
|
when :AVG
|
73
82
|
value = @json_hash["#{name}__CA"]
|
74
|
-
return value if value
|
75
83
|
when :STDDEV
|
76
84
|
value = @json_hash["#{name}__CS"]
|
77
|
-
return value if value
|
78
85
|
when :MIN
|
79
86
|
value = @json_hash["#{name}__CN"]
|
80
|
-
return value if value
|
81
87
|
when :MAX
|
82
88
|
value = @json_hash["#{name}__CX"]
|
83
|
-
|
89
|
+
end
|
90
|
+
if value
|
91
|
+
value = value[array_index] if array_index
|
92
|
+
return value
|
84
93
|
end
|
85
94
|
end
|
86
95
|
case reduced_type
|
87
96
|
when :AVG
|
88
97
|
value = @json_hash["#{name}__A"]
|
89
|
-
return value if value
|
90
98
|
when :STDDEV
|
91
99
|
value = @json_hash["#{name}__S"]
|
92
|
-
return value if value
|
93
100
|
when :MIN
|
94
101
|
value = @json_hash["#{name}__N"]
|
95
|
-
return value if value
|
96
102
|
when :MAX
|
97
103
|
value = @json_hash["#{name}__X"]
|
98
|
-
|
104
|
+
end
|
105
|
+
if value
|
106
|
+
value = value[array_index] if array_index
|
107
|
+
return value
|
99
108
|
end
|
100
109
|
end
|
101
110
|
if value_type == :WITH_UNITS
|
102
111
|
value = @json_hash["#{name}__U"]
|
103
|
-
|
112
|
+
if value
|
113
|
+
value = value[array_index] if array_index
|
114
|
+
return value
|
115
|
+
end
|
104
116
|
end
|
105
117
|
if value_type == :WITH_UNITS or value_type == :FORMATTED
|
106
118
|
value = @json_hash["#{name}__F"]
|
107
|
-
|
119
|
+
if value
|
120
|
+
value = value[array_index] if array_index
|
121
|
+
return value
|
122
|
+
end
|
108
123
|
|
109
124
|
value = @json_hash["#{name}__C"]
|
110
|
-
|
125
|
+
if value
|
126
|
+
value = value[array_index] if array_index
|
127
|
+
return value.to_s
|
128
|
+
end
|
111
129
|
|
112
130
|
value = @json_hash[name]
|
113
|
-
|
131
|
+
if value
|
132
|
+
value = value[array_index] if array_index
|
133
|
+
return value.to_s
|
134
|
+
end
|
114
135
|
|
115
136
|
return nil
|
116
137
|
end
|
117
138
|
if value_type == :CONVERTED
|
118
139
|
value = @json_hash["#{name}__C"]
|
119
|
-
|
140
|
+
if value
|
141
|
+
value = value[array_index] if array_index
|
142
|
+
return value
|
143
|
+
end
|
120
144
|
end
|
121
|
-
|
145
|
+
value = @json_hash[name]
|
146
|
+
if value
|
147
|
+
value = value[array_index] if array_index
|
148
|
+
return value
|
149
|
+
end
|
150
|
+
return nil
|
122
151
|
end
|
123
152
|
|
124
153
|
def read_with_limits_state(name, value_type = :CONVERTED, reduced_type = nil)
|
125
154
|
value = read(name, value_type, reduced_type)
|
126
155
|
limits_state = @json_hash["#{name}__L"]
|
127
|
-
|
156
|
+
if limits_state
|
157
|
+
limits_state = limits_state.intern
|
158
|
+
end
|
128
159
|
return [value, limits_state]
|
129
160
|
end
|
130
161
|
|
@@ -119,7 +119,8 @@ module OpenC3
|
|
119
119
|
# an xtce file to automatically determine the target name.
|
120
120
|
def process_file(filename, process_target_name)
|
121
121
|
# Handle .xtce files
|
122
|
-
|
122
|
+
extension = File.extname(filename).to_s.downcase
|
123
|
+
if extension == ".xtce" or extension == ".xml"
|
123
124
|
XtceParser.process(@commands, @telemetry, @warnings, filename, process_target_name)
|
124
125
|
return
|
125
126
|
end
|
@@ -181,7 +181,8 @@ module OpenC3
|
|
181
181
|
when 'ParameterTypeSet', 'EnumerationList', 'ParameterSet', 'ContainerSet',
|
182
182
|
'EntryList', 'DefaultCalibrator', 'DefaultAlarm', 'RestrictionCriteria',
|
183
183
|
'ComparisonList', 'MetaCommandSet', 'ArgumentTypeSet', 'ArgumentList',
|
184
|
-
'ArgumentAssignmentList', 'LocationInContainerInBits', 'ReferenceTime'
|
184
|
+
'ArgumentAssignmentList', 'LocationInContainerInBits', 'ReferenceTime',
|
185
|
+
'AncillaryDataSet', 'AncillaryData'
|
185
186
|
# Do Nothing
|
186
187
|
|
187
188
|
when 'ErrorDetectCorrect'
|
@@ -446,6 +447,9 @@ module OpenC3
|
|
446
447
|
process_ref_entry(element)
|
447
448
|
return false # Already recursed
|
448
449
|
|
450
|
+
when 'ContainerRefEntry'
|
451
|
+
xtce_handle_base_container('ContainerRefEntry', element)
|
452
|
+
|
449
453
|
when 'BaseContainer'
|
450
454
|
# Handled in SequenceContainer/CommandContainer
|
451
455
|
|
@@ -69,7 +69,7 @@ module OpenC3
|
|
69
69
|
method += ", #{orig_kwargs}" unless orig_kwargs.empty?
|
70
70
|
method += ")"
|
71
71
|
rescue Exception => error
|
72
|
-
|
72
|
+
puts "CHECK: #{method} raised #{error.class}:#{error.message}"
|
73
73
|
else
|
74
74
|
raise(CheckError, "#{method} should have raised an exception but did not.")
|
75
75
|
end
|
@@ -107,10 +107,10 @@ module OpenC3
|
|
107
107
|
end
|
108
108
|
|
109
109
|
if all_checks_ok
|
110
|
-
|
110
|
+
puts message
|
111
111
|
else
|
112
112
|
if $disconnect
|
113
|
-
|
113
|
+
puts "ERROR: #{message}"
|
114
114
|
else
|
115
115
|
raise CheckError, message
|
116
116
|
end
|
@@ -120,11 +120,11 @@ module OpenC3
|
|
120
120
|
check_str = "CHECK: #{_upcase(target_name, packet_name, item_name)}"
|
121
121
|
range_str = "range #{range.first} to #{range.last} with value == #{value}"
|
122
122
|
if range.include?(value)
|
123
|
-
|
123
|
+
puts "#{check_str} was within #{range_str}"
|
124
124
|
else
|
125
125
|
message = "#{check_str} failed to be within #{range_str}"
|
126
126
|
if $disconnect
|
127
|
-
|
127
|
+
puts "ERROR: #{message}"
|
128
128
|
else
|
129
129
|
raise CheckError, message
|
130
130
|
end
|
@@ -142,11 +142,11 @@ module OpenC3
|
|
142
142
|
def check_expression(exp_to_eval, context = nil, scope: $openc3_scope, token: $openc3_token)
|
143
143
|
success = _openc3_script_wait_implementation_expression(exp_to_eval, 0, DEFAULT_TLM_POLLING_RATE, context, scope: scope, token: token)
|
144
144
|
if success
|
145
|
-
|
145
|
+
puts "CHECK: #{exp_to_eval} is TRUE"
|
146
146
|
else
|
147
147
|
message = "CHECK: #{exp_to_eval} is FALSE"
|
148
148
|
if $disconnect
|
149
|
-
|
149
|
+
puts "ERROR: #{message}"
|
150
150
|
else
|
151
151
|
raise CheckError, message
|
152
152
|
end
|
@@ -171,7 +171,7 @@ module OpenC3
|
|
171
171
|
start_time = Time.now.sys
|
172
172
|
openc3_script_sleep()
|
173
173
|
time_diff = Time.now.sys - start_time
|
174
|
-
|
174
|
+
puts "WAIT: Indefinite for actual time of #{time_diff} seconds" unless quiet
|
175
175
|
|
176
176
|
# wait(5) # absolute wait time
|
177
177
|
when 1
|
@@ -179,7 +179,7 @@ module OpenC3
|
|
179
179
|
start_time = Time.now.sys
|
180
180
|
openc3_script_sleep(args[0])
|
181
181
|
time_diff = Time.now.sys - start_time
|
182
|
-
|
182
|
+
puts "WAIT: #{args[0]} seconds with actual time of #{time_diff} seconds" unless quiet
|
183
183
|
else
|
184
184
|
raise "Non-numeric wait time specified"
|
185
185
|
end
|
@@ -254,9 +254,9 @@ module OpenC3
|
|
254
254
|
end
|
255
255
|
|
256
256
|
if success
|
257
|
-
|
257
|
+
puts message unless quiet
|
258
258
|
else
|
259
|
-
|
259
|
+
puts "WARN: #{message}" unless quiet
|
260
260
|
end
|
261
261
|
else
|
262
262
|
success, value = _openc3_script_wait_implementation_tolerance(target_name, packet_name, item_name, type, expected_value, tolerance, timeout, polling_rate, scope: scope, token: token)
|
@@ -265,9 +265,9 @@ module OpenC3
|
|
265
265
|
wait_str = "WAIT: #{_upcase(target_name, packet_name, item_name)}"
|
266
266
|
range_str = "range #{range.first} to #{range.last} with value == #{value} after waiting #{time} seconds"
|
267
267
|
if success
|
268
|
-
|
268
|
+
puts "#{wait_str} was within #{range_str}" unless quiet
|
269
269
|
else
|
270
|
-
|
270
|
+
puts "WARN: #{wait_str} failed to be within #{range_str}" unless quiet
|
271
271
|
end
|
272
272
|
end
|
273
273
|
time
|
@@ -284,9 +284,9 @@ module OpenC3
|
|
284
284
|
success = _openc3_script_wait_implementation_expression(exp_to_eval, timeout, polling_rate, context, scope: scope, token: token)
|
285
285
|
time_diff = Time.now.sys - start_time
|
286
286
|
if success
|
287
|
-
|
287
|
+
puts "WAIT: #{exp_to_eval} is TRUE after waiting #{time_diff} seconds" unless quiet
|
288
288
|
else
|
289
|
-
|
289
|
+
puts "WARN: WAIT: #{exp_to_eval} is FALSE after waiting #{time_diff} seconds" unless quiet
|
290
290
|
end
|
291
291
|
time_diff
|
292
292
|
end
|
@@ -312,11 +312,11 @@ module OpenC3
|
|
312
312
|
end
|
313
313
|
with_value_str = "with value == #{value} after waiting #{time_diff} seconds"
|
314
314
|
if success
|
315
|
-
|
315
|
+
puts "#{check_str} success #{with_value_str}"
|
316
316
|
else
|
317
317
|
message = "#{check_str} failed #{with_value_str}"
|
318
318
|
if $disconnect
|
319
|
-
|
319
|
+
puts "ERROR: #{message}"
|
320
320
|
else
|
321
321
|
raise CheckError, message
|
322
322
|
end
|
@@ -363,10 +363,10 @@ module OpenC3
|
|
363
363
|
end
|
364
364
|
|
365
365
|
if success
|
366
|
-
|
366
|
+
puts message
|
367
367
|
else
|
368
368
|
if $disconnect
|
369
|
-
|
369
|
+
puts "ERROR: #{message}"
|
370
370
|
else
|
371
371
|
raise CheckError, message
|
372
372
|
end
|
@@ -378,11 +378,11 @@ module OpenC3
|
|
378
378
|
check_str = "CHECK: #{_upcase(target_name, packet_name, item_name)}"
|
379
379
|
range_str = "range #{range.first} to #{range.last} with value == #{value} after waiting #{time_diff} seconds"
|
380
380
|
if success
|
381
|
-
|
381
|
+
puts "#{check_str} was within #{range_str}"
|
382
382
|
else
|
383
383
|
message = "#{check_str} failed to be within #{range_str}"
|
384
384
|
if $disconnect
|
385
|
-
|
385
|
+
puts "ERROR: #{message}"
|
386
386
|
else
|
387
387
|
raise CheckError, message
|
388
388
|
end
|
@@ -409,11 +409,11 @@ module OpenC3
|
|
409
409
|
context, scope: scope, token: token, &block)
|
410
410
|
time_diff = Time.now.sys - start_time
|
411
411
|
if success
|
412
|
-
|
412
|
+
puts "CHECK: #{exp_to_eval} is TRUE after waiting #{time_diff} seconds"
|
413
413
|
else
|
414
414
|
message = "CHECK: #{exp_to_eval} is FALSE after waiting #{time_diff} seconds"
|
415
415
|
if $disconnect
|
416
|
-
|
416
|
+
puts "ERROR: #{message}"
|
417
417
|
else
|
418
418
|
raise CheckError, message
|
419
419
|
end
|
@@ -540,7 +540,7 @@ module OpenC3
|
|
540
540
|
if comparison_to_eval
|
541
541
|
_check_eval(target_name, packet_name, item_name, comparison_to_eval, value)
|
542
542
|
else
|
543
|
-
|
543
|
+
puts "CHECK: #{_upcase(target_name, packet_name, item_name)} == #{value}"
|
544
544
|
end
|
545
545
|
end
|
546
546
|
|
@@ -621,17 +621,17 @@ module OpenC3
|
|
621
621
|
value = 0 unless value
|
622
622
|
time_diff = Time.now.sys - start_time
|
623
623
|
if success
|
624
|
-
|
624
|
+
puts "#{type}: #{target_name.upcase} #{packet_name.upcase} received #{value - initial_count} times after waiting #{time_diff} seconds" unless quiet
|
625
625
|
else
|
626
626
|
message = "#{type}: #{target_name.upcase} #{packet_name.upcase} expected to be received #{num_packets} times but only received #{value - initial_count} times after waiting #{time_diff} seconds"
|
627
627
|
if check
|
628
628
|
if $disconnect
|
629
|
-
|
629
|
+
puts "ERROR: #{message}"
|
630
630
|
else
|
631
631
|
raise CheckError, message
|
632
632
|
end
|
633
633
|
else
|
634
|
-
|
634
|
+
puts "WARN: #{message}" unless quiet
|
635
635
|
end
|
636
636
|
end
|
637
637
|
time_diff
|
@@ -645,9 +645,9 @@ module OpenC3
|
|
645
645
|
wait_str = "WAIT: #{_upcase(target_name, packet_name, item_name)} #{comparison_to_eval}"
|
646
646
|
value_str = "with value == #{value} after waiting #{time_diff} seconds"
|
647
647
|
if success
|
648
|
-
|
648
|
+
puts "#{wait_str} success #{value_str}" unless quiet
|
649
649
|
else
|
650
|
-
|
650
|
+
puts "WARN: #{wait_str} failed #{value_str}" unless quiet
|
651
651
|
end
|
652
652
|
end
|
653
653
|
|
@@ -873,11 +873,11 @@ module OpenC3
|
|
873
873
|
value_str = value.is_a?(String) ? "'#{value}'" : value
|
874
874
|
with_value = "with value == #{value_str}"
|
875
875
|
if eval(string)
|
876
|
-
|
876
|
+
puts "#{check_str} success #{with_value}"
|
877
877
|
else
|
878
878
|
message = "#{check_str} failed #{with_value}"
|
879
879
|
if $disconnect
|
880
|
-
|
880
|
+
puts "ERROR: #{message}"
|
881
881
|
else
|
882
882
|
raise CheckError, message
|
883
883
|
end
|
@@ -69,12 +69,12 @@ module OpenC3
|
|
69
69
|
# NOTE: This is a helper method and should not be called directly
|
70
70
|
def _log_cmd(target_name, cmd_name, cmd_params, raw, no_range, no_hazardous)
|
71
71
|
if no_range
|
72
|
-
|
72
|
+
puts "WARN: Command #{target_name} #{cmd_name} being sent ignoring range checks"
|
73
73
|
end
|
74
74
|
if no_hazardous
|
75
|
-
|
75
|
+
puts "WARN: Command #{target_name} #{cmd_name} being sent ignoring hazardous warnings"
|
76
76
|
end
|
77
|
-
|
77
|
+
puts _cmd_string(target_name, cmd_name, cmd_params, raw)
|
78
78
|
end
|
79
79
|
|
80
80
|
def _cmd_disconnect(cmd, raw, no_range, no_hazardous, *args, scope: $openc3_scope)
|
@@ -95,7 +95,7 @@ module OpenC3
|
|
95
95
|
end
|
96
96
|
|
97
97
|
# Get the command and validate the parameters
|
98
|
-
command = $api_server.
|
98
|
+
command = $api_server.get_cmd(target_name, cmd_name, scope: scope)
|
99
99
|
cmd_params.each do |param_name, param_value|
|
100
100
|
param = command['items'].find { |item| item['name'] == param_name }
|
101
101
|
unless param
|
@@ -108,7 +108,7 @@ module OpenC3
|
|
108
108
|
# Send the command and log the results
|
109
109
|
# This method signature has to include the keyword params present in cmd_api.rb cmd_implementation()
|
110
110
|
# NOTE: This is a helper method and should not be called directly
|
111
|
-
def _cmd(cmd, cmd_no_hazardous, *args, scope: $openc3_scope, token: $openc3_token,
|
111
|
+
def _cmd(cmd, cmd_no_hazardous, *args, timeout: nil, log_message: nil, scope: $openc3_scope, token: $openc3_token, **kwargs)
|
112
112
|
extract_string_kwargs_to_args(args, kwargs)
|
113
113
|
raw = cmd.include?('raw')
|
114
114
|
no_range = cmd.include?('no_range') || cmd.include?('no_checks')
|
@@ -118,14 +118,18 @@ module OpenC3
|
|
118
118
|
_cmd_disconnect(cmd, raw, no_range, no_hazardous, *args, scope: scope)
|
119
119
|
else
|
120
120
|
begin
|
121
|
-
target_name, cmd_name, cmd_params = $api_server.method_missing(cmd, *args, scope: scope, token: token
|
122
|
-
|
121
|
+
target_name, cmd_name, cmd_params = $api_server.method_missing(cmd, *args, timeout: timeout, log_message: log_message, scope: scope, token: token)
|
122
|
+
if log_message.nil? or log_message
|
123
|
+
_log_cmd(target_name, cmd_name, cmd_params, raw, no_range, no_hazardous)
|
124
|
+
end
|
123
125
|
rescue HazardousError => e
|
124
126
|
# This opens a prompt at which point they can cancel and stop the script
|
125
127
|
# or say Yes and send the command. Thus we don't care about the return value.
|
126
128
|
prompt_for_hazardous(e.target_name, e.cmd_name, e.hazardous_description)
|
127
|
-
target_name, cmd_name, cmd_params = $api_server.method_missing(cmd_no_hazardous, *args, scope: scope, token: token
|
128
|
-
|
129
|
+
target_name, cmd_name, cmd_params = $api_server.method_missing(cmd_no_hazardous, *args, timeout: timeout, log_message: log_message, scope: scope, token: token)
|
130
|
+
if log_message.nil? or log_message
|
131
|
+
_log_cmd(target_name, cmd_name, cmd_params, raw, no_range, no_hazardous)
|
132
|
+
end
|
129
133
|
end
|
130
134
|
end
|
131
135
|
end
|
@@ -171,12 +175,14 @@ module OpenC3
|
|
171
175
|
# Builds a command binary
|
172
176
|
#
|
173
177
|
# Accepts two different calling styles:
|
174
|
-
#
|
175
|
-
#
|
176
|
-
def
|
178
|
+
# build_cmd("TGT CMD with PARAM1 val, PARAM2 val")
|
179
|
+
# build_cmd('TGT','CMD',{'PARAM1'=>val,'PARAM2'=>val})
|
180
|
+
def build_cmd(*args, range_check: true, raw: false, scope: $openc3_scope, **kwargs)
|
177
181
|
extract_string_kwargs_to_args(args, kwargs)
|
178
182
|
$api_server.build_command(*args)
|
179
183
|
end
|
184
|
+
# build_command is DEPRECATED
|
185
|
+
alias build_command build_cmd
|
180
186
|
|
181
187
|
# Returns whether the specified command is hazardous
|
182
188
|
#
|
data/lib/openc3/script/limits.rb
CHANGED
@@ -29,7 +29,7 @@ module OpenC3
|
|
29
29
|
define_method(method_name) do |*args, **kw_args, &block|
|
30
30
|
kw_args[:scope] = $openc3_scope unless kw_args[:scope]
|
31
31
|
if $disconnect
|
32
|
-
|
32
|
+
puts "DISCONNECT: #{method_name}(#{args}) ignored"
|
33
33
|
else
|
34
34
|
$api_server.public_send(method_name, *args, **kw_args, &block)
|
35
35
|
end
|
@@ -37,7 +37,7 @@ module OpenC3
|
|
37
37
|
# Only delete from the targets_modified
|
38
38
|
delete_path = "#{scope}/targets_modified/#{path}"
|
39
39
|
endpoint = "/openc3-api/storage/delete/#{delete_path}"
|
40
|
-
|
40
|
+
puts "Deleting #{delete_path}"
|
41
41
|
# Pass the name of the ENV variable name where we pull the actual bucket name
|
42
42
|
response = $api_server.request('delete', endpoint, query: { bucket: 'OPENC3_CONFIG_BUCKET' }, scope: scope)
|
43
43
|
if response.nil? || response.status != 200
|
@@ -65,7 +65,7 @@ module OpenC3
|
|
65
65
|
|
66
66
|
endpoint = "/openc3-api/storage/upload/#{upload_path}"
|
67
67
|
result = _get_presigned_request(endpoint, scope: scope)
|
68
|
-
|
68
|
+
puts "Writing #{upload_path}"
|
69
69
|
|
70
70
|
# Try to put the file
|
71
71
|
begin
|
@@ -104,7 +104,7 @@ module OpenC3
|
|
104
104
|
if part == "targets_modified" and ENV['OPENC3_LOCAL_MODE']
|
105
105
|
local_file = OpenC3::LocalMode.open_local_file(path, scope: scope)
|
106
106
|
if local_file
|
107
|
-
|
107
|
+
puts "Reading local #{scope}/#{part}/#{path}"
|
108
108
|
file = Tempfile.new('target', binmode: true)
|
109
109
|
file.filename = path
|
110
110
|
file.write(local_file.read)
|
@@ -138,7 +138,7 @@ module OpenC3
|
|
138
138
|
|
139
139
|
endpoint = "/openc3-api/storage/download/#{scope}/#{path}"
|
140
140
|
result = _get_presigned_request(endpoint, scope: scope)
|
141
|
-
|
141
|
+
puts "Reading #{scope}/#{path}"
|
142
142
|
|
143
143
|
# Try to get the file
|
144
144
|
uri = _get_uri(result['url'])
|