openc3 6.10.4 → 7.0.0.pre.rc2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (350) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -1
  3. data/Guardfile +4 -9
  4. data/LICENSE.md +85 -0
  5. data/README.md +8 -8
  6. data/Rakefile +3 -9
  7. data/bin/cstol_converter +3 -8
  8. data/bin/openc3cli +64 -35
  9. data/data/config/command_modifiers.yaml +18 -1
  10. data/data/config/interface_modifiers.yaml +0 -2
  11. data/data/config/plugins.yaml +14 -18
  12. data/data/config/screen.yaml +1 -1
  13. data/data/config/target.yaml +26 -79
  14. data/data/config/telemetry_modifiers.yaml +15 -0
  15. data/data/config/widgets.yaml +32 -32
  16. data/ext/openc3/ext/array/array.c +4 -9
  17. data/ext/openc3/ext/buffered_file/buffered_file.c +4 -9
  18. data/ext/openc3/ext/burst_protocol/burst_protocol.c +3 -8
  19. data/ext/openc3/ext/config_parser/config_parser.c +2 -7
  20. data/ext/openc3/ext/crc/crc.c +3 -8
  21. data/ext/openc3/ext/openc3_io/openc3_io.c +4 -9
  22. data/ext/openc3/ext/packet/packet.c +7 -9
  23. data/ext/openc3/ext/platform/platform.c +3 -8
  24. data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +16 -12
  25. data/ext/openc3/ext/string/string.c +4 -9
  26. data/ext/openc3/ext/structure/structure.c +5 -9
  27. data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +4 -9
  28. data/ext/openc3/ext/telemetry/telemetry.c +8 -12
  29. data/lib/cosmos.rb +4 -9
  30. data/lib/cosmosc2.rb +4 -9
  31. data/lib/openc3/accessors/accessor.rb +10 -13
  32. data/lib/openc3/accessors/binary_accessor.rb +18 -17
  33. data/lib/openc3/accessors/cbor_accessor.rb +3 -8
  34. data/lib/openc3/accessors/form_accessor.rb +4 -9
  35. data/lib/openc3/accessors/html_accessor.rb +3 -8
  36. data/lib/openc3/accessors/http_accessor.rb +4 -9
  37. data/lib/openc3/accessors/json_accessor.rb +4 -9
  38. data/lib/openc3/accessors/template_accessor.rb +4 -9
  39. data/lib/openc3/accessors/xml_accessor.rb +4 -9
  40. data/lib/openc3/accessors.rb +3 -8
  41. data/lib/openc3/api/README.md +1 -1
  42. data/lib/openc3/api/api.rb +3 -8
  43. data/lib/openc3/api/authorized_api.rb +4 -9
  44. data/lib/openc3/api/cmd_api.rb +3 -8
  45. data/lib/openc3/api/config_api.rb +3 -8
  46. data/lib/openc3/api/interface_api.rb +4 -9
  47. data/lib/openc3/api/limits_api.rb +3 -8
  48. data/lib/openc3/api/metrics_api.rb +2 -19
  49. data/lib/openc3/api/offline_access_api.rb +2 -7
  50. data/lib/openc3/api/router_api.rb +5 -10
  51. data/lib/openc3/api/settings_api.rb +3 -8
  52. data/lib/openc3/api/stash_api.rb +2 -7
  53. data/lib/openc3/api/target_api.rb +3 -8
  54. data/lib/openc3/api/tlm_api.rb +15 -38
  55. data/lib/openc3/bridge/bridge.rb +3 -8
  56. data/lib/openc3/bridge/bridge_config.rb +5 -10
  57. data/lib/openc3/bridge/bridge_interface_thread.rb +4 -9
  58. data/lib/openc3/bridge/bridge_router_thread.rb +4 -9
  59. data/lib/openc3/ccsds/ccsds_packet.rb +4 -9
  60. data/lib/openc3/ccsds/ccsds_parser.rb +3 -8
  61. data/lib/openc3/config/config_parser.rb +3 -8
  62. data/lib/openc3/config/meta_config_parser.rb +3 -8
  63. data/lib/openc3/conversions/bit_reverse_conversion.rb +3 -8
  64. data/lib/openc3/conversions/conversion.rb +3 -8
  65. data/lib/openc3/conversions/generic_conversion.rb +3 -8
  66. data/lib/openc3/conversions/ip_read_conversion.rb +3 -8
  67. data/lib/openc3/conversions/ip_write_conversion.rb +3 -8
  68. data/lib/openc3/conversions/object_read_conversion.rb +3 -8
  69. data/lib/openc3/conversions/object_write_conversion.rb +3 -8
  70. data/lib/openc3/conversions/packet_time_formatted_conversion.rb +4 -9
  71. data/lib/openc3/conversions/packet_time_seconds_conversion.rb +4 -9
  72. data/lib/openc3/conversions/polynomial_conversion.rb +6 -8
  73. data/lib/openc3/conversions/processor_conversion.rb +3 -8
  74. data/lib/openc3/conversions/received_count_conversion.rb +4 -9
  75. data/lib/openc3/conversions/received_time_formatted_conversion.rb +4 -9
  76. data/lib/openc3/conversions/received_time_seconds_conversion.rb +4 -9
  77. data/lib/openc3/conversions/segmented_polynomial_conversion.rb +6 -8
  78. data/lib/openc3/conversions/unix_time_conversion.rb +3 -8
  79. data/lib/openc3/conversions/unix_time_formatted_conversion.rb +3 -8
  80. data/lib/openc3/conversions/unix_time_seconds_conversion.rb +3 -8
  81. data/lib/openc3/conversions.rb +3 -8
  82. data/lib/openc3/core_ext/array.rb +3 -8
  83. data/lib/openc3/core_ext/binding.rb +4 -9
  84. data/lib/openc3/core_ext/class.rb +4 -9
  85. data/lib/openc3/core_ext/exception.rb +3 -8
  86. data/lib/openc3/core_ext/file.rb +4 -9
  87. data/lib/openc3/core_ext/io.rb +4 -9
  88. data/lib/openc3/core_ext/kernel.rb +3 -8
  89. data/lib/openc3/core_ext/math.rb +4 -9
  90. data/lib/openc3/core_ext/matrix.rb +4 -9
  91. data/lib/openc3/core_ext/objectspace.rb +4 -9
  92. data/lib/openc3/core_ext/openc3_io.rb +4 -9
  93. data/lib/openc3/core_ext/range.rb +4 -9
  94. data/lib/openc3/core_ext/socket.rb +4 -9
  95. data/lib/openc3/core_ext/string.rb +3 -8
  96. data/lib/openc3/core_ext/stringio.rb +4 -9
  97. data/lib/openc3/core_ext/tempfile.rb +4 -9
  98. data/lib/openc3/core_ext/time.rb +3 -8
  99. data/lib/openc3/core_ext.rb +3 -8
  100. data/lib/openc3/interfaces/file_interface.rb +3 -8
  101. data/lib/openc3/interfaces/http_client_interface.rb +3 -8
  102. data/lib/openc3/interfaces/http_server_interface.rb +3 -8
  103. data/lib/openc3/interfaces/interface.rb +3 -8
  104. data/lib/openc3/interfaces/mqtt_interface.rb +3 -8
  105. data/lib/openc3/interfaces/mqtt_stream_interface.rb +3 -8
  106. data/lib/openc3/interfaces/protocols/burst_protocol.rb +3 -8
  107. data/lib/openc3/interfaces/protocols/cmd_response_protocol.rb +3 -8
  108. data/lib/openc3/interfaces/protocols/cobs_protocol.rb +3 -8
  109. data/lib/openc3/interfaces/protocols/crc_protocol.rb +3 -8
  110. data/lib/openc3/interfaces/protocols/fixed_protocol.rb +3 -8
  111. data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +3 -8
  112. data/lib/openc3/interfaces/protocols/length_protocol.rb +3 -8
  113. data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +3 -8
  114. data/lib/openc3/interfaces/protocols/protocol.rb +3 -8
  115. data/lib/openc3/interfaces/protocols/slip_protocol.rb +3 -8
  116. data/lib/openc3/interfaces/protocols/template_protocol.rb +3 -8
  117. data/lib/openc3/interfaces/protocols/terminated_protocol.rb +3 -8
  118. data/lib/openc3/interfaces/serial_interface.rb +3 -8
  119. data/lib/openc3/interfaces/simulated_target_interface.rb +3 -8
  120. data/lib/openc3/interfaces/stream_interface.rb +3 -8
  121. data/lib/openc3/interfaces/tcpip_client_interface.rb +3 -8
  122. data/lib/openc3/interfaces/tcpip_server_interface.rb +3 -8
  123. data/lib/openc3/interfaces/udp_interface.rb +3 -8
  124. data/lib/openc3/interfaces.rb +3 -8
  125. data/lib/openc3/io/buffered_file.rb +4 -9
  126. data/lib/openc3/io/io_multiplexer.rb +4 -9
  127. data/lib/openc3/io/json_api.rb +3 -8
  128. data/lib/openc3/io/json_api_object.rb +4 -9
  129. data/lib/openc3/io/json_drb.rb +3 -8
  130. data/lib/openc3/io/json_drb_object.rb +4 -9
  131. data/lib/openc3/io/json_drb_rack.rb +4 -9
  132. data/lib/openc3/io/json_rpc.rb +3 -8
  133. data/lib/openc3/io/posix_serial_driver.rb +3 -8
  134. data/lib/openc3/io/serial_driver.rb +3 -8
  135. data/lib/openc3/io/stderr.rb +4 -9
  136. data/lib/openc3/io/stdout.rb +4 -9
  137. data/lib/openc3/io/udp_sockets.rb +3 -8
  138. data/lib/openc3/io/win32_serial_driver.rb +4 -9
  139. data/lib/openc3/logs/buffered_packet_log_reader.rb +3 -8
  140. data/lib/openc3/logs/buffered_packet_log_writer.rb +3 -8
  141. data/lib/openc3/logs/log_writer.rb +3 -8
  142. data/lib/openc3/logs/packet_log_constants.rb +3 -8
  143. data/lib/openc3/logs/packet_log_reader.rb +3 -8
  144. data/lib/openc3/logs/packet_log_writer.rb +3 -8
  145. data/lib/openc3/logs/stream_log.rb +3 -8
  146. data/lib/openc3/logs/stream_log_pair.rb +3 -8
  147. data/lib/openc3/logs/text_log_writer.rb +3 -8
  148. data/lib/openc3/logs.rb +3 -8
  149. data/lib/openc3/microservices/cleanup_microservice.rb +4 -14
  150. data/lib/openc3/microservices/decom_microservice.rb +3 -8
  151. data/lib/openc3/microservices/interface_decom_common.rb +3 -8
  152. data/lib/openc3/microservices/interface_microservice.rb +5 -9
  153. data/lib/openc3/microservices/log_microservice.rb +3 -8
  154. data/lib/openc3/microservices/microservice.rb +24 -12
  155. data/lib/openc3/microservices/multi_microservice.rb +2 -7
  156. data/lib/openc3/microservices/periodic_microservice.rb +3 -8
  157. data/lib/openc3/microservices/plugin_microservice.rb +3 -8
  158. data/lib/openc3/microservices/queue_microservice.rb +3 -8
  159. data/lib/openc3/microservices/router_microservice.rb +3 -8
  160. data/lib/openc3/microservices/scope_cleanup_microservice.rb +3 -8
  161. data/lib/openc3/microservices/text_log_microservice.rb +3 -8
  162. data/lib/openc3/migrations/20251213120000_reinstall_plugins.rb +45 -0
  163. data/lib/openc3/migrations/20260204000000_remove_decom_reducer.rb +60 -0
  164. data/lib/openc3/models/activity_model.rb +4 -8
  165. data/lib/openc3/models/auth_model.rb +57 -38
  166. data/lib/openc3/models/cvt_model.rb +203 -62
  167. data/lib/openc3/models/environment_model.rb +4 -9
  168. data/lib/openc3/models/gem_model.rb +3 -8
  169. data/lib/openc3/models/info_model.rb +4 -9
  170. data/lib/openc3/models/interface_model.rb +6 -10
  171. data/lib/openc3/models/interface_status_model.rb +4 -9
  172. data/lib/openc3/models/metadata_model.rb +3 -8
  173. data/lib/openc3/models/metric_model.rb +3 -8
  174. data/lib/openc3/models/microservice_model.rb +24 -10
  175. data/lib/openc3/models/microservice_status_model.rb +3 -8
  176. data/lib/openc3/models/migration_model.rb +3 -8
  177. data/lib/openc3/models/model.rb +3 -8
  178. data/lib/openc3/models/news_model.rb +3 -8
  179. data/lib/openc3/models/note_model.rb +3 -8
  180. data/lib/openc3/models/offline_access_model.rb +3 -8
  181. data/lib/openc3/models/ping_model.rb +4 -9
  182. data/lib/openc3/models/plugin_model.rb +14 -9
  183. data/lib/openc3/models/plugin_store_model.rb +21 -17
  184. data/lib/openc3/models/process_status_model.rb +4 -9
  185. data/lib/openc3/models/python_package_model.rb +3 -8
  186. data/lib/openc3/models/queue_model.rb +3 -8
  187. data/lib/openc3/models/reaction_model.rb +9 -10
  188. data/lib/openc3/models/router_model.rb +4 -9
  189. data/lib/openc3/models/router_status_model.rb +4 -9
  190. data/lib/openc3/models/scope_model.rb +4 -9
  191. data/lib/openc3/models/script_engine_model.rb +3 -8
  192. data/lib/openc3/models/script_status_model.rb +3 -8
  193. data/lib/openc3/models/secret_model.rb +3 -8
  194. data/lib/openc3/models/setting_model.rb +3 -8
  195. data/lib/openc3/models/sorted_model.rb +3 -8
  196. data/lib/openc3/models/stash_model.rb +3 -8
  197. data/lib/openc3/models/target_model.rb +99 -229
  198. data/lib/openc3/models/timeline_model.rb +3 -8
  199. data/lib/openc3/models/tool_config_model.rb +3 -8
  200. data/lib/openc3/models/tool_model.rb +10 -10
  201. data/lib/openc3/models/trigger_group_model.rb +3 -8
  202. data/lib/openc3/models/trigger_model.rb +3 -8
  203. data/lib/openc3/models/widget_model.rb +3 -8
  204. data/lib/openc3/operators/microservice_operator.rb +7 -8
  205. data/lib/openc3/operators/operator.rb +3 -8
  206. data/lib/openc3/packets/command_validator.rb +3 -8
  207. data/lib/openc3/packets/commands.rb +32 -14
  208. data/lib/openc3/packets/json_packet.rb +7 -19
  209. data/lib/openc3/packets/limits.rb +3 -8
  210. data/lib/openc3/packets/limits_response.rb +3 -8
  211. data/lib/openc3/packets/packet.rb +38 -32
  212. data/lib/openc3/packets/packet_config.rb +23 -13
  213. data/lib/openc3/packets/packet_item.rb +3 -8
  214. data/lib/openc3/packets/packet_item_limits.rb +3 -8
  215. data/lib/openc3/packets/parsers/format_string_parser.rb +3 -8
  216. data/lib/openc3/packets/parsers/limits_parser.rb +3 -8
  217. data/lib/openc3/packets/parsers/limits_response_parser.rb +3 -8
  218. data/lib/openc3/packets/parsers/packet_item_parser.rb +7 -8
  219. data/lib/openc3/packets/parsers/packet_parser.rb +3 -8
  220. data/lib/openc3/packets/parsers/processor_parser.rb +3 -8
  221. data/lib/openc3/packets/parsers/state_parser.rb +3 -8
  222. data/lib/openc3/packets/parsers/xtce_converter.rb +12 -9
  223. data/lib/openc3/packets/parsers/xtce_parser.rb +3 -8
  224. data/lib/openc3/packets/structure.rb +14 -11
  225. data/lib/openc3/packets/structure_item.rb +4 -9
  226. data/lib/openc3/packets/telemetry.rb +7 -11
  227. data/lib/openc3/processors/processor.rb +5 -10
  228. data/lib/openc3/processors/statistics_processor.rb +4 -9
  229. data/lib/openc3/processors/watermark_processor.rb +4 -9
  230. data/lib/openc3/processors.rb +4 -9
  231. data/lib/openc3/script/api_shared.rb +8 -37
  232. data/lib/openc3/script/autonomic.rb +3 -8
  233. data/lib/openc3/script/calendar.rb +3 -8
  234. data/lib/openc3/script/commands.rb +3 -8
  235. data/lib/openc3/script/critical_cmd.rb +3 -8
  236. data/lib/openc3/script/exceptions.rb +4 -9
  237. data/lib/openc3/script/extract.rb +3 -8
  238. data/lib/openc3/script/limits.rb +3 -8
  239. data/lib/openc3/script/metadata.rb +3 -8
  240. data/lib/openc3/script/packages.rb +3 -8
  241. data/lib/openc3/script/plugins.rb +3 -8
  242. data/lib/openc3/script/queue.rb +3 -8
  243. data/lib/openc3/script/screen.rb +7 -8
  244. data/lib/openc3/script/script.rb +3 -8
  245. data/lib/openc3/script/script_runner.rb +3 -8
  246. data/lib/openc3/script/storage.rb +6 -10
  247. data/lib/openc3/script/suite.rb +3 -8
  248. data/lib/openc3/script/suite_results.rb +3 -8
  249. data/lib/openc3/script/suite_runner.rb +3 -8
  250. data/lib/openc3/script/tables.rb +3 -8
  251. data/lib/openc3/script/telemetry.rb +3 -8
  252. data/lib/openc3/script/web_socket_api.rb +8 -13
  253. data/lib/openc3/script.rb +4 -9
  254. data/lib/openc3/script_engines/script_engine.rb +3 -8
  255. data/lib/openc3/streams/mqtt_stream.rb +3 -8
  256. data/lib/openc3/streams/serial_stream.rb +3 -8
  257. data/lib/openc3/streams/stream.rb +3 -8
  258. data/lib/openc3/streams/tcpip_client_stream.rb +3 -8
  259. data/lib/openc3/streams/tcpip_socket_stream.rb +3 -8
  260. data/lib/openc3/streams/web_socket_client_stream.rb +3 -8
  261. data/lib/openc3/system/system.rb +3 -8
  262. data/lib/openc3/system/target.rb +3 -8
  263. data/lib/openc3/system.rb +3 -8
  264. data/lib/openc3/tools/cmd_tlm_server/api.rb +4 -9
  265. data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +3 -8
  266. data/lib/openc3/tools/table_manager/table.rb +3 -8
  267. data/lib/openc3/tools/table_manager/table_config.rb +3 -8
  268. data/lib/openc3/tools/table_manager/table_item.rb +4 -9
  269. data/lib/openc3/tools/table_manager/table_item_parser.rb +3 -8
  270. data/lib/openc3/tools/table_manager/table_manager_core.rb +3 -8
  271. data/lib/openc3/tools/table_manager/table_parser.rb +3 -8
  272. data/lib/openc3/tools/test_runner/test.rb +4 -9
  273. data/lib/openc3/top_level.rb +3 -8
  274. data/lib/openc3/topics/autonomic_topic.rb +4 -9
  275. data/lib/openc3/topics/calendar_topic.rb +4 -9
  276. data/lib/openc3/topics/command_decom_topic.rb +14 -17
  277. data/lib/openc3/topics/command_topic.rb +14 -10
  278. data/lib/openc3/topics/config_topic.rb +3 -8
  279. data/lib/openc3/topics/decom_interface_topic.rb +3 -8
  280. data/lib/openc3/topics/interface_topic.rb +3 -8
  281. data/lib/openc3/topics/limits_event_topic.rb +3 -8
  282. data/lib/openc3/topics/notebook_topic.rb +32 -0
  283. data/lib/openc3/topics/queue_topic.rb +3 -8
  284. data/lib/openc3/topics/router_topic.rb +3 -8
  285. data/lib/openc3/topics/system_events_topic.rb +3 -8
  286. data/lib/openc3/topics/telemetry_decom_topic.rb +12 -12
  287. data/lib/openc3/topics/telemetry_topic.rb +3 -8
  288. data/lib/openc3/topics/timeline_topic.rb +4 -9
  289. data/lib/openc3/topics/topic.rb +3 -8
  290. data/lib/openc3/utilities/authentication.rb +29 -10
  291. data/lib/openc3/utilities/authorization.rb +4 -9
  292. data/lib/openc3/utilities/aws_bucket.rb +126 -16
  293. data/lib/openc3/utilities/bucket.rb +9 -9
  294. data/lib/openc3/utilities/bucket_file_cache.rb +3 -13
  295. data/lib/openc3/utilities/bucket_require.rb +3 -8
  296. data/lib/openc3/utilities/bucket_utilities.rb +3 -10
  297. data/lib/openc3/utilities/cli_generator.rb +11 -16
  298. data/lib/openc3/utilities/cmd_log.rb +3 -8
  299. data/lib/openc3/utilities/crc.rb +3 -8
  300. data/lib/openc3/utilities/csv.rb +4 -9
  301. data/lib/openc3/utilities/local_bucket.rb +5 -10
  302. data/lib/openc3/utilities/local_mode.rb +14 -18
  303. data/lib/openc3/utilities/logger.rb +3 -8
  304. data/lib/openc3/utilities/message_log.rb +3 -8
  305. data/lib/openc3/utilities/metric.rb +3 -8
  306. data/lib/openc3/utilities/migration.rb +3 -8
  307. data/lib/openc3/utilities/open_telemetry.rb +3 -8
  308. data/lib/openc3/utilities/process_manager.rb +3 -8
  309. data/lib/openc3/utilities/python_proxy.rb +3 -8
  310. data/lib/openc3/utilities/quaternion.rb +3 -8
  311. data/lib/openc3/utilities/questdb_client.rb +210 -0
  312. data/lib/openc3/utilities/redis_secrets.rb +3 -8
  313. data/lib/openc3/utilities/ruby_lex_utils.rb +3 -8
  314. data/lib/openc3/utilities/running_script.rb +13 -11
  315. data/lib/openc3/utilities/s3_autoload.rb +9 -2
  316. data/lib/openc3/utilities/secrets.rb +8 -9
  317. data/lib/openc3/utilities/simulated_target.rb +4 -9
  318. data/lib/openc3/utilities/sleeper.rb +3 -8
  319. data/lib/openc3/utilities/store.rb +4 -9
  320. data/lib/openc3/utilities/store_autoload.rb +7 -14
  321. data/lib/openc3/utilities/store_queued.rb +6 -9
  322. data/lib/openc3/utilities/target_file.rb +3 -8
  323. data/lib/openc3/utilities/thread_manager.rb +3 -8
  324. data/lib/openc3/utilities/throttle.rb +3 -8
  325. data/lib/openc3/utilities/zip.rb +4 -9
  326. data/lib/openc3/utilities.rb +4 -9
  327. data/lib/openc3/version.rb +8 -8
  328. data/lib/openc3/win32/excel.rb +4 -9
  329. data/lib/openc3/win32/win32.rb +4 -9
  330. data/lib/openc3/win32/win32_main.rb +3 -8
  331. data/lib/openc3.rb +3 -12
  332. data/tasks/gemfile_stats.rake +4 -9
  333. data/tasks/spec.rake +4 -9
  334. data/templates/plugin/README.md +2 -2
  335. data/templates/plugin/plugin.gemspec +1 -1
  336. data/templates/tool_angular/package.json +1 -1
  337. data/templates/tool_vue/package.json +3 -3
  338. data/templates/tool_vue/vite.config.js +2 -1
  339. data/templates/widget/package.json +3 -3
  340. data/templates/widget/vite.config.js +1 -1
  341. metadata +49 -26
  342. data/LICENSE.txt +0 -729
  343. data/bin/rubysloc +0 -142
  344. data/ext/openc3/ext/reducer_microservice/extconf.rb +0 -13
  345. data/ext/openc3/ext/reducer_microservice/reducer_microservice.c +0 -165
  346. data/lib/openc3/microservices/reducer_microservice.rb +0 -640
  347. data/lib/openc3/models/reducer_model.rb +0 -72
  348. data/lib/openc3/topics/telemetry_reduced_topics.rb +0 -80
  349. /data/templates/plugin/{LICENSE.txt → LICENSE.md} +0 -0
  350. /data/templates/widget/{LICENSE.txt → LICENSE.md} +0 -0
@@ -3,18 +3,13 @@
3
3
  # Copyright 2022 Ball Aerospace & Technologies Corp.
4
4
  # All Rights Reserved.
5
5
  #
6
- # This program is free software; you can modify and/or redistribute it
7
- # under the terms of the GNU Affero 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
6
  # This program is distributed in the hope that it will be useful,
12
7
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- # GNU Affero General Public License for more details.
8
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9
+ # See LICENSE.md for more details.
15
10
 
16
11
  # Modified by OpenC3, Inc.
17
- # All changes Copyright 2025, OpenC3, Inc.
12
+ # All changes Copyright 2026, OpenC3, Inc.
18
13
  # All Rights Reserved
19
14
  #
20
15
  # This file may also be used under the terms of a commercial license
@@ -53,7 +48,10 @@ module OpenC3
53
48
  VALID_TYPES = %i(CMD TLM)
54
49
  ERB_EXTENSIONS = %w(.txt .rb .py .json .yaml .yml)
55
50
  ITEM_MAP_CACHE_TIMEOUT = 10.0
51
+ PACKET_CACHE_TIMEOUT = 10.0
56
52
  @@item_map_cache = {}
53
+ @@packet_cache = {}
54
+ @@packet_cache_mutex = Mutex.new
57
55
  @@sync_packet_count_data = {}
58
56
  @@sync_packet_count_time = nil
59
57
  @@sync_packet_count_delay_seconds = 1.0 # Sync packet counts every second
@@ -69,19 +67,12 @@ module OpenC3
69
67
  attr_accessor :cmd_log_cycle_time
70
68
  attr_accessor :cmd_log_cycle_size
71
69
  attr_accessor :cmd_log_retain_time
72
- attr_accessor :cmd_decom_log_cycle_time
73
- attr_accessor :cmd_decom_log_cycle_size
74
- attr_accessor :cmd_decom_log_retain_time
75
70
  attr_accessor :tlm_buffer_depth
76
71
  attr_accessor :tlm_log_cycle_time
77
72
  attr_accessor :tlm_log_cycle_size
78
73
  attr_accessor :tlm_log_retain_time
79
- attr_accessor :tlm_decom_log_cycle_time
80
- attr_accessor :tlm_decom_log_cycle_size
81
- attr_accessor :tlm_decom_log_retain_time
82
- attr_accessor :reduced_minute_log_retain_time
83
- attr_accessor :reduced_hour_log_retain_time
84
- attr_accessor :reduced_day_log_retain_time
74
+ attr_accessor :cmd_decom_retain_time
75
+ attr_accessor :tlm_decom_retain_time
85
76
  attr_accessor :cleanup_poll_time
86
77
  attr_accessor :needs_dependencies
87
78
  attr_accessor :target_microservices
@@ -208,11 +199,33 @@ module OpenC3
208
199
  def self.packet(target_name, packet_name, type: :TLM, scope:)
209
200
  raise "Unknown type #{type} for #{target_name} #{packet_name}" unless VALID_TYPES.include?(type)
210
201
 
202
+ # Check cache first
203
+ cache_key = "#{scope}__#{type}__#{target_name}__#{packet_name}"
204
+ @@packet_cache_mutex.synchronize do
205
+ cached = @@packet_cache[cache_key]
206
+ if cached && (Time.now - cached[:time]) < PACKET_CACHE_TIMEOUT
207
+ return cached[:packet]
208
+ end
209
+ end
210
+
211
211
  # Assume it exists and just try to get it to avoid an extra call to Store.exist?
212
212
  json = Store.hget("#{scope}__openc3#{type.to_s.downcase}__#{target_name}", packet_name)
213
213
  raise "Packet '#{target_name} #{packet_name}' does not exist" if json.nil?
214
214
 
215
- JSON.parse(json, allow_nan: true, create_additions: true)
215
+ packet = JSON.parse(json, allow_nan: true, create_additions: true)
216
+
217
+ # Store in cache
218
+ @@packet_cache_mutex.synchronize do
219
+ @@packet_cache[cache_key] = { packet: packet, time: Time.now }
220
+ end
221
+
222
+ packet
223
+ end
224
+
225
+ def self.clear_packet_cache
226
+ @@packet_cache_mutex.synchronize do
227
+ @@packet_cache.clear
228
+ end
216
229
  end
217
230
 
218
231
  # @return [Array<Hash>] All packet hashes under the target_name
@@ -236,6 +249,12 @@ module OpenC3
236
249
  def self.set_packet(target_name, packet_name, packet, type: :TLM, scope:)
237
250
  raise "Unknown type #{type} for #{target_name} #{packet_name}" unless VALID_TYPES.include?(type)
238
251
 
252
+ # Invalidate cache entry
253
+ cache_key = "#{scope}__#{type}__#{target_name}__#{packet_name}"
254
+ @@packet_cache_mutex.synchronize do
255
+ @@packet_cache.delete(cache_key)
256
+ end
257
+
239
258
  begin
240
259
  Store.hset("#{scope}__openc3#{type.to_s.downcase}__#{target_name}", packet_name, JSON.generate(packet.as_json, allow_nan: true))
241
260
  rescue JSON::GeneratorError => e
@@ -359,24 +378,15 @@ module OpenC3
359
378
  cmd_log_cycle_time: 600,
360
379
  cmd_log_cycle_size: 50_000_000,
361
380
  cmd_log_retain_time: nil,
362
- cmd_decom_log_cycle_time: 600,
363
- cmd_decom_log_cycle_size: 50_000_000,
364
- cmd_decom_log_retain_time: nil,
365
381
  tlm_buffer_depth: 60,
366
382
  tlm_log_cycle_time: 600,
367
383
  tlm_log_cycle_size: 50_000_000,
368
384
  tlm_log_retain_time: nil,
369
- tlm_decom_log_cycle_time: 600,
370
- tlm_decom_log_cycle_size: 50_000_000,
371
- tlm_decom_log_retain_time: nil,
372
- reduced_minute_log_retain_time: nil,
373
- reduced_hour_log_retain_time: nil,
374
- reduced_day_log_retain_time: nil,
375
- cleanup_poll_time: 600,
385
+ cmd_decom_retain_time: nil,
386
+ tlm_decom_retain_time: nil,
387
+ cleanup_poll_time: 3600,
376
388
  needs_dependencies: false,
377
- target_microservices: {'REDUCER' => [[]]},
378
- reducer_disable: false,
379
- reducer_max_cpu_utilization: 30.0,
389
+ target_microservices: {},
380
390
  disable_erb: nil,
381
391
  shard: 0,
382
392
  scope:
@@ -384,16 +394,10 @@ module OpenC3
384
394
  super("#{scope}__#{PRIMARY_KEY}", name: name, plugin: plugin, updated_at: updated_at,
385
395
  cmd_buffer_depth: cmd_buffer_depth, cmd_log_cycle_time: cmd_log_cycle_time, cmd_log_cycle_size: cmd_log_cycle_size,
386
396
  cmd_log_retain_time: cmd_log_retain_time,
387
- cmd_decom_log_cycle_time: cmd_decom_log_cycle_time, cmd_decom_log_cycle_size: cmd_decom_log_cycle_size,
388
- cmd_decom_log_retain_time: cmd_decom_log_retain_time,
389
397
  tlm_buffer_depth: tlm_buffer_depth, tlm_log_cycle_time: tlm_log_cycle_time, tlm_log_cycle_size: tlm_log_cycle_size,
390
398
  tlm_log_retain_time: tlm_log_retain_time,
391
- tlm_decom_log_cycle_time: tlm_decom_log_cycle_time, tlm_decom_log_cycle_size: tlm_decom_log_cycle_size,
392
- tlm_decom_log_retain_time: tlm_decom_log_retain_time,
393
- reduced_minute_log_retain_time: reduced_minute_log_retain_time,
394
- reduced_hour_log_retain_time: reduced_hour_log_retain_time, reduced_day_log_retain_time: reduced_day_log_retain_time,
399
+ cmd_decom_retain_time: cmd_decom_retain_time, tlm_decom_retain_time: tlm_decom_retain_time,
395
400
  cleanup_poll_time: cleanup_poll_time, needs_dependencies: needs_dependencies, target_microservices: target_microservices,
396
- reducer_disable: reducer_disable, reducer_max_cpu_utilization: reducer_max_cpu_utilization,
397
401
  scope: scope)
398
402
  @folder_name = folder_name
399
403
  @requires = requires
@@ -406,24 +410,15 @@ module OpenC3
406
410
  @cmd_log_cycle_time = cmd_log_cycle_time
407
411
  @cmd_log_cycle_size = cmd_log_cycle_size
408
412
  @cmd_log_retain_time = cmd_log_retain_time
409
- @cmd_decom_log_cycle_time = cmd_decom_log_cycle_time
410
- @cmd_decom_log_cycle_size = cmd_decom_log_cycle_size
411
- @cmd_decom_log_retain_time = cmd_decom_log_retain_time
412
413
  @tlm_buffer_depth = tlm_buffer_depth
413
414
  @tlm_log_cycle_time = tlm_log_cycle_time
414
415
  @tlm_log_cycle_size = tlm_log_cycle_size
415
416
  @tlm_log_retain_time = tlm_log_retain_time
416
- @tlm_decom_log_cycle_time = tlm_decom_log_cycle_time
417
- @tlm_decom_log_cycle_size = tlm_decom_log_cycle_size
418
- @tlm_decom_log_retain_time = tlm_decom_log_retain_time
419
- @reduced_minute_log_retain_time = reduced_minute_log_retain_time
420
- @reduced_hour_log_retain_time = reduced_hour_log_retain_time
421
- @reduced_day_log_retain_time = reduced_day_log_retain_time
417
+ @cmd_decom_retain_time = cmd_decom_retain_time
418
+ @tlm_decom_retain_time = tlm_decom_retain_time
422
419
  @cleanup_poll_time = cleanup_poll_time
423
420
  @needs_dependencies = needs_dependencies
424
421
  @target_microservices = target_microservices
425
- @reducer_disable = reducer_disable
426
- @reducer_max_cpu_utilization = reducer_max_cpu_utilization
427
422
  @disable_erb = disable_erb
428
423
  @shard = shard.to_i # to_i to handle nil
429
424
  @bucket = Bucket.getClient()
@@ -446,24 +441,15 @@ module OpenC3
446
441
  'cmd_log_cycle_time' => @cmd_log_cycle_time,
447
442
  'cmd_log_cycle_size' => @cmd_log_cycle_size,
448
443
  'cmd_log_retain_time' => @cmd_log_retain_time,
449
- 'cmd_decom_log_cycle_time' => @cmd_decom_log_cycle_time,
450
- 'cmd_decom_log_cycle_size' => @cmd_decom_log_cycle_size,
451
- 'cmd_decom_log_retain_time' => @cmd_decom_log_retain_time,
452
444
  'tlm_buffer_depth' => @tlm_buffer_depth,
453
445
  'tlm_log_cycle_time' => @tlm_log_cycle_time,
454
446
  'tlm_log_cycle_size' => @tlm_log_cycle_size,
455
447
  'tlm_log_retain_time' => @tlm_log_retain_time,
456
- 'tlm_decom_log_cycle_time' => @tlm_decom_log_cycle_time,
457
- 'tlm_decom_log_cycle_size' => @tlm_decom_log_cycle_size,
458
- 'tlm_decom_log_retain_time' => @tlm_decom_log_retain_time,
459
- 'reduced_minute_log_retain_time' => @reduced_minute_log_retain_time,
460
- 'reduced_hour_log_retain_time' => @reduced_hour_log_retain_time,
461
- 'reduced_day_log_retain_time' => @reduced_day_log_retain_time,
448
+ 'cmd_decom_retain_time' => @cmd_decom_retain_time,
449
+ 'tlm_decom_retain_time' => @tlm_decom_retain_time,
462
450
  'cleanup_poll_time' => @cleanup_poll_time,
463
451
  'needs_dependencies' => @needs_dependencies,
464
452
  'target_microservices' => @target_microservices.as_json(),
465
- 'reducer_disable' => @reducer_disable,
466
- 'reducer_max_cpu_utilization' => @reducer_max_cpu_utilization,
467
453
  'disable_erb' => @disable_erb,
468
454
  'shard' => @shard,
469
455
  }
@@ -482,19 +468,11 @@ module OpenC3
482
468
  parser.verify_num_parameters(1, 1, "#{keyword} <Maximum file size in bytes>")
483
469
  @cmd_log_cycle_size = parameters[0].to_i
484
470
  when 'CMD_LOG_RETAIN_TIME'
485
- parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for cmd log files in seconds - nil = Forever>")
471
+ parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for raw cmd log files in seconds - nil = Forever>")
486
472
  @cmd_log_retain_time = ConfigParser.handle_nil(parameters[0])
487
473
  @cmd_log_retain_time = @cmd_log_retain_time.to_i if @cmd_log_retain_time
488
- when 'CMD_DECOM_LOG_CYCLE_TIME'
489
- parser.verify_num_parameters(1, 1, "#{keyword} <Maximum time between files in seconds>")
490
- @cmd_decom_log_cycle_time = parameters[0].to_i
491
- when 'CMD_DECOM_LOG_CYCLE_SIZE'
492
- parser.verify_num_parameters(1, 1, "#{keyword} <Maximum file size in bytes>")
493
- @cmd_decom_log_cycle_size = parameters[0].to_i
494
- when 'CMD_DECOM_LOG_RETAIN_TIME'
495
- parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for cmd decom log files in seconds - nil = Forever>")
496
- @cmd_decom_log_retain_time = ConfigParser.handle_nil(parameters[0])
497
- @cmd_decom_log_retain_time = @cmd_decom_log_retain_time.to_i if @cmd_decom_log_retain_time
474
+ when 'CMD_DECOM_LOG_CYCLE_TIME', 'CMD_DECOM_LOG_CYCLE_SIZE', 'CMD_DECOM_LOG_RETAIN_TIME'
475
+ # DEPRECATED keywords - do nothing
498
476
  when 'TLM_BUFFER_DEPTH'
499
477
  parser.verify_num_parameters(1, 1, "#{keyword} <Number of telemetry packets to buffer to ensure logged in order>")
500
478
  @tlm_buffer_depth = parameters[0].to_i
@@ -505,60 +483,41 @@ module OpenC3
505
483
  parser.verify_num_parameters(1, 1, "#{keyword} <Maximum file size in bytes>")
506
484
  @tlm_log_cycle_size = parameters[0].to_i
507
485
  when 'TLM_LOG_RETAIN_TIME'
508
- parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for tlm log files in seconds - nil = Forever>")
486
+ parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for raw tlm log files in seconds - nil = Forever>")
509
487
  @tlm_log_retain_time = ConfigParser.handle_nil(parameters[0])
510
488
  @tlm_log_retain_time = @tlm_log_retain_time.to_i if @tlm_log_retain_time
511
- when 'TLM_DECOM_LOG_CYCLE_TIME'
512
- parser.verify_num_parameters(1, 1, "#{keyword} <Maximum time between files in seconds>")
513
- @tlm_decom_log_cycle_time = parameters[0].to_i
514
- when 'TLM_DECOM_LOG_CYCLE_SIZE'
515
- parser.verify_num_parameters(1, 1, "#{keyword} <Maximum file size in bytes>")
516
- @tlm_decom_log_cycle_size = parameters[0].to_i
517
- when 'TLM_DECOM_LOG_RETAIN_TIME'
518
- parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for tlm decom log files in seconds - nil = Forever>")
519
- @tlm_decom_log_retain_time = ConfigParser.handle_nil(parameters[0])
520
- @tlm_decom_log_retain_time = @tlm_decom_log_retain_time.to_i if @tlm_decom_log_retain_time
521
- when 'REDUCED_MINUTE_LOG_RETAIN_TIME'
522
- parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for reduced minute log files in seconds - nil = Forever>")
523
- @reduced_minute_log_retain_time = ConfigParser.handle_nil(parameters[0])
524
- @reduced_minute_log_retain_time = @reduced_minute_log_retain_time.to_i if @reduced_minute_log_retain_time
525
- when 'REDUCED_HOUR_LOG_RETAIN_TIME'
526
- parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for reduced hour log files in seconds - nil = Forever>")
527
- @reduced_hour_log_retain_time = ConfigParser.handle_nil(parameters[0])
528
- @reduced_hour_log_retain_time = @reduced_hour_log_retain_time.to_i if @reduced_hour_log_retain_time
529
- when 'REDUCED_DAY_LOG_RETAIN_TIME'
530
- parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for reduced day log files in seconds - nil = Forever>")
531
- @reduced_day_log_retain_time = ConfigParser.handle_nil(parameters[0])
532
- @reduced_day_log_retain_time = @reduced_day_log_retain_time.to_i if @reduced_day_log_retain_time
489
+ when 'TLM_DECOM_LOG_CYCLE_TIME', 'TLM_DECOM_LOG_CYCLE_SIZE', 'TLM_DECOM_LOG_RETAIN_TIME'
490
+ # DEPRECATED keywords - do nothing
491
+ when 'CMD_DECOM_RETAIN_TIME'
492
+ parser.verify_num_parameters(1, 1, "#{keyword} <Retention time with unit (e.g., 30d, 1y) - nil = Forever>")
493
+ @cmd_decom_retain_time = ConfigParser.handle_nil(parameters[0])
494
+ if @cmd_decom_retain_time and !@cmd_decom_retain_time.match?(/^\d+[hdwMy]$/)
495
+ raise ConfigParser::Error.new(parser, "CMD_DECOM_RETAIN_TIME must be a number followed by h, d, w, M, or y (e.g., 24h, 7d, 1y)")
496
+ end
497
+ when 'TLM_DECOM_RETAIN_TIME'
498
+ parser.verify_num_parameters(1, 1, "#{keyword} <Retention time with unit (e.g., 30d, 1y) - nil = Forever>")
499
+ @tlm_decom_retain_time = ConfigParser.handle_nil(parameters[0])
500
+ if @tlm_decom_retain_time and !@tlm_decom_retain_time.match?(/^\d+[hdwMy]$/)
501
+ raise ConfigParser::Error.new(parser, "TLM_DECOM_RETAIN_TIME must be a number followed by h, d, w, M, or y (e.g., 24h, 7d, 1y)")
502
+ end
503
+ when 'REDUCED_MINUTE_LOG_RETAIN_TIME', 'REDUCED_HOUR_LOG_RETAIN_TIME', 'REDUCED_DAY_LOG_RETAIN_TIME', 'REDUCED_LOG_RETAIN_TIME'
504
+ # DEPRECATED
505
+ when 'REDUCER_DISABLE', 'REDUCER_DISABLED', 'REDUCER_MAX_CPU_UTILIZATION', 'REDUCED_MAX_CPU_UTILIZATION'
506
+ # DEPRECATED
533
507
  when 'LOG_RETAIN_TIME'
534
- parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for all log files in seconds - nil = Forever>")
508
+ parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for all raw log files in seconds - nil = Forever>")
535
509
  log_retain_time = ConfigParser.handle_nil(parameters[0])
536
510
  if log_retain_time
537
511
  @cmd_log_retain_time = log_retain_time.to_i
538
- @cmd_decom_log_retain_time = log_retain_time.to_i
539
512
  @tlm_log_retain_time = log_retain_time.to_i
540
- @tlm_decom_log_retain_time = log_retain_time.to_i
541
513
  end
542
- when 'REDUCED_LOG_RETAIN_TIME'
543
- parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for all reduced log files in seconds - nil = Forever>")
544
- reduced_log_retain_time = ConfigParser.handle_nil(parameters[0])
545
- if reduced_log_retain_time
546
- @reduced_minute_log_retain_time = reduced_log_retain_time.to_i
547
- @reduced_hour_log_retain_time = reduced_log_retain_time.to_i
548
- @reduced_day_log_retain_time = reduced_log_retain_time.to_i
549
- end
550
- when 'REDUCER_DISABLE', 'REDUCER_DISABLED' # Handle typos
551
- @reducer_disable = true
552
- when 'REDUCER_MAX_CPU_UTILIZATION', 'REDUCED_MAX_CPU_UTILIZATION' # Handle typos
553
- parser.verify_num_parameters(1, 1, "#{keyword} <Max cpu utilization to allocate to the reducer microservice - 0.0 to 100.0>")
554
- @reducer_max_cpu_utilization = Float(parameters[0])
555
514
  when 'CLEANUP_POLL_TIME'
556
515
  parser.verify_num_parameters(1, 1, "#{keyword} <Cleanup polling period in seconds>")
557
516
  @cleanup_poll_time = parameters[0].to_i
558
517
  when 'TARGET_MICROSERVICE'
559
- parser.verify_num_parameters(1, 1, "#{keyword} <Type: DECOM COMMANDLOG DECOMCMDLOG PACKETLOG DECOMLOG REDUCER CLEANUP>")
518
+ parser.verify_num_parameters(1, 1, "#{keyword} <Type: DECOM COMMANDLOG PACKETLOG CLEANUP>")
560
519
  type = parameters[0].to_s.upcase
561
- unless %w(DECOM COMMANDLOG DECOMCMDLOG PACKETLOG DECOMLOG REDUCER CLEANUP).include?(type)
520
+ unless %w(DECOM COMMANDLOG PACKETLOG CLEANUP).include?(type)
562
521
  raise "Unknown TARGET_MICROSERVICE #{type}"
563
522
  end
564
523
  @target_microservices[type] ||= []
@@ -567,7 +526,7 @@ module OpenC3
567
526
  when 'PACKET'
568
527
  if @current_target_microservice
569
528
  parser.verify_num_parameters(1, 1, "#{keyword} <Packet Name>")
570
- if @current_target_microservice == 'REDUCER' or @current_target_microservice == 'CLEANUP'
529
+ if @current_target_microservice == 'CLEANUP'
571
530
  raise ConfigParser::Error.new(parser, "PACKET cannot be used with target microservice #{@current_target_microservice}")
572
531
  end
573
532
  @target_microservices[@current_target_microservice][-1] << parameters[0].to_s.upcase
@@ -654,8 +613,13 @@ module OpenC3
654
613
 
655
614
  def undeploy
656
615
  prefix = "#{@scope}/targets/#{@name}/"
657
- @bucket.list_objects(bucket: ENV['OPENC3_CONFIG_BUCKET'], prefix: prefix).each do |object|
658
- @bucket.delete_object(bucket: ENV['OPENC3_CONFIG_BUCKET'], key: object.key)
616
+ objects = @bucket.list_objects(bucket: ENV['OPENC3_CONFIG_BUCKET'], prefix: prefix)
617
+ keys = objects.map(&:key)
618
+ if keys.length > 0
619
+ # Batch delete in chunks of 1000 (S3 limit)
620
+ keys.each_slice(1000) do |key_batch|
621
+ @bucket.delete_objects(bucket: ENV['OPENC3_CONFIG_BUCKET'], keys: key_batch)
622
+ end
659
623
  end
660
624
 
661
625
  self.class.get_model(name: @name, scope: @scope).limits_groups.each do |group|
@@ -668,9 +632,6 @@ module OpenC3
668
632
  self.class.packets(@name, scope: @scope).each do |packet|
669
633
  Topic.del("#{@scope}__TELEMETRY__{#{@name}}__#{packet['packet_name']}")
670
634
  Topic.del("#{@scope}__DECOM__{#{@name}}__#{packet['packet_name']}")
671
- Topic.del("#{@scope}__REDUCED_MINUTE__{#{@name}}__#{packet['packet_name']}")
672
- Topic.del("#{@scope}__REDUCED_HOUR__{#{@name}}__#{packet['packet_name']}")
673
- Topic.del("#{@scope}__REDUCED_DAY__{#{@name}}__#{packet['packet_name']}")
674
635
  CvtModel.del(target_name: @name, packet_name: packet['packet_name'], scope: @scope)
675
636
  end
676
637
  LimitsEventTopic.delete(@name, scope: @scope)
@@ -680,7 +641,7 @@ module OpenC3
680
641
  Store.del("#{@scope}__COMMANDCNTS__{#{@name}}")
681
642
 
682
643
  # Note: these match the names of the services in deploy_microservices
683
- %w(MULTI DECOM COMMANDLOG DECOMCMDLOG PACKETLOG DECOMLOG REDUCER CLEANUP).each do |type|
644
+ %w(MULTI DECOM COMMANDLOG PACKETLOG CLEANUP).each do |type|
684
645
  target_microservices = @target_microservices[type]
685
646
  if target_microservices
686
647
  max_instances = target_microservices.length + 1
@@ -929,16 +890,14 @@ module OpenC3
929
890
  if cmd_or_tlm == :TELEMETRY
930
891
  Topic.write_topic("MICROSERVICE__#{@scope}__PACKETLOG__#{@name}", {'command' => 'ADD_TOPICS', 'topics' => raw_topics.as_json.to_json})
931
892
  add_topics_to_microservice("#{@scope}__PACKETLOG__#{@name}", raw_topics)
932
- Topic.write_topic("MICROSERVICE__#{@scope}__DECOMLOG__#{@name}", {'command' => 'ADD_TOPICS', 'topics' => decom_topics.as_json.to_json})
933
- add_topics_to_microservice("#{@scope}__DECOMLOG__#{@name}", decom_topics)
934
893
  Topic.write_topic("MICROSERVICE__#{@scope}__DECOM__#{@name}", {'command' => 'ADD_TOPICS', 'topics' => raw_topics.as_json.to_json})
935
894
  add_topics_to_microservice("#{@scope}__DECOM__#{@name}", raw_topics)
936
895
  else
937
896
  Topic.write_topic("MICROSERVICE__#{@scope}__COMMANDLOG__#{@name}", {'command' => 'ADD_TOPICS', 'topics' => raw_topics.as_json.to_json})
938
897
  add_topics_to_microservice("#{@scope}__COMMANDLOG__#{@name}", raw_topics)
939
- Topic.write_topic("MICROSERVICE__#{@scope}__DECOMCMDLOG__#{@name}", {'command' => 'ADD_TOPICS', 'topics' => decom_topics.as_json.to_json})
940
- add_topics_to_microservice("#{@scope}__DECOMCMDLOG__#{@name}", decom_topics)
941
898
  end
899
+ Topic.write_topic("MICROSERVICE__#{@scope}__TSDB__#{@name}", {'command' => 'ADD_TOPICS', 'topics' => decom_topics.as_json.to_json})
900
+ add_topics_to_microservice("#{@scope}__TSDB__#{@name}", decom_topics)
942
901
  end
943
902
 
944
903
  def add_topics_to_microservice(microservice_name, topics)
@@ -976,33 +935,6 @@ module OpenC3
976
935
  Logger.info "Configured microservice #{microservice_name}"
977
936
  end
978
937
 
979
- def deploy_decomcmdlog_microservice(gem_path, variables, topics, instance = nil, parent = nil)
980
- microservice_name = "#{@scope}__DECOMCMDLOG#{instance}__#{@name}"
981
- microservice = MicroserviceModel.new(
982
- name: microservice_name,
983
- folder_name: @folder_name,
984
- cmd: ["ruby", "log_microservice.rb", microservice_name],
985
- work_dir: '/openc3/lib/openc3/microservices',
986
- options: [
987
- ["RAW_OR_DECOM", "DECOM"],
988
- ["CMD_OR_TLM", "CMD"],
989
- ["CYCLE_TIME", @cmd_decom_log_cycle_time],
990
- ["CYCLE_SIZE", @cmd_decom_log_cycle_size],
991
- ["BUFFER_DEPTH", @cmd_buffer_depth]
992
- ],
993
- topics: topics,
994
- plugin: @plugin,
995
- parent: parent,
996
- needs_dependencies: @needs_dependencies,
997
- shard: @shard,
998
- scope: @scope
999
- )
1000
- microservice.create
1001
- microservice.deploy(gem_path, variables)
1002
- @children << microservice_name if parent
1003
- Logger.info "Configured microservice #{microservice_name}"
1004
- end
1005
-
1006
938
  def deploy_packetlog_microservice(gem_path, variables, topics, instance = nil, parent = nil)
1007
939
  microservice_name = "#{@scope}__PACKETLOG#{instance}__#{@name}"
1008
940
  microservice = MicroserviceModel.new(
@@ -1030,47 +962,23 @@ module OpenC3
1030
962
  Logger.info "Configured microservice #{microservice_name}"
1031
963
  end
1032
964
 
1033
- def deploy_decomlog_microservice(gem_path, variables, topics, instance = nil, parent = nil)
1034
- microservice_name = "#{@scope}__DECOMLOG#{instance}__#{@name}"
1035
- microservice = MicroserviceModel.new(
1036
- name: microservice_name,
1037
- folder_name: @folder_name,
1038
- cmd: ["ruby", "log_microservice.rb", microservice_name],
1039
- work_dir: '/openc3/lib/openc3/microservices',
1040
- options: [
1041
- ["RAW_OR_DECOM", "DECOM"],
1042
- ["CMD_OR_TLM", "TLM"],
1043
- ["CYCLE_TIME", @tlm_decom_log_cycle_time],
1044
- ["CYCLE_SIZE", @tlm_decom_log_cycle_size],
1045
- ["BUFFER_DEPTH", @tlm_buffer_depth]
1046
- ],
1047
- topics: topics,
1048
- plugin: @plugin,
1049
- parent: parent,
1050
- needs_dependencies: @needs_dependencies,
1051
- shard: @shard,
1052
- scope: @scope
1053
- )
1054
- microservice.create
1055
- microservice.deploy(gem_path, variables)
1056
- @children << microservice_name if parent
1057
- Logger.info "Configured microservice #{microservice_name}"
1058
- end
1059
-
1060
965
  def deploy_decom_microservice(target, gem_path, variables, topics, instance = nil, parent = nil)
1061
966
  microservice_name = "#{@scope}__DECOM#{instance}__#{@name}"
1062
967
  # Assume Ruby initially
1063
968
  filename = 'decom_microservice.rb'
1064
969
  work_dir = '/openc3/lib/openc3/microservices'
970
+ language_cmd = target.language
1065
971
  if target.language == 'python'
1066
972
  filename = 'decom_microservice.py'
1067
973
  work_dir.sub!('openc3/lib', 'openc3/python')
1068
974
  parent = nil
975
+ # Use venv Python to ensure editable packages are found
976
+ language_cmd = ENV['OPENC3_PYTHON_BIN'] || '/openc3/python/.venv/bin/python'
1069
977
  end
1070
978
  microservice = MicroserviceModel.new(
1071
979
  name: microservice_name,
1072
980
  folder_name: @folder_name,
1073
- cmd: [target.language, filename, microservice_name],
981
+ cmd: [language_cmd, filename, microservice_name],
1074
982
  work_dir: work_dir,
1075
983
  topics: topics,
1076
984
  target_names: [@name],
@@ -1088,11 +996,15 @@ module OpenC3
1088
996
 
1089
997
  def deploy_tsdb_microservice(gem_path, variables, topics, instance = nil, parent = nil)
1090
998
  microservice_name = "#{@scope}__TSDB#{instance}__#{@name}"
999
+ options = []
1000
+ options << ["CMD_DECOM_RETAIN_TIME", @cmd_decom_retain_time] if @cmd_decom_retain_time
1001
+ options << ["TLM_DECOM_RETAIN_TIME", @tlm_decom_retain_time] if @tlm_decom_retain_time
1091
1002
  microservice = MicroserviceModel.new(
1092
1003
  name: microservice_name,
1093
1004
  folder_name: @folder_name,
1094
- cmd: ["python", "quest_microservice.py", microservice_name],
1005
+ cmd: [ENV['OPENC3_PYTHON_BIN'] || '/openc3/python/.venv/bin/python', "tsdb_microservice.py", microservice_name],
1095
1006
  work_dir: "/openc3/python/openc3/microservices",
1007
+ options: options,
1096
1008
  topics: topics,
1097
1009
  plugin: @plugin,
1098
1010
  parent: nil,
@@ -1105,30 +1017,6 @@ module OpenC3
1105
1017
  Logger.info "Configured microservice #{microservice_name}"
1106
1018
  end
1107
1019
 
1108
- def deploy_reducer_microservice(gem_path, variables, topics, instance = nil, parent = nil)
1109
- microservice_name = "#{@scope}__REDUCER#{instance}__#{@name}"
1110
- microservice = MicroserviceModel.new(
1111
- name: microservice_name,
1112
- folder_name: @folder_name,
1113
- cmd: ["ruby", "reducer_microservice.rb", microservice_name],
1114
- work_dir: '/openc3/lib/openc3/microservices',
1115
- options: [
1116
- ["MAX_CPU_UTILIZATION", @reducer_max_cpu_utilization],
1117
- ["BUFFER_DEPTH", @tlm_buffer_depth]
1118
- ],
1119
- topics: topics,
1120
- plugin: @plugin,
1121
- parent: parent,
1122
- needs_dependencies: @needs_dependencies,
1123
- shard: @shard,
1124
- scope: @scope
1125
- )
1126
- microservice.create
1127
- microservice.deploy(gem_path, variables)
1128
- @children << microservice_name if parent
1129
- Logger.info "Configured microservice #{microservice_name}"
1130
- end
1131
-
1132
1020
  def deploy_cleanup_microservice(gem_path, variables, instance = nil, parent = nil)
1133
1021
  microservice_name = "#{@scope}__CLEANUP#{instance}__#{@name}"
1134
1022
  microservice = MicroserviceModel.new(
@@ -1232,7 +1120,7 @@ module OpenC3
1232
1120
  end
1233
1121
 
1234
1122
  @parent = nil
1235
- %w(DECOM COMMANDLOG DECOMCMDLOG PACKETLOG DECOMLOG REDUCER CLEANUP).each do |type|
1123
+ %w(DECOM COMMANDLOG PACKETLOG CLEANUP).each do |type|
1236
1124
  unless @target_microservices[type]
1237
1125
  @parent = "#{@scope}__MULTI__#{@name}"
1238
1126
  break
@@ -1244,11 +1132,6 @@ module OpenC3
1244
1132
  deploy_target_microservices('COMMANDLOG', command_topic_list, "#{@scope}__COMMAND__{#{@name}}") do |topics, instance, parent|
1245
1133
  deploy_commmandlog_microservice(gem_path, variables, topics, instance, parent)
1246
1134
  end
1247
-
1248
- # DecomCmdLog Microservice
1249
- deploy_target_microservices('DECOMCMDLOG', decom_command_topic_list, "#{@scope}__DECOMCMD__{#{@name}}") do |topics, instance, parent|
1250
- deploy_decomcmdlog_microservice(gem_path, variables, topics, instance, parent)
1251
- end
1252
1135
  end
1253
1136
 
1254
1137
  unless packet_topic_list.empty?
@@ -1257,34 +1140,21 @@ module OpenC3
1257
1140
  deploy_packetlog_microservice(gem_path, variables, topics, instance, parent)
1258
1141
  end
1259
1142
 
1260
- # DecomLog Microservice
1261
- deploy_target_microservices('DECOMLOG', decom_topic_list, "#{@scope}__DECOM__{#{@name}}") do |topics, instance, parent|
1262
- deploy_decomlog_microservice(gem_path, variables, topics, instance, parent)
1263
- end
1264
-
1265
1143
  # Decommutation Microservice
1266
1144
  deploy_target_microservices('DECOM', packet_topic_list, "#{@scope}__TELEMETRY__{#{@name}}") do |topics, instance, parent|
1267
1145
  deploy_decom_microservice(system.targets[@name], gem_path, variables, topics, instance, parent)
1268
1146
  end
1147
+ end
1269
1148
 
1270
- # TSDB Microservice
1271
- if ENV['OPENC3_TSDB_HOSTNAME'] and ENV['OPENC3_TSDB_QUERY_PORT'] and ENV['OPENC3_TSDB_INGEST_PORT'] and ENV['OPENC3_TSDB_USERNAME'] and ENV['OPENC3_TSDB_PASSWORD']
1272
- deploy_target_microservices('TSDB', decom_topic_list, "#{@scope}__DECOM__{#{@name}}") do |topics, instance, parent|
1273
- deploy_tsdb_microservice(gem_path, variables, topics, instance, parent)
1274
- end
1275
- end
1276
-
1277
- # Reducer Microservice
1278
- unless @reducer_disable
1279
- # TODO: Does Reducer even need a topic list?
1280
- deploy_target_microservices('REDUCER', decom_topic_list, "#{@scope}__DECOM__{#{@name}}") do |topics, instance, parent|
1281
- deploy_reducer_microservice(gem_path, variables, topics, instance, parent)
1282
- end
1149
+ # TSDB Microservice - subscribes to both decommutated telemetry and commands
1150
+ tsdb_topic_list = decom_topic_list + decom_command_topic_list
1151
+ if !tsdb_topic_list.empty? and ENV['OPENC3_TSDB_HOSTNAME'] and ENV['OPENC3_TSDB_QUERY_PORT'] and ENV['OPENC3_TSDB_INGEST_PORT'] and ENV['OPENC3_TSDB_USERNAME'] and ENV['OPENC3_TSDB_PASSWORD']
1152
+ deploy_target_microservices('TSDB', tsdb_topic_list, "#{@scope}__DECOM") do |topics, instance, parent|
1153
+ deploy_tsdb_microservice(gem_path, variables, topics, instance, parent)
1283
1154
  end
1284
1155
  end
1285
1156
 
1286
- if @cmd_log_retain_time or @cmd_decom_log_retain_time or @tlm_log_retain_time or @tlm_decom_log_retain_time or
1287
- @reduced_minute_log_retain_time or @reduced_hour_log_retain_time or @reduced_day_log_retain_time
1157
+ if @cmd_log_retain_time or @tlm_log_retain_time
1288
1158
  # Cleanup Microservice
1289
1159
  deploy_target_microservices('CLEANUP', nil, nil) do |_, instance, parent|
1290
1160
  deploy_cleanup_microservice(gem_path, variables, instance, parent)
@@ -3,18 +3,13 @@
3
3
  # Copyright 2022 Ball Aerospace & Technologies Corp.
4
4
  # All Rights Reserved.
5
5
  #
6
- # This program is free software; you can modify and/or redistribute it
7
- # under the terms of the GNU Affero 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
6
  # This program is distributed in the hope that it will be useful,
12
7
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- # GNU Affero General Public License for more details.
8
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9
+ # See LICENSE.md for more details.
15
10
 
16
11
  # Modified by OpenC3, Inc.
17
- # All changes Copyright 2024, OpenC3, Inc.
12
+ # All changes Copyright 2026, OpenC3, Inc.
18
13
  # All Rights Reserved
19
14
  #
20
15
  # This file may also be used under the terms of a commercial license
@@ -3,18 +3,13 @@
3
3
  # Copyright 2022 Ball Aerospace & Technologies Corp.
4
4
  # All Rights Reserved.
5
5
  #
6
- # This program is free software; you can modify and/or redistribute it
7
- # under the terms of the GNU Affero 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
6
  # This program is distributed in the hope that it will be useful,
12
7
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- # GNU Affero General Public License for more details.
8
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9
+ # See LICENSE.md for more details.
15
10
 
16
11
  # Modified by OpenC3, Inc.
17
- # All changes Copyright 2022, OpenC3, Inc.
12
+ # All changes Copyright 2026, OpenC3, Inc.
18
13
  # All Rights Reserved
19
14
  #
20
15
  # This file may also be used under the terms of a commercial license
@@ -3,18 +3,13 @@
3
3
  # Copyright 2022 Ball Aerospace & Technologies Corp.
4
4
  # All Rights Reserved.
5
5
  #
6
- # This program is free software; you can modify and/or redistribute it
7
- # under the terms of the GNU Affero 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
6
  # This program is distributed in the hope that it will be useful,
12
7
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- # GNU Affero General Public License for more details.
8
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9
+ # See LICENSE.md for more details.
15
10
 
16
11
  # Modified by OpenC3, Inc.
17
- # All changes Copyright 2022, OpenC3, Inc.
12
+ # All changes Copyright 2026, OpenC3, Inc.
18
13
  # All Rights Reserved
19
14
  #
20
15
  # This file may also be used under the terms of a commercial license
@@ -281,8 +276,13 @@ module OpenC3
281
276
  if @folder_name and @folder_name.to_s.length > 0
282
277
  bucket = Bucket.getClient
283
278
  prefix = "#{@folder_name}/"
284
- bucket.list_objects(bucket: ENV['OPENC3_TOOLS_BUCKET'], prefix: prefix).each do |object|
285
- bucket.delete_object(bucket: ENV['OPENC3_TOOLS_BUCKET'], key: object.key)
279
+ objects = bucket.list_objects(bucket: ENV['OPENC3_TOOLS_BUCKET'], prefix: prefix)
280
+ keys = objects.map(&:key)
281
+ if keys.length > 0
282
+ # Batch delete in chunks of 1000 (S3 limit)
283
+ keys.each_slice(1000) do |key_batch|
284
+ bucket.delete_objects(bucket: ENV['OPENC3_TOOLS_BUCKET'], keys: key_batch)
285
+ end
286
286
  ConfigTopic.write({ kind: 'deleted', type: 'tool', name: @folder_name, plugin: @plugin }, scope: @scope)
287
287
  end
288
288
  end