cosmos 4.1.1-java → 4.2.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.
- checksums.yaml +4 -4
- data/.gitignore +0 -2
- data/.travis.yml +2 -0
- data/.yardopts +1 -0
- data/Gemfile +1 -0
- data/Manifest.txt +130 -0
- data/autohotkey/tools/ConfigEditorAHK +19 -0
- data/autohotkey/tools/cmd_extractor.ahk +4 -4
- data/autohotkey/tools/cmd_sequence.ahk +9 -5
- data/autohotkey/tools/config_editor.ahk +197 -0
- data/autohotkey/tools/packet_viewer.ahk +12 -6
- data/autohotkey/tools/replay.ahk +29 -29
- data/autohotkey/tools/script_runner.ahk +10 -2
- data/autohotkey/tools/tlm_extractor.ahk +7 -8
- data/autohotkey/tools/tlm_grapher.ahk +21 -9
- data/bin/dart_import +2 -0
- data/cosmos.gemspec +18 -16
- data/data/config/cmd_tlm_server.yaml +9 -0
- data/data/config/interface_modifiers.yaml +17 -0
- data/data/config/item_modifiers.yaml +3 -3
- data/data/crc.txt +184 -90
- data/data/dart.png +0 -0
- data/demo/Gemfile +1 -0
- data/demo/Rakefile +4 -0
- data/demo/config/dart/Gemfile +54 -0
- data/demo/config/data/crc.txt +28 -21
- data/demo/config/system/system.txt +3 -0
- data/demo/config/system/system2.txt +3 -0
- data/demo/config/targets/INST/cmd_tlm/inst_cmds.txt +3 -3
- data/demo/config/targets/INST/cmd_tlm/inst_tlm.txt +1 -1
- data/demo/config/targets/INST/lib/sim_inst.rb +1 -1
- data/demo/config/targets/INST/screens/adcs.txt +2 -1
- data/demo/config/targets/INST/screens/array.txt +1 -1
- data/demo/config/targets/INST/screens/block.txt +1 -1
- data/demo/config/targets/INST/screens/commanding.txt +7 -2
- data/demo/config/targets/INST/screens/graphs.txt +1 -1
- data/demo/config/targets/INST/screens/ground.txt +1 -1
- data/demo/config/targets/INST/screens/hs.txt +2 -1
- data/demo/config/targets/INST/screens/latest.txt +1 -1
- data/demo/config/targets/INST/screens/limits.txt +1 -1
- data/demo/config/targets/INST/screens/other.txt +1 -1
- data/demo/config/targets/INST/screens/tabs.txt +1 -1
- data/demo/config/tools/cmd_tlm_server/cmd_tlm_server.txt +2 -2
- data/demo/config/tools/cmd_tlm_server/cmd_tlm_server2.txt +3 -1
- data/demo/config/tools/launcher/launcher.txt +3 -2
- data/demo/tools/Dart +16 -0
- data/demo/tools/Dart.bat +9 -0
- data/demo/tools/mac/CmdSequence.app/Contents/MacOS/main.sh +0 -0
- data/demo/tools/mac/ConfigEditor.app/Contents/MacOS/main.sh +0 -0
- data/install/Gemfile +1 -0
- data/install/Rakefile +4 -0
- data/install/config/dart/Gemfile +54 -0
- data/install/config/data/crc.txt +6 -3
- data/install/config/system/system.txt +3 -0
- data/install/config/tools/launcher/launcher.txt +3 -2
- data/install/tools/Dart +16 -0
- data/install/tools/Dart.bat +9 -0
- data/install/tools/mac/CmdSequence.app/Contents/MacOS/main.sh +0 -0
- data/install/tools/mac/ConfigEditor.app/Contents/MacOS/main.sh +0 -0
- data/lib/cosmos/core_ext/time.rb +8 -8
- data/lib/cosmos/dart/.rspec +1 -0
- data/lib/cosmos/dart/Gemfile +69 -0
- data/lib/cosmos/dart/Rakefile +7 -0
- data/lib/cosmos/dart/app/assets/config/manifest.js +4 -0
- data/lib/cosmos/dart/app/assets/images/.keep +0 -0
- data/lib/cosmos/dart/app/assets/javascripts/application.js +13 -0
- data/lib/cosmos/dart/app/assets/javascripts/cable.js +13 -0
- data/lib/cosmos/dart/app/assets/stylesheets/application.css.scss +15 -0
- data/lib/cosmos/dart/app/channels/application_cable/channel.rb +4 -0
- data/lib/cosmos/dart/app/channels/application_cable/connection.rb +4 -0
- data/lib/cosmos/dart/app/controllers/application_controller.rb +3 -0
- data/lib/cosmos/dart/app/helpers/application_helper.rb +2 -0
- data/lib/cosmos/dart/app/jobs/application_job.rb +2 -0
- data/lib/cosmos/dart/app/mailers/application_mailer.rb +4 -0
- data/lib/cosmos/dart/app/models/application_record.rb +3 -0
- data/lib/cosmos/dart/app/models/item.rb +6 -0
- data/lib/cosmos/dart/app/models/item_to_decom_table_mapping.rb +9 -0
- data/lib/cosmos/dart/app/models/packet.rb +4 -0
- data/lib/cosmos/dart/app/models/packet_config.rb +7 -0
- data/lib/cosmos/dart/app/models/packet_log.rb +3 -0
- data/lib/cosmos/dart/app/models/packet_log_entry.rb +41 -0
- data/lib/cosmos/dart/app/models/system_config.rb +2 -0
- data/lib/cosmos/dart/app/models/target.rb +4 -0
- data/lib/cosmos/dart/app/views/layouts/application.html.erb +14 -0
- data/lib/cosmos/dart/app/views/layouts/mailer.html.erb +13 -0
- data/lib/cosmos/dart/app/views/layouts/mailer.text.erb +1 -0
- data/lib/cosmos/dart/bin/bundle +3 -0
- data/lib/cosmos/dart/bin/rails +4 -0
- data/lib/cosmos/dart/bin/rake +4 -0
- data/lib/cosmos/dart/bin/setup +34 -0
- data/lib/cosmos/dart/bin/update +29 -0
- data/lib/cosmos/dart/config.ru +5 -0
- data/lib/cosmos/dart/config/application.rb +29 -0
- data/lib/cosmos/dart/config/boot.rb +3 -0
- data/lib/cosmos/dart/config/cable.yml +9 -0
- data/lib/cosmos/dart/config/database.yml +23 -0
- data/lib/cosmos/dart/config/environment.rb +5 -0
- data/lib/cosmos/dart/config/environments/development.rb +62 -0
- data/lib/cosmos/dart/config/environments/production.rb +84 -0
- data/lib/cosmos/dart/config/environments/test.rb +42 -0
- data/lib/cosmos/dart/config/initializers/application_controller_renderer.rb +6 -0
- data/lib/cosmos/dart/config/initializers/assets.rb +12 -0
- data/lib/cosmos/dart/config/initializers/backtrace_silencers.rb +7 -0
- data/lib/cosmos/dart/config/initializers/cookies_serializer.rb +5 -0
- data/lib/cosmos/dart/config/initializers/filter_parameter_logging.rb +4 -0
- data/lib/cosmos/dart/config/initializers/inflections.rb +16 -0
- data/lib/cosmos/dart/config/initializers/mime_types.rb +4 -0
- data/lib/cosmos/dart/config/initializers/new_framework_defaults.rb +25 -0
- data/lib/cosmos/dart/config/initializers/session_store.rb +3 -0
- data/lib/cosmos/dart/config/initializers/wrap_parameters.rb +14 -0
- data/lib/cosmos/dart/config/locales/en.yml +23 -0
- data/lib/cosmos/dart/config/puma.rb +47 -0
- data/lib/cosmos/dart/config/routes.rb +3 -0
- data/lib/cosmos/dart/config/secrets.yml +22 -0
- data/lib/cosmos/dart/db/migrate/20170406172907_create_targets.rb +8 -0
- data/lib/cosmos/dart/db/migrate/20170406172927_create_packets.rb +10 -0
- data/lib/cosmos/dart/db/migrate/20170406172937_create_packet_logs.rb +9 -0
- data/lib/cosmos/dart/db/migrate/20170406172943_create_packet_log_entries.rb +16 -0
- data/lib/cosmos/dart/db/migrate/20170406183500_change_packet_log_entries_primary_key.rb +5 -0
- data/lib/cosmos/dart/db/migrate/20170407153618_add_unique_requirements.rb +7 -0
- data/lib/cosmos/dart/db/migrate/20170511155447_add_meta_id_to_packet_log_entries.rb +6 -0
- data/lib/cosmos/dart/db/migrate/20170523185056_rename_received_time_and_add_is_tlm_to_packet_log_entries.rb +7 -0
- data/lib/cosmos/dart/db/migrate/20170525201157_create_items.rb +10 -0
- data/lib/cosmos/dart/db/migrate/20170525201315_create_system_configs.rb +9 -0
- data/lib/cosmos/dart/db/migrate/20170525201624_create_packet_configs.rb +11 -0
- data/lib/cosmos/dart/db/migrate/20170525201745_create_item_to_decom_table_mappings.rb +12 -0
- data/lib/cosmos/dart/db/migrate/20170525201939_create_decom_tables.rb +12 -0
- data/lib/cosmos/dart/db/migrate/20170525202051_add_decom_state_to_packet_log_entry.rb +5 -0
- data/lib/cosmos/dart/db/migrate/20170913160409_update_items.rb +6 -0
- data/lib/cosmos/dart/db/migrate/20170913160558_update_item_to_decom_table_mapping.rb +11 -0
- data/lib/cosmos/dart/db/migrate/20170913160916_udpate_decom_table.rb +6 -0
- data/lib/cosmos/dart/db/migrate/20170913212026_add_ready_to_packet_configs.rb +5 -0
- data/lib/cosmos/dart/db/migrate/20170913223556_modify_tables.rb +9 -0
- data/lib/cosmos/dart/db/migrate/20170914215744_modify_mapping_table.rb +6 -0
- data/lib/cosmos/dart/db/migrate/20170919201433_add_system_config_id_to_packet_config.rb +11 -0
- data/lib/cosmos/dart/db/migrate/20170919210307_add_max_table_index_to_packet_configs.rb +5 -0
- data/lib/cosmos/dart/db/migrate/20171215225546_add_ready_to_packet_log_entries.rb +5 -0
- data/lib/cosmos/dart/db/migrate/20180116214338_add_index_for_ple_ready_to_packet_log_entries.rb +5 -0
- data/lib/cosmos/dart/db/schema.rb +103 -0
- data/lib/cosmos/dart/db/seeds.rb +7 -0
- data/lib/cosmos/dart/examples/dart_decom_client.rb +45 -0
- data/lib/cosmos/dart/examples/dart_stream_client.rb +93 -0
- data/lib/cosmos/dart/lib/dart_common.rb +749 -0
- data/lib/cosmos/dart/lib/dart_database_cleaner.rb +172 -0
- data/lib/cosmos/dart/lib/dart_decom_query.rb +184 -0
- data/lib/cosmos/dart/lib/dart_decommutator.rb +235 -0
- data/lib/cosmos/dart/lib/dart_importer.rb +154 -0
- data/lib/cosmos/dart/lib/dart_logging.rb +50 -0
- data/lib/cosmos/dart/lib/dart_packet_log_writer.rb +139 -0
- data/lib/cosmos/dart/lib/dart_reducer_manager.rb +85 -0
- data/lib/cosmos/dart/lib/dart_reducer_worker_thread.rb +263 -0
- data/lib/cosmos/dart/lib/dart_tcpip_server_interface.rb +142 -0
- data/lib/cosmos/dart/processes/dart.rb +145 -0
- data/lib/cosmos/dart/processes/dart_decom_server.rb +39 -0
- data/lib/cosmos/dart/processes/dart_import.rb +63 -0
- data/lib/cosmos/dart/processes/dart_ingester.rb +92 -0
- data/lib/cosmos/dart/processes/dart_reducer.rb +27 -0
- data/lib/cosmos/dart/processes/dart_stream_server.rb +31 -0
- data/lib/cosmos/dart/processes/dart_worker.rb +37 -0
- data/lib/cosmos/dart/spec/dart/dart_common_spec.rb +333 -0
- data/lib/cosmos/dart/spec/dart/dart_database_cleaner_spec.rb +455 -0
- data/lib/cosmos/dart/spec/dart/dart_decom_query_spec.rb +153 -0
- data/lib/cosmos/dart/spec/dart/dart_decommutator_spec.rb +336 -0
- data/lib/cosmos/dart/spec/dart/dart_importer_spec.rb +83 -0
- data/lib/cosmos/dart/spec/dart/dart_logging_spec.rb +30 -0
- data/lib/cosmos/dart/spec/dart/dart_packet_log_writer_spec.rb +149 -0
- data/lib/cosmos/dart/spec/dart/dart_reducer_manager_spec.rb +289 -0
- data/lib/cosmos/dart/spec/dart/dart_tcpip_server_interface_spec.rb +241 -0
- data/lib/cosmos/dart/spec/rails_helper.rb +60 -0
- data/lib/cosmos/dart/spec/spec_helper.rb +139 -0
- data/lib/cosmos/gui/dialogs/about_dialog.rb +1 -1
- data/lib/cosmos/gui/dialogs/dart_dialog.rb +60 -0
- data/lib/cosmos/gui/dialogs/legal_dialog.rb +1 -0
- data/lib/cosmos/gui/dialogs/scroll_text_dialog.rb +0 -3
- data/lib/cosmos/gui/qt.rb +10 -1
- data/lib/cosmos/gui/text/completion.rb +10 -9
- data/lib/cosmos/gui/text/completion_text_edit.rb +16 -14
- data/lib/cosmos/gui/text/ruby_editor.rb +2 -2
- data/lib/cosmos/gui/widgets/dart_frame.rb +142 -0
- data/lib/cosmos/gui/widgets/dart_meta_frame.rb +119 -0
- data/lib/cosmos/gui/widgets/packet_log_frame.rb +42 -12
- data/lib/cosmos/interfaces/interface.rb +1 -2
- data/lib/cosmos/interfaces/protocols/crc_protocol.rb +26 -8
- data/lib/cosmos/interfaces/protocols/fixed_protocol.rb +8 -2
- data/lib/cosmos/interfaces/protocols/protocol.rb +2 -1
- data/lib/cosmos/interfaces/protocols/template_protocol.rb +1 -1
- data/lib/cosmos/interfaces/stream_interface.rb +1 -0
- data/lib/cosmos/interfaces/tcpip_server_interface.rb +2 -3
- data/lib/cosmos/io/json_drb_object.rb +1 -1
- data/lib/cosmos/io/json_rpc.rb +2 -1
- data/lib/cosmos/io/win32_serial_driver.rb +2 -9
- data/lib/cosmos/packet_logs/packet_log_writer.rb +1 -1
- data/lib/cosmos/packets/packet.rb +22 -12
- data/lib/cosmos/packets/packet_config.rb +2 -1
- data/lib/cosmos/packets/packet_item.rb +26 -24
- data/lib/cosmos/packets/parsers/macro_parser.rb +5 -2
- data/lib/cosmos/packets/parsers/packet_item_parser.rb +35 -17
- data/lib/cosmos/packets/parsers/packet_parser.rb +3 -10
- data/lib/cosmos/packets/parsers/xtce_converter.rb +21 -35
- data/lib/cosmos/packets/parsers/xtce_parser.rb +54 -46
- data/lib/cosmos/packets/structure.rb +10 -2
- data/lib/cosmos/packets/structure_item.rb +22 -8
- data/lib/cosmos/processors/statistics_processor.rb +2 -0
- data/lib/cosmos/script/api_shared.rb +13 -12
- data/lib/cosmos/script/cmd_tlm_server.rb +4 -0
- data/lib/cosmos/script/commands.rb +3 -15
- data/lib/cosmos/script/script.rb +69 -23
- data/lib/cosmos/streams/tcpip_client_stream.rb +2 -2
- data/lib/cosmos/system/system.rb +42 -25
- data/lib/cosmos/system/target.rb +6 -2
- data/lib/cosmos/tools/cmd_extractor/cmd_extractor.rb +177 -36
- data/lib/cosmos/tools/cmd_sender/cmd_param_table_item_delegate.rb +3 -2
- data/lib/cosmos/tools/cmd_sender/cmd_sender.rb +34 -8
- data/lib/cosmos/tools/cmd_sequence/cmd_sequence.rb +80 -25
- data/lib/cosmos/tools/cmd_tlm_server/api.rb +19 -4
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +15 -14
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_gui.rb +15 -9
- data/lib/cosmos/tools/cmd_tlm_server/gui/interfaces_tab.rb +1 -9
- data/lib/cosmos/tools/cmd_tlm_server/gui/logging_tab.rb +1 -6
- data/lib/cosmos/tools/cmd_tlm_server/gui/packets_tab.rb +1 -3
- data/lib/cosmos/tools/cmd_tlm_server/gui/replay_tab.rb +84 -7
- data/lib/cosmos/tools/cmd_tlm_server/gui/status_tab.rb +0 -1
- data/lib/cosmos/tools/cmd_tlm_server/gui/targets_tab.rb +1 -5
- data/lib/cosmos/tools/cmd_tlm_server/limits_groups_background_task.rb +3 -2
- data/lib/cosmos/tools/cmd_tlm_server/replay_backend.rb +159 -27
- data/lib/cosmos/tools/cmd_tlm_server/routers.rb +1 -1
- data/lib/cosmos/tools/config_editor/config_editor.rb +17 -52
- data/lib/cosmos/tools/config_editor/config_editor_frame.rb +0 -5
- data/lib/cosmos/tools/data_viewer/data_viewer.rb +111 -0
- data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +31 -18
- data/lib/cosmos/tools/packet_viewer/packet_viewer.rb +12 -3
- data/lib/cosmos/tools/script_runner/script_runner.rb +27 -14
- data/lib/cosmos/tools/script_runner/script_runner_frame.rb +104 -37
- data/lib/cosmos/tools/table_manager/table_config.rb +1 -1
- data/lib/cosmos/tools/table_manager/table_item_parser.rb +4 -2
- data/lib/cosmos/tools/table_manager/table_manager.rb +0 -5
- data/lib/cosmos/tools/table_manager/table_manager_core.rb +0 -1
- data/lib/cosmos/tools/test_runner/test.rb +1 -3
- data/lib/cosmos/tools/test_runner/test_runner.rb +26 -15
- data/lib/cosmos/tools/tlm_extractor/tlm_extractor.rb +290 -137
- data/lib/cosmos/tools/tlm_extractor/tlm_extractor_config.rb +122 -25
- data/lib/cosmos/tools/tlm_extractor/tlm_extractor_processor.rb +67 -0
- data/lib/cosmos/tools/tlm_grapher/data_object_editors/housekeeping_data_object_editor.rb +28 -0
- data/lib/cosmos/tools/tlm_grapher/data_object_editors/xy_data_object_editor.rb +36 -0
- data/lib/cosmos/tools/tlm_grapher/data_objects/data_object.rb +42 -3
- data/lib/cosmos/tools/tlm_grapher/data_objects/housekeeping_data_object.rb +88 -14
- data/lib/cosmos/tools/tlm_grapher/data_objects/linegraph_data_object.rb +2 -5
- data/lib/cosmos/tools/tlm_grapher/data_objects/singlexy_data_object.rb +2 -6
- data/lib/cosmos/tools/tlm_grapher/data_objects/xy_data_object.rb +74 -18
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_config.rb +3 -7
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_dart_thread.rb +159 -0
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_tool.rb +49 -2
- data/lib/cosmos/tools/tlm_viewer/screen.rb +3 -0
- data/lib/cosmos/tools/tlm_viewer/tlm_viewer_config.rb +0 -2
- data/lib/cosmos/tools/tlm_viewer/widgets.rb +1 -0
- data/lib/cosmos/tools/tlm_viewer/widgets/backgroundbutton_widget.rb +54 -0
- data/lib/cosmos/tools/tlm_viewer/widgets/button_widget.rb +5 -5
- data/lib/cosmos/top_level.rb +1 -0
- data/lib/cosmos/utilities/crc.rb +3 -0
- data/lib/cosmos/utilities/csv.rb +1 -0
- data/lib/cosmos/utilities/message_log.rb +2 -1
- data/lib/cosmos/utilities/simulated_target.rb +8 -8
- data/lib/cosmos/version.rb +5 -5
- data/lib/cosmos/win32/win32.rb +4 -10
- data/run_gui_tests.bat +2 -1
- data/spec/config/config_parser_spec.rb +4 -4
- data/spec/core_ext/array_spec.rb +1 -1
- data/spec/core_ext/exception_spec.rb +12 -12
- data/spec/core_ext/file_spec.rb +6 -6
- data/spec/core_ext/hash_spec.rb +1 -1
- data/spec/core_ext/socket_spec.rb +2 -2
- data/spec/core_ext/string_spec.rb +13 -13
- data/spec/core_ext/time_spec.rb +0 -2
- data/spec/gui/utilities/script_module_gui_spec.rb +3 -3
- data/spec/install/config/targets/INST/cmd_tlm/inst_tlm.txt +6 -6
- data/spec/install/config/tools/cmd_tlm_server/cmd_tlm_server.txt +4 -0
- data/spec/interfaces/cmd_tlm_server_interface_spec.rb +6 -2
- data/spec/interfaces/interface_spec.rb +0 -1
- data/spec/interfaces/linc_interface_spec.rb +0 -5
- data/spec/interfaces/protocols/crc_protocol_spec.rb +201 -85
- data/spec/interfaces/protocols/fixed_protocol_spec.rb +33 -9
- data/spec/interfaces/protocols/length_protocol_spec.rb +1 -1
- data/spec/interfaces/protocols/override_protocol_spec.rb +6 -2
- data/spec/interfaces/protocols/preidentified_protocol_spec.rb +1 -5
- data/spec/interfaces/protocols/template_protocol_spec.rb +0 -1
- data/spec/interfaces/simulated_target_interface_spec.rb +5 -5
- data/spec/interfaces/udp_interface_spec.rb +2 -4
- data/spec/io/buffered_file_spec.rb +8 -12
- data/spec/io/json_drb_spec.rb +9 -9
- data/spec/io/json_rpc_spec.rb +4 -4
- data/spec/io/raw_logger_spec.rb +4 -3
- data/spec/packet_logs/packet_log_reader_spec.rb +3 -6
- data/spec/packet_logs/packet_log_writer_spec.rb +4 -4
- data/spec/packets/binary_accessor_spec.rb +5 -8
- data/spec/packets/commands_spec.rb +2 -2
- data/spec/packets/limits_spec.rb +2 -2
- data/spec/packets/packet_config_spec.rb +12 -0
- data/spec/packets/packet_item_limits_spec.rb +1 -1
- data/spec/packets/packet_item_spec.rb +9 -9
- data/spec/packets/packet_spec.rb +15 -5
- data/spec/packets/parsers/packet_item_parser_spec.rb +27 -0
- data/spec/packets/parsers/xtce_parser_spec.rb +27 -30
- data/spec/packets/structure_spec.rb +2 -1
- data/spec/packets/telemetry_spec.rb +3 -5
- data/spec/processors/statistics_processor_spec.rb +35 -0
- data/spec/script/cmd_tlm_server_spec.rb +4 -21
- data/spec/script/commands_disconnect_spec.rb +46 -58
- data/spec/script/commands_spec.rb +40 -61
- data/spec/script/limits_spec.rb +1 -21
- data/spec/script/script_spec.rb +32 -41
- data/spec/script/scripting_spec.rb +166 -185
- data/spec/script/telemetry_spec.rb +10 -5
- data/spec/script/tools_spec.rb +2 -24
- data/spec/spec_helper.rb +11 -5
- data/spec/system/system_spec.rb +17 -12
- data/spec/tools/cmd_tlm_server/api_spec.rb +21 -10
- data/spec/tools/cmd_tlm_server/background_tasks_spec.rb +15 -16
- data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +0 -1
- data/spec/tools/cmd_tlm_server/cmd_tlm_server_spec.rb +16 -27
- data/spec/tools/cmd_tlm_server/commanding_spec.rb +2 -6
- data/spec/tools/cmd_tlm_server/connections_spec.rb +0 -4
- data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +13 -13
- data/spec/tools/cmd_tlm_server/interfaces_spec.rb +5 -9
- data/spec/tools/cmd_tlm_server/limits_groups_background_task_spec.rb +11 -3
- data/spec/tools/cmd_tlm_server/packet_logging_spec.rb +0 -4
- data/spec/tools/cmd_tlm_server/router_thread_spec.rb +5 -5
- data/spec/tools/cmd_tlm_server/routers_spec.rb +5 -9
- data/spec/tools/table_manager/table_config_spec.rb +0 -1
- data/spec/tools/table_manager/tablemanager_core_spec.rb +23 -23
- data/spec/tools/tlm_viewer/tlm_viewer_config_spec.rb +6 -4
- data/spec/top_level/top_level_spec.rb +9 -9
- data/spec/utilities/csv_spec.rb +2 -12
- data/spec/utilities/logger_spec.rb +6 -6
- data/spec/utilities/message_log_spec.rb +3 -11
- data/tasks/gemfile_stats.rake +2 -2
- metadata +167 -60
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# This file should contain all the record creation needed to seed the database with its default values.
|
|
2
|
+
# The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup).
|
|
3
|
+
#
|
|
4
|
+
# Examples:
|
|
5
|
+
#
|
|
6
|
+
# movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
|
|
7
|
+
# Character.create(name: 'Luke', movie: movies.first)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
|
|
3
|
+
# Copyright 2018 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
|
+
ENV['COSMOS_USERPATH'] = 'C:/git/COSMOS/demo'
|
|
12
|
+
require 'cosmos'
|
|
13
|
+
require 'cosmos/io/json_drb_object'
|
|
14
|
+
Cosmos::Logger.level = Cosmos::Logger::DEBUG
|
|
15
|
+
|
|
16
|
+
start_time = Time.utc(1970, 1, 1, 0, 0, 0)
|
|
17
|
+
end_time = Time.utc(2020, 1, 1, 0, 0, 0)
|
|
18
|
+
|
|
19
|
+
request = {}
|
|
20
|
+
request['start_time_sec'] = start_time.tv_sec
|
|
21
|
+
request['start_time_usec'] = start_time.tv_usec
|
|
22
|
+
request['end_time_sec'] = end_time.tv_sec
|
|
23
|
+
request['end_time_usec'] = end_time.tv_usec
|
|
24
|
+
request['item'] = ['INST', 'HEALTH_STATUS', 'TEMP1']
|
|
25
|
+
request['reduction'] = 'HOUR'
|
|
26
|
+
request['cmd_tlm'] = 'TLM'
|
|
27
|
+
request['offset'] = 0
|
|
28
|
+
request['limit'] = 100000
|
|
29
|
+
request['value_type'] = 'RAW_AVG'
|
|
30
|
+
# request['meta_ids'] = [1, 1062642]
|
|
31
|
+
request['meta_filters'] = ["OPERATOR_NAME == 'Unspecified'"]
|
|
32
|
+
|
|
33
|
+
puts "Connecting to Dart Decom Server..."
|
|
34
|
+
server = Cosmos::JsonDRbObject.new(Cosmos::System.connect_hosts['DART_DECOM'], Cosmos::System.ports['DART_DECOM'])
|
|
35
|
+
puts "Getting SYSTEM META fields"
|
|
36
|
+
result = server.item_names("SYSTEM", "META")
|
|
37
|
+
puts result.inspect(10000)
|
|
38
|
+
puts "Making request"
|
|
39
|
+
begin_time = Time.now
|
|
40
|
+
result = server.query(request)
|
|
41
|
+
finish_time = Time.now
|
|
42
|
+
puts result.inspect(10000)
|
|
43
|
+
puts "Got result of length #{result.length} in #{finish_time - begin_time} seconds"
|
|
44
|
+
puts "Closing..."
|
|
45
|
+
server.shutdown
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
|
|
3
|
+
# Copyright 2018 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
|
+
ENV['COSMOS_USERPATH'] = 'C:/git/COSMOS/demo'
|
|
12
|
+
require 'cosmos'
|
|
13
|
+
Cosmos::Logger.level = Cosmos::Logger::DEBUG
|
|
14
|
+
|
|
15
|
+
request_packet = Cosmos::Packet.new('DART', 'DART')
|
|
16
|
+
request_packet.define_item('REQUEST', 0, 0, :BLOCK)
|
|
17
|
+
|
|
18
|
+
start_time = Time.utc(1970, 1, 1, 0, 0, 0)
|
|
19
|
+
end_time = Time.utc(2020, 1, 1, 0, 0, 0)
|
|
20
|
+
|
|
21
|
+
request = {}
|
|
22
|
+
request['start_time_sec'] = start_time.tv_sec
|
|
23
|
+
request['start_time_usec'] = start_time.tv_usec
|
|
24
|
+
request['end_time_sec'] = end_time.tv_sec
|
|
25
|
+
request['end_time_usec'] = end_time.tv_usec
|
|
26
|
+
#~ request['cmd_tlm'] = 'CMD'
|
|
27
|
+
#~ request['packets'] = [['INST', 'HEALTH_STATUS'], ['INST', 'ADCS']]
|
|
28
|
+
#~ request['meta_ids'] = [4962]
|
|
29
|
+
request['meta_filters'] = ["OPERATOR_NAME == 'Unspecified'"]
|
|
30
|
+
request_packet.write('REQUEST', JSON.dump(request))
|
|
31
|
+
|
|
32
|
+
interface = Cosmos::TcpipClientInterface.new(
|
|
33
|
+
Cosmos::System.connect_hosts['DART_STREAM'],
|
|
34
|
+
Cosmos::System.ports['DART_STREAM'],
|
|
35
|
+
Cosmos::System.ports['DART_STREAM'],
|
|
36
|
+
10, 10, 'PREIDENTIFIED')
|
|
37
|
+
puts "Connecting to Dart Stream Server..."
|
|
38
|
+
interface.connect
|
|
39
|
+
puts "Requesting #{request['packets'].inspect} from #{start_time} to #{end_time}..."
|
|
40
|
+
interface.write(request_packet)
|
|
41
|
+
puts "Receiving packets..."
|
|
42
|
+
while true
|
|
43
|
+
packet = interface.read
|
|
44
|
+
unless packet
|
|
45
|
+
puts "Connection closed by Dart Stream Server"
|
|
46
|
+
break
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Identify and update packet
|
|
50
|
+
if packet.identified?
|
|
51
|
+
begin
|
|
52
|
+
# Preidentifed packet - place it into the current value table
|
|
53
|
+
identified_packet = Cosmos::System.telemetry.update!(packet.target_name,
|
|
54
|
+
packet.packet_name,
|
|
55
|
+
packet.buffer)
|
|
56
|
+
rescue RuntimeError
|
|
57
|
+
# Packet identified but we don't know about it
|
|
58
|
+
# Clear packet_name and target_name and try to identify
|
|
59
|
+
Logger.warn "Received unknown identified telemetry: #{packet.target_name} #{packet.packet_name}"
|
|
60
|
+
packet.target_name = nil
|
|
61
|
+
packet.packet_name = nil
|
|
62
|
+
identified_packet = Cosmos::System.telemetry.identify!(packet.buffer,
|
|
63
|
+
@interface.target_names)
|
|
64
|
+
end
|
|
65
|
+
else
|
|
66
|
+
# Packet needs to be identified
|
|
67
|
+
identified_packet = Cosmos::System.telemetry.identify!(packet.buffer,
|
|
68
|
+
@interface.target_names)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
if identified_packet
|
|
72
|
+
identified_packet.received_time = packet.received_time
|
|
73
|
+
packet = identified_packet
|
|
74
|
+
else
|
|
75
|
+
unknown_packet = Cosmos::System.telemetry.update!('UNKNOWN', 'UNKNOWN', packet.buffer)
|
|
76
|
+
unknown_packet.received_time = packet.received_time
|
|
77
|
+
packet = unknown_packet
|
|
78
|
+
data_length = packet.length
|
|
79
|
+
string = "#{@interface.name} - Unknown #{data_length} byte packet starting: "
|
|
80
|
+
num_bytes_to_print = [UNKNOWN_BYTES_TO_PRINT, data_length].min
|
|
81
|
+
data_to_print = packet.buffer(false)[0..(num_bytes_to_print - 1)]
|
|
82
|
+
data_to_print.each_byte do |byte|
|
|
83
|
+
string << sprintf("%02X", byte)
|
|
84
|
+
end
|
|
85
|
+
Logger.error string
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Switch to correct configuration from SYSTEM META when needed
|
|
89
|
+
if packet.target_name == 'SYSTEM'.freeze and packet.packet_name == 'META'.freeze
|
|
90
|
+
Cosmos::System.load_configuration(packet.read('CONFIG'))
|
|
91
|
+
end
|
|
92
|
+
puts "Got: #{packet.target_name} #{packet.packet_name}"
|
|
93
|
+
end
|
|
@@ -0,0 +1,749 @@
|
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
|
|
3
|
+
# Copyright 2018 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 'cosmos/script'
|
|
12
|
+
require 'optparse'
|
|
13
|
+
|
|
14
|
+
# Autoload models here to remove problems loading within Cosmos namespace
|
|
15
|
+
Target
|
|
16
|
+
Packet
|
|
17
|
+
PacketLog
|
|
18
|
+
PacketLogEntry
|
|
19
|
+
|
|
20
|
+
# Implement methods common to DART (Data Archival Retrieval and Trending).
|
|
21
|
+
# Most of these methods handle accessing the DART database.
|
|
22
|
+
module DartCommon
|
|
23
|
+
# @return [Integer] Maximimum byte size of strings in the database
|
|
24
|
+
MAX_STRING_BYTE_SIZE = 191 # Works well with mysql utf8mb4 if we want to support mysql in the future
|
|
25
|
+
# @return [Integer] Maximimum bit size of strings in the database
|
|
26
|
+
MAX_STRING_BIT_SIZE = MAX_STRING_BYTE_SIZE * 8
|
|
27
|
+
# @return [Integer] Maximum number of columns in a database table
|
|
28
|
+
MAX_COLUMNS_PER_TABLE = 200
|
|
29
|
+
# @return [Array<Symbol>] Data types which can be reduced over a time period.
|
|
30
|
+
# These data types will result in minute, hour, and daily database tables.
|
|
31
|
+
REDUCED_TYPES = [:integer, :bigint, :decimal, :float]
|
|
32
|
+
|
|
33
|
+
# States for the Decommutation table reduced_state field
|
|
34
|
+
INITIALIZING = 0 # New rows being created
|
|
35
|
+
READY_TO_REDUCE = 1 # Once all new rows have been created
|
|
36
|
+
REDUCED = 2 # After the data has been reduced
|
|
37
|
+
|
|
38
|
+
# Regular expression used to break up an individual line into a keyword and
|
|
39
|
+
# comma delimited parameters. Handles parameters in single or double quotes.
|
|
40
|
+
PARSING_REGEX = %r{ (?:"(?:[^\\"]|\\.)*") | (?:'(?:[^\\']|\\.)*') | \S+ }x #"
|
|
41
|
+
|
|
42
|
+
# Argument parser for the DART command line tools
|
|
43
|
+
def self.handle_argv(parse = true)
|
|
44
|
+
parser = OptionParser.new do |option_parser|
|
|
45
|
+
option_parser.banner = "Usage: ruby #{option_parser.program_name} [options]"
|
|
46
|
+
option_parser.separator("")
|
|
47
|
+
|
|
48
|
+
# Create the help option
|
|
49
|
+
option_parser.on("-h", "--help", "Show this message") do
|
|
50
|
+
puts option_parser
|
|
51
|
+
exit
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Create the version option
|
|
55
|
+
option_parser.on("-v", "--version", "Show version") do
|
|
56
|
+
puts "COSMOS Version: #{COSMOS_VERSION}"
|
|
57
|
+
puts "User Version: #{USER_VERSION}" if defined? USER_VERSION
|
|
58
|
+
exit
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Create the system option
|
|
62
|
+
option_parser.on("--system FILE", "Use an alternative system.txt file") do |arg|
|
|
63
|
+
System.instance(File.join(USERPATH, 'config', 'system', arg))
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
parser.parse! if parse
|
|
67
|
+
parser
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Get the ActiveRecord database handle to the decommutation table
|
|
71
|
+
#
|
|
72
|
+
# @param packet_config_id [Integer] PacketConfig table ID
|
|
73
|
+
# @param table_index [Integer] Index into one of multiple decommutation tables.
|
|
74
|
+
# Since the number of columns is limited to MAX_COLUMNS_PER_TABLE there will
|
|
75
|
+
# be multiple tables for large packets.
|
|
76
|
+
# @param reduction_modifier [String] Blank or one of '_m' for minutes, '_h' for hours,
|
|
77
|
+
# '_d' for days. These are the reduction tables.
|
|
78
|
+
# @return [ActiveRecord::Base] The decommutation table model
|
|
79
|
+
def get_decom_table_model(packet_config_id, table_index, reduction_modifier = "")
|
|
80
|
+
return get_table_model("t#{packet_config_id}_#{table_index}", reduction_modifier)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Get the ActiveRecord model for a database table
|
|
84
|
+
#
|
|
85
|
+
# @param table [String] Database table name
|
|
86
|
+
# @param reduction_modifier [String] One of "_m", "_h", "_d"
|
|
87
|
+
# @return [ActiveRecord] Database model for a commutation or reduction table
|
|
88
|
+
# Commutatiohn tables are named tXXX_YYY where XXX is the PacketConfig ID,
|
|
89
|
+
# and YYY is the table index. Reduction tables have a _m, _h, _d extension
|
|
90
|
+
# on the table name.
|
|
91
|
+
def get_table_model(table, reduction_modifier = "")
|
|
92
|
+
model_name = "T" + table[1..-1] + reduction_modifier
|
|
93
|
+
begin
|
|
94
|
+
model = Cosmos.const_get(model_name)
|
|
95
|
+
rescue
|
|
96
|
+
# Need to create model
|
|
97
|
+
model = Class.new(ActiveRecord::Base) do
|
|
98
|
+
self.table_name = table + reduction_modifier
|
|
99
|
+
end
|
|
100
|
+
Cosmos.const_set(model_name, model)
|
|
101
|
+
end
|
|
102
|
+
return model
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Iterate through each decom and reduced table currently in DART
|
|
106
|
+
#
|
|
107
|
+
def each_decom_and_reduced_table
|
|
108
|
+
ActiveRecord::Base.connection.tables.each do |table|
|
|
109
|
+
# Since the decommutation tables are created dynamically we search
|
|
110
|
+
# through all the tables looking for tables named something like
|
|
111
|
+
# tXXX_YYY where XXX is the PacketConfig ID and YYY is the table index
|
|
112
|
+
if table.to_s =~ /^t(\d+)_(\d+)$/ # ASCII art? No! Regex!
|
|
113
|
+
packet_config_id = $1.to_i
|
|
114
|
+
table_index = $2.to_i
|
|
115
|
+
# Get the base decommutation table model
|
|
116
|
+
decom_model = get_table_model(table)
|
|
117
|
+
# Find the reduction table models
|
|
118
|
+
minute_model = get_table_model(table, "_m")
|
|
119
|
+
hour_model = get_table_model(table, "_h")
|
|
120
|
+
day_model = get_table_model(table, "_d")
|
|
121
|
+
|
|
122
|
+
yield packet_config_id, table_index, decom_model, minute_model, hour_model, day_model
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Determine if the item must have separate raw and converted value tables
|
|
128
|
+
#
|
|
129
|
+
# @param item [Cosmos::PacketItem] Packet item
|
|
130
|
+
# @return [Boolean] Whether the item must have separate raw and converted value tables
|
|
131
|
+
def separate_raw_con?(item)
|
|
132
|
+
# All items with states must have separate raw and converted values
|
|
133
|
+
return true if item.states
|
|
134
|
+
if item.data_type != :DERIVED
|
|
135
|
+
# Non-derived items with a well defined read conversion have separate raw and converted
|
|
136
|
+
return true if well_defined_read_conversion(item)
|
|
137
|
+
end
|
|
138
|
+
return false
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Create the packet configuration in the database. This includes the
|
|
142
|
+
# ItemToDecomTableMapping which maps a telemetry item to its location in the
|
|
143
|
+
# decommutation table as well as the actual decommutation tables which hold
|
|
144
|
+
# the decommutated data. These tables are all named tXXX_YYY where XXX is the
|
|
145
|
+
# PacketConfig ID and YYY is a table index when the packet has more than
|
|
146
|
+
# MAX_COLUMNS_PER_TABLE and must span multiple tables. In addition the
|
|
147
|
+
# reduction tables are setup with the '_m' (minute), '_h' (hour), '_d' (day)
|
|
148
|
+
# extensions added to the tXXX_YYY tables (assuming the packets contain
|
|
149
|
+
# data which can be reduced.)
|
|
150
|
+
#
|
|
151
|
+
# @param packet [Cosmos::Packet] Packet to create database tables for
|
|
152
|
+
# @param packet_id [Integer] Id in the Packet table
|
|
153
|
+
# @param packet_config [PacketConfig] ActiveRecord access to the PacketConfig table
|
|
154
|
+
def setup_packet_config(packet, packet_id, packet_config)
|
|
155
|
+
data_types = setup_item_to_decom_table_mapping(packet, packet_id, packet_config)
|
|
156
|
+
table_index = 0
|
|
157
|
+
# Grab MAX_COLUMNS_PER_TABLE of the total data_types and create a decommutation table
|
|
158
|
+
# This will create a column for each data item named iX where X is a simple counter.
|
|
159
|
+
# Thus the only way to know what data is in these tables is to use the
|
|
160
|
+
# ItemToDecomTableMapping table.
|
|
161
|
+
data_types.each_slice(MAX_COLUMNS_PER_TABLE) do |table_data_types|
|
|
162
|
+
# Create overall decommutation table
|
|
163
|
+
create_table("t#{packet_config.id}_#{table_index}") do |t|
|
|
164
|
+
t.datetime :time
|
|
165
|
+
t.bigint :ple_id
|
|
166
|
+
t.bigint :meta_id
|
|
167
|
+
t.bigint :reduced_id
|
|
168
|
+
t.integer :reduced_state, :default => 0
|
|
169
|
+
table_data_types.each_with_index do |data_type, index|
|
|
170
|
+
item_index = (table_index * MAX_COLUMNS_PER_TABLE) + index
|
|
171
|
+
Cosmos::Logger::info("creating t#{packet_config.id}_#{table_index}:i#{item_index}")
|
|
172
|
+
case data_type
|
|
173
|
+
when :integer_array, :bigint_array, :float_array, :text_array, :binary_array, :decimal_array
|
|
174
|
+
t.column "i#{item_index}", data_type.to_s.split("_")[0].intern, :array => true
|
|
175
|
+
when :integer, :bigint, :float, :text, :binary, :decimal
|
|
176
|
+
t.column "i#{item_index}", data_type
|
|
177
|
+
when :string_array
|
|
178
|
+
t.column "i#{item_index}", data_type.to_s.split("_")[0].intern, :array => true, :limit => MAX_STRING_BYTE_SIZE
|
|
179
|
+
when :string
|
|
180
|
+
t.column "i#{item_index}", data_type, :limit => MAX_STRING_BYTE_SIZE
|
|
181
|
+
else
|
|
182
|
+
raise "Unhandled db type: #{data_type}"
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
t.index :time
|
|
186
|
+
t.index :meta_id
|
|
187
|
+
t.index :reduced_state
|
|
188
|
+
t.index :reduced_id
|
|
189
|
+
end
|
|
190
|
+
create_reduction_table("t#{packet_config.id}_#{table_index}_h", table_data_types, table_index) # hour
|
|
191
|
+
create_reduction_table("t#{packet_config.id}_#{table_index}_m", table_data_types, table_index) # month
|
|
192
|
+
create_reduction_table("t#{packet_config.id}_#{table_index}_d", table_data_types, table_index) # day
|
|
193
|
+
table_index += 1
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# Mark packet config ready
|
|
197
|
+
packet_config.max_table_index = table_index
|
|
198
|
+
packet_config.ready = true
|
|
199
|
+
packet_config.save!
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# Attempts to load a name system configuration. If the system configuration
|
|
203
|
+
# can't be loaded locally, it is requested from the server and copied
|
|
204
|
+
# locally before proceeding.
|
|
205
|
+
#
|
|
206
|
+
# @param system_config_name [String] System configuration name (MD5) to load
|
|
207
|
+
def switch_and_get_system_config(system_config_name)
|
|
208
|
+
# Switch to this new system configuration
|
|
209
|
+
current_config, error = Cosmos::System.load_configuration(system_config_name)
|
|
210
|
+
|
|
211
|
+
if current_config != system_config_name
|
|
212
|
+
Cosmos::Logger.warn("Failed to load system_config: #{system_config_name}")
|
|
213
|
+
Cosmos::Logger.warn(" Current config: #{current_config}")
|
|
214
|
+
Cosmos::Logger.warn(" Error: #{error.formatted}") if error
|
|
215
|
+
Cosmos::Logger.warn(" Will attempt to retrieve...")
|
|
216
|
+
filename, data = get_saved_config(system_config_name)
|
|
217
|
+
raise "No saved config" unless filename and data and data.length > 0
|
|
218
|
+
configuration = File.join(Cosmos::System.paths['SAVED_CONFIG'], filename)
|
|
219
|
+
unless File.exist?(configuration) and File.size(configuration) > 0
|
|
220
|
+
File.open(configuration, 'wb') {|file| file.write(data)}
|
|
221
|
+
File.chmod(0444, configuration) # Mark readonly
|
|
222
|
+
end
|
|
223
|
+
Cosmos::Logger.info("Configuration retrieved: #{configuration}")
|
|
224
|
+
current_config, error = Cosmos::System.load_configuration(system_config_name)
|
|
225
|
+
raise "Could not load config" if current_config != system_config_name
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# Iterate through all the defined commands and telemetry and create database
|
|
230
|
+
# entries for all targets (Target table) and packets (Packet table).
|
|
231
|
+
def sync_targets_and_packets
|
|
232
|
+
sync_targets_packets(Cosmos::System.telemetry.all, is_tlm: true)
|
|
233
|
+
sync_targets_packets(Cosmos::System.commands.all, is_tlm: false)
|
|
234
|
+
build_lookups()
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# Look up the database IDs of the given target and packet names
|
|
238
|
+
#
|
|
239
|
+
# @param target_name [String] Name of the target
|
|
240
|
+
# @param packet_name [String] Name of the packet
|
|
241
|
+
# @param is_tlm [Boolean] Whether the packet is telemetry (true) or commands (false)
|
|
242
|
+
def lookup_target_and_packet_id(target_name, packet_name, is_tlm)
|
|
243
|
+
target_id = @target_name_to_id[target_name] # Check cache
|
|
244
|
+
unless target_id
|
|
245
|
+
target = sync_target(target_name)
|
|
246
|
+
target_id = target.id
|
|
247
|
+
@target_name_to_id[target_name] = target_id # Update cache
|
|
248
|
+
if is_tlm
|
|
249
|
+
@target_id_tlm_packet_name_to_id[target_id] = {}
|
|
250
|
+
else
|
|
251
|
+
@target_id_cmd_packet_name_to_id[target_id] = {}
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
if is_tlm
|
|
255
|
+
packet_name_hash = @target_id_tlm_packet_name_to_id[target_id]
|
|
256
|
+
else
|
|
257
|
+
packet_name_hash = @target_id_cmd_packet_name_to_id[target_id]
|
|
258
|
+
end
|
|
259
|
+
packet_id = packet_name_hash[packet_name] # Check cache
|
|
260
|
+
unless packet_id
|
|
261
|
+
packet = sync_packet(target.id, packet_name, is_tlm)
|
|
262
|
+
packet_id = packet.id
|
|
263
|
+
packet_name_hash[packet_name] = packet.id # Update cache
|
|
264
|
+
end
|
|
265
|
+
return [target_id, packet_id]
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
# Find the ActiveRecord database object for the given packet
|
|
269
|
+
#
|
|
270
|
+
# @param packet [Cosmos::Packet] COSMOS Packet to lookup
|
|
271
|
+
# @param is_tlm [Boolean] Whether the packet is telemetry (true) or commands (false)
|
|
272
|
+
# @return [ActiveRecord] PacketLogEntry ActiveRecord object
|
|
273
|
+
def find_packet_log_entry(packet, is_tlm)
|
|
274
|
+
target_id, packet_id = lookup_target_and_packet_id(packet.target_name, packet.packet_name, is_tlm)
|
|
275
|
+
return PacketLogEntry.where("target_id = ? and packet_id = ? and is_tlm = ? and time = ?", target_id, packet_id, is_tlm, packet.received_time).first
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
# Read a Packet from the binary file by using the PacketLogEntry
|
|
279
|
+
#
|
|
280
|
+
# @param ple [ActiveRecord] PacketLogEntry ActiveRecord object
|
|
281
|
+
# @return [Cosmos::Packet] Packet located by the PacketLookupTable
|
|
282
|
+
def read_packet_from_ple(ple)
|
|
283
|
+
begin
|
|
284
|
+
@plr_cache ||= {}
|
|
285
|
+
reader = @plr_cache[ple.packet_log_id]
|
|
286
|
+
unless reader
|
|
287
|
+
packet_log = PacketLog.find(ple.packet_log_id)
|
|
288
|
+
reader = Cosmos::PacketLogReader.new
|
|
289
|
+
reader.open(packet_log.filename)
|
|
290
|
+
@plr_cache[packet_log.id] = reader
|
|
291
|
+
end
|
|
292
|
+
return reader.read_at_offset(ple.data_offset)
|
|
293
|
+
rescue Exception => error
|
|
294
|
+
Cosmos::Logger.error("Error Reading Packet Log Entry:\n#{error.formatted}")
|
|
295
|
+
return nil
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
def decommutate_item?(item)
|
|
300
|
+
# RECEIVED_COUNT is a relative count and should not be decommutated
|
|
301
|
+
return false if item.name == 'RECEIVED_COUNT'
|
|
302
|
+
# ProcessorConversion items are calculated on the fly thus can't
|
|
303
|
+
# be decommutated as they change based on when they're read
|
|
304
|
+
return false if item.read_conversion.class == Cosmos::ProcessorConversion
|
|
305
|
+
# We don't handle DERIVED items without explicit types and sizes
|
|
306
|
+
if item.data_type == :DERIVED
|
|
307
|
+
return false unless well_defined_read_conversion(item)
|
|
308
|
+
end
|
|
309
|
+
true
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
def query_decom_reduced(
|
|
313
|
+
target_name,
|
|
314
|
+
packet_name,
|
|
315
|
+
item_name,
|
|
316
|
+
value_type,
|
|
317
|
+
is_tlm,
|
|
318
|
+
start_time,
|
|
319
|
+
end_time,
|
|
320
|
+
reduction,
|
|
321
|
+
reduction_modifier,
|
|
322
|
+
item_name_modifier,
|
|
323
|
+
limit = 10000,
|
|
324
|
+
offset = 0,
|
|
325
|
+
meta_ids = [])
|
|
326
|
+
|
|
327
|
+
# Upon receiving the above request, the corresponding Target, Packet, and Item
|
|
328
|
+
# objects are requested from the database
|
|
329
|
+
target_model = Target.where("name = ?", target_name).first
|
|
330
|
+
raise "Target: #{target_name} not found" unless target_model
|
|
331
|
+
packet_model = Packet.where("target_id = ? and name = ? and is_tlm = ?", target_model.id, packet_name, is_tlm).first
|
|
332
|
+
raise "Packet: #{packet_name} not found" unless packet_model
|
|
333
|
+
item_model = Item.where("packet_id = ? and name = ?", packet_model.id, item_name).first
|
|
334
|
+
raise "Item: #{item_name} not found" unless item_model
|
|
335
|
+
|
|
336
|
+
# Next the corresponding PacketConfigs are loaded within the requested times.
|
|
337
|
+
# Note the PacketConfig time range covers when that particular packet configuration
|
|
338
|
+
# was valid. Thus it can cover a much larger time period than the data requested.
|
|
339
|
+
packet_configs = PacketConfig.where("packet_id = ?", packet_model.id)
|
|
340
|
+
packet_configs.where("start_time >= ?", start_time) if start_time
|
|
341
|
+
packet_configs.where("end_time <= ?", end_time) if end_time
|
|
342
|
+
packet_configs = packet_configs.order("start_time ASC")
|
|
343
|
+
packet_config_ids = []
|
|
344
|
+
packet_configs.each do |pc|
|
|
345
|
+
packet_config_ids << pc.id
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
# Then, the ItemToDecomTableMapping table is queried to find all entries that match
|
|
349
|
+
# the requested item, value_type, and packet configuration. These entries represent
|
|
350
|
+
# all the entries in the decommutation and reduction tables for the requested item
|
|
351
|
+
# when that PacketConfig was valid.
|
|
352
|
+
mappings = ItemToDecomTableMapping.where("item_id = ? and value_type != ?", item_model.id, value_type).where("packet_config_id" => packet_config_ids)
|
|
353
|
+
# Sort mappings into packet config id order
|
|
354
|
+
mappings.to_a.sort do |a, b|
|
|
355
|
+
packet_config_ids.index(a.packet_config_id) <=> packet_config_ids.index(b.packet_config_id)
|
|
356
|
+
end
|
|
357
|
+
data = []
|
|
358
|
+
current_count = 0
|
|
359
|
+
batch_size = 1000
|
|
360
|
+
mappings.each do |mapping|
|
|
361
|
+
# The item to decommutation table entries are then used to access the actual
|
|
362
|
+
# decommutation table model (ActiveRecord object).
|
|
363
|
+
row_model = get_decom_table_model(mapping.packet_config_id, mapping.table_index, reduction_modifier)
|
|
364
|
+
|
|
365
|
+
batch_count = 0
|
|
366
|
+
loop do
|
|
367
|
+
# The decommutation table itself is then quered for the values with final filters on the requested
|
|
368
|
+
# time range and optional filtering by meta_id. The correct decommutation table is selected by
|
|
369
|
+
# using the passed in reduction value in the request.
|
|
370
|
+
remaining = limit - current_count
|
|
371
|
+
if remaining > batch_size
|
|
372
|
+
limit_value = batch_size
|
|
373
|
+
else
|
|
374
|
+
limit_value = remaining
|
|
375
|
+
end
|
|
376
|
+
if reduction == :NONE
|
|
377
|
+
# For reduced data the time field is called start_time, for non-reduced it is just time
|
|
378
|
+
model_item_name = "i#{mapping.item_index}#{item_name_modifier}"
|
|
379
|
+
rows = row_model.order(time: :asc)
|
|
380
|
+
rows = rows.where("time >= ?", start_time) if start_time
|
|
381
|
+
rows = rows.where("time <= ?", end_time) if end_time
|
|
382
|
+
rows = rows.where("meta_id" => meta_ids) if meta_ids.length > 0
|
|
383
|
+
rows = rows.limit(limit_value).offset(offset + (batch_count * batch_size))
|
|
384
|
+
rows.select(model_item_name, "time", "meta_id")
|
|
385
|
+
break if rows.length <= 0
|
|
386
|
+
rows.each do |row|
|
|
387
|
+
data << [row.read_attribute(model_item_name), row.time.tv_sec, row.time.tv_usec, 1, row.meta_id]
|
|
388
|
+
current_count += 1
|
|
389
|
+
break if current_count >= limit
|
|
390
|
+
end
|
|
391
|
+
elsif mapping.reduced
|
|
392
|
+
# For reduced data the time field is called start_time, for non-reduced it is just time
|
|
393
|
+
model_item_name = "i#{mapping.item_index}#{item_name_modifier}"
|
|
394
|
+
rows = row_model.order(start_time: :asc)
|
|
395
|
+
rows = rows.where("start_time >= ?", start_time) if start_time
|
|
396
|
+
rows = rows.where("start_time <= ?", end_time) if end_time
|
|
397
|
+
rows = rows.where("meta_id" => meta_ids) if meta_ids.length > 0
|
|
398
|
+
rows = rows.limit(limit_value).offset(offset + (batch_count * batch_size))
|
|
399
|
+
rows.select(model_item_name, "start_time", "num_samples", "meta_id")
|
|
400
|
+
break if rows.length <= 0
|
|
401
|
+
rows.each do |row|
|
|
402
|
+
data << [row.read_attribute(model_item_name), row.start_time.tv_sec, row.start_time.tv_usec, row.num_samples, row.meta_id]
|
|
403
|
+
current_count += 1
|
|
404
|
+
break if current_count >= limit
|
|
405
|
+
end
|
|
406
|
+
end
|
|
407
|
+
break if limit_value != batch_size
|
|
408
|
+
batch_count += 1
|
|
409
|
+
end
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
return data
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
def comparison_cast(value1, value2)
|
|
416
|
+
case value1
|
|
417
|
+
when Integer
|
|
418
|
+
return Integer(value2)
|
|
419
|
+
when Float
|
|
420
|
+
return Float(value2)
|
|
421
|
+
when String
|
|
422
|
+
return value2.to_s
|
|
423
|
+
end
|
|
424
|
+
return value2
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
def process_meta_filters(meta_filters, is_tlm, end_time)
|
|
428
|
+
found = []
|
|
429
|
+
meta_filters.each_with_index do |query_string, index|
|
|
430
|
+
found[index] = []
|
|
431
|
+
this_found = found[index]
|
|
432
|
+
item_name, comparison, comparison_value = query_string.scan(PARSING_REGEX)
|
|
433
|
+
item_name = item_name.remove_quotes
|
|
434
|
+
comparison_value = comparison_value.remove_quotes
|
|
435
|
+
comparison_value = nil if comparison_value.to_s.upcase == "NULL"
|
|
436
|
+
|
|
437
|
+
meta_data = query_decom_reduced(
|
|
438
|
+
"SYSTEM", "META", item_name,
|
|
439
|
+
ItemToDecomTableMapping::CONVERTED, is_tlm,
|
|
440
|
+
nil, end_time,
|
|
441
|
+
:NONE, "",
|
|
442
|
+
"", 100000, 0, [])
|
|
443
|
+
|
|
444
|
+
case comparison
|
|
445
|
+
when "=", "=="
|
|
446
|
+
meta_data.each { |value, tv_sec, tv_usec, num_samples, meta_id| this_found << meta_id if value == comparison_cast(value, comparison_value) }
|
|
447
|
+
when "!="
|
|
448
|
+
meta_data.each { |value, tv_sec, tv_usec, num_samples, meta_id| this_found << meta_id if value != comparison_cast(value, comparison_value) }
|
|
449
|
+
when ">"
|
|
450
|
+
meta_data.each { |value, tv_sec, tv_usec, num_samples, meta_id| this_found << meta_id if value > comparison_cast(value, comparison_value) }
|
|
451
|
+
when "<"
|
|
452
|
+
meta_data.each { |value, tv_sec, tv_usec, num_samples, meta_id| this_found << meta_id if value < comparison_cast(value, comparison_value) }
|
|
453
|
+
when ">="
|
|
454
|
+
meta_data.each { |value, tv_sec, tv_usec, num_samples, meta_id| this_found << meta_id if value >= comparison_cast(value, comparison_value) }
|
|
455
|
+
when "<="
|
|
456
|
+
meta_data.each { |value, tv_sec, tv_usec, num_samples, meta_id| this_found << meta_id if value <= comparison_cast(value, comparison_value) }
|
|
457
|
+
end
|
|
458
|
+
end
|
|
459
|
+
meta_ids = found.inject(:&) # Reduce to only common meta_ids to all meta_filters
|
|
460
|
+
meta_ids = [0] if !meta_ids or meta_ids.length == 0
|
|
461
|
+
|
|
462
|
+
return meta_ids
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
protected
|
|
466
|
+
|
|
467
|
+
# Build the internal lookup tables to convert names to database ids
|
|
468
|
+
def build_lookups
|
|
469
|
+
# Get full target name and packet name lists from database
|
|
470
|
+
targets = Target.all
|
|
471
|
+
@target_name_to_id = {}
|
|
472
|
+
@target_id_tlm_packet_name_to_id = {}
|
|
473
|
+
@target_id_cmd_packet_name_to_id = {}
|
|
474
|
+
@packet_id_item_name_to_id = {}
|
|
475
|
+
targets.each do |target|
|
|
476
|
+
@target_name_to_id[target.name] = target.id
|
|
477
|
+
@target_id_tlm_packet_name_to_id[target.id] = {}
|
|
478
|
+
@target_id_cmd_packet_name_to_id[target.id] = {}
|
|
479
|
+
packets = Packet.where("target_id = #{target.id} and is_tlm = true").all
|
|
480
|
+
packets.each do |packet|
|
|
481
|
+
@target_id_tlm_packet_name_to_id[target.id][packet.name] = packet.id
|
|
482
|
+
@packet_id_item_name_to_id[packet.id] = {}
|
|
483
|
+
items = Item.where("packet_id = #{packet.id}").all
|
|
484
|
+
items.each do |item|
|
|
485
|
+
@packet_id_item_name_to_id[packet.id][item.name] = item.id
|
|
486
|
+
end
|
|
487
|
+
end
|
|
488
|
+
packets = Packet.where("target_id = #{target.id} and is_tlm = false").all
|
|
489
|
+
packets.each do |packet|
|
|
490
|
+
@target_id_cmd_packet_name_to_id[target.id][packet.name] = packet.id
|
|
491
|
+
@packet_id_item_name_to_id[packet.id] = {}
|
|
492
|
+
items = Item.where("packet_id = #{packet.id}").all
|
|
493
|
+
items.each do |item|
|
|
494
|
+
@packet_id_item_name_to_id[packet.id][item.name] = item.id
|
|
495
|
+
end
|
|
496
|
+
end
|
|
497
|
+
end
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
# Look up the item id in the Item table based on the previously acquired packet id
|
|
501
|
+
# Note: This method is only safe if lookup_target_and_packet_id was called
|
|
502
|
+
# before it to get the packet_id
|
|
503
|
+
#
|
|
504
|
+
# @param packet_id [Integer] Database ID of the packet
|
|
505
|
+
# @param item_name [String] Name of the item
|
|
506
|
+
# @return [Integer] Database ID of the item
|
|
507
|
+
def lookup_item_id(packet_id, item_name)
|
|
508
|
+
@packet_id_item_name_to_id[packet_id] ||= {}
|
|
509
|
+
item_name_hash = @packet_id_item_name_to_id[packet_id]
|
|
510
|
+
item_id = item_name_hash[item_name] # Check cache
|
|
511
|
+
unless item_id
|
|
512
|
+
item = sync_item(packet_id, item_name)
|
|
513
|
+
item_id = item.id
|
|
514
|
+
item_name_hash[item_name] = item.id # Update cache
|
|
515
|
+
end
|
|
516
|
+
return item_id
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
# Convert the COSMOS data type, bit size, and array into a type used
|
|
520
|
+
# by the SQL database.
|
|
521
|
+
#
|
|
522
|
+
# @param data_type [Symbol] One of :INT, :UINT, :FLOAT, :STRING, :BLOCK
|
|
523
|
+
# @param bit_size [Integer] Size of the COSMOS data type
|
|
524
|
+
# @param array_size [Integer, nil] Size of the array or nil if no array
|
|
525
|
+
# @return [Symbol] Database type such as :integer, :bigint, :string, etc.
|
|
526
|
+
def cosmos_data_type_to_db_type(data_type, bit_size, array_size)
|
|
527
|
+
db_type = nil
|
|
528
|
+
case data_type
|
|
529
|
+
when :INT
|
|
530
|
+
if bit_size <= 32
|
|
531
|
+
db_type = :integer
|
|
532
|
+
elsif bit_size <= 64
|
|
533
|
+
db_type = :bigint
|
|
534
|
+
else
|
|
535
|
+
db_type = :decimal
|
|
536
|
+
end
|
|
537
|
+
when :UINT
|
|
538
|
+
if bit_size <= 31
|
|
539
|
+
db_type = :integer
|
|
540
|
+
elsif bit_size <= 63
|
|
541
|
+
db_type = :bigint
|
|
542
|
+
else
|
|
543
|
+
db_type = :decimal
|
|
544
|
+
end
|
|
545
|
+
when :FLOAT
|
|
546
|
+
db_type = :float
|
|
547
|
+
when :STRING
|
|
548
|
+
if bit_size <= 0 or bit_size > MAX_STRING_BIT_SIZE
|
|
549
|
+
db_type = :text
|
|
550
|
+
else
|
|
551
|
+
db_type = :string
|
|
552
|
+
end
|
|
553
|
+
when :BLOCK
|
|
554
|
+
db_type = :binary
|
|
555
|
+
else
|
|
556
|
+
raise "Unsupported data type for db: #{data_type}:#{bit_size}"
|
|
557
|
+
end
|
|
558
|
+
db_type = (db_type.to_s + "_array").intern if array_size
|
|
559
|
+
return db_type
|
|
560
|
+
end
|
|
561
|
+
|
|
562
|
+
# @param item [Cosmos::PacketItem] Item to convert to a SQL database type
|
|
563
|
+
# @return [Array<Symbol, Symbol | nil>] SQL database type for the raw item
|
|
564
|
+
# followed by the converted item or nil if there is no conversion
|
|
565
|
+
def get_db_types(item)
|
|
566
|
+
raw_data_type = nil
|
|
567
|
+
converted_data_type = nil
|
|
568
|
+
if item.data_type == :DERIVED
|
|
569
|
+
if item.read_conversion
|
|
570
|
+
converted_data_type = cosmos_data_type_to_db_type(item.read_conversion.converted_type, item.read_conversion.converted_bit_size, item.read_conversion.converted_array_size)
|
|
571
|
+
raw_data_type = converted_data_type
|
|
572
|
+
end
|
|
573
|
+
if item.states
|
|
574
|
+
converted_data_type = cosmos_data_type_to_db_type(:STRING, MAX_STRING_BIT_SIZE, item.array_size)
|
|
575
|
+
end
|
|
576
|
+
else
|
|
577
|
+
raw_data_type = cosmos_data_type_to_db_type(item.data_type, item.bit_size, item.array_size)
|
|
578
|
+
if item.read_conversion
|
|
579
|
+
converted_data_type = cosmos_data_type_to_db_type(item.read_conversion.converted_type, item.read_conversion.converted_bit_size, item.read_conversion.converted_array_size)
|
|
580
|
+
elsif item.states
|
|
581
|
+
converted_data_type = cosmos_data_type_to_db_type(:STRING, MAX_STRING_BIT_SIZE, item.array_size)
|
|
582
|
+
end
|
|
583
|
+
end
|
|
584
|
+
return raw_data_type, converted_data_type
|
|
585
|
+
end
|
|
586
|
+
|
|
587
|
+
# Create the item to decommutation table mapping
|
|
588
|
+
#
|
|
589
|
+
# @param packet [Cosmos::Packet] Packet to create item mappings for
|
|
590
|
+
# @param packet_id [Integer] Id in the Packet table
|
|
591
|
+
# @param packet_config [PacketConfig] ActiveRecord access to the PacketConfig table
|
|
592
|
+
# @return [Array<Symbol>] SQL database types for each item in the packet. Note there
|
|
593
|
+
# can be multiple values per item if an item has a raw and converted type.
|
|
594
|
+
def setup_item_to_decom_table_mapping(packet, packet_id, packet_config)
|
|
595
|
+
item_index = 0
|
|
596
|
+
data_types = []
|
|
597
|
+
|
|
598
|
+
# Cleanup old
|
|
599
|
+
ItemToDecomTableMapping.where("packet_config_id = ?", packet_config.id).destroy_all
|
|
600
|
+
|
|
601
|
+
packet.sorted_items.each do |item|
|
|
602
|
+
next unless decommutate_item?(item)
|
|
603
|
+
|
|
604
|
+
raw_data_type, converted_data_type = get_db_types(item)
|
|
605
|
+
item_id = lookup_item_id(packet_id, item.name)
|
|
606
|
+
if separate_raw_con?(item)
|
|
607
|
+
# Need both RAW and CONVERTED
|
|
608
|
+
ItemToDecomTableMapping.create(
|
|
609
|
+
:item_id => item_id,
|
|
610
|
+
:value_type => ItemToDecomTableMapping::RAW,
|
|
611
|
+
:reduced => REDUCED_TYPES.include?(raw_data_type),
|
|
612
|
+
:packet_config_id => packet_config.id,
|
|
613
|
+
:table_index => item_index / MAX_COLUMNS_PER_TABLE,
|
|
614
|
+
:item_index => item_index
|
|
615
|
+
)
|
|
616
|
+
item_index += 1
|
|
617
|
+
data_types << raw_data_type
|
|
618
|
+
ItemToDecomTableMapping.create(
|
|
619
|
+
:item_id => item_id,
|
|
620
|
+
:value_type => ItemToDecomTableMapping::CONVERTED,
|
|
621
|
+
:reduced => REDUCED_TYPES.include?(converted_data_type),
|
|
622
|
+
:packet_config_id => packet_config.id,
|
|
623
|
+
:table_index => item_index / MAX_COLUMNS_PER_TABLE,
|
|
624
|
+
:item_index => item_index
|
|
625
|
+
)
|
|
626
|
+
item_index += 1
|
|
627
|
+
data_types << converted_data_type
|
|
628
|
+
else
|
|
629
|
+
# Can combine RAW and CONVERTED (RAW_CON)
|
|
630
|
+
ItemToDecomTableMapping.create(
|
|
631
|
+
:item_id => item_id,
|
|
632
|
+
:value_type => ItemToDecomTableMapping::RAW_CON,
|
|
633
|
+
:reduced => REDUCED_TYPES.include?(raw_data_type),
|
|
634
|
+
:packet_config_id => packet_config.id,
|
|
635
|
+
:table_index => item_index / MAX_COLUMNS_PER_TABLE,
|
|
636
|
+
:item_index => item_index
|
|
637
|
+
)
|
|
638
|
+
item_index += 1
|
|
639
|
+
data_types << raw_data_type
|
|
640
|
+
end
|
|
641
|
+
end
|
|
642
|
+
|
|
643
|
+
return data_types
|
|
644
|
+
end
|
|
645
|
+
|
|
646
|
+
# Create a table in the database. Tables are first checked for existance
|
|
647
|
+
# and dropped if they exist to ensure a clean table is created.
|
|
648
|
+
def create_table(table_name)
|
|
649
|
+
# Normally there would not be an existing decommutation table, however
|
|
650
|
+
# in the off chance that DART crashed halfway through creating a packet
|
|
651
|
+
# configuration we drop anything that may be existing.
|
|
652
|
+
if ActiveRecord::Base.connection.table_exists?(table_name)
|
|
653
|
+
ActiveRecord::Base.connection.drop_table(table_name)
|
|
654
|
+
end
|
|
655
|
+
ActiveRecord::Base.connection.create_table(table_name) do |table|
|
|
656
|
+
yield table
|
|
657
|
+
end
|
|
658
|
+
# Need to create model
|
|
659
|
+
model = Class.new(ActiveRecord::Base) do
|
|
660
|
+
self.table_name = table_name.dup
|
|
661
|
+
end
|
|
662
|
+
model.reset_column_information
|
|
663
|
+
model_name = table_name.upcase
|
|
664
|
+
Cosmos.send(:remove_const, model_name) if Cosmos.const_defined?(model_name)
|
|
665
|
+
Cosmos.const_set(model_name, model)
|
|
666
|
+
end
|
|
667
|
+
|
|
668
|
+
# Create a data reduction table. These tables hold min, max, and average
|
|
669
|
+
# data points for values that can be reduced over longer time periods
|
|
670
|
+
# for quicker access.
|
|
671
|
+
def create_reduction_table(table_name, table_data_types, table_index)
|
|
672
|
+
create_table(table_name) do |t|
|
|
673
|
+
t.datetime :start_time
|
|
674
|
+
t.integer :num_samples
|
|
675
|
+
t.bigint :meta_id
|
|
676
|
+
t.bigint :reduced_id
|
|
677
|
+
t.integer :reduced_state, :default => 0
|
|
678
|
+
table_data_types.each_with_index do |data_type, index|
|
|
679
|
+
item_index = (table_index * MAX_COLUMNS_PER_TABLE) + index
|
|
680
|
+
case data_type
|
|
681
|
+
when :integer, :bigint, :float, :decimal
|
|
682
|
+
t.column "i#{item_index}max", data_type
|
|
683
|
+
t.column "i#{item_index}min", data_type
|
|
684
|
+
t.column "i#{item_index}avg", :float # Average is always floating point
|
|
685
|
+
t.column "i#{item_index}stddev", :float # Standard deviation is always floating point
|
|
686
|
+
end
|
|
687
|
+
end
|
|
688
|
+
t.index :start_time
|
|
689
|
+
t.index :meta_id
|
|
690
|
+
t.index :reduced_state
|
|
691
|
+
t.index :reduced_id
|
|
692
|
+
end
|
|
693
|
+
end
|
|
694
|
+
|
|
695
|
+
def sync_target(target_name)
|
|
696
|
+
target = Target.where("name = ?", target_name).first
|
|
697
|
+
begin
|
|
698
|
+
unless target
|
|
699
|
+
target = Target.create(:name => target_name)
|
|
700
|
+
Cosmos::Logger::info("Created Target:#{target.id}:#{target.name}")
|
|
701
|
+
end
|
|
702
|
+
rescue
|
|
703
|
+
# Another thread probably already created it - Try to get it one more time
|
|
704
|
+
target = Target.where("name = ?", target_name).first
|
|
705
|
+
end
|
|
706
|
+
target
|
|
707
|
+
end
|
|
708
|
+
|
|
709
|
+
def sync_packet(target_id, packet_name, is_tlm)
|
|
710
|
+
packet = Packet.where("target_id = ? and name = ? and is_tlm = #{is_tlm}", target_id, packet_name).first
|
|
711
|
+
begin
|
|
712
|
+
unless packet
|
|
713
|
+
packet = Packet.create(:target_id => target_id, :name => packet_name, :is_tlm => is_tlm)
|
|
714
|
+
Cosmos::Logger::info("Created Packet:#{packet.id}:#{packet.target_id}:#{packet.name}:#{packet.is_tlm}")
|
|
715
|
+
end
|
|
716
|
+
rescue
|
|
717
|
+
# Another thread probably already created it - Try to get it one more time
|
|
718
|
+
packet = Packet.where("target_id = ? and name = ? and is_tlm = #{is_tlm}", target_id, packet_name).first
|
|
719
|
+
end
|
|
720
|
+
packet
|
|
721
|
+
end
|
|
722
|
+
|
|
723
|
+
def sync_item(packet_id, item_name)
|
|
724
|
+
item = Item.where("packet_id = ? and name = ?", packet_id, item_name).first
|
|
725
|
+
begin
|
|
726
|
+
unless item
|
|
727
|
+
item = Item.create(:packet_id => packet_id, :name => item_name)
|
|
728
|
+
Cosmos::Logger::info("Created Item:#{item.id}:#{item.packet_id}:#{item.name}")
|
|
729
|
+
end
|
|
730
|
+
rescue
|
|
731
|
+
# Another thread probably already created it - Try to get it one more time
|
|
732
|
+
item = Item.where("packet_id = ? and name = ?", packet_id, item_name).first
|
|
733
|
+
end
|
|
734
|
+
item
|
|
735
|
+
end
|
|
736
|
+
|
|
737
|
+
def sync_targets_packets(tgt_pkt_hash, is_tlm:)
|
|
738
|
+
tgt_pkt_hash.each do |target_name, packets|
|
|
739
|
+
target = sync_target(target_name)
|
|
740
|
+
packets.each do |packet_name, packet_obj|
|
|
741
|
+
sync_packet(target.id, packet_name, is_tlm)
|
|
742
|
+
end
|
|
743
|
+
end
|
|
744
|
+
end
|
|
745
|
+
|
|
746
|
+
def well_defined_read_conversion(item)
|
|
747
|
+
item.read_conversion && item.read_conversion.converted_type && item.read_conversion.converted_bit_size
|
|
748
|
+
end
|
|
749
|
+
end
|