openc3 5.18.0 → 5.19.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/Gemfile +7 -4
- data/bin/cstol_converter +14 -14
- data/bin/openc3cli +189 -7
- data/data/config/_interfaces.yaml +1 -1
- data/data/config/command_modifiers.yaml +55 -0
- data/data/config/interface_modifiers.yaml +1 -1
- data/data/config/param_item_modifiers.yaml +1 -1
- data/data/config/parameter_modifiers.yaml +1 -1
- data/data/config/plugins.yaml +6 -2
- data/data/config/screen.yaml +2 -2
- data/data/config/table_manager.yaml +2 -2
- data/data/config/tool.yaml +4 -1
- data/data/config/widgets.yaml +3 -3
- data/ext/openc3/ext/config_parser/config_parser.c +1 -1
- data/ext/openc3/ext/packet/packet.c +1 -1
- data/ext/openc3/ext/platform/platform.c +3 -3
- data/ext/openc3/ext/structure/structure.c +56 -76
- data/lib/openc3/accessors/binary_accessor.rb +4 -4
- data/lib/openc3/accessors/form_accessor.rb +2 -2
- data/lib/openc3/accessors/http_accessor.rb +1 -1
- data/lib/openc3/accessors/json_accessor.rb +6 -4
- data/lib/openc3/accessors/template_accessor.rb +6 -9
- data/lib/openc3/accessors/xml_accessor.rb +1 -1
- data/lib/openc3/api/cmd_api.rb +35 -11
- data/lib/openc3/api/limits_api.rb +1 -1
- data/lib/openc3/config/config_parser.rb +1 -1
- data/lib/openc3/conversions/segmented_polynomial_conversion.rb +7 -7
- data/lib/openc3/core_ext/array.rb +5 -5
- data/lib/openc3/core_ext/exception.rb +9 -2
- data/lib/openc3/core_ext/string.rb +2 -2
- data/lib/openc3/interfaces/http_server_interface.rb +1 -0
- data/lib/openc3/interfaces/interface.rb +1 -1
- data/lib/openc3/interfaces/linc_interface.rb +3 -3
- data/lib/openc3/io/json_api.rb +11 -6
- data/lib/openc3/io/json_rpc.rb +1 -1
- data/lib/openc3/logs/buffered_packet_log_writer.rb +3 -3
- data/lib/openc3/logs/log_writer.rb +7 -8
- data/lib/openc3/logs/packet_log_writer.rb +7 -7
- data/lib/openc3/logs/text_log_writer.rb +4 -4
- data/lib/openc3/microservices/decom_microservice.rb +19 -4
- data/lib/openc3/microservices/interface_microservice.rb +41 -3
- data/lib/openc3/microservices/reaction_microservice.rb +2 -2
- data/lib/openc3/microservices/trigger_group_microservice.rb +3 -3
- data/lib/openc3/migrations/20240915000000_activity_uuid.rb +28 -0
- data/lib/openc3/models/activity_model.rb +109 -80
- data/lib/openc3/models/auth_model.rb +31 -2
- data/lib/openc3/models/cvt_model.rb +11 -5
- data/lib/openc3/models/gem_model.rb +8 -8
- data/lib/openc3/models/plugin_model.rb +3 -3
- data/lib/openc3/models/reducer_model.rb +2 -2
- data/lib/openc3/models/scope_model.rb +1 -1
- data/lib/openc3/models/sorted_model.rb +4 -4
- data/lib/openc3/models/target_model.rb +3 -3
- data/lib/openc3/models/tool_config_model.rb +1 -1
- data/lib/openc3/models/tool_model.rb +4 -4
- data/lib/openc3/models/widget_model.rb +11 -5
- data/lib/openc3/operators/operator.rb +5 -3
- data/lib/openc3/packets/command_validator.rb +48 -0
- data/lib/openc3/packets/commands.rb +6 -14
- data/lib/openc3/packets/packet.rb +31 -15
- data/lib/openc3/packets/packet_config.rb +10 -9
- data/lib/openc3/packets/parsers/packet_parser.rb +3 -3
- data/lib/openc3/packets/structure.rb +21 -13
- data/lib/openc3/packets/structure_item.rb +33 -47
- data/lib/openc3/packets/telemetry.rb +6 -27
- data/lib/openc3/script/api_shared.rb +7 -5
- data/lib/openc3/script/calendar.rb +2 -2
- data/lib/openc3/script/commands.rb +6 -4
- data/lib/openc3/script/metadata.rb +2 -2
- data/lib/openc3/script/suite.rb +17 -17
- data/lib/openc3/streams/serial_stream.rb +2 -3
- data/lib/openc3/streams/stream.rb +2 -2
- data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +10 -10
- data/lib/openc3/tools/table_manager/table_manager_core.rb +11 -11
- data/lib/openc3/tools/table_manager/table_parser.rb +2 -3
- data/lib/openc3/topics/command_decom_topic.rb +2 -1
- data/lib/openc3/topics/command_topic.rb +3 -3
- data/lib/openc3/topics/decom_interface_topic.rb +2 -2
- data/lib/openc3/topics/telemetry_decom_topic.rb +1 -1
- data/lib/openc3/utilities/authorization.rb +2 -1
- data/lib/openc3/utilities/cli_generator.rb +15 -8
- data/lib/openc3/utilities/cosmos_rails_formatter.rb +60 -0
- data/lib/openc3/utilities/crc.rb +6 -6
- data/lib/openc3/utilities/local_mode.rb +2 -1
- data/lib/openc3/utilities/logger.rb +44 -34
- data/lib/openc3/utilities/metric.rb +1 -2
- data/lib/openc3/utilities/quaternion.rb +18 -18
- data/lib/openc3/utilities/target_file.rb +4 -4
- data/lib/openc3/version.rb +5 -5
- data/lib/openc3/win32/win32_main.rb +2 -2
- data/templates/tool_angular/package.json +21 -21
- data/templates/tool_react/package.json +10 -10
- data/templates/tool_svelte/package.json +11 -11
- data/templates/tool_svelte/src/services/openc3-api.js +17 -17
- data/templates/tool_vue/package.json +9 -9
- data/templates/widget/package.json +6 -7
- metadata +5 -2
|
@@ -31,7 +31,7 @@ module OpenC3
|
|
|
31
31
|
#
|
|
32
32
|
# This should not be confused with the Api module which implements the JSON
|
|
33
33
|
# API that is used by tools when accessing the Server. The Api module always
|
|
34
|
-
# provides Ruby
|
|
34
|
+
# provides Ruby primitives where the Telemetry class can return actual
|
|
35
35
|
# Packet or PacketItem objects. While there are some overlapping methods between
|
|
36
36
|
# the two, these are separate interfaces into the system.
|
|
37
37
|
class Telemetry
|
|
@@ -295,7 +295,7 @@ module OpenC3
|
|
|
295
295
|
target = System.targets[target_name]
|
|
296
296
|
if target and target.tlm_unique_id_mode
|
|
297
297
|
# Iterate through the packets and see if any represent the buffer
|
|
298
|
-
target_packets.each do |
|
|
298
|
+
target_packets.each do |_packet_name, packet|
|
|
299
299
|
return packet if packet.identify?(packet_data)
|
|
300
300
|
end
|
|
301
301
|
else
|
|
@@ -365,43 +365,22 @@ module OpenC3
|
|
|
365
365
|
#
|
|
366
366
|
# @param limits_change_callback
|
|
367
367
|
def limits_change_callback=(limits_change_callback)
|
|
368
|
-
@config.telemetry.each do |
|
|
369
|
-
packets.each do |
|
|
368
|
+
@config.telemetry.each do |_target_name, packets|
|
|
369
|
+
packets.each do |_packet_name, packet|
|
|
370
370
|
packet.limits_change_callback = limits_change_callback
|
|
371
371
|
end
|
|
372
372
|
end
|
|
373
373
|
end
|
|
374
374
|
|
|
375
|
-
# Clears the received_count value on every packet in every target
|
|
376
|
-
def clear_counters
|
|
377
|
-
@config.telemetry.each do |target_name, target_packets|
|
|
378
|
-
target_packets.each do |packet_name, packet|
|
|
379
|
-
packet.received_count = 0
|
|
380
|
-
end
|
|
381
|
-
end
|
|
382
|
-
end
|
|
383
|
-
|
|
384
375
|
# Resets metadata on every packet in every target
|
|
385
376
|
def reset
|
|
386
|
-
@config.telemetry.each do |
|
|
387
|
-
target_packets.each do |
|
|
377
|
+
@config.telemetry.each do |_target_name, target_packets|
|
|
378
|
+
target_packets.each do |_packet_name, packet|
|
|
388
379
|
packet.reset
|
|
389
380
|
end
|
|
390
381
|
end
|
|
391
382
|
end
|
|
392
383
|
|
|
393
|
-
# Returns the first non-hidden packet
|
|
394
|
-
def first_non_hidden
|
|
395
|
-
@config.telemetry.each do |target_name, target_packets|
|
|
396
|
-
next if target_name == 'UNKNOWN'
|
|
397
|
-
|
|
398
|
-
target_packets.each do |packet_name, packet|
|
|
399
|
-
return packet unless packet.hidden
|
|
400
|
-
end
|
|
401
|
-
end
|
|
402
|
-
nil
|
|
403
|
-
end
|
|
404
|
-
|
|
405
384
|
# Returns an array with a "TARGET_NAME PACKET_NAME ITEM_NAME" string for every item in the system
|
|
406
385
|
def all_item_strings(include_hidden = false, splash = nil)
|
|
407
386
|
strings = []
|
|
@@ -14,13 +14,14 @@
|
|
|
14
14
|
# GNU Affero General Public License for more details.
|
|
15
15
|
|
|
16
16
|
# Modified by OpenC3, Inc.
|
|
17
|
-
# All changes Copyright
|
|
17
|
+
# All changes Copyright 2024, OpenC3, Inc.
|
|
18
18
|
# All Rights Reserved
|
|
19
19
|
#
|
|
20
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'
|
|
24
|
+
require 'openc3/script/exceptions'
|
|
24
25
|
|
|
25
26
|
module OpenC3
|
|
26
27
|
module ApiShared
|
|
@@ -460,8 +461,9 @@ module OpenC3
|
|
|
460
461
|
end
|
|
461
462
|
|
|
462
463
|
def set_line_delay(delay)
|
|
463
|
-
if defined? RunningScript
|
|
464
|
-
RunningScript.line_delay = delay
|
|
464
|
+
if defined? RunningScript and delay >= 0.0
|
|
465
|
+
RunningScript.line_delay = delay
|
|
466
|
+
puts "set_line_delay(#{delay})"
|
|
465
467
|
end
|
|
466
468
|
end
|
|
467
469
|
|
|
@@ -529,7 +531,7 @@ module OpenC3
|
|
|
529
531
|
###########################################################################
|
|
530
532
|
|
|
531
533
|
# This must be here for custom microservices that might block.
|
|
532
|
-
#
|
|
534
|
+
# Overridden by running_script.rb for script sleep
|
|
533
535
|
def openc3_script_sleep(sleep_time = nil)
|
|
534
536
|
if sleep_time
|
|
535
537
|
sleep(sleep_time)
|
|
@@ -544,7 +546,7 @@ module OpenC3
|
|
|
544
546
|
"#{target_name.upcase} #{packet_name.upcase} #{item_name.upcase}"
|
|
545
547
|
end
|
|
546
548
|
|
|
547
|
-
#
|
|
549
|
+
# Implementation of the various check commands. It yields back to the
|
|
548
550
|
# caller to allow the return of the value through various telemetry calls.
|
|
549
551
|
# This method should not be called directly by application code.
|
|
550
552
|
def _check(*args, scope: $openc3_scope, token: $openc3_token)
|
|
@@ -86,8 +86,8 @@ module OpenC3
|
|
|
86
86
|
return _handle_response(response, 'Failed to get timeline activity')
|
|
87
87
|
end
|
|
88
88
|
|
|
89
|
-
def delete_timeline_activity(name, start, scope: $openc3_scope, token: $openc3_token)
|
|
90
|
-
response = $api_server.request('delete', "/openc3-api/timeline/#{name}/activity/#{start}", scope: scope)
|
|
89
|
+
def delete_timeline_activity(name, start, uuid, scope: $openc3_scope, token: $openc3_token)
|
|
90
|
+
response = $api_server.request('delete', "/openc3-api/timeline/#{name}/activity/#{start}/#{uuid}", scope: scope)
|
|
91
91
|
return _handle_response(response, 'Failed to delete timeline activity')
|
|
92
92
|
end
|
|
93
93
|
|
|
@@ -106,9 +106,11 @@ 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
|
|
109
|
+
# This method signature has to include the keyword params present in cmd_api.rb _cmd_implementation()
|
|
110
|
+
# except for range_check, hazardous_check, and raw as they are part of the cmd name
|
|
111
|
+
# manual is always false since this is called from script and that is the default
|
|
110
112
|
# NOTE: This is a helper method and should not be called directly
|
|
111
|
-
def _cmd(cmd, cmd_no_hazardous, *args, timeout: nil, log_message: nil, scope: $openc3_scope, token: $openc3_token, **kwargs)
|
|
113
|
+
def _cmd(cmd, cmd_no_hazardous, *args, timeout: nil, log_message: nil, validate: true, scope: $openc3_scope, token: $openc3_token, **kwargs)
|
|
112
114
|
extract_string_kwargs_to_args(args, kwargs)
|
|
113
115
|
raw = cmd.include?('raw')
|
|
114
116
|
no_range = cmd.include?('no_range') || cmd.include?('no_checks')
|
|
@@ -118,7 +120,7 @@ module OpenC3
|
|
|
118
120
|
_cmd_disconnect(cmd, raw, no_range, no_hazardous, *args, scope: scope)
|
|
119
121
|
else
|
|
120
122
|
begin
|
|
121
|
-
target_name, cmd_name, cmd_params = $api_server.method_missing(cmd, *args, timeout: timeout, log_message: log_message, scope: scope, token: token)
|
|
123
|
+
target_name, cmd_name, cmd_params = $api_server.method_missing(cmd, *args, timeout: timeout, log_message: log_message, validate: validate, scope: scope, token: token)
|
|
122
124
|
if log_message.nil? or log_message
|
|
123
125
|
_log_cmd(target_name, cmd_name, cmd_params, raw, no_range, no_hazardous)
|
|
124
126
|
end
|
|
@@ -126,7 +128,7 @@ module OpenC3
|
|
|
126
128
|
# This opens a prompt at which point they can cancel and stop the script
|
|
127
129
|
# or say Yes and send the command. Thus we don't care about the return value.
|
|
128
130
|
prompt_for_hazardous(e.target_name, e.cmd_name, e.hazardous_description)
|
|
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)
|
|
131
|
+
target_name, cmd_name, cmd_params = $api_server.method_missing(cmd_no_hazardous, *args, timeout: timeout, log_message: log_message, validate: validate, scope: scope, token: token)
|
|
130
132
|
if log_message.nil? or log_message
|
|
131
133
|
_log_cmd(target_name, cmd_name, cmd_params, raw, no_range, no_hazardous)
|
|
132
134
|
end
|
|
@@ -34,7 +34,7 @@ module OpenC3
|
|
|
34
34
|
# @return The result of the method call.
|
|
35
35
|
def metadata_all(limit: 100, scope: $openc3_scope)
|
|
36
36
|
response = $api_server.request('get', "/openc3-api/metadata", query: { limit: limit }, scope: scope)
|
|
37
|
-
# Non-
|
|
37
|
+
# Non-existent just returns nil
|
|
38
38
|
return nil if response.nil? || response.status != 200
|
|
39
39
|
return JSON.parse(response.body, :allow_nan => true, :create_additions => true)
|
|
40
40
|
end
|
|
@@ -49,7 +49,7 @@ module OpenC3
|
|
|
49
49
|
else
|
|
50
50
|
response = $api_server.request('get', "/openc3-api/metadata/latest", scope: scope)
|
|
51
51
|
end
|
|
52
|
-
# Non-
|
|
52
|
+
# Non-existent just returns nil
|
|
53
53
|
return nil if response.nil? || response.status != 200
|
|
54
54
|
return JSON.parse(response.body, :allow_nan => true, :create_additions => true)
|
|
55
55
|
end
|
data/lib/openc3/script/suite.rb
CHANGED
|
@@ -42,7 +42,7 @@ module OpenC3
|
|
|
42
42
|
# START PUBLIC API
|
|
43
43
|
###########################################################################
|
|
44
44
|
|
|
45
|
-
#
|
|
45
|
+
# Explicitly avoid creating an initialize method which forces end users to call super()
|
|
46
46
|
|
|
47
47
|
# Add a group to the suite
|
|
48
48
|
def add_group(group_class)
|
|
@@ -84,8 +84,8 @@ module OpenC3
|
|
|
84
84
|
# END PUBLIC API
|
|
85
85
|
###########################################################################
|
|
86
86
|
|
|
87
|
-
def <=>(
|
|
88
|
-
self.name <=>
|
|
87
|
+
def <=>(other)
|
|
88
|
+
self.name <=> other.name
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
# Name of the suite
|
|
@@ -100,7 +100,7 @@ module OpenC3
|
|
|
100
100
|
# Returns the number of scripts in the suite including setup and teardown methods
|
|
101
101
|
def get_num_scripts
|
|
102
102
|
num_scripts = 0
|
|
103
|
-
@plans.each do |type, group_class,
|
|
103
|
+
@plans.each do |type, group_class, _script|
|
|
104
104
|
case type
|
|
105
105
|
when :GROUP
|
|
106
106
|
num_scripts += group_class.get_num_scripts
|
|
@@ -114,7 +114,7 @@ module OpenC3
|
|
|
114
114
|
end
|
|
115
115
|
|
|
116
116
|
# Run all the scripts
|
|
117
|
-
def run(&
|
|
117
|
+
def run(&)
|
|
118
118
|
ScriptResult.suite = name()
|
|
119
119
|
ScriptStatus.instance.total = get_num_scripts()
|
|
120
120
|
results = []
|
|
@@ -131,7 +131,7 @@ module OpenC3
|
|
|
131
131
|
@plans.each do |type, group_class, script|
|
|
132
132
|
case type
|
|
133
133
|
when :GROUP
|
|
134
|
-
results.concat(run_group(group_class, true, &
|
|
134
|
+
results.concat(run_group(group_class, true, &))
|
|
135
135
|
when :SCRIPT
|
|
136
136
|
result = run_script(group_class, script, true)
|
|
137
137
|
results << result
|
|
@@ -167,7 +167,7 @@ module OpenC3
|
|
|
167
167
|
end
|
|
168
168
|
|
|
169
169
|
# Run a specific group
|
|
170
|
-
def run_group(group_class, internal = false, &
|
|
170
|
+
def run_group(group_class, internal = false, &)
|
|
171
171
|
ScriptResult.suite = name() unless internal
|
|
172
172
|
|
|
173
173
|
# Determine if this group_class is in the plan and the number of scripts associated with this group_class
|
|
@@ -186,7 +186,7 @@ module OpenC3
|
|
|
186
186
|
|
|
187
187
|
if in_plan
|
|
188
188
|
ScriptStatus.instance.total = group_class.get_num_scripts() unless internal
|
|
189
|
-
results = @scripts[group_class].run(&
|
|
189
|
+
results = @scripts[group_class].run(&)
|
|
190
190
|
else
|
|
191
191
|
results = []
|
|
192
192
|
ScriptStatus.instance.total = num_scripts unless internal
|
|
@@ -278,7 +278,7 @@ module OpenC3
|
|
|
278
278
|
@@abort_on_exception = false
|
|
279
279
|
@@current_result = nil
|
|
280
280
|
|
|
281
|
-
#
|
|
281
|
+
# Explicitly avoid creating an initialize method which forces end users to call super()
|
|
282
282
|
|
|
283
283
|
def self.abort_on_exception
|
|
284
284
|
@@abort_on_exception
|
|
@@ -374,26 +374,26 @@ module OpenC3
|
|
|
374
374
|
result.result = :FAIL
|
|
375
375
|
RunningScript.instance.exceptions = nil
|
|
376
376
|
end
|
|
377
|
-
rescue StandardError, SyntaxError =>
|
|
377
|
+
rescue StandardError, SyntaxError => e
|
|
378
378
|
# Check that the error belongs to the StopScript inheritance chain
|
|
379
|
-
if
|
|
379
|
+
if e.class <= StopScript
|
|
380
380
|
result.stopped = true
|
|
381
381
|
result.result = :STOP
|
|
382
382
|
end
|
|
383
383
|
# Check that the error belongs to the SkipScript inheritance chain
|
|
384
|
-
if
|
|
384
|
+
if e.class <= SkipScript
|
|
385
385
|
result.result = :SKIP
|
|
386
386
|
result.message ||= ''
|
|
387
|
-
result.message <<
|
|
387
|
+
result.message << (e.message + "\n")
|
|
388
388
|
else
|
|
389
|
-
if
|
|
389
|
+
if e.class != StopScript and
|
|
390
390
|
(not RunningScript.instance or
|
|
391
391
|
not RunningScript.instance.exceptions or
|
|
392
|
-
not RunningScript.instance.exceptions.include?
|
|
392
|
+
not RunningScript.instance.exceptions.include? e)
|
|
393
393
|
result.exceptions ||= []
|
|
394
|
-
result.exceptions <<
|
|
394
|
+
result.exceptions << e
|
|
395
395
|
puts "*** Exception in Control Statement:"
|
|
396
|
-
|
|
396
|
+
e.formatted.each_line do |line|
|
|
397
397
|
puts ' ' + line
|
|
398
398
|
end
|
|
399
399
|
end
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
# This file may also be used under the terms of a commercial license
|
|
21
21
|
# if purchased from OpenC3, Inc.
|
|
22
22
|
|
|
23
|
-
require 'thread' # For Mutex
|
|
24
23
|
require 'openc3/streams/stream'
|
|
25
24
|
require 'openc3/config/config_parser'
|
|
26
25
|
require 'openc3/io/serial_driver'
|
|
@@ -40,11 +39,11 @@ module OpenC3
|
|
|
40
39
|
# @param parity [Symbol] Must be :NONE, :EVEN, or :ODD
|
|
41
40
|
# @param stop_bits [Integer] Stop bits. Must be 1 or 2.
|
|
42
41
|
# @param write_timeout [Integer] Seconds to wait for the write to complete.
|
|
43
|
-
# The {SerialDriver} will
|
|
42
|
+
# The {SerialDriver} will continuously try to send the data until
|
|
44
43
|
# it has been sent or an error occurs.
|
|
45
44
|
# @param read_timeout [Integer] Seconds to wait for the read to complete.
|
|
46
45
|
# Pass nil to block until the read is complete. The {SerialDriver} will
|
|
47
|
-
#
|
|
46
|
+
# continuously try to read data until it has received data or an error occurs.
|
|
48
47
|
# @param flow_control [Symbol] Currently supported :NONE and :RTSCTS (default :NONE)
|
|
49
48
|
# @param data_bits [Integer] Number of data bits (default 8)
|
|
50
49
|
def initialize(write_port_name,
|
|
@@ -17,11 +17,11 @@
|
|
|
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
|
|
24
|
-
# Class that
|
|
24
|
+
# Class that implements the following methods: read, write(data),
|
|
25
25
|
# connect, connected? and disconnect. Streams are simply data sources which
|
|
26
26
|
# {Protocol} classes read and write to. This separation of concerns
|
|
27
27
|
# allows Streams to simply focus on getting and sending raw data while the
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
module OpenC3
|
|
24
24
|
# Encapsulates an {Interface} in a Ruby thread. When the thread is started by
|
|
25
|
-
# the {#start} method, it loops trying to connect. It then
|
|
25
|
+
# the {#start} method, it loops trying to connect. It then continuously reads
|
|
26
26
|
# from the interface while handling the packets it receives.
|
|
27
27
|
class InterfaceThread
|
|
28
28
|
# The number of bytes to print when an UNKNOWN packet is received
|
|
@@ -82,8 +82,8 @@ module OpenC3
|
|
|
82
82
|
connect() unless @cancel_thread
|
|
83
83
|
end
|
|
84
84
|
break if @cancel_thread
|
|
85
|
-
rescue Exception =>
|
|
86
|
-
handle_connection_failed(
|
|
85
|
+
rescue Exception => e
|
|
86
|
+
handle_connection_failed(e)
|
|
87
87
|
if @cancel_thread
|
|
88
88
|
break
|
|
89
89
|
else
|
|
@@ -105,8 +105,8 @@ module OpenC3
|
|
|
105
105
|
end
|
|
106
106
|
end
|
|
107
107
|
packet.received_time = Time.now.sys unless packet.received_time
|
|
108
|
-
rescue Exception =>
|
|
109
|
-
handle_connection_lost(
|
|
108
|
+
rescue Exception => e
|
|
109
|
+
handle_connection_lost(e)
|
|
110
110
|
if @cancel_thread
|
|
111
111
|
break
|
|
112
112
|
else
|
|
@@ -120,12 +120,12 @@ module OpenC3
|
|
|
120
120
|
handle_connection_lost(nil) if !@interface.connected?
|
|
121
121
|
end
|
|
122
122
|
end # loop
|
|
123
|
-
rescue Exception =>
|
|
123
|
+
rescue Exception => e
|
|
124
124
|
if @fatal_exception_callback
|
|
125
|
-
@fatal_exception_callback.call(
|
|
125
|
+
@fatal_exception_callback.call(e)
|
|
126
126
|
else
|
|
127
127
|
Logger.error "Packet reading thread unexpectedly died for #{@interface.name}"
|
|
128
|
-
OpenC3.handle_fatal_exception(
|
|
128
|
+
OpenC3.handle_fatal_exception(e)
|
|
129
129
|
end
|
|
130
130
|
end
|
|
131
131
|
Logger.info "Stopped packet reading for #{@interface.name}"
|
|
@@ -207,8 +207,8 @@ module OpenC3
|
|
|
207
207
|
# Write to routers
|
|
208
208
|
@interface.routers.each do |router|
|
|
209
209
|
router.write(packet) if router.write_allowed? and router.connected?
|
|
210
|
-
rescue =>
|
|
211
|
-
Logger.error "Problem writing to router #{router.name} - #{
|
|
210
|
+
rescue => e
|
|
211
|
+
Logger.error "Problem writing to router #{router.name} - #{e.class}:#{e.message}"
|
|
212
212
|
end
|
|
213
213
|
|
|
214
214
|
# Write to packet log writers
|
|
@@ -50,8 +50,8 @@ module OpenC3
|
|
|
50
50
|
config = TableConfig.process_file(definition_filename)
|
|
51
51
|
begin
|
|
52
52
|
load_binary(config, binary)
|
|
53
|
-
rescue CoreError =>
|
|
54
|
-
report.puts "Error: #{
|
|
53
|
+
rescue CoreError => e
|
|
54
|
+
report.puts "Error: #{e.message}\n"
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
config.tables.each do |table_name, table|
|
|
@@ -83,7 +83,7 @@ module OpenC3
|
|
|
83
83
|
report.write "#{rowtext}, "
|
|
84
84
|
(0...table.num_columns).each do |c|
|
|
85
85
|
if table.type == :ROW_COLUMN
|
|
86
|
-
table_item = items[c + r * table.num_columns]
|
|
86
|
+
table_item = items[c + (r * table.num_columns)]
|
|
87
87
|
else
|
|
88
88
|
table_item = items[r]
|
|
89
89
|
end
|
|
@@ -104,7 +104,7 @@ module OpenC3
|
|
|
104
104
|
def self.generate(definition_filename)
|
|
105
105
|
config = TableConfig.process_file(definition_filename)
|
|
106
106
|
binary = ''
|
|
107
|
-
config.tables.each do |
|
|
107
|
+
config.tables.each do |_table_name, table|
|
|
108
108
|
table.restore_defaults
|
|
109
109
|
binary += table.buffer
|
|
110
110
|
end
|
|
@@ -125,7 +125,7 @@ module OpenC3
|
|
|
125
125
|
end
|
|
126
126
|
end
|
|
127
127
|
binary = ''
|
|
128
|
-
config.tables.each { |
|
|
128
|
+
config.tables.each { |_table_name, table| binary += table.buffer }
|
|
129
129
|
binary
|
|
130
130
|
end
|
|
131
131
|
|
|
@@ -137,8 +137,8 @@ module OpenC3
|
|
|
137
137
|
json = { tables: tables }
|
|
138
138
|
begin
|
|
139
139
|
load_binary(config, binary)
|
|
140
|
-
rescue CoreError =>
|
|
141
|
-
json['errors'] =
|
|
140
|
+
rescue CoreError => e
|
|
141
|
+
json['errors'] = e.message
|
|
142
142
|
end
|
|
143
143
|
config.tables.each do |table_name, table|
|
|
144
144
|
tables << {
|
|
@@ -150,7 +150,7 @@ module OpenC3
|
|
|
150
150
|
}
|
|
151
151
|
col = 0
|
|
152
152
|
row = 0
|
|
153
|
-
table.sorted_items.each_with_index do |item,
|
|
153
|
+
table.sorted_items.each_with_index do |item, _index|
|
|
154
154
|
next if item.hidden
|
|
155
155
|
if table.num_columns == 1
|
|
156
156
|
if row == 0
|
|
@@ -197,10 +197,10 @@ module OpenC3
|
|
|
197
197
|
def self.load_binary(config, data)
|
|
198
198
|
binary_data_index = 0
|
|
199
199
|
total_table_length = 0
|
|
200
|
-
config.tables.each do |
|
|
200
|
+
config.tables.each do |_table_name, table|
|
|
201
201
|
total_table_length += table.length
|
|
202
202
|
end
|
|
203
|
-
config.tables.each do |
|
|
203
|
+
config.tables.each do |_table_name, table|
|
|
204
204
|
if binary_data_index + table.length > data.length
|
|
205
205
|
table.buffer = data[binary_data_index..-1]
|
|
206
206
|
raise MismatchError,
|
|
@@ -213,7 +213,7 @@ module OpenC3
|
|
|
213
213
|
if binary_data_index < data.length
|
|
214
214
|
raise MismatchError,
|
|
215
215
|
"Binary size of #{data.length} larger than table definition of length #{total_table_length}. "+
|
|
216
|
-
"Discarding the
|
|
216
|
+
"Discarding the remaining #{data.length - binary_data_index} bytes."
|
|
217
217
|
end
|
|
218
218
|
end
|
|
219
219
|
|
|
@@ -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/parsers/packet_parser'
|
|
@@ -29,7 +29,7 @@ module OpenC3
|
|
|
29
29
|
# @param parser [ConfigParser] Configuration parser
|
|
30
30
|
# @param tables [Hash] Hash of the currently defined tables
|
|
31
31
|
# @param warnings [Array<String>] Any warning strings generated while
|
|
32
|
-
# parsing this command will be
|
|
32
|
+
# parsing this command will be appended to this array
|
|
33
33
|
def self.parse_table(parser, tables, warnings)
|
|
34
34
|
parser = TableParser.new(parser)
|
|
35
35
|
parser.verify_parameters
|
|
@@ -76,7 +76,6 @@ module OpenC3
|
|
|
76
76
|
TableParser.finish_create_table(table, tables, warnings)
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
-
protected
|
|
80
79
|
|
|
81
80
|
def self.check_for_duplicate(tables, table)
|
|
82
81
|
msg = nil
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
# GNU Affero General Public License for more details.
|
|
15
15
|
|
|
16
16
|
# Modified by OpenC3, Inc.
|
|
17
|
-
# All changes Copyright
|
|
17
|
+
# All changes Copyright 2024, OpenC3, Inc.
|
|
18
18
|
# All Rights Reserved
|
|
19
19
|
#
|
|
20
20
|
# This file may also be used under the terms of a commercial license
|
|
@@ -39,6 +39,7 @@ module OpenC3
|
|
|
39
39
|
json_hash[item.name + "__F"] = packet.read_item(item, :FORMATTED) if item.format_string
|
|
40
40
|
json_hash[item.name + "__U"] = packet.read_item(item, :WITH_UNITS) if item.units
|
|
41
41
|
end
|
|
42
|
+
json_hash['extra'] = JSON.generate(packet.extra.as_json(:allow_nan => true))
|
|
42
43
|
msg_hash['json_data'] = JSON.generate(json_hash.as_json(:allow_nan => true))
|
|
43
44
|
EphemeralStoreQueued.write_topic(topic, msg_hash)
|
|
44
45
|
end
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
# GNU Affero General Public License for more details.
|
|
15
15
|
|
|
16
16
|
# Modified by OpenC3, Inc.
|
|
17
|
-
# All changes Copyright
|
|
17
|
+
# All changes Copyright 2024, OpenC3, Inc.
|
|
18
18
|
# All Rights Reserved
|
|
19
19
|
#
|
|
20
20
|
# This file may also be used under the terms of a commercial license
|
|
@@ -26,7 +26,7 @@ require 'openc3/utilities/open_telemetry'
|
|
|
26
26
|
|
|
27
27
|
module OpenC3
|
|
28
28
|
class CommandTopic < Topic
|
|
29
|
-
COMMAND_ACK_TIMEOUT_S =
|
|
29
|
+
COMMAND_ACK_TIMEOUT_S = 30
|
|
30
30
|
|
|
31
31
|
def self.write_packet(packet, scope:)
|
|
32
32
|
topic = "#{scope}__COMMAND__{#{packet.target_name}}__#{packet.packet_name}"
|
|
@@ -52,7 +52,7 @@ module OpenC3
|
|
|
52
52
|
cmd_id = Topic.write_topic("{#{scope}__CMD}TARGET__#{command['target_name']}", command, '*', 100)
|
|
53
53
|
time = Time.now
|
|
54
54
|
while (Time.now - time) < timeout
|
|
55
|
-
Topic.read_topics([ack_topic]) do |
|
|
55
|
+
Topic.read_topics([ack_topic]) do |_topic, _msg_id, msg_hash, _redis|
|
|
56
56
|
if msg_hash["id"] == cmd_id
|
|
57
57
|
if msg_hash["result"] == "SUCCESS"
|
|
58
58
|
return [command['target_name'], command['cmd_name'], cmd_params]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# encoding: ascii-8bit
|
|
2
2
|
|
|
3
|
-
# Copyright
|
|
3
|
+
# Copyright 2024 OpenC3, Inc.
|
|
4
4
|
# All Rights Reserved.
|
|
5
5
|
#
|
|
6
6
|
# This program is free software; you can modify and/or redistribute it
|
|
@@ -37,7 +37,7 @@ module OpenC3
|
|
|
37
37
|
timeout = 5 # Arbitrary 5s timeout
|
|
38
38
|
time = Time.now
|
|
39
39
|
while (Time.now - time) < timeout
|
|
40
|
-
Topic.read_topics([ack_topic]) do |
|
|
40
|
+
Topic.read_topics([ack_topic]) do |_topic, _msg_id, msg_hash, _redis|
|
|
41
41
|
if msg_hash["id"] == decom_id
|
|
42
42
|
if msg_hash["result"] == "SUCCESS"
|
|
43
43
|
return msg_hash
|
|
@@ -32,7 +32,7 @@ module OpenC3
|
|
|
32
32
|
# everything base name is RAW (including DERIVED)
|
|
33
33
|
# Request for WITH_UNITS, etc will look down until it finds something
|
|
34
34
|
# If nothing - item does not exist - nil
|
|
35
|
-
# __ as
|
|
35
|
+
# __ as separators ITEM1, ITEM1__C, ITEM1__F, ITEM1__U
|
|
36
36
|
|
|
37
37
|
json_hash = CvtModel.build_json_from_packet(packet)
|
|
38
38
|
# Write to stream
|
|
@@ -43,9 +43,10 @@ rescue LoadError
|
|
|
43
43
|
if $openc3_authorize
|
|
44
44
|
raise AuthError.new("Token is required") unless token
|
|
45
45
|
unless OpenC3::AuthModel.verify(token)
|
|
46
|
-
raise AuthError.new("Password is invalid
|
|
46
|
+
raise AuthError.new("Password is invalid")
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
|
+
return "anonymous"
|
|
49
50
|
end
|
|
50
51
|
|
|
51
52
|
def user_info(_token)
|
|
@@ -41,10 +41,17 @@ module OpenC3
|
|
|
41
41
|
abort("No gemspec file detected. #{args[0].to_s.downcase} generator should be run within an existing plugin.")
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
gen_lang = ENV['OPENC3_LANGUAGE']
|
|
45
|
+
if (args[-1] == '--python' || args[-1] == '--ruby')
|
|
46
|
+
gen_lang = args[-1][2, 6]
|
|
47
|
+
end
|
|
48
|
+
case gen_lang
|
|
49
|
+
when 'python'
|
|
45
50
|
@@language = 'py'
|
|
46
|
-
|
|
51
|
+
when 'ruby'
|
|
47
52
|
@@language = 'rb'
|
|
53
|
+
else
|
|
54
|
+
abort("One of --python or --ruby is required unless OPENC3_LANGUAGE is set.")
|
|
48
55
|
end
|
|
49
56
|
end
|
|
50
57
|
|
|
@@ -72,8 +79,8 @@ module OpenC3
|
|
|
72
79
|
end
|
|
73
80
|
|
|
74
81
|
def self.generate_plugin(args)
|
|
75
|
-
if args.length
|
|
76
|
-
abort("Usage: cli generate #{args[0]} <NAME>")
|
|
82
|
+
if args.length < 2 or args.length > 3
|
|
83
|
+
abort("Usage: cli generate #{args[0]} <NAME> (--ruby or --python)")
|
|
77
84
|
end
|
|
78
85
|
|
|
79
86
|
# Create the local variables
|
|
@@ -196,8 +203,8 @@ module OpenC3
|
|
|
196
203
|
end
|
|
197
204
|
|
|
198
205
|
def self.generate_widget(args)
|
|
199
|
-
if args.length
|
|
200
|
-
abort("Usage: cli generate #{args[0]} <SuperdataWidget>")
|
|
206
|
+
if args.length < 2 or args.length > 3
|
|
207
|
+
abort("Usage: cli generate #{args[0]} <SuperdataWidget> (--ruby or --python)")
|
|
201
208
|
end
|
|
202
209
|
# Per https://stackoverflow.com/a/47591707/453280
|
|
203
210
|
if args[1] !~ /.*Widget$/ or args[1][0...-6] != args[1][0...-6].capitalize
|
|
@@ -242,8 +249,8 @@ module OpenC3
|
|
|
242
249
|
end
|
|
243
250
|
|
|
244
251
|
def self.generate_tool(args)
|
|
245
|
-
if args.length
|
|
246
|
-
abort("Usage: cli generate #{args[0]} 'Tool Name'")
|
|
252
|
+
if args.length < 2 or args.length > 3
|
|
253
|
+
abort("Usage: cli generate #{args[0]} 'Tool Name' (--ruby or --python)")
|
|
247
254
|
end
|
|
248
255
|
|
|
249
256
|
# Create the local variables
|