cosmos 4.0.3-java → 4.1.0-java

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.
Files changed (123) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -5
  3. data/Manifest.txt +11 -1
  4. data/README.md +3 -2
  5. data/Rakefile +18 -4
  6. data/appveyor.yml +19 -0
  7. data/cosmos.gemspec +12 -3
  8. data/data/config/cmd_tlm_server.yaml +3 -0
  9. data/data/crc.txt +63 -60
  10. data/demo/config/targets/INST/cmd_tlm_server.txt +1 -0
  11. data/demo/config/targets/INST/cmd_tlm_server2.txt +7 -0
  12. data/demo/config/tools/cmd_sequence/cmd_sequence.txt +2 -0
  13. data/demo/config/tools/cmd_tlm_server/cmd_tlm_server.txt +8 -12
  14. data/demo/config/tools/cmd_tlm_server/cmd_tlm_server2.txt +7 -9
  15. data/demo/lib/cmd_sequence_exporter.rb +52 -0
  16. data/demo/lib/example_background_task.rb +1 -0
  17. data/demo/procedures/replay_test.rb +32 -0
  18. data/ext/cosmos/ext/structure/structure.c +39 -3
  19. data/install/config/tools/cmd_tlm_server/cmd_tlm_server.txt +1 -0
  20. data/install/config/tools/launcher/launcher.txt +2 -0
  21. data/lib/cosmos/config/config_parser.rb +2 -0
  22. data/lib/cosmos/core_ext/io.rb +89 -60
  23. data/lib/cosmos/gui/qt.rb +5 -8
  24. data/lib/cosmos/gui/qt_tool.rb +8 -8
  25. data/lib/cosmos/gui/text/ruby_editor.rb +12 -12
  26. data/lib/cosmos/gui/utilities/script_module_gui.rb +9 -9
  27. data/lib/cosmos/gui/widgets/realtime_button_bar.rb +18 -17
  28. data/lib/cosmos/interfaces/protocols/fixed_protocol.rb +2 -2
  29. data/lib/cosmos/interfaces/protocols/template_protocol.rb +3 -0
  30. data/lib/cosmos/interfaces/udp_interface.rb +27 -14
  31. data/lib/cosmos/io/buffered_file.rb +0 -1
  32. data/lib/cosmos/io/json_drb.rb +134 -214
  33. data/lib/cosmos/io/json_drb_object.rb +22 -61
  34. data/lib/cosmos/io/json_drb_rack.rb +79 -0
  35. data/lib/cosmos/io/json_rpc.rb +27 -0
  36. data/lib/cosmos/io/udp_sockets.rb +102 -58
  37. data/lib/cosmos/packets/commands.rb +1 -1
  38. data/lib/cosmos/packets/structure.rb +1 -1
  39. data/lib/cosmos/packets/structure_item.rb +37 -5
  40. data/lib/cosmos/script/cmd_tlm_server.rb +76 -2
  41. data/lib/cosmos/script/replay.rb +60 -0
  42. data/lib/cosmos/script/script.rb +20 -2
  43. data/lib/cosmos/script/scripting.rb +9 -9
  44. data/lib/cosmos/script/tools.rb +14 -0
  45. data/lib/cosmos/system/system.rb +185 -92
  46. data/lib/cosmos/system/target.rb +1 -1
  47. data/lib/cosmos/tools/cmd_sequence/cmd_sequence.rb +44 -4
  48. data/lib/cosmos/tools/cmd_sequence/sequence_item.rb +4 -0
  49. data/lib/cosmos/tools/cmd_sequence/sequence_list.rb +7 -0
  50. data/lib/cosmos/tools/cmd_tlm_server/api.rb +347 -20
  51. data/lib/cosmos/tools/cmd_tlm_server/background_tasks.rb +3 -0
  52. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +329 -111
  53. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +13 -0
  54. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_gui.rb +261 -95
  55. data/lib/cosmos/tools/cmd_tlm_server/gui/interfaces_tab.rb +46 -35
  56. data/lib/cosmos/tools/cmd_tlm_server/gui/logging_tab.rb +18 -8
  57. data/lib/cosmos/tools/cmd_tlm_server/gui/packets_tab.rb +39 -28
  58. data/lib/cosmos/tools/cmd_tlm_server/gui/replay_tab.rb +242 -0
  59. data/lib/cosmos/tools/cmd_tlm_server/gui/status_tab.rb +24 -8
  60. data/lib/cosmos/tools/cmd_tlm_server/gui/targets_tab.rb +18 -6
  61. data/lib/cosmos/tools/cmd_tlm_server/limits_groups_background_task.rb +5 -4
  62. data/lib/cosmos/tools/cmd_tlm_server/replay_backend.rb +375 -0
  63. data/lib/cosmos/tools/cmd_tlm_server/routers.rb +10 -2
  64. data/lib/cosmos/tools/data_viewer/data_viewer.rb +40 -5
  65. data/lib/cosmos/tools/handbook_creator/handbook_creator_config.rb +18 -20
  66. data/lib/cosmos/tools/launcher/launcher_config.rb +5 -16
  67. data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +65 -39
  68. data/lib/cosmos/tools/packet_viewer/packet_viewer.rb +19 -0
  69. data/lib/cosmos/tools/replay/replay.rb +5 -505
  70. data/lib/cosmos/tools/script_runner/script_audit.rb +1 -0
  71. data/lib/cosmos/tools/script_runner/script_runner.rb +3 -4
  72. data/lib/cosmos/tools/script_runner/script_runner_config.rb +3 -4
  73. data/lib/cosmos/tools/script_runner/script_runner_frame.rb +44 -23
  74. data/lib/cosmos/tools/test_runner/results_writer.rb +4 -0
  75. data/lib/cosmos/tools/test_runner/test_runner.rb +0 -3
  76. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_realtime_thread.rb +6 -2
  77. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_tool.rb +26 -1
  78. data/lib/cosmos/tools/tlm_viewer/screen.rb +24 -1
  79. data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +25 -0
  80. data/lib/cosmos/tools/tlm_viewer/tlm_viewer_config.rb +24 -14
  81. data/lib/cosmos/top_level.rb +34 -24
  82. data/lib/cosmos/utilities/csv.rb +60 -8
  83. data/lib/cosmos/version.rb +5 -5
  84. data/spec/config/config_parser_spec.rb +10 -1
  85. data/spec/core_ext/socket_spec.rb +4 -2
  86. data/spec/gui/utilities/script_module_gui_spec.rb +102 -0
  87. data/spec/install/config/data/data.txt +1 -0
  88. data/spec/install/config/targets/INST/cmd_tlm/inst_cmds.txt +2 -0
  89. data/spec/interfaces/cmd_tlm_server_interface_spec.rb +1 -2
  90. data/spec/interfaces/protocols/template_protocol_spec.rb +72 -2
  91. data/spec/interfaces/serial_interface_spec.rb +1 -1
  92. data/spec/interfaces/udp_interface_spec.rb +14 -0
  93. data/spec/io/buffered_file_spec.rb +37 -0
  94. data/spec/io/json_drb_object_spec.rb +2 -15
  95. data/spec/io/json_drb_spec.rb +61 -121
  96. data/spec/io/udp_sockets_spec.rb +42 -2
  97. data/spec/packet_logs/packet_log_reader_spec.rb +5 -2
  98. data/spec/packets/binary_accessor_spec.rb +1 -1
  99. data/spec/packets/packet_item_spec.rb +1 -1
  100. data/spec/packets/structure_item_spec.rb +5 -6
  101. data/spec/script/cmd_tlm_server_spec.rb +39 -4
  102. data/spec/script/commands_disconnect_spec.rb +1 -1
  103. data/spec/script/commands_spec.rb +2 -1
  104. data/spec/script/scripting_spec.rb +18 -3
  105. data/spec/script/telemetry_spec.rb +5 -0
  106. data/spec/spec_helper.rb +43 -26
  107. data/spec/streams/tcpip_socket_stream_spec.rb +2 -2
  108. data/spec/system/system_spec.rb +11 -9
  109. data/spec/system/target_spec.rb +3 -0
  110. data/spec/tools/cmd_tlm_server/api_spec.rb +543 -29
  111. data/spec/tools/cmd_tlm_server/background_task_spec.rb +2 -2
  112. data/spec/tools/cmd_tlm_server/background_tasks_spec.rb +31 -75
  113. data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +199 -66
  114. data/spec/tools/cmd_tlm_server/cmd_tlm_server_spec.rb +85 -9
  115. data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +29 -127
  116. data/spec/tools/cmd_tlm_server/router_thread_spec.rb +10 -50
  117. data/spec/tools/launcher/launcher_config_spec.rb +1 -1
  118. data/spec/tools/table_manager/table_item_spec.rb +1 -1
  119. data/spec/tools/table_manager/tablemanager_core_spec.rb +4 -4
  120. data/spec/top_level/top_level_spec.rb +151 -3
  121. data/spec/utilities/csv_spec.rb +24 -5
  122. metadata +61 -9
  123. data/lib/cosmos/tools/replay/replay_server.rb +0 -91
@@ -126,7 +126,7 @@ module Cosmos
126
126
  begin
127
127
  # Require absolute path to file in target lib folder. Prevents name
128
128
  # conflicts at the require step
129
- Cosmos.require_file(File.join(@dir, 'lib', parameters[0]))
129
+ Cosmos.require_file(File.join(@dir, 'lib', parameters[0]), false)
130
130
  rescue LoadError
131
131
  begin
132
132
  # If we couldn't load at the target/lib level check everywhere
@@ -34,6 +34,7 @@ module Cosmos
34
34
  option_parser, options = create_default_options()
35
35
  options.width = 600
36
36
  options.height = 425
37
+ option_parser.separator "Command Sequence Specific Options:"
37
38
  option_parser.on("-o", "--output DIRECTORY", "Save files in the specified directory") do |arg|
38
39
  options.output_dir = File.expand_path(arg)
39
40
  end
@@ -59,6 +60,13 @@ module Cosmos
59
60
  end
60
61
  @filename = "Untitled"
61
62
  @run_thread = nil
63
+ @exporter = nil
64
+
65
+ begin
66
+ process_config(options.config_file) if options.config_file
67
+ rescue => error
68
+ ExceptionDialog.new(self, error, "Error parsing #{options.config_file}")
69
+ end
62
70
 
63
71
  initialize_actions()
64
72
  initialize_menus()
@@ -104,10 +112,10 @@ module Cosmos
104
112
  @file_save_as.statusTip = tr('Save the sequence')
105
113
  @file_save_as.connect(SIGNAL('triggered()')) { file_save(true) }
106
114
 
107
- @export_action = Qt::Action.new(tr('&Export Sequence'), self)
108
- @export_action.shortcut = Qt::KeySequence.new(tr('Ctrl+E'))
109
- @export_action.statusTip = tr('Export the current sequence to a custom binary format')
110
- @export_action.connect(SIGNAL('triggered()')) { export() }
115
+ @file_export = Qt::Action.new(tr('&Export Sequence'), self)
116
+ @file_export.shortcut = Qt::KeySequence.new(tr('Ctrl+E'))
117
+ @file_export.statusTip = tr('Export the current sequence to a custom binary format')
118
+ @file_export.connect(SIGNAL('triggered()')) { file_export() }
111
119
 
112
120
  @show_ignored = Qt::Action.new(tr('&Show Ignored Parameters'), self)
113
121
  @show_ignored.statusTip = tr('Show ignored parameters which are normally hidden')
@@ -163,6 +171,10 @@ module Cosmos
163
171
 
164
172
  file_menu.addAction(@file_save)
165
173
  file_menu.addAction(@file_save_as)
174
+ if @exporter
175
+ file_menu.addSeparator()
176
+ file_menu.addAction(@file_export)
177
+ end
166
178
  file_menu.addSeparator()
167
179
  file_menu.addAction(@exit_action)
168
180
 
@@ -252,6 +264,12 @@ module Cosmos
252
264
  splitter.setStretchFactor(1,0)
253
265
  end
254
266
 
267
+ # Export the sequence list into a custom binary format
268
+ def file_export
269
+ return if @sequence_list.empty? || @exporter.nil?
270
+ @exporter.export(@filename, @sequence_dir, @sequence_list)
271
+ end
272
+
255
273
  # Clears the sequence list
256
274
  def file_new
257
275
  return unless prompt_for_save_if_needed()
@@ -648,5 +666,27 @@ module Cosmos
648
666
  @output.ensureCursorVisible()
649
667
  end
650
668
  end
669
+
670
+ def process_config(filename)
671
+ parser = ConfigParser.new
672
+ parser.parse_file(filename) do |keyword, params|
673
+ case keyword
674
+
675
+ when 'EXPORTER'
676
+ usage = "#{keyword} <exporter class filename> <exporter specific options...>"
677
+ parser.verify_num_parameters(1, nil, usage)
678
+ exporter_class = Cosmos.require_class(params[0])
679
+ if params.length >= 2
680
+ @exporter = exporter_class.new(self, *params[1..-1])
681
+ else
682
+ @exporter = exporter_class.new(self)
683
+ end
684
+
685
+ # Unknown keyword
686
+ else
687
+ raise "Unhandled keyword: #{keyword}" if keyword
688
+ end
689
+ end
690
+ end
651
691
  end
652
692
  end
@@ -164,6 +164,10 @@ module Cosmos
164
164
  time
165
165
  end
166
166
 
167
+ def command
168
+ System.commands.build_cmd(@command.target_name, @command.packet_name, command_params(), false)
169
+ end
170
+
167
171
  # @return [String] Time and command string
168
172
  def save
169
173
  "COMMAND \"#{time}\" \"#{command_string}\""
@@ -95,6 +95,13 @@ module Cosmos
95
95
  @modified
96
96
  end
97
97
 
98
+ def empty?
99
+ empty = true
100
+ # The layout always has the header so count must be > 1
101
+ Qt.execute_in_main_thread { empty = false if layout.count > 1 }
102
+ empty
103
+ end
104
+
98
105
  # Yield each SequenceItem to enable the included Enumerable module
99
106
  def each
100
107
  total_items = 1
@@ -10,6 +10,7 @@
10
10
 
11
11
  require 'cosmos/script/extract'
12
12
  require 'cosmos/script/api_shared'
13
+ require 'cosmos/tools/tlm_viewer/tlm_viewer_config'
13
14
 
14
15
  module Cosmos
15
16
 
@@ -74,6 +75,9 @@ module Cosmos
74
75
  'subscribe_packet_data',
75
76
  'unsubscribe_packet_data',
76
77
  'get_packet_data',
78
+ 'subscribe_server_messages',
79
+ 'unsubscribe_server_messages',
80
+ 'get_server_message',
77
81
  'get_interface_targets',
78
82
  'get_interface_names',
79
83
  'connect_interface',
@@ -84,12 +88,25 @@ module Cosmos
84
88
  'connect_router',
85
89
  'disconnect_router',
86
90
  'router_state',
91
+ 'get_all_target_info',
87
92
  'get_target_info',
93
+ 'get_target_ignored_parameters',
94
+ 'get_target_ignored_items',
88
95
  'get_interface_info',
96
+ 'get_all_interface_info',
89
97
  'get_router_info',
98
+ 'get_all_router_info',
99
+ 'get_all_cmd_info',
100
+ 'get_all_tlm_info',
90
101
  'get_cmd_cnt',
91
102
  'get_tlm_cnt',
103
+ 'get_packet_loggers',
92
104
  'get_packet_logger_info',
105
+ 'get_all_packet_logger_info',
106
+ 'get_background_tasks',
107
+ 'start_background_task',
108
+ 'stop_background_task',
109
+ 'get_server_status',
93
110
  'get_cmd_log_filename',
94
111
  'get_tlm_log_filename',
95
112
  'start_logging',
@@ -103,7 +120,26 @@ module Cosmos
103
120
  'start_raw_logging_router',
104
121
  'stop_raw_logging_router',
105
122
  'get_server_message_log_filename',
106
- 'start_new_server_message_log']
123
+ 'start_new_server_message_log',
124
+ 'cmd_tlm_reload',
125
+ 'cmd_tlm_clear_counters',
126
+ 'get_output_logs_filenames',
127
+ 'replay_select_file',
128
+ 'replay_status',
129
+ 'replay_set_playback_delay',
130
+ 'replay_play',
131
+ 'replay_reverse_play',
132
+ 'replay_stop',
133
+ 'replay_step_forward',
134
+ 'replay_step_back',
135
+ 'replay_move_start',
136
+ 'replay_move_end',
137
+ 'replay_move_index',
138
+ 'get_screen_list',
139
+ 'get_screen_definition',
140
+ ]
141
+ @tlm_viewer_config_filename = nil
142
+ @tlm_viewer_config = nil
107
143
  end
108
144
 
109
145
  ############################################################################
@@ -278,12 +314,12 @@ module Cosmos
278
314
  System.commands.params(target_name, command_name).each do |parameter|
279
315
  if parameter.format_string
280
316
  unless parameter.default.kind_of?(Array)
281
- list << [parameter.name, sprintf(parameter.format_string, parameter.default), parameter.states, parameter.description, parameter.units_full, parameter.units, parameter.required]
317
+ list << [parameter.name, sprintf(parameter.format_string, parameter.default), parameter.states, parameter.description, parameter.units_full, parameter.units, parameter.required, parameter.data_type.to_s]
282
318
  else
283
- list << [parameter.name, "[]", parameter.states, parameter.description, parameter.units_full, parameter.units, parameter.required]
319
+ list << [parameter.name, "[]", parameter.states, parameter.description, parameter.units_full, parameter.units, parameter.required, parameter.data_type.to_s]
284
320
  end
285
321
  else
286
- list << [parameter.name, parameter.default, parameter.states, parameter.description, parameter.units_full, parameter.units, parameter.required]
322
+ list << [parameter.name, parameter.default, parameter.states, parameter.description, parameter.units_full, parameter.units, parameter.required, parameter.data_type.to_s]
287
323
  end
288
324
  end
289
325
  return list
@@ -536,7 +572,7 @@ module Cosmos
536
572
  # Update the packet with item_hash
537
573
  value_type = value_type.to_s.intern
538
574
  item_hash.each do |item_name, item_value|
539
- packet.write(item_name, item_value, value_type)
575
+ packet.write(item_name.to_s, item_value, value_type)
540
576
  end
541
577
  end
542
578
 
@@ -581,10 +617,12 @@ module Cosmos
581
617
  # Write to routers
582
618
  if send_routers
583
619
  router = CmdTlmServer.instance.routers.all['PREIDENTIFIED_ROUTER']
584
- begin
585
- router.write(packet) if router.write_allowed? and router.connected?
586
- rescue => err
587
- Logger.error "Problem writing to router #{router.name} - #{err.class}:#{err.message}"
620
+ if router
621
+ begin
622
+ router.write(packet) if router.write_allowed? and router.connected?
623
+ rescue => err
624
+ Logger.error "Problem writing to router #{router.name} - #{err.class}:#{err.message}"
625
+ end
588
626
  end
589
627
  end
590
628
 
@@ -592,11 +630,13 @@ module Cosmos
592
630
  # Handle packet logging
593
631
  packet_log_writer_pair = CmdTlmServer.instance.packet_logging.all['DEFAULT']
594
632
 
595
- # Optionally create new logs
596
- packet_log_writer_pair.tlm_log_writer.start if create_new_logs
633
+ if packet_log_writer_pair
634
+ # Optionally create new logs
635
+ packet_log_writer_pair.tlm_log_writer.start if create_new_logs
597
636
 
598
- # Optionally write to packet logs - Write errors are handled by the log writer
599
- packet_log_writer_pair.tlm_log_writer.write(packet) if send_packet_log_writers
637
+ # Optionally write to packet logs - Write errors are handled by the log writer
638
+ packet_log_writer_pair.tlm_log_writer.write(packet) if send_packet_log_writers
639
+ end
600
640
  end
601
641
  end
602
642
 
@@ -656,17 +696,22 @@ module Cosmos
656
696
  private
657
697
 
658
698
  def _override(method, tgt_pkt_item)
699
+ target = System.targets[tgt_pkt_item[0]]
700
+ raise "Target '#{tgt_pkt_item[0]}' does not exist" unless target
659
701
  interface = System.targets[tgt_pkt_item[0]].interface
702
+ raise "Target '#{tgt_pkt_item[0]}' has no interface" unless interface
660
703
  found = false
661
- interface.read_protocols.each do |protocol|
662
- found = true if protocol.kind_of? OverrideProtocol
704
+ if interface.read_protocols
705
+ interface.read_protocols.each do |protocol|
706
+ found = true if protocol.kind_of? OverrideProtocol
707
+ end
663
708
  end
664
709
  if found
665
710
  # Test to see if this telemetry item exists
666
711
  System.telemetry.value(tgt_pkt_item[0], tgt_pkt_item[1], tgt_pkt_item[2], :RAW)
667
712
  interface.public_send("_#{method}", *tgt_pkt_item)
668
713
  else
669
- raise "Interface #{interface.name} does not have override ability. Is 'PROTOCOL OverrideProtocol' under the interface definition?"
714
+ raise "Interface #{interface.name} does not have override ability. Is 'PROTOCOL READ_WRITE OverrideProtocol' under the interface definition?"
670
715
  end
671
716
  nil
672
717
  end
@@ -947,6 +992,21 @@ module Cosmos
947
992
  CmdTlmServer.get_packet_data(id, non_block)
948
993
  end
949
994
 
995
+ # @see CmdTlmServer.subscribe_server_messages
996
+ def subscribe_server_messages(queue_size = CmdTlmServer::DEFAULT_SERVER_MESSAGES_QUEUE_SIZE)
997
+ CmdTlmServer.subscribe_server_messages(queue_size)
998
+ end
999
+
1000
+ # @see CmdTlmServer.unsubscribe_server_messages
1001
+ def unsubscribe_server_messages(id)
1002
+ CmdTlmServer.unsubscribe_server_messages(id)
1003
+ end
1004
+
1005
+ # @see CmdTlmServer.get_server_message
1006
+ def get_server_message(id, non_block = false)
1007
+ CmdTlmServer.get_server_message(id, non_block)
1008
+ end
1009
+
950
1010
  # Get a packet which was previously subscribed to by
951
1011
  # subscribe_packet_data. This method can block waiting for new packets or
952
1012
  # not based on the second parameter. It returns a single Cosmos::Packet instance
@@ -1060,6 +1120,38 @@ module Cosmos
1060
1120
  return [target.cmd_cnt, target.tlm_cnt]
1061
1121
  end
1062
1122
 
1123
+ # Get information about all targets
1124
+ #
1125
+ # @return [Array<Array<String, Numeric, Numeric>] Array of Arrays \[name, cmd_cnt, tlm_cnt]
1126
+ def get_all_target_info
1127
+ info = []
1128
+ System.targets.sort.each do |target_name, target|
1129
+ interface_name = target.interface ? target.interface.name : ''
1130
+ info << [target_name, interface_name, target.cmd_cnt, target.tlm_cnt]
1131
+ end
1132
+ info
1133
+ end
1134
+
1135
+ # Get the list of ignored command parameters for a target
1136
+ #
1137
+ # @param target_name [String] Target name
1138
+ # @return [Array<String>] All of the ignored command parameters for a target.
1139
+ def get_target_ignored_parameters(target_name)
1140
+ target = System.targets[target_name.upcase]
1141
+ raise "Unknown target: #{target_name}" unless target
1142
+ return target.ignored_parameters
1143
+ end
1144
+
1145
+ # Get the list of ignored telemetry items for a target
1146
+ #
1147
+ # @param target_name [String] Target name
1148
+ # @return [Array<String>] All of the ignored telemetry items for a target.
1149
+ def get_target_ignored_items(target_name)
1150
+ target = System.targets[target_name.upcase]
1151
+ raise "Unknown target: #{target_name}" unless target
1152
+ return target.ignored_items
1153
+ end
1154
+
1063
1155
  # Get information about an interface
1064
1156
  #
1065
1157
  # @param interface_name [String] Interface name
@@ -1071,6 +1163,20 @@ module Cosmos
1071
1163
  CmdTlmServer.interfaces.get_info(interface_name)
1072
1164
  end
1073
1165
 
1166
+ # Get information about all interfaces
1167
+ #
1168
+ # @return [Array<Array<String, Numeric, Numeric, Numeric, Numeric, Numeric,
1169
+ # Numeric, Numeric>>] Array of Arrays containing \[name, state, num clients,
1170
+ # TX queue size, RX queue size, TX bytes, RX bytes, Command count,
1171
+ # Telemetry count] for all interfaces
1172
+ def get_all_interface_info
1173
+ info = []
1174
+ CmdTlmServer.interfaces.names.sort.each do |interface_name|
1175
+ info << [interface_name].concat(CmdTlmServer.interfaces.get_info(interface_name))
1176
+ end
1177
+ info
1178
+ end
1179
+
1074
1180
  # Get information about a router
1075
1181
  #
1076
1182
  # @param router_name [String] Router name
@@ -1082,6 +1188,20 @@ module Cosmos
1082
1188
  CmdTlmServer.routers.get_info(router_name)
1083
1189
  end
1084
1190
 
1191
+ # Get information about all routers
1192
+ #
1193
+ # @return [Array<Array<String, Numeric, Numeric, Numeric, Numeric, Numeric,
1194
+ # Numeric, Numeric>>] Array of Arrays containing \[name, state, num clients,
1195
+ # TX queue size, RX queue size, TX bytes, RX bytes, Command count,
1196
+ # Telemetry count] for all routers
1197
+ def get_all_router_info
1198
+ info = []
1199
+ CmdTlmServer.routers.names.sort.each do |router_name|
1200
+ info << [router_name].concat(CmdTlmServer.routers.get_info(router_name))
1201
+ end
1202
+ info
1203
+ end
1204
+
1085
1205
  # Get the transmit count for a command packet
1086
1206
  #
1087
1207
  # @param target_name [String] Target name of the command
@@ -1089,7 +1209,7 @@ module Cosmos
1089
1209
  # @return [Numeric] Transmit count for the command
1090
1210
  def get_cmd_cnt(target_name, command_name)
1091
1211
  packet = System.commands.packet(target_name, command_name)
1092
- return packet.received_count
1212
+ packet.received_count
1093
1213
  end
1094
1214
 
1095
1215
  # Get the receive count for a telemetry packet
@@ -1099,7 +1219,41 @@ module Cosmos
1099
1219
  # @return [Numeric] Receive count for the telemetry packet
1100
1220
  def get_tlm_cnt(target_name, packet_name)
1101
1221
  packet = System.telemetry.packet(target_name, packet_name)
1102
- return packet.received_count
1222
+ packet.received_count
1223
+ end
1224
+
1225
+ # Get information on all command packets
1226
+ #
1227
+ # @return [Numeric] Transmit count for the command
1228
+ def get_all_cmd_info
1229
+ info = []
1230
+ System.commands.all.sort.each do |target_name, packets|
1231
+ packets.sort.each do |packet_name, packet|
1232
+ info << [target_name, packet_name, packet.received_count]
1233
+ end
1234
+ end
1235
+ info
1236
+ end
1237
+
1238
+ # Get information on all telemetry packets
1239
+ #
1240
+ # @return [Numeric] Receive count for the telemetry packet
1241
+ def get_all_tlm_info
1242
+ info = []
1243
+ System.telemetry.all.sort.each do |target_name, packets|
1244
+ packets.sort.each do |packet_name, packet|
1245
+ info << [target_name, packet_name, packet.received_count]
1246
+ end
1247
+ end
1248
+ info
1249
+ end
1250
+
1251
+ # Get the list of packet loggers.
1252
+ #
1253
+ # @param packet_logger_name [String] Name of the packet logger
1254
+ # @return [<Array<String>] Array containing the names of all packet loggers
1255
+ def get_packet_loggers
1256
+ return CmdTlmServer.packet_logging.all.keys
1103
1257
  end
1104
1258
 
1105
1259
  # Get information about a packet logger.
@@ -1122,6 +1276,75 @@ module Cosmos
1122
1276
  return [interfaces] + logger_info
1123
1277
  end
1124
1278
 
1279
+ def get_all_packet_logger_info
1280
+ info = []
1281
+ CmdTlmServer.packet_logging.all.keys.sort.each do |packet_logger_name|
1282
+ packet_log_writer_pair = CmdTlmServer.packet_logging.all[packet_logger_name.upcase]
1283
+ interfaces = []
1284
+ CmdTlmServer.interfaces.all.each do |interface_name, interface|
1285
+ if interface.packet_log_writer_pairs.include?(packet_log_writer_pair)
1286
+ interfaces << interface.name
1287
+ end
1288
+ end
1289
+ info << [packet_logger_name, interfaces].concat(CmdTlmServer.packet_logging.get_info(packet_logger_name))
1290
+ end
1291
+ info
1292
+ end
1293
+
1294
+ # Get background task information
1295
+ #
1296
+ # @return [Array<Array<String, String, String>>] Array of Arrays containing
1297
+ # the background task name, thread status, and task status
1298
+ def get_background_tasks
1299
+ result = []
1300
+ CmdTlmServer.background_tasks.all.each do |task|
1301
+ if task.thread
1302
+ thread_status = task.thread.status
1303
+ thread_status = 'complete' if thread_status == false
1304
+ else
1305
+ thread_status = 'no thread'
1306
+ end
1307
+ result << [task.name, thread_status, task.status]
1308
+ end
1309
+ result
1310
+ end
1311
+
1312
+ # Start a background task
1313
+ def start_background_task(task_name)
1314
+ CmdTlmServer.background_tasks.all.each_with_index do |task, index|
1315
+ if task.name == task_name
1316
+ CmdTlmServer.background_tasks.start(index)
1317
+ break
1318
+ end
1319
+ end
1320
+ end
1321
+
1322
+ # Stop a background task
1323
+ def stop_background_task(task_name)
1324
+ CmdTlmServer.background_tasks.all.each_with_index do |task, index|
1325
+ if task.name == task_name
1326
+ CmdTlmServer.background_tasks.stop(index)
1327
+ break
1328
+ end
1329
+ end
1330
+ end
1331
+
1332
+ # Get JSON DRB information
1333
+ #
1334
+ # @return [String, Integer, Integer, Integer, Float, Integer] Server
1335
+ # status including Limits Set, API Port, JSON DRB num clients,
1336
+ # JSON DRB request count, JSON DRB average request time, and the total
1337
+ # number of Ruby threads in the server/
1338
+ def get_server_status
1339
+ [ System.limits_set.to_s,
1340
+ CmdTlmServer.mode == :CMD_TLM_SERVER ? System.ports['CTS_API'] : System.ports['REPLAY_API'],
1341
+ CmdTlmServer.json_drb.num_clients,
1342
+ CmdTlmServer.json_drb.request_count,
1343
+ CmdTlmServer.json_drb.average_request_time,
1344
+ Thread.list.length
1345
+ ]
1346
+ end
1347
+
1125
1348
  # @param packet_log_writer_name [String] The name of the packet log writer which
1126
1349
  # is writing the command packet log
1127
1350
  # @return [String] The command packet log filename
@@ -1230,15 +1453,119 @@ module Cosmos
1230
1453
 
1231
1454
  # @return [String] The server message log filename
1232
1455
  def get_server_message_log_filename
1233
- CmdTlmServer.message_log.filename
1456
+ if CmdTlmServer.message_log
1457
+ CmdTlmServer.message_log.filename
1458
+ else
1459
+ nil
1460
+ end
1234
1461
  end
1235
1462
 
1236
1463
  # Starts a new server message log
1237
1464
  def start_new_server_message_log
1238
- CmdTlmServer.message_log.start
1465
+ CmdTlmServer.message_log.start if CmdTlmServer.message_log
1239
1466
  nil
1240
1467
  end
1241
1468
 
1469
+ # Reload the default configuration
1470
+ def cmd_tlm_reload
1471
+ Thread.new do
1472
+ CmdTlmServer.instance.reload
1473
+ end
1474
+ nil
1475
+ end
1476
+
1477
+ # Clear server counters
1478
+ def cmd_tlm_clear_counters
1479
+ CmdTlmServer.clear_counters
1480
+ end
1481
+
1482
+ # Get the list of filenames in the outputs logs folder
1483
+ def get_output_logs_filenames(filter = '*tlm.bin')
1484
+ raise "Filter must not contain slashes" if filter.index('/') or filter.index('\\')
1485
+ Dir.glob(File.join(System.paths['LOGS'], '**', filter))
1486
+ end
1487
+
1488
+ # Select and start analyzing a file for replay
1489
+ #
1490
+ # filename [String] filename relative to output logs folder or absolute filename
1491
+ def replay_select_file(filename, packet_log_reader = "DEFAULT")
1492
+ CmdTlmServer.replay_backend.select_file(filename, packet_log_reader)
1493
+ end
1494
+
1495
+ # Get current replay status
1496
+ #
1497
+ # status, delay, filename, file_start, file_current, file_end, file_index, file_max_index
1498
+ def replay_status
1499
+ CmdTlmServer.replay_backend.status
1500
+ end
1501
+
1502
+ # Set the replay delay
1503
+ #
1504
+ # @param delay [Float] delay between packets in seconds 0.0 to 1.0, nil = REALTIME
1505
+ def replay_set_playback_delay(delay)
1506
+ CmdTlmServer.replay_backend.set_playback_delay(delay)
1507
+ end
1508
+
1509
+ # Replay start playing forward
1510
+ def replay_play
1511
+ CmdTlmServer.replay_backend.play
1512
+ end
1513
+
1514
+ # Replay start playing backward
1515
+ def replay_reverse_play
1516
+ CmdTlmServer.replay_backend.reverse_play
1517
+ end
1518
+
1519
+ # Replay stop
1520
+ def replay_stop
1521
+ CmdTlmServer.replay_backend.stop
1522
+ end
1523
+
1524
+ # Replay step forward one packet
1525
+ def replay_step_forward
1526
+ CmdTlmServer.replay_backend.step_forward
1527
+ end
1528
+
1529
+ # Replay step backward one packet
1530
+ def replay_step_back
1531
+ CmdTlmServer.replay_backend.step_back
1532
+ end
1533
+
1534
+ # Replay move to start of file
1535
+ def replay_move_start
1536
+ CmdTlmServer.replay_backend.move_start
1537
+ end
1538
+
1539
+ # Replay move to end of file
1540
+ def replay_move_end
1541
+ CmdTlmServer.replay_backend.move_end
1542
+ end
1543
+
1544
+ # Replay move to index
1545
+ #
1546
+ # @param index [Integer] packet index into file
1547
+ def replay_move_index(index)
1548
+ CmdTlmServer.replay_backend.move_index(index)
1549
+ end
1550
+
1551
+ # Get the organized list of available telemetry screens
1552
+ def get_screen_list(config_filename = nil, force_refresh = false)
1553
+ if force_refresh or !@tlm_viewer_config or @tlm_viewer_config_filename != config_filename
1554
+ @tlm_viewer_config = TlmViewerConfig.new(config_filename, true)
1555
+ @tlm_viewer_config_filename = config_filename
1556
+ end
1557
+ return @tlm_viewer_config.columns
1558
+ end
1559
+
1560
+ # Get a specific screen definition
1561
+ def get_screen_definition(screen_full_name, config_filename = nil, force_refresh = false)
1562
+ get_screen_list(config_filename, force_refresh) if force_refresh or !@tlm_viewer_config
1563
+ screen_info = @tlm_viewer_config.screen_infos[screen_full_name.upcase]
1564
+ raise "Unknown screen: #{screen_full_name.upcase}" unless screen_info
1565
+ screen_definition = File.read(screen_info.filename)
1566
+ return screen_definition
1567
+ end
1568
+
1242
1569
  private
1243
1570
 
1244
1571
  def cmd_implementation(range_check, hazardous_check, raw, method_name, *args)