openc3 7.2.1 → 7.4.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/Gemfile +1 -1
- data/Guardfile +0 -0
- data/LICENSE.md +0 -0
- data/README.md +0 -0
- data/Rakefile +0 -0
- data/bin/openc3cli +235 -6
- data/bin/pipinstall +5 -4
- data/bin/pipuninstall +5 -1
- data/bin/uvinstall +156 -0
- data/data/config/_array_params.yaml +0 -0
- data/data/config/_canvas_values.yaml +0 -0
- data/data/config/_graph_params.yaml +0 -0
- data/data/config/_id_items.yaml +0 -0
- data/data/config/_id_params.yaml +0 -0
- data/data/config/_interfaces.yaml +0 -0
- data/data/config/_items.yaml +0 -0
- data/data/config/_params.yaml +0 -0
- data/data/config/command.yaml +0 -0
- data/data/config/command_modifiers.yaml +2 -0
- data/data/config/command_telemetry.yaml +0 -0
- data/data/config/conversions.yaml +0 -0
- data/data/config/graph_settings.yaml +0 -0
- data/data/config/interface_modifiers.yaml +103 -1
- data/data/config/item_modifiers.yaml +2 -1
- data/data/config/microservice.yaml +9 -2
- data/data/config/param_item_modifiers.yaml +0 -0
- data/data/config/parameter_modifiers.yaml +0 -0
- data/data/config/plugins.yaml +0 -0
- data/data/config/processors.yaml +0 -0
- data/data/config/protocols.yaml +0 -0
- data/data/config/screen.yaml +2 -1
- data/data/config/settings.yaml +0 -0
- data/data/config/table_manager.yaml +0 -0
- data/data/config/table_parameter_modifiers.yaml +0 -0
- data/data/config/target.yaml +21 -0
- data/data/config/target_config.yaml +0 -0
- data/data/config/telemetry.yaml +0 -0
- data/data/config/telemetry_modifiers.yaml +2 -0
- data/data/config/tool.yaml +3 -1
- data/data/config/unknown.yaml +0 -0
- data/data/config/widgets.yaml +22 -3
- data/data/xtce_schemas/SpaceSystem_20180204.xsd +5918 -0
- data/data/xtce_schemas/xml.xsd +116 -0
- data/ext/openc3/ext/array/array.c +0 -0
- data/ext/openc3/ext/array/extconf.rb +0 -0
- data/ext/openc3/ext/buffered_file/buffered_file.c +0 -0
- data/ext/openc3/ext/buffered_file/extconf.rb +0 -0
- data/ext/openc3/ext/burst_protocol/burst_protocol.c +6 -0
- data/ext/openc3/ext/burst_protocol/extconf.rb +0 -0
- data/ext/openc3/ext/config_parser/config_parser.c +0 -0
- data/ext/openc3/ext/config_parser/extconf.rb +0 -0
- data/ext/openc3/ext/crc/crc.c +0 -0
- data/ext/openc3/ext/crc/extconf.rb +0 -0
- data/ext/openc3/ext/openc3_io/extconf.rb +0 -0
- data/ext/openc3/ext/openc3_io/openc3_io.c +0 -0
- data/ext/openc3/ext/packet/extconf.rb +0 -0
- data/ext/openc3/ext/packet/packet.c +0 -0
- data/ext/openc3/ext/platform/extconf.rb +0 -0
- data/ext/openc3/ext/platform/platform.c +4 -1
- data/ext/openc3/ext/polynomial_conversion/extconf.rb +0 -0
- data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +0 -0
- data/ext/openc3/ext/string/extconf.rb +0 -0
- data/ext/openc3/ext/string/string.c +0 -0
- data/ext/openc3/ext/structure/structure.c +49 -17
- data/ext/openc3/ext/tabbed_plots_config/extconf.rb +0 -0
- data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +0 -0
- data/ext/openc3/ext/telemetry/extconf.rb +0 -0
- data/ext/openc3/ext/telemetry/telemetry.c +1 -1
- data/lib/cosmos.rb +0 -0
- data/lib/cosmosc2.rb +0 -0
- data/lib/openc3/accessors/accessor.rb +0 -0
- data/lib/openc3/accessors/binary_accessor.rb +63 -9
- data/lib/openc3/accessors/cbor_accessor.rb +0 -0
- data/lib/openc3/accessors/form_accessor.rb +0 -0
- data/lib/openc3/accessors/html_accessor.rb +0 -0
- data/lib/openc3/accessors/http_accessor.rb +0 -0
- data/lib/openc3/accessors/json_accessor.rb +0 -0
- data/lib/openc3/accessors/template_accessor.rb +2 -2
- data/lib/openc3/accessors/xml_accessor.rb +0 -0
- data/lib/openc3/accessors.rb +0 -0
- data/lib/openc3/api/README.md +0 -0
- data/lib/openc3/api/api.rb +0 -0
- data/lib/openc3/api/authorized_api.rb +0 -0
- data/lib/openc3/api/calendar_api.rb +0 -0
- data/lib/openc3/api/cmd_api.rb +1 -1
- data/lib/openc3/api/config_api.rb +0 -0
- data/lib/openc3/api/interface_api.rb +2 -2
- data/lib/openc3/api/limits_api.rb +27 -13
- data/lib/openc3/api/metrics_api.rb +1 -1
- data/lib/openc3/api/offline_access_api.rb +1 -1
- data/lib/openc3/api/router_api.rb +3 -3
- data/lib/openc3/api/settings_api.rb +22 -18
- data/lib/openc3/api/stash_api.rb +1 -1
- data/lib/openc3/api/target_api.rb +0 -0
- data/lib/openc3/api/tlm_api.rb +5 -4
- data/lib/openc3/bridge/bridge.rb +0 -0
- data/lib/openc3/bridge/bridge_config.rb +0 -0
- data/lib/openc3/bridge/bridge_interface_thread.rb +0 -0
- data/lib/openc3/bridge/bridge_router_thread.rb +0 -0
- data/lib/openc3/ccsds/ccsds_packet.rb +0 -0
- data/lib/openc3/ccsds/ccsds_parser.rb +0 -0
- data/lib/openc3/config/config_parser.rb +78 -17
- data/lib/openc3/config/meta_config_parser.rb +0 -0
- data/lib/openc3/conversions/bit_reverse_conversion.rb +0 -0
- data/lib/openc3/conversions/conversion.rb +0 -0
- data/lib/openc3/conversions/generic_conversion.rb +0 -0
- data/lib/openc3/conversions/ip_read_conversion.rb +0 -0
- data/lib/openc3/conversions/ip_write_conversion.rb +0 -0
- data/lib/openc3/conversions/object_read_conversion.rb +0 -0
- data/lib/openc3/conversions/object_write_conversion.rb +0 -0
- data/lib/openc3/conversions/packet_time_formatted_conversion.rb +0 -0
- data/lib/openc3/conversions/packet_time_seconds_conversion.rb +0 -0
- data/lib/openc3/conversions/polynomial_conversion.rb +0 -0
- data/lib/openc3/conversions/processor_conversion.rb +0 -0
- data/lib/openc3/conversions/received_count_conversion.rb +0 -0
- data/lib/openc3/conversions/received_time_formatted_conversion.rb +0 -0
- data/lib/openc3/conversions/received_time_seconds_conversion.rb +0 -0
- data/lib/openc3/conversions/segmented_polynomial_conversion.rb +0 -0
- data/lib/openc3/conversions/unix_time_conversion.rb +0 -0
- data/lib/openc3/conversions/unix_time_formatted_conversion.rb +0 -0
- data/lib/openc3/conversions/unix_time_seconds_conversion.rb +0 -0
- data/lib/openc3/conversions.rb +0 -0
- data/lib/openc3/core_ext/array.rb +0 -0
- data/lib/openc3/core_ext/binding.rb +0 -0
- data/lib/openc3/core_ext/class.rb +0 -0
- data/lib/openc3/core_ext/exception.rb +0 -0
- data/lib/openc3/core_ext/faraday.rb +0 -0
- data/lib/openc3/core_ext/file.rb +0 -0
- data/lib/openc3/core_ext/io.rb +0 -0
- data/lib/openc3/core_ext/kernel.rb +0 -0
- data/lib/openc3/core_ext/math.rb +0 -0
- data/lib/openc3/core_ext/matrix.rb +0 -0
- data/lib/openc3/core_ext/objectspace.rb +0 -0
- data/lib/openc3/core_ext/openc3_io.rb +0 -0
- data/lib/openc3/core_ext/range.rb +0 -0
- data/lib/openc3/core_ext/socket.rb +0 -0
- data/lib/openc3/core_ext/string.rb +0 -0
- data/lib/openc3/core_ext/stringio.rb +0 -0
- data/lib/openc3/core_ext/tempfile.rb +0 -0
- data/lib/openc3/core_ext/time.rb +0 -0
- data/lib/openc3/core_ext.rb +0 -0
- data/lib/openc3/ext/.keep +0 -0
- data/lib/openc3/interfaces/file_interface.rb +0 -0
- data/lib/openc3/interfaces/http_client_interface.rb +1 -1
- data/lib/openc3/interfaces/http_server_interface.rb +0 -0
- data/lib/openc3/interfaces/interface.rb +5 -4
- data/lib/openc3/interfaces/mqtt_interface.rb +0 -0
- data/lib/openc3/interfaces/mqtt_stream_interface.rb +2 -0
- data/lib/openc3/interfaces/protocols/burst_protocol.rb +27 -0
- data/lib/openc3/interfaces/protocols/cmd_response_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/cobs_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/crc_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/fixed_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/length_protocol.rb +7 -0
- data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +7 -0
- data/lib/openc3/interfaces/protocols/protocol.rb +4 -4
- data/lib/openc3/interfaces/protocols/slip_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/template_protocol.rb +2 -2
- data/lib/openc3/interfaces/protocols/terminated_protocol.rb +0 -0
- data/lib/openc3/interfaces/serial_interface.rb +2 -0
- data/lib/openc3/interfaces/simulated_target_interface.rb +0 -0
- data/lib/openc3/interfaces/stream_interface.rb +0 -0
- data/lib/openc3/interfaces/tcpip_client_interface.rb +2 -0
- data/lib/openc3/interfaces/tcpip_server_interface.rb +0 -0
- data/lib/openc3/interfaces/udp_interface.rb +16 -5
- data/lib/openc3/interfaces.rb +0 -0
- data/lib/openc3/io/buffered_file.rb +0 -0
- data/lib/openc3/io/io_multiplexer.rb +0 -0
- data/lib/openc3/io/json_api.rb +3 -2
- data/lib/openc3/io/json_api_object.rb +0 -0
- data/lib/openc3/io/json_drb.rb +44 -12
- data/lib/openc3/io/json_drb_object.rb +0 -0
- data/lib/openc3/io/json_drb_rack.rb +0 -0
- data/lib/openc3/io/json_rpc.rb +0 -2
- data/lib/openc3/io/posix_serial_driver.rb +0 -0
- data/lib/openc3/io/serial_driver.rb +0 -0
- data/lib/openc3/io/stderr.rb +0 -0
- data/lib/openc3/io/stdout.rb +0 -0
- data/lib/openc3/io/udp_sockets.rb +38 -8
- data/lib/openc3/io/win32_serial_driver.rb +1 -0
- data/lib/openc3/logs/buffered_packet_log_reader.rb +0 -0
- data/lib/openc3/logs/buffered_packet_log_writer.rb +0 -0
- data/lib/openc3/logs/log_writer.rb +43 -7
- data/lib/openc3/logs/packet_log_constants.rb +0 -0
- data/lib/openc3/logs/packet_log_reader.rb +23 -2
- data/lib/openc3/logs/packet_log_writer.rb +6 -2
- data/lib/openc3/logs/stream_log.rb +1 -1
- data/lib/openc3/logs/stream_log_pair.rb +0 -0
- data/lib/openc3/logs/text_log_writer.rb +0 -0
- data/lib/openc3/logs.rb +0 -0
- data/lib/openc3/microservices/cleanup_microservice.rb +0 -0
- data/lib/openc3/microservices/decom_common.rb +0 -0
- data/lib/openc3/microservices/decom_microservice.rb +0 -0
- data/lib/openc3/microservices/interface_decom_common.rb +2 -1
- data/lib/openc3/microservices/interface_microservice.rb +73 -26
- data/lib/openc3/microservices/log_microservice.rb +0 -0
- data/lib/openc3/microservices/microservice.rb +3 -3
- data/lib/openc3/microservices/multi_microservice.rb +1 -1
- data/lib/openc3/microservices/periodic_microservice.rb +2 -2
- data/lib/openc3/microservices/plugin_microservice.rb +0 -0
- data/lib/openc3/microservices/queue_microservice.rb +0 -0
- data/lib/openc3/microservices/router_microservice.rb +0 -0
- data/lib/openc3/microservices/scope_cleanup_microservice.rb +0 -0
- data/lib/openc3/microservices/text_log_microservice.rb +0 -0
- data/lib/openc3/migrations/20220420190000_log_stuff.rb +0 -0
- data/lib/openc3/migrations/20221202214600_add_target_names.rb +0 -0
- data/lib/openc3/migrations/20221210174900_convert_to_multi.rb +0 -0
- data/lib/openc3/migrations/20230915000002_no_scope_log_messages.rb +0 -0
- data/lib/openc3/migrations/20231022000000_tlm_viewer_config.rb +0 -0
- data/lib/openc3/migrations/20241208080000_no_critical_cmd.rb +0 -0
- data/lib/openc3/migrations/20241208080001_no_trigger_group.rb +0 -0
- data/lib/openc3/migrations/20250108060000_news_feed.rb +0 -0
- data/lib/openc3/migrations/20250402000000_periodic_only_default.rb +0 -0
- data/lib/openc3/migrations/20260203000000_remove_store_id.rb +0 -0
- data/lib/openc3/migrations/20260204000000_remove_decom_reducer.rb +0 -0
- data/lib/openc3/migrations/20260701000000_updated_at_to_int.rb +0 -0
- data/lib/openc3/migrations/20260704000000_default_bridge.rb +38 -0
- data/lib/openc3/migrations/20260731000000_system_health_json.rb +52 -0
- data/lib/openc3/models/activity_model.rb +0 -0
- data/lib/openc3/models/auth_model.rb +35 -7
- data/lib/openc3/models/bridge_model.rb +133 -0
- data/lib/openc3/models/config_keyword_model.rb +63 -0
- data/lib/openc3/models/cvt_model.rb +5 -5
- data/lib/openc3/models/db_sharded_model.rb +0 -0
- data/lib/openc3/models/environment_model.rb +0 -0
- data/lib/openc3/models/gem_model.rb +13 -10
- data/lib/openc3/models/host_interface_microservice_model.rb +114 -0
- data/lib/openc3/models/info_model.rb +0 -0
- data/lib/openc3/models/interface_model.rb +179 -20
- data/lib/openc3/models/interface_status_model.rb +0 -0
- data/lib/openc3/models/metadata_model.rb +0 -0
- data/lib/openc3/models/metric_model.rb +0 -0
- data/lib/openc3/models/microservice_model.rb +26 -18
- data/lib/openc3/models/microservice_status_model.rb +0 -0
- data/lib/openc3/models/migration_model.rb +0 -0
- data/lib/openc3/models/model.rb +0 -0
- data/lib/openc3/models/news_model.rb +0 -0
- data/lib/openc3/models/note_model.rb +0 -0
- data/lib/openc3/models/offline_access_model.rb +0 -0
- data/lib/openc3/models/ping_model.rb +0 -0
- data/lib/openc3/models/plugin_model.rb +211 -50
- data/lib/openc3/models/plugin_store_model.rb +0 -0
- data/lib/openc3/models/process_status_model.rb +0 -0
- data/lib/openc3/models/python_package_model.rb +211 -15
- data/lib/openc3/models/queue_model.rb +0 -0
- data/lib/openc3/models/reaction_model.rb +0 -0
- data/lib/openc3/models/reingest_job_model.rb +0 -0
- data/lib/openc3/models/router_model.rb +0 -0
- data/lib/openc3/models/router_status_model.rb +0 -0
- data/lib/openc3/models/scope_model.rb +85 -56
- data/lib/openc3/models/script_engine_model.rb +0 -0
- data/lib/openc3/models/script_status_model.rb +0 -0
- data/lib/openc3/models/secret_model.rb +0 -0
- data/lib/openc3/models/setting_model.rb +546 -3
- data/lib/openc3/models/sorted_model.rb +0 -0
- data/lib/openc3/models/stash_model.rb +0 -0
- data/lib/openc3/models/target_model.rb +210 -31
- data/lib/openc3/models/timeline_model.rb +0 -0
- data/lib/openc3/models/tool_config_model.rb +0 -0
- data/lib/openc3/models/tool_model.rb +34 -20
- data/lib/openc3/models/trigger_group_model.rb +0 -0
- data/lib/openc3/models/trigger_model.rb +20 -0
- data/lib/openc3/models/widget_model.rb +0 -0
- data/lib/openc3/operators/microservice_operator.rb +79 -8
- data/lib/openc3/operators/operator.rb +4 -4
- data/lib/openc3/packets/binary_accessor.rb +0 -0
- data/lib/openc3/packets/command_validator.rb +0 -0
- data/lib/openc3/packets/commands.rb +4 -4
- data/lib/openc3/packets/json_packet.rb +0 -0
- data/lib/openc3/packets/limits.rb +15 -7
- data/lib/openc3/packets/limits_response.rb +0 -0
- data/lib/openc3/packets/packet.rb +5 -1
- data/lib/openc3/packets/packet_config.rb +0 -0
- data/lib/openc3/packets/packet_item.rb +0 -0
- data/lib/openc3/packets/packet_item_limits.rb +0 -0
- data/lib/openc3/packets/parsers/format_string_parser.rb +0 -0
- data/lib/openc3/packets/parsers/limits_parser.rb +0 -0
- data/lib/openc3/packets/parsers/limits_response_parser.rb +0 -0
- data/lib/openc3/packets/parsers/packet_item_parser.rb +0 -0
- data/lib/openc3/packets/parsers/packet_parser.rb +0 -0
- data/lib/openc3/packets/parsers/processor_parser.rb +0 -0
- data/lib/openc3/packets/parsers/state_parser.rb +1 -1
- data/lib/openc3/packets/parsers/xtce_converter.rb +183 -103
- data/lib/openc3/packets/parsers/xtce_parser.rb +71 -23
- data/lib/openc3/packets/structure.rb +9 -3
- data/lib/openc3/packets/structure_item.rb +0 -0
- data/lib/openc3/packets/telemetry.rb +3 -3
- data/lib/openc3/processors/processor.rb +2 -0
- data/lib/openc3/processors/statistics_processor.rb +0 -0
- data/lib/openc3/processors/watermark_processor.rb +0 -0
- data/lib/openc3/processors.rb +0 -0
- data/lib/openc3/script/api_shared.rb +0 -0
- data/lib/openc3/script/autonomic.rb +12 -12
- data/lib/openc3/script/calendar.rb +0 -0
- data/lib/openc3/script/commands.rb +1 -1
- data/lib/openc3/script/critical_cmd.rb +0 -0
- data/lib/openc3/script/exceptions.rb +0 -0
- data/lib/openc3/script/extract.rb +20 -25
- data/lib/openc3/script/limits.rb +0 -0
- data/lib/openc3/script/metadata.rb +0 -0
- data/lib/openc3/script/packages.rb +0 -0
- data/lib/openc3/script/plugins.rb +0 -0
- data/lib/openc3/script/queue.rb +0 -0
- data/lib/openc3/script/screen.rb +0 -0
- data/lib/openc3/script/script.rb +2 -2
- data/lib/openc3/script/script_runner.rb +0 -0
- data/lib/openc3/script/storage.rb +4 -4
- data/lib/openc3/script/suite.rb +0 -0
- data/lib/openc3/script/suite_results.rb +0 -0
- data/lib/openc3/script/suite_runner.rb +26 -0
- data/lib/openc3/script/tables.rb +0 -0
- data/lib/openc3/script/telemetry.rb +9 -3
- data/lib/openc3/script/web_socket_api.rb +247 -134
- data/lib/openc3/script.rb +0 -0
- data/lib/openc3/script_engines/script_engine.rb +0 -0
- data/lib/openc3/streams/mqtt_stream.rb +0 -0
- data/lib/openc3/streams/serial_stream.rb +0 -0
- data/lib/openc3/streams/stream.rb +0 -0
- data/lib/openc3/streams/tcpip_client_stream.rb +0 -0
- data/lib/openc3/streams/tcpip_socket_stream.rb +0 -0
- data/lib/openc3/streams/web_socket_client_stream.rb +0 -0
- data/lib/openc3/subpacketizers/subpacketizer.rb +0 -0
- data/lib/openc3/system/system.rb +0 -0
- data/lib/openc3/system/target.rb +0 -0
- data/lib/openc3/system.rb +0 -0
- data/lib/openc3/tools/cmd_tlm_server/api.rb +0 -0
- data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +7 -0
- data/lib/openc3/tools/table_manager/table.rb +0 -0
- data/lib/openc3/tools/table_manager/table_config.rb +0 -0
- data/lib/openc3/tools/table_manager/table_item.rb +0 -0
- data/lib/openc3/tools/table_manager/table_item_parser.rb +0 -0
- data/lib/openc3/tools/table_manager/table_manager_core.rb +0 -0
- data/lib/openc3/tools/table_manager/table_parser.rb +0 -0
- data/lib/openc3/tools/test_runner/test.rb +0 -0
- data/lib/openc3/top_level.rb +1 -1
- data/lib/openc3/topics/autonomic_topic.rb +0 -0
- data/lib/openc3/topics/calendar_topic.rb +0 -0
- data/lib/openc3/topics/command_decom_topic.rb +16 -1
- data/lib/openc3/topics/command_topic.rb +0 -0
- data/lib/openc3/topics/config_topic.rb +0 -0
- data/lib/openc3/topics/decom_interface_topic.rb +2 -1
- data/lib/openc3/topics/interface_topic.rb +8 -2
- data/lib/openc3/topics/limits_event_topic.rb +1 -1
- data/lib/openc3/topics/notebook_topic.rb +0 -0
- data/lib/openc3/topics/queue_topic.rb +0 -0
- data/lib/openc3/topics/router_topic.rb +6 -1
- data/lib/openc3/topics/system_events_topic.rb +0 -0
- data/lib/openc3/topics/telemetry_decom_topic.rb +0 -0
- data/lib/openc3/topics/telemetry_topic.rb +0 -0
- data/lib/openc3/topics/timeline_topic.rb +0 -0
- data/lib/openc3/topics/topic.rb +0 -0
- data/lib/openc3/utilities/authentication.rb +4 -4
- data/lib/openc3/utilities/authorization.rb +0 -0
- data/lib/openc3/utilities/aws_bucket.rb +12 -4
- data/lib/openc3/utilities/bucket.rb +1 -1
- data/lib/openc3/utilities/bucket_file_cache.rb +55 -22
- data/lib/openc3/utilities/bucket_require.rb +0 -0
- data/lib/openc3/utilities/bucket_utilities.rb +3 -4
- data/lib/openc3/utilities/cli_generator.rb +0 -0
- data/lib/openc3/utilities/cmd_log.rb +0 -0
- data/lib/openc3/utilities/config_overlay.rb +75 -0
- data/lib/openc3/utilities/cosmos_rails_formatter.rb +0 -0
- data/lib/openc3/utilities/crc.rb +59 -32
- data/lib/openc3/utilities/csv.rb +5 -5
- data/lib/openc3/utilities/ctrf.rb +0 -0
- data/lib/openc3/utilities/env_helper.rb +0 -0
- data/lib/openc3/utilities/local_bucket.rb +0 -0
- data/lib/openc3/utilities/local_mode.rb +36 -7
- data/lib/openc3/utilities/logger.rb +30 -8
- data/lib/openc3/utilities/message_log.rb +0 -0
- data/lib/openc3/utilities/metric.rb +0 -0
- data/lib/openc3/utilities/migration.rb +0 -0
- data/lib/openc3/utilities/open_telemetry.rb +0 -0
- data/lib/openc3/utilities/process_manager.rb +0 -0
- data/lib/openc3/utilities/pypi_url.rb +0 -0
- data/lib/openc3/utilities/python_proxy.rb +0 -0
- data/lib/openc3/utilities/python_venv.rb +135 -0
- data/lib/openc3/utilities/quaternion.rb +0 -0
- data/lib/openc3/utilities/questdb_client.rb +0 -0
- data/lib/openc3/utilities/redis_secrets.rb +0 -0
- data/lib/openc3/utilities/reingest_job.rb +0 -0
- data/lib/openc3/utilities/ruby_lex_utils.rb +5 -1
- data/lib/openc3/utilities/rubygems_url.rb +39 -0
- data/lib/openc3/utilities/running_script.rb +119 -95
- data/lib/openc3/utilities/s3_autoload.rb +5 -5
- data/lib/openc3/utilities/script.rb +52 -12
- data/lib/openc3/utilities/secrets.rb +48 -3
- data/lib/openc3/utilities/simulated_target.rb +0 -0
- data/lib/openc3/utilities/sleeper.rb +0 -0
- data/lib/openc3/utilities/store.rb +0 -0
- data/lib/openc3/utilities/store_autoload.rb +2 -2
- data/lib/openc3/utilities/store_queued.rb +0 -0
- data/lib/openc3/utilities/target_file.rb +18 -1
- data/lib/openc3/utilities/thread_manager.rb +0 -0
- data/lib/openc3/utilities/throttle.rb +0 -0
- data/lib/openc3/utilities/zip.rb +0 -0
- data/lib/openc3/utilities.rb +0 -0
- data/lib/openc3/version.rb +6 -6
- data/lib/openc3/win32/excel.rb +0 -0
- data/lib/openc3/win32/win32.rb +0 -0
- data/lib/openc3/win32/win32_main.rb +0 -0
- data/lib/openc3.rb +2 -2
- data/tasks/gemfile_stats.rake +0 -0
- data/tasks/spec.rake +0 -0
- data/templates/command_validator/command_validator.py +0 -0
- data/templates/command_validator/command_validator.rb +0 -0
- data/templates/conversion/conversion.py +0 -0
- data/templates/conversion/conversion.rb +0 -0
- data/templates/limits_response/response.py +0 -0
- data/templates/limits_response/response.rb +0 -0
- data/templates/microservice/microservices/TEMPLATE/microservice.py +0 -0
- data/templates/microservice/microservices/TEMPLATE/microservice.rb +0 -0
- data/templates/plugin/.gitignore +0 -0
- data/templates/plugin/LICENSE.md +0 -0
- data/templates/plugin/README.md +0 -0
- data/templates/plugin/Rakefile +0 -0
- data/templates/plugin/plugin.gemspec +1 -1
- data/templates/plugin/plugin.txt +0 -0
- data/templates/processor/processor.py +1 -1
- data/templates/processor/processor.rb +0 -0
- data/templates/target/targets/TARGET/cmd_tlm/cmd.txt +0 -0
- data/templates/target/targets/TARGET/cmd_tlm/tlm.txt +0 -0
- data/templates/target/targets/TARGET/lib/target.py +0 -0
- data/templates/target/targets/TARGET/lib/target.rb +0 -0
- data/templates/target/targets/TARGET/procedures/procedure.py +0 -0
- data/templates/target/targets/TARGET/procedures/procedure.rb +0 -0
- data/templates/target/targets/TARGET/public/README.txt +0 -0
- data/templates/target/targets/TARGET/screens/status.txt +0 -0
- data/templates/target/targets/TARGET/target.txt +0 -0
- data/templates/tool_angular/.editorconfig +0 -0
- data/templates/tool_angular/.gitignore +0 -0
- data/templates/tool_angular/.vscode/extensions.json +0 -0
- data/templates/tool_angular/.vscode/launch.json +0 -0
- data/templates/tool_angular/.vscode/tasks.json +0 -0
- data/templates/tool_angular/angular.json +0 -0
- data/templates/tool_angular/extra-webpack.config.js +0 -0
- data/templates/tool_angular/package.json +2 -2
- data/templates/tool_angular/src/app/app-routing.module.ts +0 -0
- data/templates/tool_angular/src/app/app.component.html +0 -0
- data/templates/tool_angular/src/app/app.component.scss +0 -0
- data/templates/tool_angular/src/app/app.component.spec.ts +0 -0
- data/templates/tool_angular/src/app/app.component.ts +0 -0
- data/templates/tool_angular/src/app/app.module.ts +0 -0
- data/templates/tool_angular/src/app/custom-overlay-container.ts +0 -0
- data/templates/tool_angular/src/app/empty-route/empty-route.component.ts +0 -0
- data/templates/tool_angular/src/app/openc3-api.d.ts +0 -0
- data/templates/tool_angular/src/assets/.gitkeep +0 -0
- data/templates/tool_angular/src/environments/environment.prod.ts +0 -0
- data/templates/tool_angular/src/environments/environment.ts +0 -0
- data/templates/tool_angular/src/favicon.ico +0 -0
- data/templates/tool_angular/src/index.html +0 -0
- data/templates/tool_angular/src/main.single-spa.ts +0 -0
- data/templates/tool_angular/src/single-spa/asset-url.ts +0 -0
- data/templates/tool_angular/src/single-spa/single-spa-props.ts +0 -0
- data/templates/tool_angular/src/styles.scss +0 -0
- data/templates/tool_angular/tsconfig.app.json +0 -0
- data/templates/tool_angular/tsconfig.json +0 -0
- data/templates/tool_angular/tsconfig.spec.json +0 -0
- data/templates/tool_react/.eslintrc +0 -0
- data/templates/tool_react/.gitignore +0 -0
- data/templates/tool_react/.prettierignore +0 -0
- data/templates/tool_react/babel.config.json +0 -0
- data/templates/tool_react/jest.config.js +0 -0
- data/templates/tool_react/package.json +1 -1
- data/templates/tool_react/src/openc3-tool_name.js +0 -0
- data/templates/tool_react/src/root.component.js +0 -0
- data/templates/tool_react/src/root.component.test.js +0 -0
- data/templates/tool_react/webpack.config.js +0 -0
- data/templates/tool_svelte/.gitignore +0 -0
- data/templates/tool_svelte/.prettierignore +0 -0
- data/templates/tool_svelte/.prettierrc.js +0 -0
- data/templates/tool_svelte/babel.config.js +0 -0
- data/templates/tool_svelte/build/smui.css +0 -0
- data/templates/tool_svelte/jest.config.js +0 -0
- data/templates/tool_svelte/package.json +1 -1
- data/templates/tool_svelte/rollup.config.js +0 -0
- data/templates/tool_svelte/src/App.svelte +0 -0
- data/templates/tool_svelte/src/App.test.js +0 -0
- data/templates/tool_svelte/src/theme/_smui-theme.scss +0 -0
- data/templates/tool_svelte/src/tool_name.js +0 -0
- data/templates/tool_vue/.env.standalone +0 -0
- data/templates/tool_vue/.gitignore +0 -0
- data/templates/tool_vue/.prettierrc.cjs +0 -0
- data/templates/tool_vue/eslint.config.mjs +0 -0
- data/templates/tool_vue/jsconfig.json +0 -0
- data/templates/tool_vue/package.json +3 -3
- data/templates/tool_vue/src/App.vue +0 -0
- data/templates/tool_vue/src/main.js +0 -0
- data/templates/tool_vue/src/router.js +0 -0
- data/templates/tool_vue/src/tools/tool_name/tool_name.vue +0 -0
- data/templates/tool_vue/vite.config.js +1 -1
- data/templates/widget/.prettierrc.cjs +0 -0
- data/templates/widget/LICENSE.md +0 -0
- data/templates/widget/Rakefile +0 -0
- data/templates/widget/package.json +2 -2
- data/templates/widget/src/Widget.vue +0 -0
- data/templates/widget/vite.config.js +0 -0
- metadata +40 -11
- data/templates/tool_vue/.nycrc +0 -3
- data/templates/widget/.nycrc +0 -3
|
@@ -20,14 +20,50 @@ module OpenC3
|
|
|
20
20
|
class WebSocketApi
|
|
21
21
|
USER_AGENT = 'OpenC3 / v7 (ruby/openc3/lib/io/web_socket_api)'.freeze
|
|
22
22
|
|
|
23
|
+
# Options every websocket api accepts, and their defaults. Subclasses
|
|
24
|
+
# forward **options rather than restating these.
|
|
25
|
+
DEFAULT_OPTIONS = {
|
|
26
|
+
write_timeout: 10.0,
|
|
27
|
+
read_timeout: 10.0,
|
|
28
|
+
connect_timeout: 5.0,
|
|
29
|
+
authentication: nil,
|
|
30
|
+
}.freeze
|
|
31
|
+
|
|
32
|
+
# Build a cable URL from the standard OPENC3 environment variable quartet:
|
|
33
|
+
# <prefix>_SCHEMA, <prefix>_HOSTNAME, <prefix>_CABLE_PORT, <prefix>_PORT
|
|
34
|
+
def self.cable_url(env_prefix:, default_hostname:, default_port:, path:)
|
|
35
|
+
schema = ENV.fetch("#{env_prefix}_SCHEMA", 'http')
|
|
36
|
+
# Normalize to the websocket schemes (mirrors the Python client). The
|
|
37
|
+
# websocket gem accepts http/https too, but ws/wss is what the URL
|
|
38
|
+
# actually is and Python's websockets library rejects anything else.
|
|
39
|
+
schema = 'ws' if schema == 'http'
|
|
40
|
+
schema = 'wss' if schema == 'https'
|
|
41
|
+
hostname = ENV.fetch("#{env_prefix}_HOSTNAME", nil) || (ENV['OPENC3_DEVEL'] ? '127.0.0.1' : default_hostname)
|
|
42
|
+
port = (ENV.fetch("#{env_prefix}_CABLE_PORT", nil) || ENV.fetch("#{env_prefix}_PORT", default_port)).to_i
|
|
43
|
+
return "#{schema}://#{hostname}:#{port}#{path}"
|
|
44
|
+
end
|
|
45
|
+
|
|
23
46
|
# Create the WebsocketApi object. If a block is given will automatically connect/disconnect
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
47
|
+
#
|
|
48
|
+
# @param url [String] The cable URL to connect to
|
|
49
|
+
# @param scope [String] The scope to connect with
|
|
50
|
+
# @param options [Hash] See DEFAULT_OPTIONS
|
|
51
|
+
def initialize(url:, scope: $openc3_scope, **options, &block)
|
|
52
|
+
# Restore the arity checking that explicit keyword arguments used to give
|
|
53
|
+
# us, so a typo'd option is an error rather than a silently ignored value
|
|
54
|
+
unknown = options.keys - DEFAULT_OPTIONS.keys
|
|
55
|
+
raise ArgumentError, "unknown keyword#{'s' if unknown.length > 1}: #{unknown.join(', ')}" unless unknown.empty?
|
|
56
|
+
|
|
57
|
+
options = DEFAULT_OPTIONS.merge(options)
|
|
58
|
+
# $openc3_scope is only set inside the Script Runner / microservice
|
|
59
|
+
# environment. Fall back to OPENC3_SCOPE (mirrors the Python client) so a
|
|
60
|
+
# bare `ruby script.rb` doesn't send a nil scope that the server rejects.
|
|
61
|
+
@scope = scope || ENV.fetch('OPENC3_SCOPE', 'DEFAULT')
|
|
62
|
+
@authentication = options[:authentication] || generate_auth()
|
|
27
63
|
@url = url
|
|
28
|
-
@write_timeout = write_timeout
|
|
29
|
-
@read_timeout = read_timeout
|
|
30
|
-
@connect_timeout = connect_timeout
|
|
64
|
+
@write_timeout = options[:write_timeout]
|
|
65
|
+
@read_timeout = options[:read_timeout]
|
|
66
|
+
@connect_timeout = options[:connect_timeout]
|
|
31
67
|
@subscribed = false
|
|
32
68
|
if block_given?
|
|
33
69
|
begin
|
|
@@ -55,23 +91,11 @@ module OpenC3
|
|
|
55
91
|
# loops exit cleanly instead of hitting JSON::ParserError on JSON.parse("").
|
|
56
92
|
return nil if message.nil? || message.empty?
|
|
57
93
|
|
|
58
|
-
|
|
59
|
-
json_hash = JSON.parse(message, allow_nan: true, create_additions: true)
|
|
60
|
-
rescue JSON::ParserError
|
|
61
|
-
# Defense-in-depth: treat malformed frames as end-of-stream rather than crashing.
|
|
62
|
-
return nil
|
|
63
|
-
end
|
|
94
|
+
json_hash = parse_message(message)
|
|
64
95
|
if ignore_protocol_messages
|
|
65
96
|
type = json_hash['type']
|
|
66
97
|
if type # ping, welcome, confirm_subscription, reject_subscription, disconnect
|
|
67
|
-
|
|
68
|
-
if json_hash['reason'] == 'unauthorized'
|
|
69
|
-
raise "Unauthorized"
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
if type == 'reject_subscription'
|
|
73
|
-
raise "Subscription Rejected"
|
|
74
|
-
end
|
|
98
|
+
check_protocol_frame(json_hash)
|
|
75
99
|
if timeout
|
|
76
100
|
end_time = Time.now
|
|
77
101
|
if (end_time - start_time) > timeout
|
|
@@ -95,32 +119,51 @@ module OpenC3
|
|
|
95
119
|
# ApplicationCable::Channel#authenticate_subscription! — ActionCable
|
|
96
120
|
# ignores `data` on `subscribe` commands.
|
|
97
121
|
@identifier['token'] = @authentication.token(include_bearer: false)
|
|
98
|
-
|
|
99
|
-
json_hash['command'] = 'subscribe'
|
|
100
|
-
json_hash['identifier'] = JSON.generate(@identifier, allow_nan: true)
|
|
101
|
-
@stream.write(JSON.generate(json_hash, allow_nan: true))
|
|
122
|
+
write_command('subscribe')
|
|
102
123
|
@subscribed = true
|
|
124
|
+
wait_for_subscribed()
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Block until the server confirms the subscription. ActionCable / anycable-go
|
|
129
|
+
# process 'subscribe' and 'message' commands as independent RPCs, so an action
|
|
130
|
+
# (add/remove) written immediately after subscribe can reach
|
|
131
|
+
# StreamingChannel#add before the subscription's broadcaster exists, where it
|
|
132
|
+
# is silently dropped (a no-op) and no data ever streams. Waiting for
|
|
133
|
+
# confirm_subscription guarantees the broadcaster is ready before any action
|
|
134
|
+
# is written.
|
|
135
|
+
def wait_for_subscribed
|
|
136
|
+
while true
|
|
137
|
+
message = @stream.read
|
|
138
|
+
# Unlike #read, end-of-stream is fatal here rather than a nil return:
|
|
139
|
+
# a socket that closes mid-handshake leaves nothing to carry on with.
|
|
140
|
+
raise "WebSocket closed before subscription was confirmed" if message.nil? || message.empty?
|
|
141
|
+
|
|
142
|
+
json_hash = parse_message(message)
|
|
143
|
+
check_protocol_frame(json_hash)
|
|
144
|
+
# Ignore welcome / ping and keep waiting for confirmation
|
|
145
|
+
return if json_hash['type'] == 'confirm_subscription'
|
|
103
146
|
end
|
|
104
147
|
end
|
|
105
148
|
|
|
106
149
|
# Will unsubscribe to the channel based on @identifier
|
|
107
150
|
def unsubscribe
|
|
108
151
|
if @subscribed
|
|
109
|
-
|
|
110
|
-
json_hash['command'] = 'unsubscribe'
|
|
111
|
-
json_hash['identifier'] = JSON.generate(@identifier, allow_nan: true)
|
|
112
|
-
@stream.write(JSON.generate(json_hash, allow_nan: true))
|
|
152
|
+
write_command('unsubscribe')
|
|
113
153
|
@subscribed = false
|
|
114
154
|
end
|
|
115
155
|
end
|
|
116
156
|
|
|
117
157
|
# Send an ActionCable command
|
|
118
158
|
def write_action(data_hash)
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
159
|
+
# Subscribe first so the token is present in @identifier before we
|
|
160
|
+
# serialize it below. ActionCable matches a 'message' command to its
|
|
161
|
+
# subscription by the exact identifier string; if subscribe() injected the
|
|
162
|
+
# token only afterward, the message identifier (no token) would not match
|
|
163
|
+
# the subscription identifier (with token) and the server would silently
|
|
164
|
+
# ignore the action.
|
|
165
|
+
subscribe()
|
|
166
|
+
write_command('message', data_hash)
|
|
124
167
|
end
|
|
125
168
|
|
|
126
169
|
# General write to the websocket
|
|
@@ -158,12 +201,49 @@ module OpenC3
|
|
|
158
201
|
rescue
|
|
159
202
|
# Oh well, we tried
|
|
160
203
|
end
|
|
204
|
+
# unsubscribe only clears this after a successful write. The stream is
|
|
205
|
+
# being closed regardless, so it cannot remain subscribed.
|
|
206
|
+
@subscribed = false
|
|
161
207
|
@stream.disconnect
|
|
208
|
+
else
|
|
209
|
+
@subscribed = false
|
|
162
210
|
end
|
|
163
211
|
end
|
|
164
212
|
|
|
165
213
|
# private
|
|
166
214
|
|
|
215
|
+
# Write an ActionCable command frame for the current @identifier. Writes
|
|
216
|
+
# straight to the stream because the callers have already subscribed (and
|
|
217
|
+
# subscribe itself must not recurse through write).
|
|
218
|
+
def write_command(command, data_hash = nil)
|
|
219
|
+
json_hash = {}
|
|
220
|
+
json_hash['command'] = command
|
|
221
|
+
json_hash['identifier'] = JSON.generate(@identifier, allow_nan: true)
|
|
222
|
+
json_hash['data'] = JSON.generate(data_hash, allow_nan: true) if data_hash
|
|
223
|
+
@stream.write(JSON.generate(json_hash, allow_nan: true))
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Parse a server frame. Kept in one place so the JSON options cannot drift
|
|
227
|
+
# between the two readers.
|
|
228
|
+
def parse_message(message)
|
|
229
|
+
return JSON.parse(message, allow_nan: true, create_additions: true)
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# Apply the protocol rules shared by #read and #wait_for_subscribed
|
|
233
|
+
def check_protocol_frame(json_hash)
|
|
234
|
+
case json_hash['type']
|
|
235
|
+
when 'reject_subscription'
|
|
236
|
+
raise "Subscription Rejected"
|
|
237
|
+
when 'disconnect'
|
|
238
|
+
# Any other disconnect reason is not fatal; the caller keeps reading
|
|
239
|
+
raise "Unauthorized" if json_hash['reason'] == 'unauthorized'
|
|
240
|
+
else
|
|
241
|
+
# ping, welcome, confirm_subscription and anything new the server adds
|
|
242
|
+
# are informational only
|
|
243
|
+
nil
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
|
|
167
247
|
# Generate the appropriate token for OpenC3
|
|
168
248
|
def generate_auth
|
|
169
249
|
if ENV['OPENC3_API_TOKEN'].nil? and ENV['OPENC3_API_USER'].nil?
|
|
@@ -178,62 +258,119 @@ module OpenC3
|
|
|
178
258
|
end
|
|
179
259
|
end
|
|
180
260
|
|
|
261
|
+
# Identifier for channels whose only parameter is the event history count.
|
|
262
|
+
# Including classes supply the channel name as a CHANNEL constant.
|
|
263
|
+
module HistoryCountIdentifier
|
|
264
|
+
def initialize(history_count: 0, **options)
|
|
265
|
+
@identifier = {
|
|
266
|
+
channel: self.class::CHANNEL,
|
|
267
|
+
history_count: history_count
|
|
268
|
+
}
|
|
269
|
+
super(**options)
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
181
273
|
# Base class for cmd-tlm-api websockets - Do not use directly
|
|
182
274
|
class CmdTlmWebSocketApi < WebSocketApi
|
|
183
|
-
def initialize(url: nil,
|
|
275
|
+
def initialize(url: nil, **options)
|
|
184
276
|
url = generate_url() unless url
|
|
185
|
-
super(url: url,
|
|
277
|
+
super(url: url, **options)
|
|
186
278
|
end
|
|
187
279
|
|
|
188
280
|
def generate_url
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
281
|
+
return WebSocketApi.cable_url(
|
|
282
|
+
env_prefix: 'OPENC3_API',
|
|
283
|
+
default_hostname: 'openc3-cosmos-cmd-tlm-api',
|
|
284
|
+
default_port: '3901',
|
|
285
|
+
path: '/openc3-api/cable'
|
|
286
|
+
)
|
|
194
287
|
end
|
|
195
288
|
end
|
|
196
289
|
|
|
197
290
|
# Base class for script-runner-api websockets - Do not use directly
|
|
198
291
|
class ScriptWebSocketApi < WebSocketApi
|
|
199
|
-
def initialize(url: nil,
|
|
292
|
+
def initialize(url: nil, **options)
|
|
200
293
|
url = generate_url() unless url
|
|
201
|
-
super(url: url,
|
|
294
|
+
super(url: url, **options)
|
|
202
295
|
end
|
|
203
296
|
|
|
204
297
|
def generate_url
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
298
|
+
return WebSocketApi.cable_url(
|
|
299
|
+
env_prefix: 'OPENC3_SCRIPT_API',
|
|
300
|
+
default_hostname: 'openc3-cosmos-script-runner-api',
|
|
301
|
+
default_port: '3902',
|
|
302
|
+
path: '/script-api/cable'
|
|
303
|
+
)
|
|
210
304
|
end
|
|
211
305
|
end
|
|
212
306
|
|
|
213
307
|
# Running Script WebSocket
|
|
214
308
|
class RunningScriptWebSocketApi < ScriptWebSocketApi
|
|
215
|
-
def initialize(id:,
|
|
309
|
+
def initialize(id:, **options)
|
|
310
|
+
@pending_events = []
|
|
216
311
|
@identifier = {
|
|
217
312
|
channel: "RunningScriptChannel",
|
|
218
313
|
id: id
|
|
219
314
|
}
|
|
220
|
-
super(
|
|
315
|
+
super(**options)
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
# The backlog of script events is transmitted with the subscription
|
|
319
|
+
# confirmation, but LIVE events only flow once the client reports that it is
|
|
320
|
+
# ready to stream events (see RunningScriptChannel#ready) -- a broadcast sent
|
|
321
|
+
# before the gateway has registered this subscription's stream would be
|
|
322
|
+
# silently dropped. subscribe() blocks until confirm_subscription, so the
|
|
323
|
+
# 'ready' action is guaranteed to arrive after the stream is registered.
|
|
324
|
+
def subscribe
|
|
325
|
+
was_subscribed = @subscribed
|
|
326
|
+
super
|
|
327
|
+
write_action({ 'action' => 'ready' }) unless was_subscribed
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
# RunningScriptChannel batches events to reduce ActionCable frame and
|
|
331
|
+
# client-dispatch overhead. Preserve the public API's historical contract:
|
|
332
|
+
# callers still receive one script event from each read.
|
|
333
|
+
def read(ignore_protocol_messages: true, timeout: nil)
|
|
334
|
+
return @pending_events.shift unless @pending_events.empty?
|
|
335
|
+
|
|
336
|
+
loop do
|
|
337
|
+
message = super
|
|
338
|
+
return message unless message.is_a?(Array)
|
|
339
|
+
|
|
340
|
+
@pending_events.concat(message)
|
|
341
|
+
return @pending_events.shift unless @pending_events.empty?
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
def connect
|
|
346
|
+
@pending_events.clear
|
|
347
|
+
super
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
def unsubscribe
|
|
351
|
+
@pending_events.clear
|
|
352
|
+
super
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
def disconnect
|
|
356
|
+
@pending_events.clear
|
|
357
|
+
super
|
|
221
358
|
end
|
|
222
359
|
end
|
|
223
360
|
|
|
224
361
|
# All Scripts WebSocket
|
|
225
362
|
class AllScriptsWebSocketApi < ScriptWebSocketApi
|
|
226
|
-
def initialize(
|
|
363
|
+
def initialize(**options)
|
|
227
364
|
@identifier = {
|
|
228
365
|
channel: "AllScriptsChannel",
|
|
229
366
|
}
|
|
230
|
-
super(
|
|
367
|
+
super(**options)
|
|
231
368
|
end
|
|
232
369
|
end
|
|
233
370
|
|
|
234
371
|
# Log Messages WebSocket
|
|
235
372
|
class MessagesWebSocketApi < CmdTlmWebSocketApi
|
|
236
|
-
def initialize(history_count: 0, start_time: nil, end_time: nil, level: nil, types: nil,
|
|
373
|
+
def initialize(history_count: 0, start_time: nil, end_time: nil, level: nil, types: nil, **options)
|
|
237
374
|
@identifier = {
|
|
238
375
|
channel: "MessagesChannel",
|
|
239
376
|
history_count: history_count
|
|
@@ -242,94 +379,59 @@ module OpenC3
|
|
|
242
379
|
@identifier['end_time'] = end_time if end_time
|
|
243
380
|
@identifier['level'] = level if level
|
|
244
381
|
@identifier['types'] = types if types
|
|
245
|
-
super(
|
|
382
|
+
super(**options)
|
|
246
383
|
end
|
|
247
384
|
end
|
|
248
385
|
|
|
249
386
|
# Autonomic Events WebSocket (Enterprise Only)
|
|
250
387
|
class AutonomicEventsWebSocketApi < CmdTlmWebSocketApi
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
channel: "AutonomicEventsChannel",
|
|
254
|
-
history_count: history_count
|
|
255
|
-
}
|
|
256
|
-
super(url: url, write_timeout: write_timeout, read_timeout: read_timeout, connect_timeout: connect_timeout, authentication: authentication, scope: scope)
|
|
257
|
-
end
|
|
388
|
+
CHANNEL = 'AutonomicEventsChannel'.freeze
|
|
389
|
+
include HistoryCountIdentifier
|
|
258
390
|
end
|
|
259
391
|
|
|
260
392
|
# Calendar Events WebSocket (Enterprise Only)
|
|
261
393
|
class CalendarEventsWebSocketApi < CmdTlmWebSocketApi
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
channel: "CalendarEventsChannel",
|
|
265
|
-
history_count: history_count
|
|
266
|
-
}
|
|
267
|
-
super(url: url, write_timeout: write_timeout, read_timeout: read_timeout, connect_timeout: connect_timeout, authentication: authentication, scope: scope)
|
|
268
|
-
end
|
|
394
|
+
CHANNEL = 'CalendarEventsChannel'.freeze
|
|
395
|
+
include HistoryCountIdentifier
|
|
269
396
|
end
|
|
270
397
|
|
|
271
398
|
# Config Events WebSocket
|
|
272
399
|
class ConfigEventsWebSocketApi < CmdTlmWebSocketApi
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
channel: "ConfigEventsChannel",
|
|
276
|
-
history_count: history_count
|
|
277
|
-
}
|
|
278
|
-
super(url: url, write_timeout: write_timeout, read_timeout: read_timeout, connect_timeout: connect_timeout, authentication: authentication, scope: scope)
|
|
279
|
-
end
|
|
400
|
+
CHANNEL = 'ConfigEventsChannel'.freeze
|
|
401
|
+
include HistoryCountIdentifier
|
|
280
402
|
end
|
|
281
403
|
|
|
282
404
|
# Limits Events WebSocket
|
|
283
405
|
class LimitsEventsWebSocketApi < CmdTlmWebSocketApi
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
channel: "LimitsEventsChannel",
|
|
287
|
-
history_count: history_count
|
|
288
|
-
}
|
|
289
|
-
super(url: url, write_timeout: write_timeout, read_timeout: read_timeout, connect_timeout: connect_timeout, authentication: authentication, scope: scope)
|
|
290
|
-
end
|
|
406
|
+
CHANNEL = 'LimitsEventsChannel'.freeze
|
|
407
|
+
include HistoryCountIdentifier
|
|
291
408
|
end
|
|
292
409
|
|
|
293
410
|
# System Events WebSocket
|
|
294
411
|
class SystemEventsWebSocketApi < CmdTlmWebSocketApi
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
channel: "SystemEventsChannel",
|
|
298
|
-
history_count: history_count
|
|
299
|
-
}
|
|
300
|
-
super(url: url, write_timeout: write_timeout, read_timeout: read_timeout, connect_timeout: connect_timeout, authentication: authentication, scope: scope)
|
|
301
|
-
end
|
|
412
|
+
CHANNEL = 'SystemEventsChannel'.freeze
|
|
413
|
+
include HistoryCountIdentifier
|
|
302
414
|
end
|
|
303
415
|
|
|
304
416
|
# Timeline WebSocket
|
|
305
417
|
class TimelineEventsWebSocketApi < CmdTlmWebSocketApi
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
channel: "TimelineEventsChannel",
|
|
309
|
-
history_count: history_count
|
|
310
|
-
}
|
|
311
|
-
super(url: url, write_timeout: write_timeout, read_timeout: read_timeout, connect_timeout: connect_timeout, authentication: authentication, scope: scope)
|
|
312
|
-
end
|
|
418
|
+
CHANNEL = 'TimelineEventsChannel'.freeze
|
|
419
|
+
include HistoryCountIdentifier
|
|
313
420
|
end
|
|
314
421
|
|
|
315
422
|
# Queue WebSocket
|
|
316
423
|
class QueueEventsWebSocketApi < CmdTlmWebSocketApi
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
channel: "QueueEventsChannel",
|
|
320
|
-
history_count: history_count
|
|
321
|
-
}
|
|
322
|
-
super(url: url, write_timeout: write_timeout, read_timeout: read_timeout, connect_timeout: connect_timeout, authentication: authentication, scope: scope)
|
|
323
|
-
end
|
|
424
|
+
CHANNEL = 'QueueEventsChannel'.freeze
|
|
425
|
+
include HistoryCountIdentifier
|
|
324
426
|
end
|
|
325
427
|
|
|
326
428
|
# Streaming API WebSocket
|
|
327
429
|
class StreamingWebSocketApi < CmdTlmWebSocketApi
|
|
328
|
-
def initialize(
|
|
430
|
+
def initialize(**options)
|
|
329
431
|
@identifier = {
|
|
330
432
|
channel: "StreamingChannel"
|
|
331
433
|
}
|
|
332
|
-
super(
|
|
434
|
+
super(**options)
|
|
333
435
|
end
|
|
334
436
|
|
|
335
437
|
# Request to add data to the stream
|
|
@@ -354,26 +456,11 @@ module OpenC3
|
|
|
354
456
|
# PACKET - Packet name
|
|
355
457
|
# VALUETYPE - RAW, CONVERTED, FORMATTED, or PURE (pure means all types as stored in log)
|
|
356
458
|
#
|
|
357
|
-
def add(items: nil, packets: nil, start_time: nil, end_time: nil, scope:
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
if
|
|
361
|
-
|
|
362
|
-
start_time = start_time.to_nsec_from_epoch
|
|
363
|
-
end
|
|
364
|
-
data_hash['start_time'] = start_time
|
|
365
|
-
end
|
|
366
|
-
if end_time
|
|
367
|
-
if Time === end_time
|
|
368
|
-
end_time = end_time.to_nsec_from_epoch
|
|
369
|
-
end
|
|
370
|
-
data_hash['end_time'] = end_time
|
|
371
|
-
end
|
|
372
|
-
data_hash['items'] = items if items
|
|
373
|
-
data_hash['packets'] = packets if packets
|
|
374
|
-
data_hash['scope'] = scope
|
|
375
|
-
data_hash['token'] = @authentication.token(include_bearer: false)
|
|
376
|
-
write_action(data_hash)
|
|
459
|
+
def add(items: nil, packets: nil, start_time: nil, end_time: nil, scope: nil)
|
|
460
|
+
times = {}
|
|
461
|
+
times['start_time'] = to_nsec(start_time) if start_time
|
|
462
|
+
times['end_time'] = to_nsec(end_time) if end_time
|
|
463
|
+
stream_action('add', items: items, packets: packets, scope: scope, extra: times)
|
|
377
464
|
end
|
|
378
465
|
|
|
379
466
|
# Request to remove data from the stream
|
|
@@ -395,26 +482,32 @@ module OpenC3
|
|
|
395
482
|
# PACKET - Packet name
|
|
396
483
|
# VALUETYPE - RAW, CONVERTED, FORMATTED, or PURE (pure means all types as stored in log)
|
|
397
484
|
#
|
|
398
|
-
def remove(items: nil, packets: nil, scope:
|
|
399
|
-
|
|
400
|
-
data_hash['action'] = 'remove'
|
|
401
|
-
data_hash['items'] = items if items
|
|
402
|
-
data_hash['packets'] = packets if packets
|
|
403
|
-
data_hash['scope'] = scope
|
|
404
|
-
data_hash['token'] = @authentication.token(include_bearer: false)
|
|
405
|
-
write_action(data_hash)
|
|
485
|
+
def remove(items: nil, packets: nil, scope: nil)
|
|
486
|
+
stream_action('remove', items: items, packets: packets, scope: scope)
|
|
406
487
|
end
|
|
407
488
|
|
|
408
489
|
# Convenience method to read all data until end marker is received.
|
|
490
|
+
# Omitting end_time streams realtime and endlessly: no end marker is ever
|
|
491
|
+
# sent, so a timeout is the only way the collection ends on its own.
|
|
409
492
|
# Warning: DATA IS STORED IN RAM. Do not use this with large queries
|
|
410
|
-
def self.read_all(items: nil, packets: nil, start_time: nil, end_time
|
|
493
|
+
def self.read_all(items: nil, packets: nil, start_time: nil, end_time: nil, scope: nil, timeout: nil)
|
|
411
494
|
read_all_start_time = Time.now
|
|
412
495
|
data = []
|
|
413
496
|
self.new do |api|
|
|
414
497
|
api.add(items: items, packets: packets, start_time: start_time, end_time: end_time, scope: scope)
|
|
415
498
|
while true
|
|
416
499
|
batch = api.read
|
|
417
|
-
if batch.
|
|
500
|
+
if batch.nil?
|
|
501
|
+
# A bounded query must receive its end marker; a truncated result
|
|
502
|
+
# returned as if complete is worse than an error. A realtime query
|
|
503
|
+
# never gets one, so a close is an ordinary way for it to end.
|
|
504
|
+
raise "WebSocket closed before end marker" if end_time
|
|
505
|
+
|
|
506
|
+
return data
|
|
507
|
+
end
|
|
508
|
+
# An empty batch is the explicit end marker sent after a historical
|
|
509
|
+
# query is complete.
|
|
510
|
+
if batch.empty?
|
|
418
511
|
return data
|
|
419
512
|
else
|
|
420
513
|
data.concat(batch)
|
|
@@ -427,6 +520,26 @@ module OpenC3
|
|
|
427
520
|
end
|
|
428
521
|
end
|
|
429
522
|
end
|
|
523
|
+
|
|
524
|
+
# private
|
|
525
|
+
|
|
526
|
+
# Accept either a Time or an already converted 64-bit nanosecond value
|
|
527
|
+
def to_nsec(value)
|
|
528
|
+
return Time === value ? value.to_nsec_from_epoch : value
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
# Build and write a StreamingChannel action. extra carries action specific
|
|
532
|
+
# keys (the times for 'add') and is merged first to preserve wire ordering.
|
|
533
|
+
def stream_action(action, items:, packets:, scope:, extra: {})
|
|
534
|
+
data_hash = {}
|
|
535
|
+
data_hash['action'] = action
|
|
536
|
+
data_hash.merge!(extra)
|
|
537
|
+
data_hash['items'] = items if items
|
|
538
|
+
data_hash['packets'] = packets if packets
|
|
539
|
+
data_hash['scope'] = scope || @scope
|
|
540
|
+
data_hash['token'] = @authentication.token(include_bearer: false)
|
|
541
|
+
write_action(data_hash)
|
|
542
|
+
end
|
|
430
543
|
end
|
|
431
544
|
end
|
|
432
545
|
|
data/lib/openc3/script.rb
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
data/lib/openc3/system/system.rb
CHANGED
|
File without changes
|
data/lib/openc3/system/target.rb
CHANGED
|
File without changes
|
data/lib/openc3/system.rb
CHANGED
|
File without changes
|
|
File without changes
|
|
@@ -253,6 +253,13 @@ module OpenC3
|
|
|
253
253
|
|
|
254
254
|
def connect
|
|
255
255
|
Logger.info "Connecting to #{@interface.name}..."
|
|
256
|
+
# Interface connect implementations typically overwrite their stream / socket
|
|
257
|
+
# so cleanly close any existing connection rather than leaking it
|
|
258
|
+
begin
|
|
259
|
+
@interface.disconnect if @interface.connected?
|
|
260
|
+
rescue => err
|
|
261
|
+
Logger.error "Disconnect: #{@interface.name}: #{err.formatted}"
|
|
262
|
+
end
|
|
256
263
|
@interface.connect
|
|
257
264
|
if @connection_success_callback
|
|
258
265
|
@connection_success_callback.call
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
data/lib/openc3/top_level.rb
CHANGED
|
@@ -503,7 +503,7 @@ end
|
|
|
503
503
|
# New plugins should only use openc3 paths and module OpenC3
|
|
504
504
|
unless ENV['OPENC3_NO_COSMOS_COMPATIBILITY']
|
|
505
505
|
Cosmos = OpenC3
|
|
506
|
-
ENV['COSMOS_SCOPE'] = ENV
|
|
506
|
+
ENV['COSMOS_SCOPE'] = ENV.fetch('OPENC3_SCOPE', 'DEFAULT')
|
|
507
507
|
|
|
508
508
|
# Don't apply the compatibility layer in test environments to avoid conflicts with RSpec
|
|
509
509
|
unless defined?(RSpec) || ENV['RAILS_ENV'] == 'test' || ENV['RACK_ENV'] == 'test'
|
|
File without changes
|
|
File without changes
|
|
@@ -30,13 +30,28 @@ module OpenC3
|
|
|
30
30
|
received_count: packet.received_count }
|
|
31
31
|
# Read all RAW values at once - optimized by accessor
|
|
32
32
|
json_hash = packet.read_items(packet.sorted_items)
|
|
33
|
+
# Items with a write conversion have already been transformed by the time the
|
|
34
|
+
# value lands in the buffer, so reading the buffer back does not recover what
|
|
35
|
+
# the user actually commanded. Use the given values (as passed to build_cmd)
|
|
36
|
+
# for those items. State items are the exception: the user can give either the
|
|
37
|
+
# state name or the state value, so they always read from the buffer to log the
|
|
38
|
+
# normalized state name. Raw commands bypass the write conversions entirely so
|
|
39
|
+
# their given values are raw and must not be logged as converted.
|
|
40
|
+
given_values = packet.raw ? nil : packet.given_values
|
|
41
|
+
given_values = given_values.transform_keys { |key| key.to_s.upcase } if given_values
|
|
33
42
|
# Read additional value types using given_raw to avoid re-reading from buffer
|
|
34
43
|
packet.sorted_items.each do |item|
|
|
35
44
|
if item.hidden
|
|
36
45
|
json_hash.delete(item.name)
|
|
37
46
|
else
|
|
38
47
|
given_raw = json_hash[item.name]
|
|
39
|
-
|
|
48
|
+
if item.write_conversion or item.states
|
|
49
|
+
if item.write_conversion and !item.states and given_values and given_values.key?(item.name)
|
|
50
|
+
json_hash[item.name + "__C"] = given_values[item.name]
|
|
51
|
+
else
|
|
52
|
+
json_hash[item.name + "__C"] = packet.read_item(item, :CONVERTED, packet.buffer, given_raw)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
40
55
|
json_hash[item.name + "__F"] = packet.read_item(item, :FORMATTED, packet.buffer, given_raw) if item.format_string
|
|
41
56
|
end
|
|
42
57
|
end
|
|
File without changes
|