cosmos 3.9.1 → 3.9.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -3
- data/Manifest.txt +7 -0
- data/autohotkey/tools/cmd_extractor.ahk +17 -0
- data/autohotkey/tools/tlm_extractor.ahk +62 -1
- data/bin/cosmos +182 -12
- data/data/crc.txt +35 -34
- data/demo/config/data/crc.txt +6 -2
- data/demo/config/targets/INST/screens/adcs.txt +1 -1
- data/demo/config/tools/cmd_tlm_server/cmd_tlm_server2.txt +1 -1
- data/demo/config/tools/example_application.css +58 -0
- data/demo/config/tools/launcher/launcher.css +7 -0
- data/demo/config/tools/launcher/launcher2.css +10 -0
- data/demo/config/tools/test_runner/test_runner.css +45 -0
- data/ext/cosmos/ext/packet/packet.c +6 -0
- data/lib/cosmos/gui/dialogs/scroll_text_dialog.rb +15 -6
- data/lib/cosmos/gui/qt_tool.rb +58 -8
- data/lib/cosmos/gui/text/ruby_editor.rb +54 -6
- data/lib/cosmos/gui/utilities/analyze_log.rb +153 -0
- data/lib/cosmos/interfaces/interface.rb +6 -0
- data/lib/cosmos/packets/packet_item_limits.rb +14 -2
- data/lib/cosmos/packets/structure_item.rb +22 -3
- data/lib/cosmos/script/cmd_tlm_server.rb +28 -0
- data/lib/cosmos/script/extract.rb +10 -9
- data/lib/cosmos/script/tools.rb +10 -4
- data/lib/cosmos/system/system.rb +2 -1
- data/lib/cosmos/tools/cmd_extractor/cmd_extractor.rb +12 -0
- data/lib/cosmos/tools/cmd_tlm_server/api.rb +84 -0
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +3 -2
- data/lib/cosmos/tools/cmd_tlm_server/commanding.rb +9 -0
- data/lib/cosmos/tools/cmd_tlm_server/gui/interfaces_tab.rb +2 -2
- data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +26 -17
- data/lib/cosmos/tools/cmd_tlm_server/interfaces.rb +26 -0
- data/lib/cosmos/tools/cmd_tlm_server/packet_logging.rb +29 -0
- data/lib/cosmos/tools/cmd_tlm_server/routers.rb +33 -0
- data/lib/cosmos/tools/data_viewer/data_viewer.rb +1 -1
- data/lib/cosmos/tools/launcher/launcher.rb +14 -25
- data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +3 -7
- data/lib/cosmos/tools/packet_viewer/packet_viewer.rb +6 -4
- data/lib/cosmos/tools/script_runner/script_runner.rb +58 -9
- data/lib/cosmos/tools/script_runner/script_runner_frame.rb +45 -19
- data/lib/cosmos/tools/table_manager/table_manager.rb +7 -7
- data/lib/cosmos/tools/test_runner/test_runner.rb +6 -0
- data/lib/cosmos/tools/tlm_extractor/tlm_extractor.rb +145 -8
- data/lib/cosmos/tools/tlm_extractor/tlm_extractor_config.rb +89 -19
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_config.rb +14 -0
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_realtime_thread.rb +1 -1
- data/lib/cosmos/tools/tlm_viewer/screen.rb +15 -3
- data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +23 -12
- data/lib/cosmos/version.rb +4 -4
- data/spec/packets/packet_item_limits_spec.rb +33 -6
- data/spec/packets/packet_item_spec.rb +9 -9
- data/spec/packets/packet_spec.rb +18 -6
- data/spec/packets/structure_item_spec.rb +22 -4
- data/spec/script/cmd_tlm_server_spec.rb +66 -0
- data/spec/script/extract_spec.rb +144 -0
- data/spec/script/tools_spec.rb +17 -2
- data/spec/system/system_spec.rb +1 -1
- data/spec/tools/cmd_tlm_server/api_spec.rb +6 -0
- data/spec/tools/cmd_tlm_server/cmd_tlm_server_spec.rb +1 -1
- data/spec/tools/table_manager/table_item_parser_spec.rb +61 -0
- data/spec/tools/table_manager/table_item_spec.rb +1 -1
- metadata +9 -2
@@ -0,0 +1,153 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
# Copyright 2014 Ball Aerospace & Technologies Corp.
|
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 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
|
+
module Cosmos
|
12
|
+
|
13
|
+
# Class to analyze log files and report packet counts.
|
14
|
+
class AnalyzeLog
|
15
|
+
|
16
|
+
def initialize(parent, packet_log_frame)
|
17
|
+
@parent = parent
|
18
|
+
@packet_log_frame = packet_log_frame
|
19
|
+
@input_filenames = []
|
20
|
+
@packet_log_reader = System.default_packet_log_reader.new
|
21
|
+
@time_start = nil
|
22
|
+
@time_end = nil
|
23
|
+
@cancel = false
|
24
|
+
end
|
25
|
+
|
26
|
+
def analyze_log_files
|
27
|
+
@cancel = false
|
28
|
+
pkt_counts = {}
|
29
|
+
begin
|
30
|
+
@packet_log_reader = @packet_log_frame.packet_log_reader
|
31
|
+
@input_filenames = @packet_log_frame.filenames.sort
|
32
|
+
@time_start = @packet_log_frame.time_start
|
33
|
+
@time_end = @packet_log_frame.time_end
|
34
|
+
unless @input_filenames and @input_filenames[0]
|
35
|
+
Qt::MessageBox.critical(@parent, 'Error', 'Please select at least 1 input file')
|
36
|
+
return
|
37
|
+
end
|
38
|
+
|
39
|
+
ProgressDialog.execute(@parent, # parent
|
40
|
+
'Log File Progress', # title
|
41
|
+
600, # width, height
|
42
|
+
300) do |progress_dialog|
|
43
|
+
progress_dialog.cancel_callback = method(:cancel_callback)
|
44
|
+
progress_dialog.enable_cancel_button
|
45
|
+
|
46
|
+
begin
|
47
|
+
Cosmos.set_working_dir do
|
48
|
+
pkt_counts = analyze_files(progress_dialog)
|
49
|
+
end
|
50
|
+
ensure
|
51
|
+
progress_dialog.complete
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
if !@cancel
|
56
|
+
results = "Log Analysis Complete.\n"
|
57
|
+
results << "Log Reader: #{@packet_log_reader.class.to_s}\n"
|
58
|
+
if @time_start
|
59
|
+
results << "Start time: #{@time_start.formatted}\n"
|
60
|
+
else
|
61
|
+
results << "Start time: not specified\n"
|
62
|
+
end
|
63
|
+
if @time_end
|
64
|
+
results << "End time: #{@time_end.formatted}\n"
|
65
|
+
else
|
66
|
+
results << "End time: not specified\n"
|
67
|
+
end
|
68
|
+
results << "\n"
|
69
|
+
|
70
|
+
if pkt_counts.empty?
|
71
|
+
results << "No files analyzed"
|
72
|
+
else
|
73
|
+
if pkt_counts.keys.size > 1
|
74
|
+
pkt_counts_total = {}
|
75
|
+
pkt_counts.each do |file, counts|
|
76
|
+
counts.each do |pkt, count|
|
77
|
+
pkt_counts_total[pkt] ||= 0
|
78
|
+
pkt_counts_total[pkt] += count
|
79
|
+
end
|
80
|
+
end
|
81
|
+
results << "Total count of packets found in all files:\n"
|
82
|
+
pkt_counts_total.keys.sort.each do |pkt|
|
83
|
+
results << "#{pkt}: #{pkt_counts_total[pkt]}\n"
|
84
|
+
end
|
85
|
+
results << "\n"
|
86
|
+
end
|
87
|
+
|
88
|
+
pkt_counts.each do |file, counts|
|
89
|
+
results << "Packets found in file: #{file}\n"
|
90
|
+
if counts.empty?
|
91
|
+
results << " No packets found\n"
|
92
|
+
else
|
93
|
+
counts.keys.sort.each do |pkt|
|
94
|
+
results << "#{pkt}: #{counts[pkt]}\n"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
results << "\n"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
ScrollTextDialog.new(@parent, 'Packet Counts', results)
|
101
|
+
end
|
102
|
+
|
103
|
+
rescue => error
|
104
|
+
Qt::MessageBox.critical(@parent, 'Error!', "Error Analyzing Log File(s)\n#{error.formatted}")
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def analyze_files(progress_dialog)
|
109
|
+
log_file_count = 1
|
110
|
+
pkt_counts = {}
|
111
|
+
@input_filenames.each do |log_file|
|
112
|
+
break if @cancel
|
113
|
+
begin
|
114
|
+
Cosmos.check_log_configuration(@packet_log_reader, log_file)
|
115
|
+
file_size = File.size(log_file).to_f
|
116
|
+
progress_dialog.append_text("Analyzing File #{log_file_count}/#{@input_filenames.length}: #{log_file}")
|
117
|
+
progress_dialog.set_step_progress(0.0)
|
118
|
+
@packet_log_reader.each(
|
119
|
+
log_file, # log filename
|
120
|
+
true, # identify and define packet
|
121
|
+
@time_start,
|
122
|
+
@time_end) do |packet|
|
123
|
+
|
124
|
+
break if @cancel
|
125
|
+
progress_dialog.set_step_progress(@packet_log_reader.bytes_read / file_size)
|
126
|
+
pkt_counts[log_file] ||= {}
|
127
|
+
pkt_counts[log_file]["#{packet.target_name} #{packet.packet_name}"] ||= 0
|
128
|
+
pkt_counts[log_file]["#{packet.target_name} #{packet.packet_name}"] += 1
|
129
|
+
end
|
130
|
+
progress_dialog.set_step_progress(1.0) if !@cancel
|
131
|
+
progress_dialog.set_overall_progress(log_file_count.to_f / @input_filenames.length.to_f) if !@cancel
|
132
|
+
rescue Exception => error
|
133
|
+
progress_dialog.append_text("Error analyzing: #{error.formatted}\n")
|
134
|
+
end
|
135
|
+
log_file_count += 1
|
136
|
+
end
|
137
|
+
return pkt_counts
|
138
|
+
end
|
139
|
+
|
140
|
+
def cancel_callback(progress_dialog = nil)
|
141
|
+
@cancel = true
|
142
|
+
return true, false
|
143
|
+
end
|
144
|
+
|
145
|
+
def self.execute(parent, packet_log_frame)
|
146
|
+
log_analyzer = AnalyzeLog.new(parent, packet_log_frame)
|
147
|
+
log_analyzer.analyze_log_files()
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
end # class AnalyzeLog
|
152
|
+
|
153
|
+
end # module Cosmos
|
@@ -53,6 +53,10 @@ module Cosmos
|
|
53
53
|
# read from the interface
|
54
54
|
attr_accessor :routers
|
55
55
|
|
56
|
+
# @return [Array<Routers>] Array of cmd routers that mirror packets
|
57
|
+
# sent from the interface
|
58
|
+
attr_accessor :cmd_routers
|
59
|
+
|
56
60
|
# @return [Integer] The number of packets read from this interface
|
57
61
|
attr_accessor :read_count
|
58
62
|
|
@@ -96,6 +100,7 @@ module Cosmos
|
|
96
100
|
@packet_log_writer_pairs = []
|
97
101
|
@raw_logger_pair = RawLoggerPair.new(@name)
|
98
102
|
@routers = []
|
103
|
+
@cmd_routers = []
|
99
104
|
@read_count = 0
|
100
105
|
@write_count = 0
|
101
106
|
@bytes_read = 0
|
@@ -193,6 +198,7 @@ module Cosmos
|
|
193
198
|
other_interface.disable_disconnect = self.disable_disconnect
|
194
199
|
other_interface.packet_log_writer_pairs = self.packet_log_writer_pairs.clone
|
195
200
|
other_interface.routers = self.routers.clone
|
201
|
+
other_interface.cmd_routers = self.cmd_routers.clone
|
196
202
|
other_interface.read_count = self.read_count
|
197
203
|
other_interface.write_count = self.write_count
|
198
204
|
other_interface.bytes_read = self.bytes_read
|
@@ -91,12 +91,24 @@ module Cosmos
|
|
91
91
|
end
|
92
92
|
|
93
93
|
def persistence_setting=(persistence_setting)
|
94
|
-
|
94
|
+
if 0.class == Integer
|
95
|
+
# Ruby version >= 2.4.0
|
96
|
+
raise ArgumentError, "persistence_setting must be an Integer but is a #{persistence_setting.class}" unless Integer === persistence_setting
|
97
|
+
else
|
98
|
+
# Ruby version < 2.4.0
|
99
|
+
raise ArgumentError, "persistence_setting must be a Fixnum but is a #{persistence_setting.class}" unless Fixnum === persistence_setting
|
100
|
+
end
|
95
101
|
@persistence_setting = persistence_setting
|
96
102
|
end
|
97
103
|
|
98
104
|
def persistence_count=(persistence_count)
|
99
|
-
|
105
|
+
if 0.class == Integer
|
106
|
+
# Ruby version >= 2.4.0
|
107
|
+
raise ArgumentError, "persistence_count must be an Integer but is a #{persistence_count.class}" unless Integer === persistence_count
|
108
|
+
else
|
109
|
+
# Ruby version < 2.4.0
|
110
|
+
raise ArgumentError, "persistence_count must be a Fixnum but is a #{persistence_count.class}" unless Fixnum === persistence_count
|
111
|
+
end
|
100
112
|
@persistence_count = persistence_count
|
101
113
|
end
|
102
114
|
|
@@ -104,7 +104,14 @@ module Cosmos
|
|
104
104
|
end
|
105
105
|
|
106
106
|
def bit_offset=(bit_offset)
|
107
|
-
|
107
|
+
if 0.class == Integer
|
108
|
+
# Ruby version >= 2.4.0
|
109
|
+
raise ArgumentError, "#{@name}: bit_offset must be an Integer" unless Integer === bit_offset
|
110
|
+
else
|
111
|
+
# Ruby version < 2.4.0
|
112
|
+
raise ArgumentError, "#{@name}: bit_offset must be a Fixnum" unless Fixnum === bit_offset
|
113
|
+
end
|
114
|
+
|
108
115
|
byte_aligned = ((bit_offset % 8) == 0)
|
109
116
|
if (@data_type == :FLOAT or @data_type == :STRING or @data_type == :BLOCK) and !byte_aligned
|
110
117
|
raise ArgumentError, "#{@name}: bit_offset for :FLOAT, :STRING, and :BLOCK items must be byte aligned"
|
@@ -118,7 +125,13 @@ module Cosmos
|
|
118
125
|
end
|
119
126
|
|
120
127
|
def bit_size=(bit_size)
|
121
|
-
|
128
|
+
if 0.class == Integer
|
129
|
+
# Ruby version >= 2.4.0
|
130
|
+
raise ArgumentError, "#{name}: bit_size must be an Integer" unless Integer === bit_size
|
131
|
+
else
|
132
|
+
# Ruby version < 2.4.0
|
133
|
+
raise ArgumentError, "#{name}: bit_size must be a Fixnum" unless Fixnum === bit_size
|
134
|
+
end
|
122
135
|
byte_multiple = ((bit_size % 8) == 0)
|
123
136
|
if bit_size <= 0 and (@data_type == :INT or @data_type == :UINT or @data_type == :FLOAT)
|
124
137
|
raise ArgumentError, "#{@name}: bit_size cannot be negative or zero for :INT, :UINT, and :FLOAT items: #{bit_size}"
|
@@ -150,7 +163,13 @@ module Cosmos
|
|
150
163
|
|
151
164
|
def array_size=(array_size)
|
152
165
|
if array_size
|
153
|
-
|
166
|
+
if 0.class == Integer
|
167
|
+
# Ruby version >= 2.4.0
|
168
|
+
raise ArgumentError, "#{@name}: array_size must be an Integer" unless Integer === array_size
|
169
|
+
else
|
170
|
+
# Ruby version < 2.4.0
|
171
|
+
raise ArgumentError, "#{@name}: array_size must be a Fixnum" unless Fixnum === array_size
|
172
|
+
end
|
154
173
|
raise ArgumentError, "#{@name}: array_size must be a multiple of bit_size" unless (@bit_size == 0 or (array_size % @bit_size == 0) or array_size < 0)
|
155
174
|
raise ArgumentError, "#{@name}: bit_size cannot be negative or zero for array items" if @bit_size <= 0
|
156
175
|
end
|
@@ -13,6 +13,10 @@ module Cosmos
|
|
13
13
|
module Script
|
14
14
|
private
|
15
15
|
|
16
|
+
def get_interface_targets(interface_name)
|
17
|
+
return $cmd_tlm_server.get_interface_targets(interface_name)
|
18
|
+
end
|
19
|
+
|
16
20
|
def get_interface_names
|
17
21
|
return $cmd_tlm_server.get_interface_names
|
18
22
|
end
|
@@ -49,6 +53,30 @@ module Cosmos
|
|
49
53
|
return $cmd_tlm_server.router_state(router_name)
|
50
54
|
end
|
51
55
|
|
56
|
+
def get_target_info(target_name)
|
57
|
+
return $cmd_tlm_server.get_target_info(target_name)
|
58
|
+
end
|
59
|
+
|
60
|
+
def get_interface_info(interface_name)
|
61
|
+
return $cmd_tlm_server.get_interface_info(interface_name)
|
62
|
+
end
|
63
|
+
|
64
|
+
def get_router_info(router_name)
|
65
|
+
return $cmd_tlm_server.get_router_info(router_name)
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_cmd_cnt(target_name, command_name)
|
69
|
+
return $cmd_tlm_server.get_cmd_cnt(target_name, command_name)
|
70
|
+
end
|
71
|
+
|
72
|
+
def get_tlm_cnt(target_name, packet_name)
|
73
|
+
return $cmd_tlm_server.get_tlm_cnt(target_name, packet_name)
|
74
|
+
end
|
75
|
+
|
76
|
+
def get_packet_logger_info(packet_logger_name)
|
77
|
+
return $cmd_tlm_server.get_packet_logger_info(packet_logger_name)
|
78
|
+
end
|
79
|
+
|
52
80
|
def get_cmd_log_filename(packet_log_writer_name = 'DEFAULT')
|
53
81
|
return $cmd_tlm_server.get_cmd_log_filename(packet_log_writer_name)
|
54
82
|
end
|
@@ -11,7 +11,7 @@
|
|
11
11
|
module Cosmos
|
12
12
|
|
13
13
|
module Extract
|
14
|
-
SCANNING_REGULAR_EXPRESSION = %r{ (?:"(?:[^\\"]|\\.)*") | (?:'(?:[^\\']|\\.)*') | (?:\[
|
14
|
+
SCANNING_REGULAR_EXPRESSION = %r{ (?:"(?:[^\\"]|\\.)*") | (?:'(?:[^\\']|\\.)*') | (?:\[(?:[^\\\[\]]|\\.)*\]) | \S+ }x #"
|
15
15
|
|
16
16
|
private
|
17
17
|
|
@@ -26,22 +26,23 @@ module Cosmos
|
|
26
26
|
|
27
27
|
def extract_fields_from_cmd_text(text)
|
28
28
|
split_string = text.split(/\s+with\s+/i, 2)
|
29
|
-
raise "ERROR:
|
29
|
+
raise "ERROR: text must not be empty" if split_string.length == 0
|
30
|
+
raise "ERROR: 'with' must be followed by parameters : #{text}" if (split_string.length == 1 and text =~ /\s*with\s*/i) or (split_string.length == 2 and split_string[1].empty?)
|
30
31
|
|
31
32
|
# Extract target_name and cmd_name
|
32
33
|
first_half = split_string[0].split
|
33
34
|
raise "ERROR: Both Target Name and Command Name must be given : #{text}" if first_half.length < 2
|
34
35
|
raise "ERROR: Only Target Name and Command Name must be given before 'with' : #{text}" if first_half.length > 2
|
35
36
|
target_name = first_half[0]
|
36
|
-
cmd_name
|
37
|
-
cmd_params
|
37
|
+
cmd_name = first_half[1]
|
38
|
+
cmd_params = {}
|
38
39
|
|
39
40
|
if split_string.length == 2
|
40
41
|
# Extract Command Parameters
|
41
42
|
second_half = split_string[1].scan(SCANNING_REGULAR_EXPRESSION)
|
42
|
-
keyword
|
43
|
-
value
|
44
|
-
comma
|
43
|
+
keyword = nil
|
44
|
+
value = nil
|
45
|
+
comma = nil
|
45
46
|
second_half.each do |item|
|
46
47
|
unless keyword
|
47
48
|
keyword = item
|
@@ -61,8 +62,8 @@ module Cosmos
|
|
61
62
|
end
|
62
63
|
add_cmd_parameter(keyword, value, cmd_params)
|
63
64
|
keyword = nil
|
64
|
-
value
|
65
|
-
comma
|
65
|
+
value = nil
|
66
|
+
comma = nil
|
66
67
|
end
|
67
68
|
if keyword
|
68
69
|
if value
|
data/lib/cosmos/script/tools.rb
CHANGED
@@ -18,18 +18,24 @@ module Cosmos
|
|
18
18
|
#######################################
|
19
19
|
|
20
20
|
def display(display_name, x_pos = nil, y_pos = nil)
|
21
|
-
run_tlm_viewer(
|
21
|
+
run_tlm_viewer("display", display_name) do |tlm_viewer|
|
22
22
|
tlm_viewer.display(display_name, x_pos, y_pos)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
26
|
def clear(display_name)
|
27
|
-
run_tlm_viewer(
|
27
|
+
run_tlm_viewer("clear", display_name) do |tlm_viewer|
|
28
28
|
tlm_viewer.clear(display_name)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
def
|
32
|
+
def clear_all(target = nil)
|
33
|
+
run_tlm_viewer("clear_all") do |tlm_viewer|
|
34
|
+
tlm_viewer.clear_all(target)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def run_tlm_viewer(action, display_name = '')
|
33
39
|
tlm_viewer = JsonDRbObject.new "localhost", System.ports['TLMVIEWER_API']
|
34
40
|
begin
|
35
41
|
yield tlm_viewer
|
@@ -48,7 +54,7 @@ module Cosmos
|
|
48
54
|
canceled = cosmos_script_sleep(1)
|
49
55
|
retry unless canceled
|
50
56
|
end
|
51
|
-
raise "Unable to Successfully Start Listening Telemetry Viewer:
|
57
|
+
raise "Unable to Successfully Start Listening Telemetry Viewer: Could not #{action} #{display_name}"
|
52
58
|
rescue Errno::ENOENT
|
53
59
|
raise "Display Screen File: #{display_name}.txt does not exist"
|
54
60
|
end
|
data/lib/cosmos/system/system.rb
CHANGED
@@ -60,7 +60,7 @@ module Cosmos
|
|
60
60
|
instance_attr_reader :limits_set
|
61
61
|
|
62
62
|
# Known COSMOS ports
|
63
|
-
KNOWN_PORTS = ['CTS_API', 'TLMVIEWER_API', 'CTS_PREIDENTIFIED']
|
63
|
+
KNOWN_PORTS = ['CTS_API', 'TLMVIEWER_API', 'CTS_PREIDENTIFIED', 'CTS_CMD_ROUTER']
|
64
64
|
# Known COSMOS paths
|
65
65
|
KNOWN_PATHS = ['LOGS', 'TMP', 'SAVED_CONFIG', 'TABLES', 'HANDBOOKS', 'PROCEDURES']
|
66
66
|
|
@@ -94,6 +94,7 @@ module Cosmos
|
|
94
94
|
@ports['CTS_API'] = 7777
|
95
95
|
@ports['TLMVIEWER_API'] = 7778
|
96
96
|
@ports['CTS_PREIDENTIFIED'] = 7779
|
97
|
+
@ports['CTS_CMD_ROUTER'] = 7780
|
97
98
|
|
98
99
|
@paths = {}
|
99
100
|
@paths['LOGS'] = File.join(USERPATH, 'outputs', 'logs')
|
@@ -14,6 +14,7 @@ Cosmos.catch_fatal_exception do
|
|
14
14
|
require 'cosmos/gui/dialogs/packet_log_dialog'
|
15
15
|
require 'cosmos/gui/dialogs/splash'
|
16
16
|
require 'cosmos/gui/dialogs/progress_dialog'
|
17
|
+
require 'cosmos/gui/utilities/analyze_log'
|
17
18
|
end
|
18
19
|
|
19
20
|
module Cosmos
|
@@ -52,6 +53,11 @@ module Cosmos
|
|
52
53
|
def initialize_actions
|
53
54
|
super()
|
54
55
|
|
56
|
+
# File Menu Actions
|
57
|
+
@analyze_log = Qt::Action.new(tr('&Analyze Logs'), self)
|
58
|
+
@analyze_log.statusTip = tr('Analyze log file packet counts')
|
59
|
+
@analyze_log.connect(SIGNAL('triggered()')) { analyze_log_files() }
|
60
|
+
|
55
61
|
# Mode Menu Actions
|
56
62
|
@include_raw = Qt::Action.new(tr('Include &Raw Data'), self)
|
57
63
|
@include_raw_keyseq = Qt::KeySequence.new(tr('Ctrl+R'))
|
@@ -63,6 +69,8 @@ module Cosmos
|
|
63
69
|
def initialize_menus
|
64
70
|
# File Menu
|
65
71
|
@file_menu = menuBar.addMenu(tr('&File'))
|
72
|
+
@file_menu.addAction(@analyze_log)
|
73
|
+
@file_menu.addSeparator()
|
66
74
|
@file_menu.addAction(@exit_action)
|
67
75
|
|
68
76
|
# Mode Menu
|
@@ -121,6 +129,10 @@ module Cosmos
|
|
121
129
|
# File Menu Handlers
|
122
130
|
###############################################################################
|
123
131
|
|
132
|
+
def analyze_log_files
|
133
|
+
AnalyzeLog.execute(self, @packet_log_frame)
|
134
|
+
end
|
135
|
+
|
124
136
|
def process_log_files
|
125
137
|
@cancel = false
|
126
138
|
begin
|
@@ -68,6 +68,7 @@ module Cosmos
|
|
68
68
|
'subscribe_packet_data',
|
69
69
|
'unsubscribe_packet_data',
|
70
70
|
'get_packet_data',
|
71
|
+
'get_interface_targets',
|
71
72
|
'get_interface_names',
|
72
73
|
'connect_interface',
|
73
74
|
'disconnect_interface',
|
@@ -77,6 +78,12 @@ module Cosmos
|
|
77
78
|
'connect_router',
|
78
79
|
'disconnect_router',
|
79
80
|
'router_state',
|
81
|
+
'get_target_info',
|
82
|
+
'get_interface_info',
|
83
|
+
'get_router_info',
|
84
|
+
'get_cmd_cnt',
|
85
|
+
'get_tlm_cnt',
|
86
|
+
'get_packet_logger_info',
|
80
87
|
'get_cmd_log_filename',
|
81
88
|
'get_tlm_log_filename',
|
82
89
|
'start_logging',
|
@@ -768,6 +775,11 @@ module Cosmos
|
|
768
775
|
# Methods for scripting
|
769
776
|
#
|
770
777
|
|
778
|
+
# @return [Array<String>] All the targets mapped to the given interface
|
779
|
+
def get_interface_targets(interface_name)
|
780
|
+
CmdTlmServer.interfaces.targets(interface_name)
|
781
|
+
end
|
782
|
+
|
771
783
|
# @return [Array<String>] All the interface names
|
772
784
|
def get_interface_names
|
773
785
|
CmdTlmServer.interfaces.names
|
@@ -841,6 +853,78 @@ module Cosmos
|
|
841
853
|
CmdTlmServer.routers.state(router_name)
|
842
854
|
end
|
843
855
|
|
856
|
+
# Get information about a target
|
857
|
+
#
|
858
|
+
# @param target_name [String] Target name
|
859
|
+
# @return [Array<Numeric, Numeric>] Array of \[cmd_cnt, tlm_cnt]
|
860
|
+
def get_target_info(target_name)
|
861
|
+
target = System.targets[target_name.upcase]
|
862
|
+
raise "Unknown target: #{target_name}" unless target
|
863
|
+
return [target.cmd_cnt, target.tlm_cnt]
|
864
|
+
end
|
865
|
+
|
866
|
+
# Get information about an interface
|
867
|
+
#
|
868
|
+
# @param interface_name [String] Interface name
|
869
|
+
# @return [Array<String, Numeric, Numeric, Numeric, Numeric, Numeric,
|
870
|
+
# Numeric, Numeric>] Array containing \[state, num clients,
|
871
|
+
# TX queue size, RX queue size, TX bytes, RX bytes, Command count,
|
872
|
+
# Telemetry count] for the interface
|
873
|
+
def get_interface_info(interface_name)
|
874
|
+
CmdTlmServer.interfaces.get_info(interface_name)
|
875
|
+
end
|
876
|
+
|
877
|
+
# Get information about a router
|
878
|
+
#
|
879
|
+
# @param router_name [String] Router name
|
880
|
+
# @return [Array<String, Numeric, Numeric, Numeric, Numeric, Numeric,
|
881
|
+
# Numeric, Numeric>] Array containing \[state, num clients,
|
882
|
+
# TX queue size, RX queue size, TX bytes, RX bytes, Pkts received,
|
883
|
+
# Pkts sent] for the router
|
884
|
+
def get_router_info(router_name)
|
885
|
+
CmdTlmServer.routers.get_info(router_name)
|
886
|
+
end
|
887
|
+
|
888
|
+
# Get the transmit count for a command packet
|
889
|
+
#
|
890
|
+
# @param target_name [String] Target name of the command
|
891
|
+
# @param command_name [String] Packet name of the command
|
892
|
+
# @return [Numeric] Transmit count for the command
|
893
|
+
def get_cmd_cnt(target_name, command_name)
|
894
|
+
packet = System.commands.packet(target_name, command_name)
|
895
|
+
return packet.received_count
|
896
|
+
end
|
897
|
+
|
898
|
+
# Get the receive count for a telemetry packet
|
899
|
+
#
|
900
|
+
# @param target_name [String] Name of the target
|
901
|
+
# @param packet_name [String] Name of the packet
|
902
|
+
# @return [Numeric] Receive count for the telemetry packet
|
903
|
+
def get_tlm_cnt(target_name, packet_name)
|
904
|
+
packet = System.telemetry.packet(target_name, packet_name)
|
905
|
+
return packet.received_count
|
906
|
+
end
|
907
|
+
|
908
|
+
# Get information about a packet logger.
|
909
|
+
#
|
910
|
+
# @param packet_logger_name [String] Name of the packet logger
|
911
|
+
# @return [Array<<Array<String>, Boolean, Numeric, String, Numeric,
|
912
|
+
# Boolean, Numeric, String, Numeric>] Array containing \[interfaces,
|
913
|
+
# cmd logging enabled, cmd queue size, cmd filename, cmd file size,
|
914
|
+
# tlm logging enabled, tlm queue size, tlm filename, tlm file size]
|
915
|
+
# for the packet logger
|
916
|
+
def get_packet_logger_info(packet_logger_name = 'DEFAULT')
|
917
|
+
logger_info = CmdTlmServer.packet_logging.get_info(packet_logger_name)
|
918
|
+
packet_log_writer_pair = CmdTlmServer.packet_logging.all[packet_logger_name.upcase]
|
919
|
+
interfaces = []
|
920
|
+
CmdTlmServer.interfaces.all.each do |interface_name, interface|
|
921
|
+
if interface.packet_log_writer_pairs.include?(packet_log_writer_pair)
|
922
|
+
interfaces << interface.name
|
923
|
+
end
|
924
|
+
end
|
925
|
+
return [interfaces] + logger_info
|
926
|
+
end
|
927
|
+
|
844
928
|
# @param packet_log_writer_name [String] The name of the packet log writer which
|
845
929
|
# is writing the command packet log
|
846
930
|
# @return [String] The command packet log filename
|