cosmos 4.0.3 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -5
- data/Manifest.txt +11 -1
- data/README.md +3 -2
- data/Rakefile +18 -4
- data/appveyor.yml +19 -0
- data/cosmos.gemspec +14 -3
- data/data/config/cmd_tlm_server.yaml +3 -0
- data/data/crc.txt +63 -60
- data/demo/config/targets/INST/cmd_tlm_server.txt +1 -0
- data/demo/config/targets/INST/cmd_tlm_server2.txt +7 -0
- data/demo/config/tools/cmd_sequence/cmd_sequence.txt +2 -0
- data/demo/config/tools/cmd_tlm_server/cmd_tlm_server.txt +8 -12
- data/demo/config/tools/cmd_tlm_server/cmd_tlm_server2.txt +7 -9
- data/demo/lib/cmd_sequence_exporter.rb +52 -0
- data/demo/lib/example_background_task.rb +1 -0
- data/demo/procedures/replay_test.rb +32 -0
- data/ext/cosmos/ext/structure/structure.c +39 -3
- data/install/config/tools/cmd_tlm_server/cmd_tlm_server.txt +1 -0
- data/install/config/tools/launcher/launcher.txt +2 -0
- data/lib/cosmos/config/config_parser.rb +2 -0
- data/lib/cosmos/core_ext/io.rb +89 -60
- data/lib/cosmos/gui/qt.rb +5 -8
- data/lib/cosmos/gui/qt_tool.rb +8 -8
- data/lib/cosmos/gui/text/ruby_editor.rb +12 -12
- data/lib/cosmos/gui/utilities/script_module_gui.rb +9 -9
- data/lib/cosmos/gui/widgets/realtime_button_bar.rb +18 -17
- data/lib/cosmos/interfaces/protocols/fixed_protocol.rb +2 -2
- data/lib/cosmos/interfaces/protocols/template_protocol.rb +3 -0
- data/lib/cosmos/interfaces/udp_interface.rb +27 -14
- data/lib/cosmos/io/buffered_file.rb +0 -1
- data/lib/cosmos/io/json_drb.rb +134 -214
- data/lib/cosmos/io/json_drb_object.rb +22 -61
- data/lib/cosmos/io/json_drb_rack.rb +79 -0
- data/lib/cosmos/io/json_rpc.rb +27 -0
- data/lib/cosmos/io/udp_sockets.rb +102 -58
- data/lib/cosmos/packets/commands.rb +1 -1
- data/lib/cosmos/packets/structure.rb +1 -1
- data/lib/cosmos/packets/structure_item.rb +37 -5
- data/lib/cosmos/script/cmd_tlm_server.rb +76 -2
- data/lib/cosmos/script/replay.rb +60 -0
- data/lib/cosmos/script/script.rb +20 -2
- data/lib/cosmos/script/scripting.rb +9 -9
- data/lib/cosmos/script/tools.rb +14 -0
- data/lib/cosmos/system/system.rb +185 -92
- data/lib/cosmos/system/target.rb +1 -1
- data/lib/cosmos/tools/cmd_sequence/cmd_sequence.rb +44 -4
- data/lib/cosmos/tools/cmd_sequence/sequence_item.rb +4 -0
- data/lib/cosmos/tools/cmd_sequence/sequence_list.rb +7 -0
- data/lib/cosmos/tools/cmd_tlm_server/api.rb +347 -20
- data/lib/cosmos/tools/cmd_tlm_server/background_tasks.rb +3 -0
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +329 -111
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +13 -0
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_gui.rb +261 -95
- data/lib/cosmos/tools/cmd_tlm_server/gui/interfaces_tab.rb +46 -35
- data/lib/cosmos/tools/cmd_tlm_server/gui/logging_tab.rb +18 -8
- data/lib/cosmos/tools/cmd_tlm_server/gui/packets_tab.rb +39 -28
- data/lib/cosmos/tools/cmd_tlm_server/gui/replay_tab.rb +242 -0
- data/lib/cosmos/tools/cmd_tlm_server/gui/status_tab.rb +24 -8
- data/lib/cosmos/tools/cmd_tlm_server/gui/targets_tab.rb +18 -6
- data/lib/cosmos/tools/cmd_tlm_server/limits_groups_background_task.rb +5 -4
- data/lib/cosmos/tools/cmd_tlm_server/replay_backend.rb +375 -0
- data/lib/cosmos/tools/cmd_tlm_server/routers.rb +10 -2
- data/lib/cosmos/tools/data_viewer/data_viewer.rb +40 -5
- data/lib/cosmos/tools/handbook_creator/handbook_creator_config.rb +18 -20
- data/lib/cosmos/tools/launcher/launcher_config.rb +5 -16
- data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +65 -39
- data/lib/cosmos/tools/packet_viewer/packet_viewer.rb +19 -0
- data/lib/cosmos/tools/replay/replay.rb +5 -505
- data/lib/cosmos/tools/script_runner/script_audit.rb +1 -0
- data/lib/cosmos/tools/script_runner/script_runner.rb +3 -4
- data/lib/cosmos/tools/script_runner/script_runner_config.rb +3 -4
- data/lib/cosmos/tools/script_runner/script_runner_frame.rb +44 -23
- data/lib/cosmos/tools/test_runner/results_writer.rb +4 -0
- data/lib/cosmos/tools/test_runner/test_runner.rb +0 -3
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_realtime_thread.rb +6 -2
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_tool.rb +26 -1
- data/lib/cosmos/tools/tlm_viewer/screen.rb +24 -1
- data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +25 -0
- data/lib/cosmos/tools/tlm_viewer/tlm_viewer_config.rb +24 -14
- data/lib/cosmos/top_level.rb +34 -24
- data/lib/cosmos/utilities/csv.rb +60 -8
- data/lib/cosmos/version.rb +5 -5
- data/spec/config/config_parser_spec.rb +10 -1
- data/spec/core_ext/socket_spec.rb +4 -2
- data/spec/gui/utilities/script_module_gui_spec.rb +102 -0
- data/spec/install/config/data/data.txt +1 -0
- data/spec/install/config/targets/INST/cmd_tlm/inst_cmds.txt +2 -0
- data/spec/interfaces/cmd_tlm_server_interface_spec.rb +1 -2
- data/spec/interfaces/protocols/template_protocol_spec.rb +72 -2
- data/spec/interfaces/serial_interface_spec.rb +1 -1
- data/spec/interfaces/udp_interface_spec.rb +14 -0
- data/spec/io/buffered_file_spec.rb +37 -0
- data/spec/io/json_drb_object_spec.rb +2 -15
- data/spec/io/json_drb_spec.rb +61 -121
- data/spec/io/udp_sockets_spec.rb +42 -2
- data/spec/packet_logs/packet_log_reader_spec.rb +5 -2
- data/spec/packets/binary_accessor_spec.rb +1 -1
- data/spec/packets/packet_item_spec.rb +1 -1
- data/spec/packets/structure_item_spec.rb +5 -6
- data/spec/script/cmd_tlm_server_spec.rb +39 -4
- data/spec/script/commands_disconnect_spec.rb +1 -1
- data/spec/script/commands_spec.rb +2 -1
- data/spec/script/scripting_spec.rb +18 -3
- data/spec/script/telemetry_spec.rb +5 -0
- data/spec/spec_helper.rb +43 -26
- data/spec/streams/tcpip_socket_stream_spec.rb +2 -2
- data/spec/system/system_spec.rb +11 -9
- data/spec/system/target_spec.rb +3 -0
- data/spec/tools/cmd_tlm_server/api_spec.rb +543 -29
- data/spec/tools/cmd_tlm_server/background_task_spec.rb +2 -2
- data/spec/tools/cmd_tlm_server/background_tasks_spec.rb +31 -75
- data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +199 -66
- data/spec/tools/cmd_tlm_server/cmd_tlm_server_spec.rb +85 -9
- data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +29 -127
- data/spec/tools/cmd_tlm_server/router_thread_spec.rb +10 -50
- data/spec/tools/launcher/launcher_config_spec.rb +1 -1
- data/spec/tools/table_manager/table_item_spec.rb +1 -1
- data/spec/tools/table_manager/tablemanager_core_spec.rb +4 -4
- data/spec/top_level/top_level_spec.rb +151 -3
- data/spec/utilities/csv_spec.rb +24 -5
- metadata +61 -9
- data/lib/cosmos/tools/replay/replay_server.rb +0 -91
@@ -38,7 +38,11 @@ module Cosmos
|
|
38
38
|
router = TcpipServerInterface.new(port, port, 10.0, nil, 'PREIDENTIFIED')
|
39
39
|
router.name = router_name
|
40
40
|
router.disable_disconnect = true
|
41
|
-
|
41
|
+
if CmdTlmServer.mode == :CMD_TLM_SERVER
|
42
|
+
router.set_option('LISTEN_ADDRESS', [System.listen_hosts['CTS_PREIDENTIFIED']])
|
43
|
+
else
|
44
|
+
router.set_option('LISTEN_ADDRESS', [System.listen_hosts['REPLAY_PREIDENTIFIED']])
|
45
|
+
end
|
42
46
|
router.set_option('AUTO_SYSTEM_META', [true])
|
43
47
|
@config.routers[router_name] = router
|
44
48
|
@config.interfaces.each do |interface_name, interface|
|
@@ -58,7 +62,11 @@ module Cosmos
|
|
58
62
|
cmd_router = TcpipServerInterface.new(port, nil, 10.0, nil, 'PREIDENTIFIED')
|
59
63
|
cmd_router.name = cmd_router_name
|
60
64
|
cmd_router.disable_disconnect = true
|
61
|
-
|
65
|
+
if CmdTlmServer.mode == :CMD_TLM_SERVER
|
66
|
+
cmd_router.set_option('LISTEN_ADDRESS', [System.listen_hosts['CTS_CMD_ROUTER']])
|
67
|
+
else
|
68
|
+
cmd_router.set_option('LISTEN_ADDRESS', [System.listen_hosts['REPLAY_CMD_ROUTER']])
|
69
|
+
end
|
62
70
|
cmd_router.set_option('AUTO_SYSTEM_META', [true])
|
63
71
|
@config.routers[cmd_router_name] = cmd_router
|
64
72
|
@config.interfaces.each do |interface_name, interface|
|
@@ -103,6 +103,10 @@ module Cosmos
|
|
103
103
|
@handle_reset.statusTip = tr('Reset Components')
|
104
104
|
@handle_reset.connect(SIGNAL('triggered()')) { handle_reset() }
|
105
105
|
|
106
|
+
@replay_action = Qt::Action.new(tr('Toggle Replay Mode'), self)
|
107
|
+
@replay_action.statusTip = tr('Toggle Replay Mode')
|
108
|
+
@replay_action.connect(SIGNAL('triggered()')) { toggle_replay_mode() }
|
109
|
+
|
106
110
|
# Search Actions
|
107
111
|
@search_find = Qt::Action.new(Cosmos.get_icon('search.png'), tr('&Find'), self)
|
108
112
|
@search_find_keyseq = Qt::KeySequence.new(tr('Ctrl+F'))
|
@@ -139,6 +143,7 @@ module Cosmos
|
|
139
143
|
file_menu = menuBar.addMenu(tr('&File'))
|
140
144
|
file_menu.addAction(@open_log)
|
141
145
|
file_menu.addAction(@handle_reset)
|
146
|
+
file_menu.addAction(@replay_action)
|
142
147
|
file_menu.addSeparator()
|
143
148
|
file_menu.addAction(@exit_action)
|
144
149
|
|
@@ -167,6 +172,11 @@ module Cosmos
|
|
167
172
|
# Create the top level vertical layout
|
168
173
|
@top_layout = Qt::VBoxLayout.new(@central_widget)
|
169
174
|
|
175
|
+
@replay_flag = Qt::Label.new("Replay Mode")
|
176
|
+
@replay_flag.setStyleSheet("background:green;color:white;padding:5px;font-weight:bold;")
|
177
|
+
@top_layout.addWidget(@replay_flag)
|
178
|
+
@replay_flag.hide
|
179
|
+
|
170
180
|
# Realtime Button Bar
|
171
181
|
@realtime_button_bar = RealtimeButtonBar.new(self)
|
172
182
|
@realtime_button_bar.start_callback = method(:handle_start)
|
@@ -196,6 +206,19 @@ module Cosmos
|
|
196
206
|
end
|
197
207
|
end
|
198
208
|
|
209
|
+
def toggle_replay_mode
|
210
|
+
running = (@realtime_button_bar.state == 'Running')
|
211
|
+
handle_stop()
|
212
|
+
handle_reset()
|
213
|
+
set_replay_mode(!get_replay_mode())
|
214
|
+
if get_replay_mode()
|
215
|
+
@replay_flag.show
|
216
|
+
else
|
217
|
+
@replay_flag.hide
|
218
|
+
end
|
219
|
+
handle_start if running
|
220
|
+
end
|
221
|
+
|
199
222
|
def handle_tab_change(index)
|
200
223
|
# Remove existing actions
|
201
224
|
@tab_menu_actions.each do |action|
|
@@ -246,6 +269,15 @@ module Cosmos
|
|
246
269
|
@cancel_thread = false
|
247
270
|
@sleeper = Sleeper.new
|
248
271
|
if !@packets.empty?
|
272
|
+
need_meta = true
|
273
|
+
@packets.each do |target_name, packet_name|
|
274
|
+
if target_name == 'SYSTEM' and packet_name == 'META'
|
275
|
+
need_meta = false
|
276
|
+
break
|
277
|
+
end
|
278
|
+
end
|
279
|
+
@packets << ['SYSTEM', 'META'] if need_meta
|
280
|
+
|
249
281
|
begin
|
250
282
|
while true
|
251
283
|
break if @cancel_thread
|
@@ -274,6 +306,7 @@ module Cosmos
|
|
274
306
|
begin
|
275
307
|
# Get a subscribed to packet
|
276
308
|
packet_data, target_name, packet_name, received_time, received_count = get_packet_data(@subscription_id)
|
309
|
+
break unless packet_data
|
277
310
|
|
278
311
|
# Put packet data into its packet
|
279
312
|
packet = System.telemetry.packet(target_name, packet_name)
|
@@ -281,6 +314,11 @@ module Cosmos
|
|
281
314
|
packet.received_time = received_time
|
282
315
|
packet.received_count = received_count
|
283
316
|
|
317
|
+
# Make sure we are on the right configuration
|
318
|
+
if target_name == 'SYSTEM' and packet_name == 'META'
|
319
|
+
System.load_configuration(packet.read('CONFIG'))
|
320
|
+
end
|
321
|
+
|
284
322
|
# Route packet to its component(s)
|
285
323
|
index = packet.target_name + ' ' + packet.packet_name
|
286
324
|
@component_mutex.synchronize do
|
@@ -337,6 +375,8 @@ module Cosmos
|
|
337
375
|
|
338
376
|
def handle_start
|
339
377
|
if windowTitle() != 'Data Viewer'
|
378
|
+
# Switch from log back to realtime/replay
|
379
|
+
|
340
380
|
# Clear Title
|
341
381
|
setWindowTitle('Data Viewer')
|
342
382
|
|
@@ -492,11 +532,6 @@ module Cosmos
|
|
492
532
|
end
|
493
533
|
|
494
534
|
def process_config(filename)
|
495
|
-
# ensure the file exists
|
496
|
-
unless test ?f, filename
|
497
|
-
raise "Configuration File Does not Exist: #{filename}"
|
498
|
-
end
|
499
|
-
|
500
535
|
parser = ConfigParser.new
|
501
536
|
parser.parse_file(filename) do |keyword, params|
|
502
537
|
case keyword
|
@@ -14,13 +14,13 @@ require 'tempfile'
|
|
14
14
|
require 'open3'
|
15
15
|
|
16
16
|
module Cosmos
|
17
|
-
|
18
17
|
# Reads an ascii file that defines the configuration settings used to
|
19
18
|
# configure the Handbook Creator
|
20
19
|
class HandbookCreatorConfig
|
21
|
-
|
22
20
|
attr_reader :pages
|
23
21
|
|
22
|
+
# Builds a page for the handbook. Pages can be either :NORMAL or :TARGETS.
|
23
|
+
# :TARGETS page builds pages for each of the targets in the system.
|
24
24
|
class Page
|
25
25
|
attr_reader :filename
|
26
26
|
attr_reader :type
|
@@ -103,7 +103,7 @@ module Cosmos
|
|
103
103
|
protected
|
104
104
|
|
105
105
|
def create_pdf_file(progress_dialog, target_name = nil)
|
106
|
-
tmp_html_file = Tempfile.new(['pdf', '.html'])
|
106
|
+
tmp_html_file = Tempfile.new(['pdf', '.html'], System.paths['HANDBOOKS'])
|
107
107
|
if target_name
|
108
108
|
filename = File.join(System.paths['HANDBOOKS'], target_name.downcase + @filename)
|
109
109
|
create_file(tmp_html_file, [target_name], true, :PDF)
|
@@ -118,13 +118,15 @@ module Cosmos
|
|
118
118
|
system_call = "wkhtmltopdf -L #{@pdf_side_margin} -R #{@pdf_side_margin} -T #{@pdf_top_margin} -B #{@pdf_bottom_margin} -s Letter #{header} #{footer} #{cover} #{@pdf_toc} \"#{tmp_html_file.path}\" \"#{File.dirname(filename)}/#{File.basename(filename, '.*')}.pdf\""
|
119
119
|
status = nil
|
120
120
|
begin
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
121
|
+
Cosmos.set_working_dir(System.paths['HANDBOOKS']) do
|
122
|
+
Open3.popen2e(system_call) do |stdin, stdout_and_stderr, wait_thr|
|
123
|
+
while wait_thr.alive?
|
124
|
+
stdout_and_stderr.each_line do |line|
|
125
|
+
progress_dialog.append_text(line.chomp) if progress_dialog
|
126
|
+
end
|
125
127
|
end
|
128
|
+
status = wait_thr.value
|
126
129
|
end
|
127
|
-
status = wait_thr.value
|
128
130
|
end
|
129
131
|
rescue Errno::ENOENT
|
130
132
|
status = nil
|
@@ -138,7 +140,7 @@ module Cosmos
|
|
138
140
|
|
139
141
|
def make_pdf_detail(tag, filename, title, target_name = nil)
|
140
142
|
if filename
|
141
|
-
file = Tempfile.new(['pdf', '.html'])
|
143
|
+
file = Tempfile.new(['pdf', '.html'], System.paths['HANDBOOKS'])
|
142
144
|
if target_name
|
143
145
|
title = target_name + ' ' + title
|
144
146
|
else
|
@@ -228,9 +230,9 @@ module Cosmos
|
|
228
230
|
end
|
229
231
|
packets
|
230
232
|
end
|
233
|
+
end
|
231
234
|
|
232
|
-
|
233
|
-
|
235
|
+
# Encapsulates a section of the PDF or webpage which can be :CMD, :TLM, or :NONE.
|
234
236
|
class Section
|
235
237
|
attr_reader :filename
|
236
238
|
attr_reader :type
|
@@ -248,8 +250,7 @@ module Cosmos
|
|
248
250
|
def create(file, title, packets = [], ignored = {})
|
249
251
|
file.puts ERB.new(File.read(@filename)).result(binding)
|
250
252
|
end
|
251
|
-
|
252
|
-
end # class Section
|
253
|
+
end
|
253
254
|
|
254
255
|
# Parses the configuration file.
|
255
256
|
#
|
@@ -372,11 +373,8 @@ module Cosmos
|
|
372
373
|
else
|
373
374
|
# blank lines will have a nil keyword and should not raise an exception
|
374
375
|
raise parser.error("Unknown keyword: #{keyword}") unless keyword.nil?
|
375
|
-
end
|
376
|
-
end
|
377
|
-
|
376
|
+
end
|
377
|
+
end # loop
|
378
378
|
end
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
end # module Cosmos
|
379
|
+
end
|
380
|
+
end
|
@@ -14,10 +14,8 @@ require 'ostruct'
|
|
14
14
|
require 'bundler'
|
15
15
|
|
16
16
|
module Cosmos
|
17
|
-
|
18
17
|
# Reads and interprets the Launcher configuration file
|
19
18
|
class LauncherConfig
|
20
|
-
|
21
19
|
# Launcher title
|
22
20
|
attr_reader :title
|
23
21
|
|
@@ -43,13 +41,8 @@ module Cosmos
|
|
43
41
|
@label_font_settings = ['Arial', 16]
|
44
42
|
@num_columns = 4
|
45
43
|
@items = []
|
46
|
-
|
47
|
-
|
48
|
-
parse_file(filename)
|
49
|
-
else
|
50
|
-
raise "Launcher configuration file does not exist: #{filename}"
|
51
|
-
end
|
52
|
-
end # def initialize
|
44
|
+
parse_file(filename)
|
45
|
+
end
|
53
46
|
|
54
47
|
# Create a ConfigParser and parse all the lines in the configuration file
|
55
48
|
#
|
@@ -57,10 +50,8 @@ module Cosmos
|
|
57
50
|
def parse_file(filename)
|
58
51
|
multitool = nil
|
59
52
|
|
60
|
-
# Loop over each line of the configuration file
|
61
53
|
parser = ConfigParser.new("http://cosmosrb.com/docs/tools/#launcher-configuration")
|
62
54
|
parser.parse_file(filename) do |keyword, params|
|
63
|
-
# Handle each keyword
|
64
55
|
case keyword
|
65
56
|
|
66
57
|
when 'AUTO_GEM_TOOLS'
|
@@ -138,7 +129,7 @@ module Cosmos
|
|
138
129
|
|
139
130
|
else # UNKNOWN
|
140
131
|
raise parser.error("Unknown keyword '#{keyword}'.") if keyword
|
141
|
-
end
|
132
|
+
end
|
142
133
|
end # parser.parse_file
|
143
134
|
end
|
144
135
|
|
@@ -250,7 +241,5 @@ module Cosmos
|
|
250
241
|
|
251
242
|
raise "Could not find gem containing tool: #{split[1]} - Make sure the appropriate gem is in your Gemfile"
|
252
243
|
end
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
end # module Cosmos
|
244
|
+
end
|
245
|
+
end
|
@@ -63,7 +63,7 @@ class Array
|
|
63
63
|
end
|
64
64
|
|
65
65
|
module Cosmos
|
66
|
-
|
66
|
+
# Handles the low level processing of limits event for LimitsMonitor.
|
67
67
|
class LimitsItems
|
68
68
|
# @return [Array<String,String,String>] Target name, packet name, item name
|
69
69
|
attr_reader :ignored
|
@@ -102,7 +102,8 @@ module Cosmos
|
|
102
102
|
end
|
103
103
|
|
104
104
|
# Request that the limits items be refreshed from the server
|
105
|
-
def request_reset
|
105
|
+
def request_reset(toggle_mode = false)
|
106
|
+
@toggle_mode = toggle_mode
|
106
107
|
@initialized = false
|
107
108
|
end
|
108
109
|
|
@@ -128,7 +129,7 @@ module Cosmos
|
|
128
129
|
end
|
129
130
|
end
|
130
131
|
|
131
|
-
# Ignore a stale packet. Don't display it in the GUI and don't have it
|
132
|
+
# Ignore a stale packet. Don't display it in the GUI and don't have it
|
132
133
|
# count towards the overall limit state.
|
133
134
|
#
|
134
135
|
# @param item [Array<String,String>] Target name, packet name
|
@@ -161,7 +162,7 @@ module Cosmos
|
|
161
162
|
# Remove an item from the ignored_stale list to have it be displayed and
|
162
163
|
# count towards the overall limits state.
|
163
164
|
#
|
164
|
-
# @param item [Array<String,String>] Target name, packet name to remove
|
165
|
+
# @param item [Array<String,String>] Target name, packet name to remove
|
165
166
|
# from ignored list
|
166
167
|
def remove_ignored_stale(item)
|
167
168
|
index = @ignored_stale.delete_item(item)
|
@@ -249,7 +250,6 @@ module Cosmos
|
|
249
250
|
|
250
251
|
# Update the values for all the out of limits items being tracked.
|
251
252
|
def update_values
|
252
|
-
|
253
253
|
values, limits_states, limits_settings, limits_set = get_tlm_values(@out_of_limits, :WITH_UNITS)
|
254
254
|
index = 0
|
255
255
|
@out_of_limits.each do |target_name, packet_name, item_name|
|
@@ -279,34 +279,27 @@ module Cosmos
|
|
279
279
|
# expanded to find a file in the config/tools/limits_monitor dir.
|
280
280
|
# @return [String] Message indicating success or fail
|
281
281
|
def open_config(filename)
|
282
|
-
return "" unless filename
|
283
|
-
return "Configuration file #{filename} not found!" unless File.exist?(filename)
|
284
|
-
|
285
282
|
@ignored = []
|
286
283
|
@ignored_stale = []
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
@monitor_operational = false
|
303
|
-
end
|
284
|
+
parser = ConfigParser.new("http://cosmosrb.com/docs/tools/#limits-monitor-configuration")
|
285
|
+
parser.parse_file(filename) do |keyword, params|
|
286
|
+
case keyword
|
287
|
+
# TODO: Eventually we can deprecate 'IGNORE' in favor
|
288
|
+
# of 'IGNORE_ITEM' now that we also have 'IGNORE_PACKET'
|
289
|
+
when 'IGNORE', 'IGNORE_ITEM'
|
290
|
+
@ignored << ([params[0], params[1], params[2]])
|
291
|
+
when 'IGNORE_PACKET'
|
292
|
+
@ignored << ([params[0], params[1], nil])
|
293
|
+
when 'IGNORE_STALE'
|
294
|
+
@ignored_stale << ([params[0], params[1], nil])
|
295
|
+
when 'COLOR_BLIND'
|
296
|
+
@colorblind = true
|
297
|
+
when 'IGNORE_OPERATIONAL_LIMITS'
|
298
|
+
@monitor_operational = false
|
304
299
|
end
|
305
|
-
result = "#{filename} loaded. "
|
306
|
-
result << "Warning: Some items ignored" if ignored_items?
|
307
|
-
rescue => e
|
308
|
-
result = "Error loading configuration : #{e.message}"
|
309
300
|
end
|
301
|
+
result = "#{filename} loaded. "
|
302
|
+
result << "Warning: Some items ignored" if ignored_items?
|
310
303
|
# Since we may have loaded new ignored items we need to reset
|
311
304
|
request_reset()
|
312
305
|
result
|
@@ -356,6 +349,8 @@ module Cosmos
|
|
356
349
|
@stale = []
|
357
350
|
@limits_set = get_limits_set()
|
358
351
|
unsubscribe_limits_events(@queue_id) if @queue_id
|
352
|
+
set_replay_mode(!get_replay_mode()) if @toggle_mode
|
353
|
+
@toggle_mode = false
|
359
354
|
@queue_id = subscribe_limits_events(100000)
|
360
355
|
@clear_items_callback.call
|
361
356
|
get_out_of_limits().each do |target, packet, item, state|
|
@@ -405,7 +400,7 @@ module Cosmos
|
|
405
400
|
item = [target_name, packet_name, nil]
|
406
401
|
unless (@stale.includes_item?(item) || @ignored_stale.includes_item?(item) || UNKNOWN_ARRAY.includes_item?(item))
|
407
402
|
@stale << item
|
408
|
-
@items["#{item[0]} #{item[1]}"] = @new_item_callback.call(*item)
|
403
|
+
@items["#{item[0]} #{item[1]}"] = @new_item_callback.call(*item)
|
409
404
|
end
|
410
405
|
return ["INFO: Packet #{target_name} #{packet_name} is STALE\n", :BLACK]
|
411
406
|
end
|
@@ -466,7 +461,7 @@ module Cosmos
|
|
466
461
|
@ignore_button = Qt::PushButton.new('Ignore Item')
|
467
462
|
@ignore_button.connect(SIGNAL('clicked()')) { parent.ignore(self, item) }
|
468
463
|
@layout.addWidget(@ignore_button)
|
469
|
-
|
464
|
+
|
470
465
|
@ignore_packet_button = Qt::PushButton.new('Ignore Packet')
|
471
466
|
@ignore_packet_button.connect(SIGNAL('clicked()')) { parent.ignore(self, packet) }
|
472
467
|
@layout.addWidget(@ignore_packet_button)
|
@@ -476,7 +471,7 @@ module Cosmos
|
|
476
471
|
@layout.addStretch(1)
|
477
472
|
@ignore_button = Qt::PushButton.new('Ignore Stale Packet')
|
478
473
|
@ignore_button.connect(SIGNAL('clicked()')) { parent.ignore(self, packet) }
|
479
|
-
@layout.addWidget(@ignore_button)
|
474
|
+
@layout.addWidget(@ignore_button)
|
480
475
|
end
|
481
476
|
end
|
482
477
|
|
@@ -528,8 +523,14 @@ module Cosmos
|
|
528
523
|
|
529
524
|
@limits_items = LimitsItems.new(
|
530
525
|
method(:new_gui_item), method(:update_gui_item), method(:clear_gui_items), method(:remove_gui_item))
|
531
|
-
|
532
|
-
|
526
|
+
if options.config_file
|
527
|
+
begin
|
528
|
+
result = @limits_items.open_config(options.config_file)
|
529
|
+
statusBar.showMessage(tr(result))
|
530
|
+
rescue => error
|
531
|
+
ExceptionDialog.new(self, error, "Error parsing #{@options.config_file}")
|
532
|
+
end
|
533
|
+
end
|
533
534
|
|
534
535
|
limits_thread()
|
535
536
|
value_thread()
|
@@ -549,6 +550,10 @@ module Cosmos
|
|
549
550
|
@reset_action.statusTip = tr('Reset connection and clear all items. This does not modify the ignored items.')
|
550
551
|
@reset_action.connect(SIGNAL('triggered()')) { @limits_items.request_reset() }
|
551
552
|
|
553
|
+
@replay_action = Qt::Action.new(tr('Toggle Replay Mode'), self)
|
554
|
+
@replay_action.statusTip = tr('Toggle Replay Mode')
|
555
|
+
@replay_action.connect(SIGNAL('triggered()')) { toggle_replay_mode() }
|
556
|
+
|
552
557
|
@open_ignored_action = Qt::Action.new(Cosmos.get_icon('open.png'),
|
553
558
|
tr('&Open Config'), self)
|
554
559
|
@open_ignored_action_keyseq = Qt::KeySequence.new(tr('Ctrl+O'))
|
@@ -579,6 +584,7 @@ module Cosmos
|
|
579
584
|
@file_menu.addSeparator()
|
580
585
|
@file_menu.addAction(@reset_action)
|
581
586
|
@file_menu.addAction(@options_action)
|
587
|
+
@file_menu.addAction(@replay_action)
|
582
588
|
@file_menu.addSeparator()
|
583
589
|
@file_menu.addAction(@exit_action)
|
584
590
|
|
@@ -591,8 +597,18 @@ module Cosmos
|
|
591
597
|
# Layout the main GUI tab widget with a view of all the out of limits items
|
592
598
|
# in one tab and a log tab showing all limits events.
|
593
599
|
def initialize_central_widget
|
600
|
+
|
601
|
+
widget = Qt::Widget.new
|
602
|
+
layout = Qt::VBoxLayout.new(widget)
|
603
|
+
setCentralWidget(widget)
|
604
|
+
|
605
|
+
@replay_flag = Qt::Label.new("Replay Mode")
|
606
|
+
@replay_flag.setStyleSheet("background:green;color:white;padding:5px;font-weight:bold;")
|
607
|
+
layout.addWidget(@replay_flag)
|
608
|
+
@replay_flag.hide
|
609
|
+
|
594
610
|
@tabbook = Qt::TabWidget.new(self)
|
595
|
-
|
611
|
+
layout.addWidget(@tabbook)
|
596
612
|
@widget = Qt::Widget.new
|
597
613
|
@layout = Qt::VBoxLayout.new(@widget)
|
598
614
|
|
@@ -677,6 +693,10 @@ module Cosmos
|
|
677
693
|
end
|
678
694
|
end
|
679
695
|
|
696
|
+
def toggle_replay_mode
|
697
|
+
@limits_items.request_reset(true)
|
698
|
+
end
|
699
|
+
|
680
700
|
# @return [String] Fully qualified path to the configuration file
|
681
701
|
def default_config_path
|
682
702
|
# If the config file has been set then just return it
|
@@ -834,7 +854,14 @@ module Cosmos
|
|
834
854
|
|
835
855
|
# Reset the GUI by clearing all items
|
836
856
|
def clear_gui_items
|
837
|
-
Qt.execute_in_main_thread(true)
|
857
|
+
Qt.execute_in_main_thread(true) do
|
858
|
+
if get_replay_mode()
|
859
|
+
@replay_flag.show
|
860
|
+
else
|
861
|
+
@replay_flag.hide
|
862
|
+
end
|
863
|
+
@scroll_layout.removeAll
|
864
|
+
end
|
838
865
|
end
|
839
866
|
|
840
867
|
# Update front panel to ignore an item when the corresponding button is pressed.
|
@@ -967,6 +994,5 @@ module Cosmos
|
|
967
994
|
super(option_parser, options)
|
968
995
|
end
|
969
996
|
end
|
970
|
-
|
971
|
-
|
972
|
-
end # module Cosmos
|
997
|
+
end
|
998
|
+
end
|