cosmos 3.9.2 → 4.0.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/.rubocop.yml +23 -0
- data/.travis.yml +1 -0
- data/.yardopts +3 -0
- data/Gemfile +1 -1
- data/Manifest.txt +137 -52
- data/Rakefile +50 -44
- data/autohotkey/config/system/system.txt +0 -5
- data/autohotkey/config/targets/INST/cmd_tlm/inst_cmds.txt +6 -1
- data/autohotkey/config/targets/INST/screens/extra.txt +19 -0
- data/autohotkey/config/targets/INST/sequences/run_sequence.txt +1 -0
- data/autohotkey/config/targets/META/screens/data.txt +12 -0
- data/autohotkey/config/targets/SYSTEM/cmd_tlm/meta_cmd_tlm.txt +16 -0
- data/autohotkey/config/targets/{COSMOS/cmd_tlm/cosmos_server_cmds.txt → SYSTEM/cmd_tlm/system_cmds.txt} +8 -8
- data/autohotkey/config/targets/SYSTEM/cmd_tlm/system_tlm.txt +7 -0
- data/autohotkey/config/targets/SYSTEM/screens/limits_change.txt +14 -0
- data/autohotkey/config/targets/SYSTEM/screens/meta.txt +14 -0
- data/autohotkey/config/targets/SYSTEM/target.txt +12 -0
- data/autohotkey/config/tools/cmd_tlm_server/cmd_tlm_server.txt +2 -2
- data/autohotkey/config/tools/test_runner/test_runner2.txt +1 -1
- data/autohotkey/tools/CmdSequence +14 -0
- data/autohotkey/tools/CmdSequenceAHK +23 -0
- data/autohotkey/tools/CmdSequenceAHK2 +16 -0
- data/autohotkey/tools/cmd_extractor.ahk +2 -2
- data/autohotkey/tools/cmd_sender.ahk +4 -6
- data/autohotkey/tools/cmd_sequence.ahk +215 -0
- data/autohotkey/tools/cmd_sequence2.ahk +23 -0
- data/autohotkey/tools/data_viewer.ahk +2 -3
- data/autohotkey/tools/limits_monitor.ahk +9 -11
- data/autohotkey/tools/open_gl_builder.ahk +1 -2
- data/autohotkey/tools/packet_viewer.ahk +51 -35
- data/autohotkey/tools/replay.ahk +1 -2
- data/autohotkey/tools/script_runner.ahk +1 -2
- data/autohotkey/tools/script_runner2.ahk +1 -2
- data/autohotkey/tools/test_runner2.ahk +1 -5
- data/autohotkey/tools/test_runner3.ahk +1 -3
- data/autohotkey/tools/tlm_grapher.ahk +1 -3
- data/autohotkey/tools/tlm_grapher3.ahk +1 -2
- data/autohotkey/tools/tlm_viewer.ahk +8 -3
- data/autohotkey/tools/tlm_viewer2.ahk +2 -3
- data/autohotkey/tools/tlm_viewer5.ahk +1 -2
- data/cosmos.gemspec +26 -20
- data/data/cmd_sequence.png +0 -0
- data/data/config/_array_params.yaml +23 -0
- data/data/config/_id_items.yaml +24 -0
- data/data/config/_id_params.yaml +58 -0
- data/data/config/_interfaces.yaml +206 -0
- data/data/config/_items.yaml +20 -0
- data/data/config/_params.yaml +58 -0
- data/data/config/cmd_tlm_server.yaml +110 -0
- data/data/config/command.yaml +38 -0
- data/data/config/command_modifiers.yaml +127 -0
- data/data/config/command_telemetry.yaml +3 -0
- data/data/config/data_viewer.yaml +43 -0
- data/data/config/handbook_creator.yaml +23 -0
- data/data/config/housekeeping_params.yaml +71 -0
- data/data/config/interface_modifiers.yaml +44 -0
- data/data/config/item_modifiers.yaml +172 -0
- data/data/config/launcher.yaml +117 -0
- data/data/config/limits_monitor.yaml +53 -0
- data/data/config/linegraph_params.yaml +30 -0
- data/data/config/linegraph_plot.yaml +106 -0
- data/data/config/page_modifiers.yaml +128 -0
- data/data/config/param_item_modifiers.yaml +41 -0
- data/data/config/parameter_modifiers.yaml +144 -0
- data/data/config/protocols.yaml +257 -0
- data/data/config/screen.yaml +151 -0
- data/data/config/script_runner.yaml +15 -0
- data/data/config/system.yaml +153 -0
- data/data/config/table_manager.yaml +76 -0
- data/data/config/table_parameter_modifiers.yaml +9 -0
- data/data/config/target.yaml +71 -0
- data/data/config/telemetry.yaml +73 -0
- data/data/config/telemetry_modifiers.yaml +129 -0
- data/data/config/test_runner.yaml +118 -0
- data/data/config/tlm_extractor.yaml +109 -0
- data/data/config/tlm_grapher.yaml +78 -0
- data/data/config/tlm_viewer.yaml +107 -0
- data/data/config/unknown.yaml +3 -0
- data/data/config/widgets.yaml +1339 -0
- data/data/config/xy_params.yaml +50 -0
- data/data/config/xy_plot.yaml +12 -0
- data/data/config_editor.png +0 -0
- data/data/crc.txt +172 -161
- data/data/delete.png +0 -0
- data/demo/config/data/crc.txt +56 -36
- data/demo/config/data/meta_init.txt +1 -4
- data/demo/config/system/system.txt +15 -3
- data/demo/config/system/system2.txt +13 -3
- data/demo/config/targets/EXAMPLE/lib/example_interface.rb +2 -6
- data/demo/config/targets/EXAMPLE/target.txt +3 -1
- data/demo/config/targets/INST/cmd_tlm/inst_cmds.txt +1 -0
- data/demo/config/targets/INST/lib/inst_dump_component.rb +34 -0
- data/demo/config/targets/INST/screens/adcs.txt +39 -15
- data/demo/config/targets/INST/screens/commanding.txt +26 -19
- data/demo/config/targets/INST/screens/spacing_box.txt +44 -0
- data/demo/config/targets/INST/screens/spacing_grid.txt +78 -0
- data/demo/config/targets/INST/screens/tabs.txt +0 -2
- data/demo/config/targets/INST/sequences/sequence.tsv +3 -0
- data/demo/config/targets/INST/tables/EventAction.csv +9 -0
- data/demo/config/targets/INST/tables/EventAction.dat +0 -0
- data/demo/config/targets/INST/tables/McConfigTable.csv +20 -0
- data/demo/config/targets/INST/tables/McConfigTable.dat +0 -0
- data/demo/config/targets/INST/target.txt +4 -0
- data/demo/config/targets/INST/tools/data_viewer/data_viewer.txt +2 -0
- data/demo/config/targets/INST/tools/data_viewer/data_viewer2.txt +2 -0
- data/demo/config/targets/INST/tools/table_manager/EventAction_def.txt +6 -0
- data/demo/config/targets/INST/tools/table_manager/McConfigTable_def.txt +38 -0
- data/demo/config/targets/SYSTEM/cmd_tlm/limits_groups.txt +7 -3
- data/demo/config/targets/SYSTEM/cmd_tlm/meta_cmd_tlm.txt +16 -0
- data/demo/config/targets/{COSMOS/cmd_tlm/cosmos_server_cmds.txt → SYSTEM/cmd_tlm/system_cmds.txt} +8 -8
- data/demo/config/targets/SYSTEM/cmd_tlm/system_tlm.txt +7 -0
- data/demo/config/targets/{COSMOS → SYSTEM}/cmd_tlm_server.txt +2 -2
- data/demo/config/targets/SYSTEM/lib/limits_groups.rb +39 -0
- data/demo/config/targets/SYSTEM/screens/status.txt +1 -1
- data/demo/config/targets/SYSTEM/target.txt +12 -0
- data/demo/config/targets/TEMPLATED/cmd_tlm_server.txt +1 -1
- data/demo/config/targets/TEMPLATED/lib/templated_interface.rb +8 -5
- data/demo/config/targets/TEMPLATED/target.txt +2 -0
- data/demo/config/tools/cmd_tlm_server/cmd_tlm_server.txt +15 -6
- data/demo/config/tools/cmd_tlm_server/cmd_tlm_server2.txt +13 -5
- data/demo/config/tools/data_viewer/data_viewer.txt +9 -0
- data/demo/config/tools/launcher/launcher.txt +9 -6
- data/demo/config/tools/launcher/launcher2.txt +16 -13
- data/demo/config/tools/launcher/launcher_mini.txt +45 -0
- data/demo/config/tools/table_manager/MCConfigurationTable_fsw1_def.txt +12 -11
- data/demo/config/tools/table_manager/MCConfigurationTable_fsw2_def.txt +12 -11
- data/demo/config/tools/test_runner/test_runner.txt +1 -1
- data/demo/config/tools/tlm_viewer/tlm_viewer.txt +5 -5
- data/demo/lib/example_background_task.rb +9 -5
- data/demo/lib/example_target.rb +5 -15
- data/demo/lib/scpi_target.rb +4 -10
- data/demo/procedures/cosmos_api_test.rb +17 -0
- data/demo/tools/CmdSequence +16 -0
- data/demo/tools/CmdSequence.bat +9 -0
- data/demo/tools/ConfigEditor +16 -0
- data/demo/tools/ConfigEditor.bat +9 -0
- data/demo/tools/mac/CmdSequence.app/Contents/Info.plist +38 -0
- data/demo/tools/mac/CmdSequence.app/Contents/MacOS/CmdSequence.rb +16 -0
- data/demo/tools/mac/CmdSequence.app/Contents/MacOS/main.sh +10 -0
- data/demo/tools/mac/CmdSequence.app/Contents/MacOS/tool_launch.rb +38 -0
- data/demo/tools/mac/CmdSequence.app/Contents/Resources/appIcon.icns +0 -0
- data/ext/cosmos/ext/packet/packet.c +5 -5
- data/install/config/data/crc.txt +12 -8
- data/install/config/system/system.txt +13 -3
- data/install/config/targets/SYSTEM/cmd_tlm/meta_cmd_tlm.txt +14 -0
- data/install/config/targets/SYSTEM/target.txt +12 -0
- data/install/tools/CmdSequence +16 -0
- data/install/tools/CmdSequence.bat +9 -0
- data/install/tools/ConfigEditor +16 -0
- data/install/tools/ConfigEditor.bat +9 -0
- data/install/tools/mac/CmdSequence.app/Contents/Info.plist +38 -0
- data/install/tools/mac/CmdSequence.app/Contents/MacOS/CmdSequence.rb +16 -0
- data/install/tools/mac/CmdSequence.app/Contents/MacOS/main.sh +10 -0
- data/install/tools/mac/CmdSequence.app/Contents/MacOS/tool_launch.rb +38 -0
- data/install/tools/mac/CmdSequence.app/Contents/Resources/appIcon.icns +0 -0
- data/lib/cosmos.rb +1 -1
- data/lib/cosmos/config/config_parser.rb +147 -59
- data/lib/cosmos/config/meta_config_parser.rb +57 -0
- data/lib/cosmos/conversions/polynomial_conversion.rb +20 -4
- data/lib/cosmos/conversions/unix_time_conversion.rb +4 -4
- data/lib/cosmos/core_ext/array.rb +45 -5
- data/lib/cosmos/core_ext/cosmos_io.rb +31 -15
- data/lib/cosmos/core_ext/file.rb +2 -2
- data/lib/cosmos/core_ext/kernel.rb +1 -6
- data/lib/cosmos/core_ext/objectspace.rb +0 -2
- data/lib/cosmos/core_ext/string.rb +27 -4
- data/lib/cosmos/core_ext/time.rb +39 -10
- data/lib/cosmos/gui/choosers/combobox_chooser.rb +37 -26
- data/lib/cosmos/gui/choosers/file_chooser.rb +23 -6
- data/lib/cosmos/gui/choosers/float_chooser.rb +13 -11
- data/lib/cosmos/gui/choosers/integer_chooser.rb +13 -11
- data/lib/cosmos/gui/choosers/string_chooser.rb +18 -36
- data/lib/cosmos/gui/choosers/telemetry_chooser.rb +64 -64
- data/lib/cosmos/gui/choosers/value_chooser.rb +15 -15
- data/lib/cosmos/gui/dialogs/about_dialog.rb +18 -13
- data/lib/cosmos/gui/dialogs/calendar_dialog.rb +11 -3
- data/lib/cosmos/gui/dialogs/cmd_tlm_raw_dialog.rb +1 -1
- data/lib/cosmos/gui/dialogs/details_dialog.rb +1 -1
- data/lib/cosmos/gui/dialogs/exception_dialog.rb +7 -7
- data/lib/cosmos/gui/dialogs/find_replace_dialog.rb +20 -15
- data/lib/cosmos/gui/dialogs/interface_raw_dialog.rb +143 -0
- data/lib/cosmos/gui/dialogs/legal_dialog.rb +6 -5
- data/lib/cosmos/gui/dialogs/packet_log_dialog.rb +5 -2
- data/lib/cosmos/gui/dialogs/progress_dialog.rb +1 -1
- data/lib/cosmos/gui/dialogs/pry_dialog.rb +4 -4
- data/lib/cosmos/gui/dialogs/scroll_text_dialog.rb +3 -0
- data/lib/cosmos/gui/dialogs/set_tlm_dialog.rb +7 -6
- data/lib/cosmos/gui/dialogs/splash.rb +1 -1
- data/lib/cosmos/gui/dialogs/tlm_details_dialog.rb +1 -1
- data/lib/cosmos/gui/dialogs/tlm_graph_dialog.rb +114 -0
- data/lib/cosmos/gui/line_graph/line_graph.rb +9 -10
- data/lib/cosmos/gui/line_graph/line_graph_dialog.rb +7 -5
- data/lib/cosmos/gui/line_graph/line_graph_drawing.rb +3 -7
- data/lib/cosmos/gui/line_graph/line_graph_popups.rb +3 -8
- data/lib/cosmos/gui/line_graph/line_graph_scaling.rb +2 -7
- data/lib/cosmos/gui/line_graph/overview_graph.rb +6 -1
- data/lib/cosmos/gui/opengl/earth_model.rb +6 -3
- data/lib/cosmos/gui/opengl/gl_bounds.rb +11 -23
- data/lib/cosmos/gui/opengl/gl_light.rb +3 -4
- data/lib/cosmos/gui/opengl/gl_material.rb +3 -4
- data/lib/cosmos/gui/opengl/gl_scene.rb +10 -4
- data/lib/cosmos/gui/opengl/gl_shape.rb +6 -2
- data/lib/cosmos/gui/opengl/gl_viewer.rb +5 -5
- data/lib/cosmos/gui/opengl/gl_viewport.rb +11 -12
- data/lib/cosmos/gui/opengl/moon_model.rb +6 -3
- data/lib/cosmos/gui/opengl/stl_reader.rb +8 -9
- data/lib/cosmos/gui/opengl/stl_shape.rb +4 -5
- data/lib/cosmos/gui/opengl/texture_mapped_sphere.rb +7 -7
- data/lib/cosmos/gui/qt.rb +1 -1
- data/lib/cosmos/gui/qt_tool.rb +21 -10
- data/lib/cosmos/gui/text/completion.rb +23 -2
- data/lib/cosmos/gui/text/completion_text_edit.rb +38 -23
- data/lib/cosmos/gui/utilities/analyze_log.rb +1 -1
- data/lib/cosmos/gui/utilities/screenshot.rb +2 -2
- data/lib/cosmos/gui/widgets/full_text_search_line_edit.rb +11 -1
- data/lib/cosmos/gui/widgets/packet_log_frame.rb +19 -6
- data/lib/cosmos/interfaces.rb +10 -0
- data/lib/cosmos/interfaces/cmd_tlm_server_interface.rb +28 -47
- data/lib/cosmos/interfaces/interface.rb +240 -22
- data/lib/cosmos/interfaces/linc_interface.rb +3 -5
- data/lib/cosmos/interfaces/protocols/burst_protocol.rb +173 -0
- data/lib/cosmos/interfaces/protocols/crc_protocol.rb +141 -0
- data/lib/cosmos/{streams/fixed_stream_protocol.rb → interfaces/protocols/fixed_protocol.rb} +40 -37
- data/lib/cosmos/{streams/length_stream_protocol.rb → interfaces/protocols/length_protocol.rb} +55 -48
- data/lib/cosmos/interfaces/protocols/override_protocol.rb +52 -0
- data/lib/cosmos/interfaces/protocols/preidentified_protocol.rb +141 -0
- data/lib/cosmos/interfaces/protocols/protocol.rb +60 -0
- data/lib/cosmos/interfaces/protocols/template_protocol.rb +209 -0
- data/lib/cosmos/interfaces/protocols/terminated_protocol.rb +81 -0
- data/lib/cosmos/interfaces/serial_interface.rb +28 -23
- data/lib/cosmos/interfaces/simulated_target_interface.rb +27 -16
- data/lib/cosmos/interfaces/stream_interface.rb +36 -108
- data/lib/cosmos/interfaces/tcpip_client_interface.rb +21 -21
- data/lib/cosmos/interfaces/tcpip_server_interface.rb +555 -94
- data/lib/cosmos/interfaces/udp_interface.rb +51 -83
- data/lib/cosmos/io/buffered_file.rb +92 -2
- data/lib/cosmos/io/json_drb.rb +2 -2
- data/lib/cosmos/io/posix_serial_driver.rb +3 -1
- data/lib/cosmos/io/raw_logger.rb +3 -3
- data/lib/cosmos/io/serial_driver.rb +14 -5
- data/lib/cosmos/io/win32_serial_driver.rb +16 -4
- data/lib/cosmos/packet_logs.rb +0 -1
- data/lib/cosmos/packet_logs/packet_log_reader.rb +11 -1
- data/lib/cosmos/packet_logs/packet_log_writer.rb +31 -13
- data/lib/cosmos/packets/binary_accessor.rb +599 -32
- data/lib/cosmos/packets/commands.rb +48 -24
- data/lib/cosmos/packets/packet.rb +140 -54
- data/lib/cosmos/packets/packet_config.rb +0 -2
- data/lib/cosmos/packets/parsers/packet_item_parser.rb +10 -2
- data/lib/cosmos/packets/structure.rb +81 -33
- data/lib/cosmos/packets/structure_item.rb +45 -5
- data/lib/cosmos/packets/telemetry.rb +149 -55
- data/lib/cosmos/script/api_shared.rb +1000 -0
- data/lib/cosmos/script/commands.rb +2 -2
- data/lib/cosmos/script/extract.rb +19 -4
- data/lib/cosmos/script/limits.rb +2 -0
- data/lib/cosmos/script/script.rb +1 -1
- data/lib/cosmos/script/scripting.rb +4 -784
- data/lib/cosmos/script/telemetry.rb +44 -23
- data/lib/cosmos/script/tools.rb +15 -69
- data/lib/cosmos/streams/serial_stream.rb +12 -19
- data/lib/cosmos/streams/stream.rb +2 -11
- data/lib/cosmos/streams/tcpip_socket_stream.rb +3 -13
- data/lib/cosmos/system/system.rb +187 -31
- data/lib/cosmos/system/target.rb +11 -2
- data/lib/cosmos/tools/cmd_extractor/cmd_extractor.rb +12 -11
- data/lib/cosmos/tools/cmd_sender/{cmd_sender_item_delegate.rb → cmd_param_table_item_delegate.rb} +11 -10
- data/lib/cosmos/tools/cmd_sender/cmd_sender.rb +209 -164
- data/lib/cosmos/tools/cmd_sequence/cmd_sequence.rb +652 -0
- data/lib/cosmos/tools/cmd_sequence/sequence_item.rb +510 -0
- data/lib/cosmos/tools/cmd_sequence/sequence_list.rb +194 -0
- data/lib/cosmos/tools/cmd_tlm_server/api.rb +179 -5
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +31 -14
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +23 -16
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_gui.rb +92 -20
- data/lib/cosmos/tools/cmd_tlm_server/commanding.rb +1 -1
- data/lib/cosmos/tools/cmd_tlm_server/gui/interfaces_tab.rb +17 -4
- data/lib/cosmos/tools/cmd_tlm_server/gui/targets_tab.rb +0 -5
- data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +1 -2
- data/lib/cosmos/tools/cmd_tlm_server/interfaces.rb +4 -4
- data/lib/cosmos/tools/cmd_tlm_server/limits_groups_background_task.rb +121 -0
- data/lib/cosmos/tools/cmd_tlm_server/routers.rb +8 -4
- data/lib/cosmos/tools/config_editor/config_editor.rb +720 -0
- data/lib/cosmos/tools/config_editor/config_editor_frame.rb +675 -0
- data/lib/cosmos/tools/data_viewer/data_viewer.rb +44 -27
- data/lib/cosmos/tools/data_viewer/data_viewer_component.rb +8 -22
- data/lib/cosmos/tools/launcher/launcher.rb +29 -12
- data/lib/cosmos/tools/launcher/launcher_config.rb +1 -1
- data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +153 -42
- data/lib/cosmos/tools/packet_viewer/packet_viewer.rb +44 -6
- data/lib/cosmos/tools/replay/replay.rb +36 -20
- data/lib/cosmos/tools/replay/replay_server.rb +1 -1
- data/lib/cosmos/tools/script_runner/script_runner_config.rb +1 -1
- data/lib/cosmos/tools/script_runner/script_runner_frame.rb +31 -21
- data/lib/cosmos/tools/table_manager/table_config.rb +9 -3
- data/lib/cosmos/tools/table_manager/table_manager.rb +27 -7
- data/lib/cosmos/tools/test_runner/results_writer.rb +6 -6
- data/lib/cosmos/tools/test_runner/test_runner.rb +4 -6
- data/lib/cosmos/tools/tlm_extractor/tlm_extractor.rb +4 -5
- data/lib/cosmos/tools/tlm_extractor/tlm_extractor_config.rb +1 -1
- data/lib/cosmos/tools/tlm_extractor/tlm_extractor_processor.rb +1 -1
- data/lib/cosmos/tools/tlm_grapher/data_object_adders/housekeeping_data_object_adder.rb +23 -6
- data/lib/cosmos/tools/tlm_grapher/data_object_editors/housekeeping_data_object_editor.rb +44 -3
- data/lib/cosmos/tools/tlm_grapher/data_objects/housekeeping_data_object.rb +20 -7
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots/overview_tabbed_plots.rb +1 -1
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_config.rb +11 -4
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_plot_editor.rb +2 -2
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_realtime_thread.rb +1 -1
- data/lib/cosmos/tools/tlm_grapher/tlm_grapher.rb +16 -0
- data/lib/cosmos/tools/tlm_viewer/screen.rb +36 -32
- data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +59 -50
- data/lib/cosmos/tools/tlm_viewer/tlm_viewer_config.rb +2 -2
- data/lib/cosmos/tools/tlm_viewer/widgets.rb +1 -0
- data/lib/cosmos/tools/tlm_viewer/widgets/canvasvalue_widget.rb +1 -0
- data/lib/cosmos/tools/tlm_viewer/widgets/labelvalue_widget.rb +22 -4
- data/lib/cosmos/tools/tlm_viewer/widgets/matrixbycolumns_widget.rb +9 -0
- data/lib/cosmos/tools/tlm_viewer/widgets/spacer_widget.rb +55 -0
- data/lib/cosmos/tools/tlm_viewer/widgets/vertical_widget.rb +3 -2
- data/lib/cosmos/tools/tlm_viewer/widgets/verticalbox_widget.rb +3 -2
- data/lib/cosmos/tools/tlm_viewer/widgets/widget.rb +12 -12
- data/lib/cosmos/top_level.rb +34 -24
- data/lib/cosmos/utilities/crc.rb +108 -6
- data/lib/cosmos/utilities/csv.rb +68 -14
- data/lib/cosmos/utilities/logger.rb +2 -2
- data/lib/cosmos/utilities/low_fragmentation_array.rb +9 -1
- data/lib/cosmos/version.rb +6 -6
- data/lib/cosmos/win32/win32_main.rb +50 -46
- data/run_gui_tests.bat +3 -1
- data/spec/conversions/unix_time_formatted_conversion_spec.rb +2 -2
- data/spec/conversions/unix_time_seconds_conversion_spec.rb +2 -2
- data/spec/core_ext/file_spec.rb +1 -1
- data/spec/core_ext/objectspace_spec.rb +12 -9
- data/spec/core_ext/string_spec.rb +6 -0
- data/spec/core_ext/time_spec.rb +10 -0
- data/spec/gui/line_graph/line_clip_spec.rb +226 -224
- data/spec/gui/qt_spec.rb +81 -79
- data/spec/install/config/system/system.txt +0 -6
- data/spec/install/config/targets/INST/cmd_tlm/inst_cmd_linc.txt +5 -5
- data/spec/install/config/targets/INST/cmd_tlm/inst_tlm_linc.txt +8 -8
- data/spec/install/config/targets/SYSTEM/cmd_tlm/meta_cmd_tlm.txt +16 -0
- data/{install/config/targets/COSMOS/cmd_tlm/cosmos_server_cmds.txt → spec/install/config/targets/SYSTEM/cmd_tlm/system_cmds.txt} +8 -8
- data/spec/install/config/targets/SYSTEM/cmd_tlm/system_tlm.txt +7 -0
- data/spec/install/config/targets/{COSMOS → SYSTEM}/cmd_tlm_server.txt +2 -2
- data/spec/install/config/targets/SYSTEM/screens/status.txt +12 -0
- data/spec/install/config/targets/SYSTEM/target.txt +12 -0
- data/spec/interfaces/cmd_tlm_server_interface_spec.rb +9 -13
- data/spec/interfaces/interface_spec.rb +402 -18
- data/spec/interfaces/linc_interface_spec.rb +37 -39
- data/spec/interfaces/protocols/burst_protocol_spec.rb +300 -0
- data/spec/interfaces/protocols/crc_protocol_spec.rb +709 -0
- data/spec/interfaces/protocols/fixed_protocol_spec.rb +119 -0
- data/spec/interfaces/protocols/length_protocol_spec.rb +499 -0
- data/spec/interfaces/protocols/override_protocol_spec.rb +158 -0
- data/spec/interfaces/protocols/preidentified_protocol_spec.rb +149 -0
- data/spec/interfaces/protocols/template_protocol_spec.rb +218 -0
- data/spec/interfaces/protocols/terminated_protocol_spec.rb +174 -0
- data/spec/interfaces/serial_interface_spec.rb +35 -34
- data/spec/interfaces/simulated_target_interface_spec.rb +13 -13
- data/spec/interfaces/tcpip_client_interface_spec.rb +21 -16
- data/spec/interfaces/tcpip_server_interface_spec.rb +66 -69
- data/spec/interfaces/udp_interface_spec.rb +120 -55
- data/spec/io/serial_driver_spec.rb +41 -39
- data/spec/io/udp_sockets_spec.rb +13 -8
- data/spec/io/win32_serial_driver_spec.rb +62 -59
- data/spec/packet_logs/packet_log_reader_spec.rb +68 -47
- data/spec/packet_logs/packet_log_writer_spec.rb +7 -5
- data/spec/packets/commands_spec.rb +5 -5
- data/spec/packets/packet_spec.rb +2 -14
- data/spec/script/extract_spec.rb +21 -7
- data/spec/script/scripting_spec.rb +261 -6
- data/spec/script/telemetry_spec.rb +17 -9
- data/spec/spec_helper.rb +26 -10
- data/spec/streams/serial_stream_spec.rb +87 -82
- data/spec/streams/tcpip_client_stream_spec.rb +12 -4
- data/spec/streams/tcpip_socket_stream_spec.rb +5 -0
- data/spec/system/system_spec.rb +66 -50
- data/spec/system/target_spec.rb +33 -11
- data/spec/tools/cmd_tlm_server/api_spec.rb +5 -5
- data/spec/tools/cmd_tlm_server/background_tasks_spec.rb +75 -15
- data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +125 -5
- data/spec/tools/cmd_tlm_server/cmd_tlm_server_spec.rb +244 -232
- data/spec/tools/cmd_tlm_server/commanding_spec.rb +18 -18
- data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +124 -29
- data/spec/tools/cmd_tlm_server/interfaces_spec.rb +2 -2
- data/spec/tools/cmd_tlm_server/limits_groups_background_task_spec.rb +145 -0
- data/spec/tools/cmd_tlm_server/router_thread_spec.rb +50 -10
- data/spec/tools/table_manager/tablemanager_core_spec.rb +0 -1
- data/spec/top_level/top_level_spec.rb +39 -11
- data/spec/utilities/csv_spec.rb +62 -20
- data/tasks/gemfile_stats.rake +6 -3
- data/test/performance/config/system/system_packets.txt +0 -1
- data/test/performance/config/system/system_threads.txt +0 -1
- metadata +177 -92
- data/autohotkey/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +0 -15
- data/autohotkey/config/targets/COSMOS/cmd_tlm_server.txt +0 -6
- data/autohotkey/config/targets/COSMOS/target.txt +0 -5
- data/autohotkey/userpath.txt +0 -1
- data/demo/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +0 -15
- data/demo/config/targets/COSMOS/screens/limits_change.txt +0 -20
- data/demo/config/targets/COSMOS/screens/version.txt +0 -19
- data/demo/config/targets/COSMOS/target.txt +0 -11
- data/demo/config/targets/META/cmd_tlm/meta_cmd.txt +0 -10
- data/demo/config/targets/META/cmd_tlm/meta_tlm.txt +0 -13
- data/demo/userpath.txt +0 -1
- data/install/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +0 -15
- data/install/config/targets/COSMOS/cmd_tlm_server.txt +0 -6
- data/install/config/targets/COSMOS/screens/limits_change.txt +0 -20
- data/install/config/targets/COSMOS/screens/version.txt +0 -19
- data/install/config/targets/COSMOS/target.txt +0 -9
- data/install/config/targets/SYSTEM/README.txt +0 -1
- data/install/userpath.txt +0 -1
- data/lib/cosmos/io/tcpip_server.rb +0 -571
- data/lib/cosmos/packet_logs/meta_packet_log_writer.rb +0 -107
- data/lib/cosmos/streams/burst_stream_protocol.rb +0 -25
- data/lib/cosmos/streams/preidentified_stream_protocol.rb +0 -118
- data/lib/cosmos/streams/stream_protocol.rb +0 -373
- data/lib/cosmos/streams/template_stream_protocol.rb +0 -140
- data/lib/cosmos/streams/terminated_stream_protocol.rb +0 -85
- data/spec/install/config/targets/COSMOS/cmd_tlm/cosmos_server_cmds.txt +0 -41
- data/spec/install/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +0 -15
- data/spec/install/config/targets/COSMOS/screens/limits_change.txt +0 -20
- data/spec/install/config/targets/COSMOS/screens/version.txt +0 -19
- data/spec/install/config/targets/COSMOS/target.txt +0 -5
- data/spec/install/config/targets/META/cmd_tlm/meta_cmd.txt +0 -4
- data/spec/install/config/targets/META/cmd_tlm/meta_tlm.txt +0 -4
- data/spec/install/userpath.txt +0 -1
- data/spec/interfaces/stream_interface_spec.rb +0 -157
- data/spec/io/tcpip_server_spec.rb +0 -338
- data/spec/packet_logs/meta_packet_log_writer_spec.rb +0 -170
- data/spec/streams/burst_stream_protocol_spec.rb +0 -32
- data/spec/streams/fixed_stream_protocol_spec.rb +0 -113
- data/spec/streams/length_stream_protocol_spec.rb +0 -300
- data/spec/streams/preidentified_stream_protocol_spec.rb +0 -121
- data/spec/streams/stream_protocol_spec.rb +0 -346
- data/spec/streams/template_stream_protocol_spec.rb +0 -156
- data/spec/streams/terminated_stream_protocol_spec.rb +0 -127
- data/test/performance/userpath.txt +0 -1
|
@@ -0,0 +1,652 @@
|
|
|
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
|
+
require 'time'
|
|
12
|
+
require 'cosmos'
|
|
13
|
+
Cosmos.catch_fatal_exception do
|
|
14
|
+
require 'cosmos/script'
|
|
15
|
+
require 'cosmos/config/config_parser'
|
|
16
|
+
require 'cosmos/gui/qt_tool'
|
|
17
|
+
require 'cosmos/gui/utilities/script_module_gui'
|
|
18
|
+
require 'cosmos/gui/dialogs/splash'
|
|
19
|
+
require 'cosmos/gui/widgets/realtime_button_bar'
|
|
20
|
+
require 'cosmos/gui/choosers/file_chooser'
|
|
21
|
+
require 'cosmos/tools/cmd_sequence/sequence_list'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
module Cosmos
|
|
25
|
+
# Creates and executes command sequences. Commands are choosen through a GUI
|
|
26
|
+
# similar to CmdSender where the user selects a target, command, and then
|
|
27
|
+
# sets the command parameters in a table layout. Sequences can be saved and
|
|
28
|
+
# loaded and can have relative or absolute delays.
|
|
29
|
+
class CmdSequence < QtTool
|
|
30
|
+
# Runs the CmdSequence application
|
|
31
|
+
def self.run(option_parser = nil, options = nil)
|
|
32
|
+
Cosmos.catch_fatal_exception do
|
|
33
|
+
unless option_parser && options
|
|
34
|
+
option_parser, options = create_default_options()
|
|
35
|
+
options.width = 600
|
|
36
|
+
options.height = 425
|
|
37
|
+
option_parser.on("-o", "--output DIRECTORY", "Save files in the specified directory") do |arg|
|
|
38
|
+
options.output_dir = File.expand_path(arg)
|
|
39
|
+
end
|
|
40
|
+
options.run_sequence = nil
|
|
41
|
+
option_parser.on("-r", "--run FILE", "Open and run the specified sequence") do |arg|
|
|
42
|
+
options.run_sequence = arg
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
super(option_parser, options)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Creates the CmdSequence instance
|
|
50
|
+
# @param options [OpenStruct] Application command line options
|
|
51
|
+
def initialize(options)
|
|
52
|
+
# MUST BE FIRST - All code before super is executed twice in RubyQt Based classes
|
|
53
|
+
super(options)
|
|
54
|
+
Cosmos.load_cosmos_icon("cmd_sequence.png")
|
|
55
|
+
if options.output_dir
|
|
56
|
+
@sequence_dir = options.output_dir
|
|
57
|
+
else
|
|
58
|
+
@sequence_dir = System.paths['SEQUENCES']
|
|
59
|
+
end
|
|
60
|
+
@filename = "Untitled"
|
|
61
|
+
@run_thread = nil
|
|
62
|
+
|
|
63
|
+
initialize_actions()
|
|
64
|
+
initialize_menus()
|
|
65
|
+
initialize_central_widget()
|
|
66
|
+
complete_initialize() # defined in qt_tool
|
|
67
|
+
update_title()
|
|
68
|
+
|
|
69
|
+
# Bring up slash screen for long duration tasks after creation
|
|
70
|
+
Splash.execute(self) do |splash|
|
|
71
|
+
# Configure CosmosConfig to interact with splash screen
|
|
72
|
+
ConfigParser.splash = splash
|
|
73
|
+
|
|
74
|
+
System.commands
|
|
75
|
+
Qt.execute_in_main_thread(true) do
|
|
76
|
+
update_targets()
|
|
77
|
+
@target_select.setCurrentText(options.packet[0]) if options.packet
|
|
78
|
+
update_commands()
|
|
79
|
+
@cmd_select.setCurrentText(options.packet[1]) if options.packet
|
|
80
|
+
end
|
|
81
|
+
# Unconfigure CosmosConfig to interact with splash screen
|
|
82
|
+
ConfigParser.splash = nil
|
|
83
|
+
end
|
|
84
|
+
run_sequence(options.run_sequence) if options.run_sequence
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Creates the menu actions
|
|
88
|
+
def initialize_actions
|
|
89
|
+
super()
|
|
90
|
+
|
|
91
|
+
@file_new = Qt::Action.new(Cosmos.get_icon('file.png'), tr('&New'), self)
|
|
92
|
+
@file_new_keyseq = Qt::KeySequence.new(tr('Ctrl+N'))
|
|
93
|
+
@file_new.shortcut = @file_new_keyseq
|
|
94
|
+
@file_new.statusTip = tr('Start a new sequence')
|
|
95
|
+
@file_new.connect(SIGNAL('triggered()')) { file_new() }
|
|
96
|
+
|
|
97
|
+
@file_save = Qt::Action.new(Cosmos.get_icon('save.png'), tr('&Save'), self)
|
|
98
|
+
@file_save_keyseq = Qt::KeySequence.new(tr('Ctrl+S'))
|
|
99
|
+
@file_save.shortcut = @file_save_keyseq
|
|
100
|
+
@file_save.statusTip = tr('Save the sequence')
|
|
101
|
+
@file_save.connect(SIGNAL('triggered()')) { file_save(false) }
|
|
102
|
+
|
|
103
|
+
@file_save_as = Qt::Action.new(Cosmos.get_icon('save_as.png'), tr('Save &As'), self)
|
|
104
|
+
@file_save_as.statusTip = tr('Save the sequence')
|
|
105
|
+
@file_save_as.connect(SIGNAL('triggered()')) { file_save(true) }
|
|
106
|
+
|
|
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() }
|
|
111
|
+
|
|
112
|
+
@show_ignored = Qt::Action.new(tr('&Show Ignored Parameters'), self)
|
|
113
|
+
@show_ignored.statusTip = tr('Show ignored parameters which are normally hidden')
|
|
114
|
+
@show_ignored.setCheckable(true)
|
|
115
|
+
@show_ignored.setChecked(false)
|
|
116
|
+
@show_ignored.connect(SIGNAL('toggled(bool)')) do |bool|
|
|
117
|
+
@sequence_list.map {|item| item.show_ignored(bool) }
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
@states_in_hex = Qt::Action.new(tr('&Display State Values in Hex'), self)
|
|
121
|
+
@states_in_hex.statusTip = tr('Display states values in hex instead of decimal')
|
|
122
|
+
@states_in_hex.setCheckable(true)
|
|
123
|
+
@states_in_hex.setChecked(false)
|
|
124
|
+
@states_in_hex.connect(SIGNAL('toggled(bool)')) do |bool|
|
|
125
|
+
@sequence_list.map {|item| item.states_in_hex(bool) }
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
@expand_action = Qt::Action.new(tr('&Expand All'), self)
|
|
129
|
+
@expand_action.statusTip = tr('Expand all currently visible commands')
|
|
130
|
+
@expand_action.connect(SIGNAL('triggered()')) do
|
|
131
|
+
@sequence_list.map {|item| item.expand }
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
@collapse_action = Qt::Action.new(tr('&Collapse All'), self)
|
|
135
|
+
@collapse_action.statusTip = tr('Collapse all currently visible commands')
|
|
136
|
+
@collapse_action.connect(SIGNAL('triggered()')) do
|
|
137
|
+
@sequence_list.map {|item| item.collapse }
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
@script_disconnect = Qt::Action.new(Cosmos.get_icon('disconnected.png'), tr('&Toggle Disconnect'), self)
|
|
141
|
+
@script_disconnect_keyseq = Qt::KeySequence.new(tr('Ctrl+T'))
|
|
142
|
+
@script_disconnect.shortcut = @script_disconnect_keyseq
|
|
143
|
+
@script_disconnect.statusTip = tr('Toggle disconnect from the server')
|
|
144
|
+
@script_disconnect.connect(SIGNAL('triggered()')) do
|
|
145
|
+
@server_config_file ||= CmdTlmServer::DEFAULT_CONFIG_FILE
|
|
146
|
+
@server_config_file = toggle_disconnect(@server_config_file)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Create the application menus and assign the actions
|
|
151
|
+
def initialize_menus
|
|
152
|
+
file_menu = menuBar.addMenu(tr('&File'))
|
|
153
|
+
file_menu.addAction(@file_new)
|
|
154
|
+
|
|
155
|
+
open_action = Qt::Action.new(self)
|
|
156
|
+
open_action.shortcut = Qt::KeySequence.new(tr('Ctrl+O'))
|
|
157
|
+
open_action.connect(SIGNAL('triggered()')) { file_open(@sequence_dir) }
|
|
158
|
+
self.addAction(open_action)
|
|
159
|
+
|
|
160
|
+
file_open = file_menu.addMenu(tr('&Open'))
|
|
161
|
+
file_open.setIcon(Cosmos.get_icon('open.png'))
|
|
162
|
+
target_dirs_action(file_open, System.paths['SEQUENCES'], 'sequences', method(:file_open))
|
|
163
|
+
|
|
164
|
+
file_menu.addAction(@file_save)
|
|
165
|
+
file_menu.addAction(@file_save_as)
|
|
166
|
+
file_menu.addSeparator()
|
|
167
|
+
file_menu.addAction(@exit_action)
|
|
168
|
+
|
|
169
|
+
action_menu = menuBar.addMenu(tr('&Actions'))
|
|
170
|
+
action_menu.addAction(@show_ignored)
|
|
171
|
+
action_menu.addAction(@states_in_hex)
|
|
172
|
+
action_menu.addSeparator()
|
|
173
|
+
action_menu.addAction(@expand_action)
|
|
174
|
+
action_menu.addAction(@collapse_action)
|
|
175
|
+
action_menu.addSeparator()
|
|
176
|
+
action_menu.addAction(@script_disconnect)
|
|
177
|
+
|
|
178
|
+
@about_string = "Sequence Generator generates and executes sequences of commands."
|
|
179
|
+
initialize_help_menu()
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Create the CmdSequence GUI
|
|
183
|
+
def initialize_central_widget
|
|
184
|
+
central_widget = Qt::Widget.new
|
|
185
|
+
setCentralWidget(central_widget)
|
|
186
|
+
central_layout = Qt::VBoxLayout.new
|
|
187
|
+
central_widget.layout = central_layout
|
|
188
|
+
|
|
189
|
+
@realtime_button_bar = RealtimeButtonBar.new(self)
|
|
190
|
+
@realtime_button_bar.start_callback = method(:handle_start)
|
|
191
|
+
@realtime_button_bar.pause_callback = method(:handle_pause)
|
|
192
|
+
@realtime_button_bar.stop_callback = method(:handle_stop)
|
|
193
|
+
@realtime_button_bar.state = 'Stopped'
|
|
194
|
+
central_layout.addWidget(@realtime_button_bar)
|
|
195
|
+
|
|
196
|
+
@target_select = Qt::ComboBox.new
|
|
197
|
+
@target_select.setMaxVisibleItems(6)
|
|
198
|
+
@target_select.connect(SIGNAL('activated(const QString&)')) do |target|
|
|
199
|
+
target_changed()
|
|
200
|
+
end
|
|
201
|
+
target_label = Qt::Label.new(tr("&Target:"))
|
|
202
|
+
target_label.setBuddy(@target_select)
|
|
203
|
+
|
|
204
|
+
@cmd_select = Qt::ComboBox.new
|
|
205
|
+
@cmd_select.setMaxVisibleItems(20)
|
|
206
|
+
cmd_label = Qt::Label.new(tr("&Command:"))
|
|
207
|
+
cmd_label.setBuddy(@cmd_select)
|
|
208
|
+
|
|
209
|
+
add = Qt::PushButton.new("Add")
|
|
210
|
+
add.connect(SIGNAL('clicked()')) do
|
|
211
|
+
command = System.commands.packet(@target_select.text, @cmd_select.text).dup
|
|
212
|
+
command.restore_defaults
|
|
213
|
+
item = @sequence_list.add(command)
|
|
214
|
+
item.show_ignored(@show_ignored.isChecked())
|
|
215
|
+
item.states_in_hex(@states_in_hex.isChecked())
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# Layout the target and command selection with Add button
|
|
219
|
+
select_layout = Qt::HBoxLayout.new
|
|
220
|
+
select_layout.addWidget(target_label)
|
|
221
|
+
select_layout.addWidget(@target_select, 1)
|
|
222
|
+
select_layout.addWidget(cmd_label)
|
|
223
|
+
select_layout.addWidget(@cmd_select, 1)
|
|
224
|
+
select_layout.addWidget(add)
|
|
225
|
+
central_layout.addLayout(select_layout)
|
|
226
|
+
|
|
227
|
+
# Create a splitter to hold the sequence area and the script output text area
|
|
228
|
+
splitter = Qt::Splitter.new(Qt::Vertical, self)
|
|
229
|
+
central_layout.addWidget(splitter)
|
|
230
|
+
|
|
231
|
+
@sequence_list = SequenceList.new
|
|
232
|
+
@sequence_list.connect(SIGNAL("modified()")) { update_title }
|
|
233
|
+
|
|
234
|
+
@scroll = Qt::ScrollArea.new()
|
|
235
|
+
@scroll.setSizePolicy(Qt::SizePolicy::Preferred, Qt::SizePolicy::Expanding)
|
|
236
|
+
@scroll.setWidgetResizable(true)
|
|
237
|
+
@scroll.setWidget(@sequence_list)
|
|
238
|
+
connect(@scroll.verticalScrollBar(), SIGNAL("valueChanged(int)"), @sequence_list, SLOT("update()"))
|
|
239
|
+
splitter.addWidget(@scroll)
|
|
240
|
+
|
|
241
|
+
bottom_frame = Qt::Widget.new
|
|
242
|
+
bottom_layout = Qt::VBoxLayout.new
|
|
243
|
+
bottom_layout.setContentsMargins(0,0,0,0)
|
|
244
|
+
bottom_layout_label = Qt::Label.new("Sequence Output:")
|
|
245
|
+
bottom_layout.addWidget(bottom_layout_label)
|
|
246
|
+
@output = Qt::TextEdit.new
|
|
247
|
+
@output.setReadOnly(true)
|
|
248
|
+
bottom_layout.addWidget(@output)
|
|
249
|
+
bottom_frame.setLayout(bottom_layout)
|
|
250
|
+
splitter.addWidget(bottom_frame)
|
|
251
|
+
splitter.setStretchFactor(0,1)
|
|
252
|
+
splitter.setStretchFactor(1,0)
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# Clears the sequence list
|
|
256
|
+
def file_new
|
|
257
|
+
return unless prompt_for_save_if_needed()
|
|
258
|
+
@sequence_list.clear
|
|
259
|
+
@filename = "Untitled"
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
# Opens a sequence list file and populates the GUI
|
|
263
|
+
# @param filename [String] Name of the file to open
|
|
264
|
+
def file_open(filename = nil)
|
|
265
|
+
return unless prompt_for_save_if_needed()
|
|
266
|
+
if File.directory?(filename)
|
|
267
|
+
filename = Qt::FileDialog.getOpenFileName(self, "Select Sequence", filename)
|
|
268
|
+
else
|
|
269
|
+
filename = Qt::FileDialog.getOpenFileName(self, "Select Sequence")
|
|
270
|
+
end
|
|
271
|
+
if !filename.nil? && File.exist?(filename) && !File.directory?(filename)
|
|
272
|
+
# Try to open and load the file. Errors are handled here.
|
|
273
|
+
@sequence_list.open(filename)
|
|
274
|
+
@sequence_list.map {|item| item.show_ignored(@show_ignored.isChecked()) }
|
|
275
|
+
@sequence_list.map {|item| item.states_in_hex(@states_in_hex.isChecked()) }
|
|
276
|
+
@filename = filename
|
|
277
|
+
@sequence_dir = File.dirname(filename)
|
|
278
|
+
@sequence_dir << '/' if @sequence_dir[-1..-1] != '/' and @sequence_dir[-1..-1] != '\\'
|
|
279
|
+
update_title()
|
|
280
|
+
end
|
|
281
|
+
rescue => error
|
|
282
|
+
@sequence_list.clear() # Errors during load invalidate the sequence
|
|
283
|
+
Qt::MessageBox.critical(self, 'Error', error.message)
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
# Saves the GUI configuration to file. Also performs SaveAs by prompting
|
|
287
|
+
# for a new filename.
|
|
288
|
+
# @param save_as [Boolean] Whether to SaveAs and prompt for a filename
|
|
289
|
+
def file_save(save_as = false)
|
|
290
|
+
filename = @filename # Start with the current filename
|
|
291
|
+
saved = false
|
|
292
|
+
if filename == 'Untitled' # No file is currently open
|
|
293
|
+
filename = Qt::FileDialog::getSaveFileName(self, # parent
|
|
294
|
+
'Save As...', # caption
|
|
295
|
+
@sequence_dir + '/sequence.txt', # dir
|
|
296
|
+
'Sequence Files (*.txt)') # filter
|
|
297
|
+
elsif save_as
|
|
298
|
+
filename = Qt::FileDialog::getSaveFileName(self, # parent
|
|
299
|
+
'Save As...', # caption
|
|
300
|
+
filename, # dir
|
|
301
|
+
'Sequence Files (*.txt)') # filter
|
|
302
|
+
end
|
|
303
|
+
if !filename.nil? && !filename.empty?
|
|
304
|
+
begin
|
|
305
|
+
@sequence_list.save(filename)
|
|
306
|
+
saved = true
|
|
307
|
+
@filename = filename
|
|
308
|
+
update_title()
|
|
309
|
+
@sequence_dir = File.dirname(filename)
|
|
310
|
+
@sequence_dir << '/' if @sequence_dir[-1..-1] != '/' and @sequence_dir[-1..-1] != '\\'
|
|
311
|
+
rescue => error
|
|
312
|
+
Qt::MessageBox.critical(self, 'Error', error.message)
|
|
313
|
+
end
|
|
314
|
+
end
|
|
315
|
+
saved
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
# Toggles whether CmdSequence is sending files to the CmdTlmServer (default)
|
|
319
|
+
# or disconnects and processes them all internally. The disconnected mode
|
|
320
|
+
# sets the background color to red to visually distinguish that no commands
|
|
321
|
+
# are actually going to the server.
|
|
322
|
+
# @param config_file [String] cmd_tlm_server.txt configuration file to
|
|
323
|
+
# process when creating the disconnected server
|
|
324
|
+
def toggle_disconnect(config_file)
|
|
325
|
+
if get_cmd_tlm_disconnect
|
|
326
|
+
set_cmd_tlm_disconnect(false)
|
|
327
|
+
self.setPalette(Cosmos::DEFAULT_PALETTE)
|
|
328
|
+
else
|
|
329
|
+
dialog = Qt::Dialog.new(self, Qt::WindowTitleHint | Qt::WindowSystemMenuHint)
|
|
330
|
+
dialog.setWindowTitle(tr("Server Config File"))
|
|
331
|
+
dialog_layout = Qt::VBoxLayout.new
|
|
332
|
+
|
|
333
|
+
chooser = FileChooser.new(self, "Config File", config_file, 'Select',
|
|
334
|
+
File.dirname(config_file))
|
|
335
|
+
chooser.callback = lambda do |filename|
|
|
336
|
+
chooser.filename = filename
|
|
337
|
+
end
|
|
338
|
+
dialog_layout.addWidget(chooser)
|
|
339
|
+
|
|
340
|
+
button_layout = Qt::HBoxLayout.new
|
|
341
|
+
ok = Qt::PushButton.new("Ok")
|
|
342
|
+
ok.setDefault(true)
|
|
343
|
+
ok.connect(SIGNAL('clicked()')) do
|
|
344
|
+
dialog.accept()
|
|
345
|
+
end
|
|
346
|
+
button_layout.addWidget(ok)
|
|
347
|
+
cancel = Qt::PushButton.new("Cancel")
|
|
348
|
+
cancel.connect(SIGNAL('clicked()')) do
|
|
349
|
+
dialog.reject()
|
|
350
|
+
end
|
|
351
|
+
button_layout.addWidget(cancel)
|
|
352
|
+
dialog_layout.addLayout(button_layout)
|
|
353
|
+
|
|
354
|
+
dialog.setLayout(dialog_layout)
|
|
355
|
+
if dialog.exec == Qt::Dialog::Accepted
|
|
356
|
+
config_file = chooser.filename
|
|
357
|
+
self.setPalette(Qt::Palette.new(Cosmos.getColor(170, 57, 57)))
|
|
358
|
+
Splash.execute(self) do |splash|
|
|
359
|
+
ConfigParser.splash = splash
|
|
360
|
+
splash.message = "Initializing Command and Telemetry Server"
|
|
361
|
+
set_cmd_tlm_disconnect(true, config_file)
|
|
362
|
+
ConfigParser.splash = nil
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
dialog.dispose
|
|
366
|
+
end
|
|
367
|
+
config_file
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
# Handle the closeEvent to check if we're running or a sequence needs to
|
|
371
|
+
# be saved before closing. Must be part of the public API.
|
|
372
|
+
def closeEvent(event)
|
|
373
|
+
if prompt_if_running_on_close()
|
|
374
|
+
handle_stop()
|
|
375
|
+
if prompt_for_save_if_needed()
|
|
376
|
+
super(event)
|
|
377
|
+
else
|
|
378
|
+
event.ignore()
|
|
379
|
+
end
|
|
380
|
+
else
|
|
381
|
+
event.ignore()
|
|
382
|
+
end
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
# Handles the start button on the realtime_button_bar. This button changes
|
|
386
|
+
# as sequences are running to "Go" which skips any remaining wait time on
|
|
387
|
+
# the command. It also continues any paused sequences.
|
|
388
|
+
def handle_start
|
|
389
|
+
case @realtime_button_bar.state
|
|
390
|
+
when 'Stopped'
|
|
391
|
+
return unless prompt_for_save_if_needed()
|
|
392
|
+
# Collapse all items
|
|
393
|
+
@sequence_list.map {|item| item.collapse }
|
|
394
|
+
@pause = false
|
|
395
|
+
@go = false
|
|
396
|
+
@realtime_button_bar.state = 'Running'
|
|
397
|
+
@realtime_button_bar.start_button.setText('Go')
|
|
398
|
+
output_append("*** Sequence Started ***")
|
|
399
|
+
@run_thread = Thread.new do
|
|
400
|
+
@sequence_list.each do |item|
|
|
401
|
+
Qt.execute_in_main_thread { @scroll.ensureWidgetVisible(item) }
|
|
402
|
+
execute_item(item)
|
|
403
|
+
end
|
|
404
|
+
# Since we're inside a new Ruby thread
|
|
405
|
+
Qt.execute_in_main_thread do
|
|
406
|
+
output_append("*** Sequence Complete ***")
|
|
407
|
+
@output.append("") # delimit the sequences in the output log
|
|
408
|
+
@realtime_button_bar.start_button.setText('Start')
|
|
409
|
+
@realtime_button_bar.state = 'Stopped'
|
|
410
|
+
end
|
|
411
|
+
end
|
|
412
|
+
when 'Paused'
|
|
413
|
+
output_append("User pressed #{@realtime_button_bar.start_button.text}")
|
|
414
|
+
@realtime_button_bar.state = 'Running'
|
|
415
|
+
@pause = false
|
|
416
|
+
when 'Running'
|
|
417
|
+
output_append("User pressed #{@realtime_button_bar.start_button.text}")
|
|
418
|
+
@go = true
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
# Handles the pause button on the realtime_button_bar.
|
|
423
|
+
def handle_pause
|
|
424
|
+
@pause = true
|
|
425
|
+
@realtime_button_bar.state = 'Paused'
|
|
426
|
+
@realtime_button_bar.start_button.setEnabled(true)
|
|
427
|
+
output_append("User pressed Pause")
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
# Handles the stop button on the realtime_button_bar. This kills the
|
|
431
|
+
# run_thread which requires the user to restart the sequence.
|
|
432
|
+
def handle_stop
|
|
433
|
+
Cosmos.kill_thread(nil, @run_thread)
|
|
434
|
+
@run_thread = nil
|
|
435
|
+
@realtime_button_bar.start_button.setEnabled(true)
|
|
436
|
+
@realtime_button_bar.start_button.setText('Start')
|
|
437
|
+
@realtime_button_bar.state = 'Stopped'
|
|
438
|
+
output_append("User pressed Stop")
|
|
439
|
+
@output.append("") # delimit the sequences in the output log
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
protected
|
|
443
|
+
|
|
444
|
+
# Executes a particular sequence item (command) by delaying for the given
|
|
445
|
+
# time and then sending the command via cmd_no_hazardous_check.
|
|
446
|
+
# @param item [SequenceItem] Item to execute, e.g. send the command
|
|
447
|
+
def execute_item(item)
|
|
448
|
+
Qt.execute_in_main_thread do
|
|
449
|
+
item.read_only(true)
|
|
450
|
+
item.setStyleSheet("color: green")
|
|
451
|
+
end
|
|
452
|
+
result = process_delay(item)
|
|
453
|
+
command = item.command_string
|
|
454
|
+
result += command # += in case we added a warning above
|
|
455
|
+
cmd_no_hazardous_check(command)
|
|
456
|
+
rescue DRb::DRbConnError
|
|
457
|
+
result = "Error Connecting to Command and Telemetry Server"
|
|
458
|
+
rescue Exception => err
|
|
459
|
+
result = "Error executing #{item.save} due to #{err}\n#{err.backtrace}"
|
|
460
|
+
ensure
|
|
461
|
+
Qt.execute_in_main_thread do
|
|
462
|
+
item.setStyleSheet("")
|
|
463
|
+
item.read_only(false)
|
|
464
|
+
output_append(result)
|
|
465
|
+
end
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
# Delays for the absolute or relative time given for the item
|
|
469
|
+
# @param item [SequenceItem] Item with given delay time
|
|
470
|
+
def process_delay(item)
|
|
471
|
+
result = ''
|
|
472
|
+
time = item.time
|
|
473
|
+
# Check for item containing a date
|
|
474
|
+
if time.include?('/')
|
|
475
|
+
start_time = Time.parse(time)
|
|
476
|
+
if start_time - Time.now > 0
|
|
477
|
+
while start_time - Time.now > 0
|
|
478
|
+
break if check_go_and_pause()
|
|
479
|
+
end
|
|
480
|
+
else
|
|
481
|
+
result = "WARNING: Start time #{start_time} has already passed!\n"
|
|
482
|
+
end
|
|
483
|
+
else # Relative delay
|
|
484
|
+
start = Time.now
|
|
485
|
+
while Time.now - start < time.to_f
|
|
486
|
+
break if check_go_and_pause()
|
|
487
|
+
end
|
|
488
|
+
end
|
|
489
|
+
result
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
# Checks the @go and @pause instance variables to determine how to proceed.
|
|
493
|
+
# If @go is true it returns true immediately. If @pause is true it sleeps
|
|
494
|
+
# continously while @pause is true. Otherwise it sleeps for a short time
|
|
495
|
+
# and returns false.
|
|
496
|
+
# @return [Boolean] true if @go is true, else false
|
|
497
|
+
def check_go_and_pause
|
|
498
|
+
if @go
|
|
499
|
+
@go = false
|
|
500
|
+
return true
|
|
501
|
+
end
|
|
502
|
+
if @pause
|
|
503
|
+
sleep 0.01 while @pause
|
|
504
|
+
else
|
|
505
|
+
sleep 0.01
|
|
506
|
+
end
|
|
507
|
+
false
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
# Called when the target select dropdown changes to force the command
|
|
511
|
+
# select to update
|
|
512
|
+
def target_changed
|
|
513
|
+
update_commands()
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
# Called once at initialization to populate the target select dropdown
|
|
517
|
+
def update_targets
|
|
518
|
+
@target_select.clearItems()
|
|
519
|
+
target_names = System.commands.target_names
|
|
520
|
+
target_names_to_delete = []
|
|
521
|
+
target_names.each do |target_name|
|
|
522
|
+
found_non_hidden = false
|
|
523
|
+
begin
|
|
524
|
+
packets = System.commands.packets(target_name)
|
|
525
|
+
packets.each do |packet_name, packet|
|
|
526
|
+
found_non_hidden = true unless packet.hidden
|
|
527
|
+
end
|
|
528
|
+
rescue
|
|
529
|
+
# Don't do anything
|
|
530
|
+
end
|
|
531
|
+
target_names_to_delete << target_name unless found_non_hidden
|
|
532
|
+
end
|
|
533
|
+
target_names_to_delete.each do |target_name|
|
|
534
|
+
target_names.delete(target_name)
|
|
535
|
+
end
|
|
536
|
+
target_names.each do |target_name|
|
|
537
|
+
@target_select.addItem(target_name)
|
|
538
|
+
end
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
# Updates the command select dropdown based on the currently selected target
|
|
542
|
+
def update_commands
|
|
543
|
+
@cmd_select.clearItems()
|
|
544
|
+
target_name = @target_select.text
|
|
545
|
+
if target_name
|
|
546
|
+
commands = System.commands.packets(target_name)
|
|
547
|
+
command_names = []
|
|
548
|
+
commands.each do |command_name, command|
|
|
549
|
+
command_names << command_name unless command.hidden
|
|
550
|
+
end
|
|
551
|
+
command_names.sort!
|
|
552
|
+
command_names.each do |command_name|
|
|
553
|
+
@cmd_select.addItem(command_name)
|
|
554
|
+
end
|
|
555
|
+
end
|
|
556
|
+
end
|
|
557
|
+
|
|
558
|
+
# Opens the given filename and executes the sequence. Implemented to allow
|
|
559
|
+
# for a command line option to immediately load and execute a sequence.
|
|
560
|
+
# @param filename [String] Sequence file to open and run
|
|
561
|
+
def run_sequence(filename)
|
|
562
|
+
filename = find_sequence(filename)
|
|
563
|
+
return unless filename
|
|
564
|
+
@sequence_list.open(filename)
|
|
565
|
+
@filename = filename
|
|
566
|
+
update_title()
|
|
567
|
+
handle_start()
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
# Finds the given filename by looking in the system sequences path as
|
|
571
|
+
# well as in each target's sequences directory. If the file can not be
|
|
572
|
+
# found an Error dialog is created.
|
|
573
|
+
# @param filename [String] Filename to locate
|
|
574
|
+
def find_sequence(filename)
|
|
575
|
+
# If the filename is already sufficient, just expand the path.
|
|
576
|
+
return File.expand_path(filename) if File.exist?(filename)
|
|
577
|
+
|
|
578
|
+
# If the filename wasn't sufficient, can we find the file in the
|
|
579
|
+
# system sequence directory?
|
|
580
|
+
new_filename = File.join(System.paths['SEQUENCES'], filename)
|
|
581
|
+
return File.expand_path(new_filename) if File.exist?(new_filename)
|
|
582
|
+
|
|
583
|
+
# Ok, how about one of the target sequence directories?
|
|
584
|
+
System.targets.each do |target_name, target|
|
|
585
|
+
new_filename = File.join(target.dir, 'sequences', filename)
|
|
586
|
+
return File.expand_path(new_filename) if File.exist?(new_filename)
|
|
587
|
+
end
|
|
588
|
+
Qt::MessageBox.critical(self, 'Error', "Could not find #{filename}")
|
|
589
|
+
|
|
590
|
+
# Couldn't find the file anywhere.
|
|
591
|
+
return nil
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
# Prompts the user that a sequence is running before they close the app
|
|
595
|
+
def prompt_if_running_on_close
|
|
596
|
+
safe_to_continue = true
|
|
597
|
+
# Check for not Stopped since it can also be Running or Paused
|
|
598
|
+
if @realtime_button_bar.state != "Stopped"
|
|
599
|
+
case Qt::MessageBox.warning(
|
|
600
|
+
self, # parent
|
|
601
|
+
'Warning!', # title
|
|
602
|
+
'A Sequence is Running! Close Anyways?', # text
|
|
603
|
+
Qt::MessageBox::Yes | Qt::MessageBox::No, # buttons
|
|
604
|
+
Qt::MessageBox::No) # default button
|
|
605
|
+
when Qt::MessageBox::Yes
|
|
606
|
+
safe_to_continue = true
|
|
607
|
+
else
|
|
608
|
+
safe_to_continue = false
|
|
609
|
+
end
|
|
610
|
+
end
|
|
611
|
+
safe_to_continue
|
|
612
|
+
end
|
|
613
|
+
|
|
614
|
+
# Prompts for save if the current sequence has been modified
|
|
615
|
+
def prompt_for_save_if_needed(message = 'Save Current Sequence?')
|
|
616
|
+
safe_to_continue = true
|
|
617
|
+
if @sequence_list.modified?
|
|
618
|
+
case Qt::MessageBox.question(
|
|
619
|
+
self, # parent
|
|
620
|
+
'Save?', # title
|
|
621
|
+
message, # text
|
|
622
|
+
Qt::MessageBox::Yes | Qt::MessageBox::No | Qt::MessageBox::Cancel, # buttons
|
|
623
|
+
Qt::MessageBox::Cancel) # default button
|
|
624
|
+
when Qt::MessageBox::Cancel
|
|
625
|
+
safe_to_continue = false
|
|
626
|
+
when Qt::MessageBox::Yes
|
|
627
|
+
saved = file_save(false) # Try save which returns true if successful
|
|
628
|
+
safe_to_continue = false if !saved
|
|
629
|
+
end
|
|
630
|
+
end
|
|
631
|
+
safe_to_continue
|
|
632
|
+
end
|
|
633
|
+
|
|
634
|
+
# Updates the title to show the sequence filename and modified status
|
|
635
|
+
def update_title
|
|
636
|
+
self.setWindowTitle("Command Sequence : #{@filename}")
|
|
637
|
+
self.setWindowTitle(self.windowTitle << '*') if @sequence_list.modified?
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
# Append string to the output with the current time
|
|
641
|
+
def output_append(string)
|
|
642
|
+
return unless string
|
|
643
|
+
Qt.execute_in_main_thread do
|
|
644
|
+
string.split("\n").each do |line|
|
|
645
|
+
@output.append(Time.now.sys.formatted + ': ' + line)
|
|
646
|
+
end
|
|
647
|
+
@output.moveCursor(Qt::TextCursor::End)
|
|
648
|
+
@output.ensureCursorVisible()
|
|
649
|
+
end
|
|
650
|
+
end
|
|
651
|
+
end
|
|
652
|
+
end
|