openc3 5.0.6

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 (307) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +18 -0
  3. data/Guardfile +35 -0
  4. data/LICENSE.txt +727 -0
  5. data/README.md +37 -0
  6. data/Rakefile +131 -0
  7. data/bin/cstol_converter +1178 -0
  8. data/bin/openc3cli +531 -0
  9. data/bin/rubysloc +139 -0
  10. data/data/config/_array_params.yaml +23 -0
  11. data/data/config/_id_items.yaml +24 -0
  12. data/data/config/_id_params.yaml +58 -0
  13. data/data/config/_interfaces.yaml +214 -0
  14. data/data/config/_interfaces.yaml.err +1017 -0
  15. data/data/config/_items.yaml +20 -0
  16. data/data/config/_params.yaml +60 -0
  17. data/data/config/cmd_tlm_server.yaml +136 -0
  18. data/data/config/command.yaml +44 -0
  19. data/data/config/command_modifiers.yaml +160 -0
  20. data/data/config/command_telemetry.yaml +3 -0
  21. data/data/config/interface_modifiers.yaml +104 -0
  22. data/data/config/item_modifiers.yaml +221 -0
  23. data/data/config/microservice.yaml +78 -0
  24. data/data/config/param_item_modifiers.yaml +52 -0
  25. data/data/config/parameter_modifiers.yaml +200 -0
  26. data/data/config/plugins.yaml +80 -0
  27. data/data/config/protocols.yaml +290 -0
  28. data/data/config/screen.yaml +147 -0
  29. data/data/config/table_manager.yaml +89 -0
  30. data/data/config/table_parameter_modifiers.yaml +9 -0
  31. data/data/config/target.yaml +142 -0
  32. data/data/config/target_config.yaml +94 -0
  33. data/data/config/telemetry.yaml +87 -0
  34. data/data/config/telemetry_modifiers.yaml +159 -0
  35. data/data/config/tool.yaml +63 -0
  36. data/data/config/unknown.yaml +3 -0
  37. data/data/config/widgets.yaml +1505 -0
  38. data/ext/mkrf_conf.rb +49 -0
  39. data/ext/openc3/ext/array/array.c +122 -0
  40. data/ext/openc3/ext/array/extconf.rb +13 -0
  41. data/ext/openc3/ext/buffered_file/buffered_file.c +198 -0
  42. data/ext/openc3/ext/buffered_file/extconf.rb +13 -0
  43. data/ext/openc3/ext/config_parser/config_parser.c +280 -0
  44. data/ext/openc3/ext/config_parser/extconf.rb +13 -0
  45. data/ext/openc3/ext/crc/crc.c +351 -0
  46. data/ext/openc3/ext/crc/extconf.rb +13 -0
  47. data/ext/openc3/ext/openc3_io/extconf.rb +13 -0
  48. data/ext/openc3/ext/openc3_io/openc3_io.c +158 -0
  49. data/ext/openc3/ext/packet/extconf.rb +13 -0
  50. data/ext/openc3/ext/packet/packet.c +318 -0
  51. data/ext/openc3/ext/platform/extconf.rb +13 -0
  52. data/ext/openc3/ext/platform/platform.c +134 -0
  53. data/ext/openc3/ext/polynomial_conversion/extconf.rb +13 -0
  54. data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +79 -0
  55. data/ext/openc3/ext/string/extconf.rb +13 -0
  56. data/ext/openc3/ext/string/string.c +63 -0
  57. data/ext/openc3/ext/structure/structure.c +1719 -0
  58. data/ext/openc3/ext/tabbed_plots_config/extconf.rb +13 -0
  59. data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +62 -0
  60. data/ext/openc3/ext/telemetry/extconf.rb +13 -0
  61. data/ext/openc3/ext/telemetry/telemetry.c +336 -0
  62. data/lib/cosmos.rb +20 -0
  63. data/lib/cosmosc2.rb +20 -0
  64. data/lib/openc3/api/api.rb +39 -0
  65. data/lib/openc3/api/authorized_api.rb +30 -0
  66. data/lib/openc3/api/cmd_api.rb +451 -0
  67. data/lib/openc3/api/config_api.rb +58 -0
  68. data/lib/openc3/api/interface_api.rb +117 -0
  69. data/lib/openc3/api/limits_api.rb +375 -0
  70. data/lib/openc3/api/router_api.rb +117 -0
  71. data/lib/openc3/api/settings_api.rb +70 -0
  72. data/lib/openc3/api/target_api.rb +78 -0
  73. data/lib/openc3/api/tlm_api.rb +455 -0
  74. data/lib/openc3/bridge/bridge.rb +54 -0
  75. data/lib/openc3/bridge/bridge_config.rb +167 -0
  76. data/lib/openc3/bridge/bridge_interface_thread.rb +42 -0
  77. data/lib/openc3/bridge/bridge_router_thread.rb +42 -0
  78. data/lib/openc3/ccsds/ccsds_packet.rb +68 -0
  79. data/lib/openc3/ccsds/ccsds_parser.rb +148 -0
  80. data/lib/openc3/config/config_parser.rb +549 -0
  81. data/lib/openc3/config/meta_config_parser.rb +74 -0
  82. data/lib/openc3/conversions/conversion.rb +70 -0
  83. data/lib/openc3/conversions/generic_conversion.rb +83 -0
  84. data/lib/openc3/conversions/packet_time_formatted_conversion.rb +43 -0
  85. data/lib/openc3/conversions/packet_time_seconds_conversion.rb +43 -0
  86. data/lib/openc3/conversions/polynomial_conversion.rb +87 -0
  87. data/lib/openc3/conversions/processor_conversion.rb +70 -0
  88. data/lib/openc3/conversions/received_count_conversion.rb +38 -0
  89. data/lib/openc3/conversions/received_time_formatted_conversion.rb +42 -0
  90. data/lib/openc3/conversions/received_time_seconds_conversion.rb +42 -0
  91. data/lib/openc3/conversions/segmented_polynomial_conversion.rb +171 -0
  92. data/lib/openc3/conversions/unix_time_conversion.rb +68 -0
  93. data/lib/openc3/conversions/unix_time_formatted_conversion.rb +49 -0
  94. data/lib/openc3/conversions/unix_time_seconds_conversion.rb +49 -0
  95. data/lib/openc3/conversions.rb +34 -0
  96. data/lib/openc3/core_ext/array.rb +416 -0
  97. data/lib/openc3/core_ext/binding.rb +29 -0
  98. data/lib/openc3/core_ext/class.rb +72 -0
  99. data/lib/openc3/core_ext/exception.rb +61 -0
  100. data/lib/openc3/core_ext/file.rb +83 -0
  101. data/lib/openc3/core_ext/hash.rb +37 -0
  102. data/lib/openc3/core_ext/io.rb +134 -0
  103. data/lib/openc3/core_ext/kernel.rb +42 -0
  104. data/lib/openc3/core_ext/math.rb +128 -0
  105. data/lib/openc3/core_ext/matrix.rb +156 -0
  106. data/lib/openc3/core_ext/objectspace.rb +36 -0
  107. data/lib/openc3/core_ext/openc3_io.rb +57 -0
  108. data/lib/openc3/core_ext/range.rb +27 -0
  109. data/lib/openc3/core_ext/socket.rb +38 -0
  110. data/lib/openc3/core_ext/string.rb +389 -0
  111. data/lib/openc3/core_ext/stringio.rb +33 -0
  112. data/lib/openc3/core_ext/time.rb +508 -0
  113. data/lib/openc3/core_ext.rb +36 -0
  114. data/lib/openc3/interfaces/interface.rb +498 -0
  115. data/lib/openc3/interfaces/linc_interface.rb +475 -0
  116. data/lib/openc3/interfaces/protocols/burst_protocol.rb +192 -0
  117. data/lib/openc3/interfaces/protocols/crc_protocol.rb +193 -0
  118. data/lib/openc3/interfaces/protocols/fixed_protocol.rb +155 -0
  119. data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +56 -0
  120. data/lib/openc3/interfaces/protocols/length_protocol.rb +165 -0
  121. data/lib/openc3/interfaces/protocols/override_protocol.rb +60 -0
  122. data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +206 -0
  123. data/lib/openc3/interfaces/protocols/protocol.rb +82 -0
  124. data/lib/openc3/interfaces/protocols/template_protocol.rb +261 -0
  125. data/lib/openc3/interfaces/protocols/terminated_protocol.rb +93 -0
  126. data/lib/openc3/interfaces/serial_interface.rb +94 -0
  127. data/lib/openc3/interfaces/simulated_target_interface.rb +168 -0
  128. data/lib/openc3/interfaces/stream_interface.rb +81 -0
  129. data/lib/openc3/interfaces/tcpip_client_interface.rb +69 -0
  130. data/lib/openc3/interfaces/tcpip_server_interface.rb +629 -0
  131. data/lib/openc3/interfaces/udp_interface.rb +169 -0
  132. data/lib/openc3/interfaces.rb +44 -0
  133. data/lib/openc3/io/buffered_file.rb +109 -0
  134. data/lib/openc3/io/io_multiplexer.rb +80 -0
  135. data/lib/openc3/io/json_api_object.rb +208 -0
  136. data/lib/openc3/io/json_drb.rb +335 -0
  137. data/lib/openc3/io/json_drb_object.rb +114 -0
  138. data/lib/openc3/io/json_drb_rack.rb +84 -0
  139. data/lib/openc3/io/json_rpc.rb +420 -0
  140. data/lib/openc3/io/openc3_snmp.rb +58 -0
  141. data/lib/openc3/io/posix_serial_driver.rb +156 -0
  142. data/lib/openc3/io/raw_logger.rb +167 -0
  143. data/lib/openc3/io/raw_logger_pair.rb +77 -0
  144. data/lib/openc3/io/serial_driver.rb +105 -0
  145. data/lib/openc3/io/stderr.rb +43 -0
  146. data/lib/openc3/io/stdout.rb +43 -0
  147. data/lib/openc3/io/udp_sockets.rb +194 -0
  148. data/lib/openc3/io/win32_serial_driver.rb +196 -0
  149. data/lib/openc3/logs/log_writer.rb +302 -0
  150. data/lib/openc3/logs/packet_log_constants.rb +62 -0
  151. data/lib/openc3/logs/packet_log_reader.rb +345 -0
  152. data/lib/openc3/logs/packet_log_writer.rb +299 -0
  153. data/lib/openc3/logs/text_log_writer.rb +68 -0
  154. data/lib/openc3/logs.rb +25 -0
  155. data/lib/openc3/microservices/cleanup_microservice.rb +68 -0
  156. data/lib/openc3/microservices/decom_microservice.rb +136 -0
  157. data/lib/openc3/microservices/interface_microservice.rb +532 -0
  158. data/lib/openc3/microservices/log_microservice.rb +108 -0
  159. data/lib/openc3/microservices/microservice.rb +204 -0
  160. data/lib/openc3/microservices/plugin_microservice.rb +43 -0
  161. data/lib/openc3/microservices/reaction_microservice.rb +541 -0
  162. data/lib/openc3/microservices/reducer_microservice.rb +313 -0
  163. data/lib/openc3/microservices/router_microservice.rb +44 -0
  164. data/lib/openc3/microservices/text_log_microservice.rb +84 -0
  165. data/lib/openc3/microservices/timeline_microservice.rb +363 -0
  166. data/lib/openc3/microservices/trigger_group_microservice.rb +638 -0
  167. data/lib/openc3/models/activity_model.rb +319 -0
  168. data/lib/openc3/models/auth_model.rb +65 -0
  169. data/lib/openc3/models/cvt_model.rb +185 -0
  170. data/lib/openc3/models/environment_model.rb +58 -0
  171. data/lib/openc3/models/gem_model.rb +137 -0
  172. data/lib/openc3/models/info_model.rb +31 -0
  173. data/lib/openc3/models/interface_model.rb +281 -0
  174. data/lib/openc3/models/interface_status_model.rb +117 -0
  175. data/lib/openc3/models/metadata_model.rb +139 -0
  176. data/lib/openc3/models/metric_model.rb +59 -0
  177. data/lib/openc3/models/microservice_model.rb +206 -0
  178. data/lib/openc3/models/microservice_status_model.rb +74 -0
  179. data/lib/openc3/models/model.rb +204 -0
  180. data/lib/openc3/models/note_model.rb +122 -0
  181. data/lib/openc3/models/notification_model.rb +40 -0
  182. data/lib/openc3/models/ping_model.rb +35 -0
  183. data/lib/openc3/models/plugin_model.rb +292 -0
  184. data/lib/openc3/models/process_status_model.rb +76 -0
  185. data/lib/openc3/models/reaction_model.rb +322 -0
  186. data/lib/openc3/models/reducer_model.rb +65 -0
  187. data/lib/openc3/models/router_model.rb +35 -0
  188. data/lib/openc3/models/router_status_model.rb +27 -0
  189. data/lib/openc3/models/scope_model.rb +153 -0
  190. data/lib/openc3/models/settings_model.rb +55 -0
  191. data/lib/openc3/models/sorted_model.rb +167 -0
  192. data/lib/openc3/models/target_model.rb +759 -0
  193. data/lib/openc3/models/timeline_model.rb +154 -0
  194. data/lib/openc3/models/tool_config_model.rb +38 -0
  195. data/lib/openc3/models/tool_model.rb +262 -0
  196. data/lib/openc3/models/trigger_group_model.rb +186 -0
  197. data/lib/openc3/models/trigger_model.rb +330 -0
  198. data/lib/openc3/models/widget_model.rb +138 -0
  199. data/lib/openc3/operators/microservice_operator.rb +128 -0
  200. data/lib/openc3/operators/operator.rb +277 -0
  201. data/lib/openc3/packets/binary_accessor.rb +1207 -0
  202. data/lib/openc3/packets/commands.rb +373 -0
  203. data/lib/openc3/packets/json_packet.rb +134 -0
  204. data/lib/openc3/packets/limits.rb +271 -0
  205. data/lib/openc3/packets/limits_response.rb +53 -0
  206. data/lib/openc3/packets/packet.rb +1168 -0
  207. data/lib/openc3/packets/packet_config.rb +625 -0
  208. data/lib/openc3/packets/packet_item.rb +586 -0
  209. data/lib/openc3/packets/packet_item_limits.rb +162 -0
  210. data/lib/openc3/packets/parsers/format_string_parser.rb +65 -0
  211. data/lib/openc3/packets/parsers/limits_parser.rb +159 -0
  212. data/lib/openc3/packets/parsers/limits_response_parser.rb +61 -0
  213. data/lib/openc3/packets/parsers/packet_item_parser.rb +272 -0
  214. data/lib/openc3/packets/parsers/packet_parser.rb +134 -0
  215. data/lib/openc3/packets/parsers/processor_parser.rb +73 -0
  216. data/lib/openc3/packets/parsers/state_parser.rb +127 -0
  217. data/lib/openc3/packets/parsers/xtce_converter.rb +442 -0
  218. data/lib/openc3/packets/parsers/xtce_parser.rb +722 -0
  219. data/lib/openc3/packets/structure.rb +553 -0
  220. data/lib/openc3/packets/structure_item.rb +365 -0
  221. data/lib/openc3/packets/telemetry.rb +487 -0
  222. data/lib/openc3/processors/processor.rb +86 -0
  223. data/lib/openc3/processors/statistics_processor.rb +82 -0
  224. data/lib/openc3/processors/watermark_processor.rb +58 -0
  225. data/lib/openc3/processors.rb +24 -0
  226. data/lib/openc3/script/api_shared.rb +828 -0
  227. data/lib/openc3/script/calendar.rb +89 -0
  228. data/lib/openc3/script/commands.rb +227 -0
  229. data/lib/openc3/script/exceptions.rb +29 -0
  230. data/lib/openc3/script/extract.rb +161 -0
  231. data/lib/openc3/script/limits.rb +60 -0
  232. data/lib/openc3/script/script.rb +299 -0
  233. data/lib/openc3/script/script_runner.rb +238 -0
  234. data/lib/openc3/script/storage.rb +146 -0
  235. data/lib/openc3/script/suite.rb +542 -0
  236. data/lib/openc3/script/suite_results.rb +196 -0
  237. data/lib/openc3/script/suite_runner.rb +217 -0
  238. data/lib/openc3/script.rb +21 -0
  239. data/lib/openc3/streams/serial_stream.rb +167 -0
  240. data/lib/openc3/streams/stream.rb +63 -0
  241. data/lib/openc3/streams/tcpip_client_stream.rb +116 -0
  242. data/lib/openc3/streams/tcpip_socket_stream.rb +195 -0
  243. data/lib/openc3/system/system.rb +127 -0
  244. data/lib/openc3/system/system_config.rb +411 -0
  245. data/lib/openc3/system/target.rb +269 -0
  246. data/lib/openc3/system.rb +24 -0
  247. data/lib/openc3/tools/cmd_tlm_server/api.rb +20 -0
  248. data/lib/openc3/tools/cmd_tlm_server/cmd_tlm_server_config.rb +320 -0
  249. data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +294 -0
  250. data/lib/openc3/tools/table_manager/table.rb +77 -0
  251. data/lib/openc3/tools/table_manager/table_config.rb +273 -0
  252. data/lib/openc3/tools/table_manager/table_item.rb +90 -0
  253. data/lib/openc3/tools/table_manager/table_item_parser.rb +66 -0
  254. data/lib/openc3/tools/table_manager/table_manager_core.rb +333 -0
  255. data/lib/openc3/tools/table_manager/table_parser.rb +93 -0
  256. data/lib/openc3/tools/test_runner/test.rb +67 -0
  257. data/lib/openc3/top_level.rb +595 -0
  258. data/lib/openc3/topics/autonomic_topic.rb +52 -0
  259. data/lib/openc3/topics/calendar_topic.rb +44 -0
  260. data/lib/openc3/topics/command_decom_topic.rb +76 -0
  261. data/lib/openc3/topics/command_topic.rb +83 -0
  262. data/lib/openc3/topics/config_topic.rb +68 -0
  263. data/lib/openc3/topics/interface_topic.rb +73 -0
  264. data/lib/openc3/topics/limits_event_topic.rb +109 -0
  265. data/lib/openc3/topics/notifications_topic.rb +28 -0
  266. data/lib/openc3/topics/router_topic.rb +85 -0
  267. data/lib/openc3/topics/telemetry_decom_topic.rb +54 -0
  268. data/lib/openc3/topics/telemetry_topic.rb +36 -0
  269. data/lib/openc3/topics/timeline_topic.rb +45 -0
  270. data/lib/openc3/topics/topic.rb +53 -0
  271. data/lib/openc3/utilities/authentication.rb +141 -0
  272. data/lib/openc3/utilities/authorization.rb +51 -0
  273. data/lib/openc3/utilities/crc.rb +278 -0
  274. data/lib/openc3/utilities/csv.rb +153 -0
  275. data/lib/openc3/utilities/logger.rb +187 -0
  276. data/lib/openc3/utilities/message_log.rb +91 -0
  277. data/lib/openc3/utilities/metric.rb +141 -0
  278. data/lib/openc3/utilities/process_manager.rb +139 -0
  279. data/lib/openc3/utilities/quaternion.rb +257 -0
  280. data/lib/openc3/utilities/ruby_lex_utils.rb +568 -0
  281. data/lib/openc3/utilities/s3.rb +202 -0
  282. data/lib/openc3/utilities/s3_autoload.rb +9 -0
  283. data/lib/openc3/utilities/s3_file_cache.rb +274 -0
  284. data/lib/openc3/utilities/simulated_target.rb +117 -0
  285. data/lib/openc3/utilities/sleeper.rb +51 -0
  286. data/lib/openc3/utilities/store.rb +23 -0
  287. data/lib/openc3/utilities/store_autoload.rb +237 -0
  288. data/lib/openc3/utilities/zip.rb +21 -0
  289. data/lib/openc3/utilities.rb +35 -0
  290. data/lib/openc3/version.rb +14 -0
  291. data/lib/openc3/win32/excel.rb +132 -0
  292. data/lib/openc3/win32/win32.rb +402 -0
  293. data/lib/openc3/win32/win32_main.rb +333 -0
  294. data/lib/openc3.rb +49 -0
  295. data/tasks/gemfile_stats.rake +113 -0
  296. data/tasks/spec.rake +30 -0
  297. data/templates/plugin-template/README.md +15 -0
  298. data/templates/plugin-template/Rakefile +12 -0
  299. data/templates/plugin-template/plugin.gemspec +23 -0
  300. data/templates/plugin-template/plugin.txt +9 -0
  301. data/templates/plugin-template/targets/TARGET/cmd_tlm/cmd.txt +8 -0
  302. data/templates/plugin-template/targets/TARGET/cmd_tlm/tlm.txt +8 -0
  303. data/templates/plugin-template/targets/TARGET/lib/target.rb +10 -0
  304. data/templates/plugin-template/targets/TARGET/procedures/procedure.rb +3 -0
  305. data/templates/plugin-template/targets/TARGET/screens/status.txt +9 -0
  306. data/templates/plugin-template/targets/TARGET/target.txt +5 -0
  307. metadata +849 -0
@@ -0,0 +1,508 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU 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
+ # This program is distributed in the hope that it will be useful,
12
+ # 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.
15
+
16
+ # Modified by OpenC3, Inc.
17
+ # All changes Copyright 2022, OpenC3, Inc.
18
+ # All Rights Reserved
19
+
20
+ require 'date'
21
+
22
+ # This file contains the OpenC3 specific additions to the Ruby Time class
23
+ #
24
+ # Time is expressed in many different ways and with many different epochs.
25
+ # This file supports the following formats:
26
+ # Julian Date (jd or julian)
27
+ # Modified Julian Date (mjd)
28
+ # yds (year, day, and seconds of day)
29
+ # mdy (year, month, day, hour, minute, second, us of second)
30
+ # ccsds (day, ms, us from Jan 1, 1958 midnight)
31
+ # time (a ruby time object with unix epoch Jan 1, 1970 midnight)
32
+ # sec (seconds since an arbitrary epoch)
33
+ class Time
34
+ # There are 365.25 days per year because of leap years. In the Gregorian
35
+ # calendar some centuries have 36524 days because of the divide by 400 rule
36
+ # while others have 36525 days. The Julian century is DEFINED as having 36525
37
+ # days.
38
+ JULIAN_DAYS_PER_CENTURY = 36525.0
39
+ # -4713/01/01 Noon
40
+ JULIAN_DATE_OF_JULIAN_EPOCH = 0.0
41
+ # 1858/11/17 Midnight
42
+ JULIAN_DATE_OF_MJD_EPOCH = 2400000.5
43
+ # 1980/01/06 Midnight
44
+ JULIAN_DATE_OF_GPS_EPOCH = 2444244.5
45
+ # 2000/01/01 Noon
46
+ JULIAN_DATE_OF_J2000_EPOCH = 2451545.0
47
+ # 1958/01/01 Midnight
48
+ JULIAN_DATE_OF_CCSDS_EPOCH = 2436204.5
49
+
50
+ DATE_TIME_MJD_EPOCH = DateTime.new(1858, 11, 17)
51
+
52
+ USEC_PER_MSEC = 1000
53
+ MSEC_PER_SECOND = 1000
54
+ SEC_PER_MINUTE = 60
55
+ MINUTES_PER_HOUR = 60
56
+ HOURS_PER_DAY = 24
57
+ NSEC_PER_SECOND = 1_000_000_000
58
+ USEC_PER_SECOND = USEC_PER_MSEC * MSEC_PER_SECOND
59
+ MSEC_PER_MINUTE = 60 * MSEC_PER_SECOND
60
+ MSEC_PER_HOUR = 60 * MSEC_PER_MINUTE
61
+ MSEC_PER_DAY = HOURS_PER_DAY * MSEC_PER_HOUR
62
+ SEC_PER_HOUR = SEC_PER_MINUTE * MINUTES_PER_HOUR
63
+ SEC_PER_DAY = HOURS_PER_DAY * SEC_PER_HOUR
64
+ USEC_PER_DAY = USEC_PER_SECOND * SEC_PER_DAY
65
+ MINUTES_PER_DAY = MINUTES_PER_HOUR * HOURS_PER_DAY
66
+
67
+ USEC_PER_MSEC_FLOAT = USEC_PER_MSEC.to_f
68
+ MSEC_PER_SECOND_FLOAT = MSEC_PER_SECOND.to_f
69
+ SEC_PER_MINUTE_FLOAT = SEC_PER_MINUTE.to_f
70
+ MINUTES_PER_HOUR_FLOAT = MINUTES_PER_HOUR.to_f
71
+ HOURS_PER_DAY_FLOAT = HOURS_PER_DAY.to_f
72
+ USEC_PER_SECOND_FLOAT = USEC_PER_SECOND.to_f
73
+ MSEC_PER_MINUTE_FLOAT = MSEC_PER_MINUTE.to_f
74
+ MSEC_PER_HOUR_FLOAT = MSEC_PER_HOUR.to_f
75
+ MSEC_PER_DAY_FLOAT = MSEC_PER_DAY.to_f
76
+ SEC_PER_HOUR_FLOAT = SEC_PER_HOUR.to_f
77
+ SEC_PER_DAY_FLOAT = SEC_PER_DAY.to_f
78
+ USEC_PER_DAY_FLOAT = USEC_PER_DAY.to_f
79
+ MINUTES_PER_DAY_FLOAT = MINUTES_PER_DAY.to_f
80
+
81
+ # Class variable that allows us to globally select whether to use
82
+ # UTC or local time.
83
+ @@use_utc = false
84
+
85
+ # Set up the Time class so that a call to the sys method will set the
86
+ # Time object being operated upon to be a UTC time.
87
+ def self.use_utc
88
+ @@use_utc = true
89
+ end
90
+
91
+ # Set up the Time class so that a call to the sys method will set the
92
+ # Time object being operated upon to be a local time.
93
+ def self.use_local
94
+ @@use_utc = false
95
+ end
96
+
97
+ # Set the Time object to be either a UTC or local time depending on the
98
+ # use_utc flag.
99
+ def sys
100
+ if @@use_utc
101
+ self.utc
102
+ else
103
+ self.localtime
104
+ end
105
+ end
106
+
107
+ # @param seconds [Numeric] Total number of seconds
108
+ # @return [String] Seconds formatted as a human readable string with days,
109
+ # hours, minutes, and seconds.
110
+ def self.format_seconds(seconds)
111
+ result = ""
112
+ mm, ss = seconds.divmod(60)
113
+ hh, mm = mm.divmod(60)
114
+ dd, hh = hh.divmod(24)
115
+ if dd != 0
116
+ if dd == 1
117
+ result << "%d day, " % dd
118
+ else
119
+ result << "%d days, " % dd
120
+ end
121
+ end
122
+ if hh != 0
123
+ if hh == 1
124
+ result << "%d hour, " % hh
125
+ else
126
+ result << "%d hours, " % hh
127
+ end
128
+ end
129
+ if mm != 0
130
+ if mm == 1
131
+ result << "%d minute, " % mm
132
+ else
133
+ result << "%d minutes, " % mm
134
+ end
135
+ end
136
+ if ss > 0
137
+ result << "%.2f seconds" % ss
138
+ else
139
+ result = result[0..-3]
140
+ end
141
+ result
142
+ end
143
+
144
+ if not defined?(LeapYearMonthDays)
145
+ # The number of days in each month during a leap year
146
+ LeapYearMonthDays = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
147
+ end
148
+
149
+ if not defined?(CommonYearMonthDays)
150
+ # The number of days in each month during a year (not a leap year)
151
+ CommonYearMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
152
+ end
153
+
154
+ # Convert the given year, month, day, hour, minute, second, and us
155
+ # into a Julian date. Julian dates are the number of days (plus fractional
156
+ # days) since Jan 1, 4713 BC at noon.
157
+ #
158
+ # @param year [Integer]
159
+ # @param month [Integer]
160
+ # @param day [Integer]
161
+ # @param hour [Integer]
162
+ # @param minute [Integer]
163
+ # @param second [Integer]
164
+ # @param us [Integer]
165
+ # @return [Float] The given time as a Julian date
166
+ def self.mdy2julian(year, month = 1, day = 1, hour = 0, minute = 0, second = 0, us = 0)
167
+ # Note DateTime does not support fractions of seconds
168
+ date_time = DateTime.new(year, month, day, hour, minute, second)
169
+ (date_time - DATE_TIME_MJD_EPOCH).to_f + JULIAN_DATE_OF_MJD_EPOCH + us / USEC_PER_DAY_FLOAT
170
+ end
171
+
172
+ # @return [Float] The Time converted to a julian date
173
+ def to_julian
174
+ return Time.mdy2julian(self.year, self.month, self.day, self.hour, self.min, self.sec, self.usec)
175
+ end
176
+ alias to_jd to_julian
177
+
178
+ # Convert the given year, month, day, hour, minute, second, and us
179
+ # into a Modified Julian date. Modified Julian dates have an Epoch of Nov 17,
180
+ # 1858 at midnight.
181
+ #
182
+ # @param year [Integer]
183
+ # @param month [Integer]
184
+ # @param day [Integer]
185
+ # @param hour [Integer]
186
+ # @param minute [Integer]
187
+ # @param second [Integer]
188
+ # @param us [Integer]
189
+ # @return [Time] The given time as a Julian date
190
+ def self.mdy2mjd(year, month = 1, day = 1, hour = 0, minute = 0, second = 0, us = 0)
191
+ return Time.mdy2julian(year, month, day, hour, minute, second, us) - JULIAN_DATE_OF_MJD_EPOCH
192
+ end
193
+
194
+ # Convert a time object to the modified julian date
195
+ def to_mjd
196
+ return Time.mdy2mjd(self.year, self.month, self.day, self.hour, self.min, self.sec, self.usec)
197
+ end
198
+
199
+ # Create a new time object given year, day of year (1-366), and seconds of day
200
+ #
201
+ # @param year [Integer]
202
+ # @param day_of_year [Integer] (1-366)
203
+ # @param sec_of_day [Integer]
204
+ def self.yds(year, day_of_year, sec_of_day)
205
+ return Time.utc(*yds2mdy(year, day_of_year, sec_of_day))
206
+ end
207
+
208
+ # @param year [Integer]
209
+ # @return [Boolean] Whether the year is a leap year
210
+ def self.leap_year?(year)
211
+ return_value = false
212
+
213
+ if (year % 4) == 0
214
+ return_value = true
215
+
216
+ if (year % 100) == 0
217
+ return_value = false
218
+
219
+ if (year % 400) == 0
220
+ return_value = true
221
+ end
222
+ end
223
+ end
224
+
225
+ return return_value
226
+ end
227
+
228
+ # @return [Boolean] Whether the year is a leap year
229
+ def leap_year?
230
+ Time.leap_year?(self.year)
231
+ end
232
+
233
+ # @param hour [Integer]
234
+ # @param minute [Integer]
235
+ # @param second [Integer]
236
+ # @param us [Integer]
237
+ # @return [Float] The number of seconds represented by the hours, minutes,
238
+ # seconds and microseconds
239
+ def self.total_seconds(hour, minute, second, us)
240
+ (hour * SEC_PER_HOUR_FLOAT) + (minute * SEC_PER_MINUTE_FLOAT) + second + (us / USEC_PER_SECOND_FLOAT)
241
+ end
242
+
243
+ # @return [Float] The number of seconds in the day (0-86399.99)
244
+ def seconds_of_day
245
+ Time.total_seconds(self.hour, self.min, self.sec, self.usec)
246
+ end
247
+
248
+ # @return [String] Date formatted as YYYY/MM/DD HH:MM:SS.US UTC_OFFSET
249
+ def formatted(include_year = true, fractional_digits = 3, include_utc_offset = false)
250
+ str = ""
251
+ str << "%Y/%m/%d " if include_year
252
+ str << "%H:%M:%S"
253
+ str << ".%#{fractional_digits}N" if fractional_digits > 0
254
+ if include_utc_offset
255
+ if self.utc?
256
+ str << " UTC"
257
+ else
258
+ str << " %z"
259
+ end
260
+ end
261
+ self.strftime(str)
262
+ end
263
+
264
+ # @return [String] Date formatted as YYYYMMDDHHmmSSNNNNNNNNN
265
+ def to_timestamp
266
+ self.strftime("%Y%m%d%H%M%S%N")
267
+ end
268
+
269
+ # @param time [Time]
270
+ # @return [Float] Number of julian days since Jan 1, 2000 at noon
271
+ def self.days_from_j2000(time)
272
+ time.to_julian - JULIAN_DATE_OF_J2000_EPOCH
273
+ end
274
+
275
+ # @param time [Time]
276
+ # @return [Float] Number of julian centuries since Jan 1, 2000 at noon
277
+ def self.julian_centuries_since_j2000(time)
278
+ self.days_from_j2000(time) / JULIAN_DAYS_PER_CENTURY
279
+ end
280
+
281
+ # Convert a Julian Date to mdy format
282
+ # Note that an array is returned rather than a Time object because Time objects cannot represent
283
+ # all possible Julian dates
284
+ #
285
+ # @param jdate [Float] Julian date
286
+ # @return [Array<Year, Month, Day, Hour, Minute, Second, Microsecond>] Julian date converted to an array of values
287
+ def self.julian2mdy(jdate)
288
+ z = (jdate + 0.5).to_i
289
+ w = ((z - 1867216.25) / 36524.25).to_i
290
+ x = w / 4
291
+ a = z + 1 + w - x
292
+ b = a + 1524
293
+ c = ((b - 122.1) / 365.25).to_i
294
+ d = (365.25 * c).to_i
295
+ e = ((b - d) / 30.6001).to_i
296
+ f = (30.6001 * e).to_i
297
+
298
+ day = b - d - f
299
+ if e > 13
300
+ month = e - 13
301
+ else
302
+ month = e - 1
303
+ end
304
+ if month > 2
305
+ year = c - 4716
306
+ else
307
+ year = c - 4715
308
+ end
309
+
310
+ fraction = jdate - jdate.to_i
311
+
312
+ if fraction >= 0.5
313
+ hour = (fraction - 0.5) * 24.0
314
+ else
315
+ hour = (fraction * 24.0) + 12.0
316
+ end
317
+
318
+ fraction = hour - hour.to_i
319
+ hour = hour.to_i
320
+
321
+ minute = fraction * 60.0
322
+
323
+ fraction = minute - minute.to_i
324
+ minute = minute.to_i
325
+
326
+ second = fraction * 60.0
327
+
328
+ fraction = second - second.to_i
329
+ second = second.to_i
330
+
331
+ us = fraction * 1000000.0
332
+ us = us.to_i
333
+
334
+ return [year, month, day, hour, minute, second, us]
335
+ end
336
+
337
+ # Convert a CCSDS Date to mdy format
338
+ # Note that an array is returned rather than a Time object because Time objects cannot represent
339
+ # all possible CCSDS dates
340
+ #
341
+ # @param day [Float] CCSDS day
342
+ # @param ms [Integer] CCSDS milliseconds
343
+ # @param us [Integer] CCSDS microseconds
344
+ # @return [Array<Year, Month, Day, Hour, Minute, Second, Microsecond>] CCSDS date converted to an array of values
345
+ def self.ccsds2mdy(day, ms, us)
346
+ jdate = day + JULIAN_DATE_OF_CCSDS_EPOCH
347
+ year, month, day, hour, minute, second, _ = julian2mdy(jdate)
348
+ hour = (ms / MSEC_PER_HOUR).to_i
349
+ temp = ms - (hour * MSEC_PER_HOUR)
350
+ minute = (temp / MSEC_PER_MINUTE).to_i
351
+ temp -= minute * MSEC_PER_MINUTE
352
+ second = temp / MSEC_PER_SECOND
353
+ temp -= second * MSEC_PER_SECOND
354
+ us = us + (temp * USEC_PER_MSEC)
355
+ return [year, month, day, hour, minute, second, us]
356
+ end
357
+
358
+ # Convert from mdy format to CCSDS Date
359
+ # Note that an array is used rather than a Time object because Time objects cannot represent
360
+ # all possible CCSDS dates
361
+ #
362
+ # @param year [Integer]
363
+ # @param month [Integer]
364
+ # @param day [Integer]
365
+ # @param hour [Integer]
366
+ # @param minute [Integer]
367
+ # @param second [Integer]
368
+ # @param us [Integer]
369
+ # @return [Array<day, ms, us>] MDY converted to CCSDS
370
+ def self.mdy2ccsds(year, month, day, hour, minute, second, us)
371
+ ms = (hour * MSEC_PER_HOUR) + (minute * MSEC_PER_MINUTE) + (second * MSEC_PER_SECOND) + (us / USEC_PER_MSEC)
372
+ us = us % USEC_PER_MSEC
373
+ jd = Time.mdy2julian(year, month, day, 0, 0, 0, 0)
374
+ day = (jd - JULIAN_DATE_OF_CCSDS_EPOCH).round
375
+ return [day, ms, us]
376
+ end
377
+
378
+ # @param day [Float] CCSDS day
379
+ # @param ms [Integer] CCSDS milliseconds
380
+ # @param us [Integer] CCSDS microseconds
381
+ # @return [Float] The CCSDS date converted to a julian date
382
+ def self.ccsds2julian(day, ms, us)
383
+ (day + JULIAN_DATE_OF_CCSDS_EPOCH) + ((ms.to_f + (us / 1000.0)) / MSEC_PER_DAY_FLOAT)
384
+ end
385
+
386
+ # @param jdate [Float] julian date
387
+ # @return [Array<day, ms, us>] Julian converted to CCSDS
388
+ def self.julian2ccsds(jdate)
389
+ day = jdate - JULIAN_DATE_OF_CCSDS_EPOCH
390
+ fraction = day % 1.0
391
+ day = day.to_i
392
+ ms = fraction * MSEC_PER_DAY_FLOAT
393
+ fraction = ms % 1.0
394
+ ms = ms.to_i
395
+ us = fraction * USEC_PER_MSEC
396
+ us = us.to_i
397
+ return [day, ms, us]
398
+ end
399
+
400
+ # @param day [Float] CCSDS day
401
+ # @param ms [Integer] CCSDS milliseconds
402
+ # @param us [Integer] CCSDS microseconds
403
+ # @param sec_epoch_jd [Float] Epoch to convert seconds from as a julian date
404
+ # @return [Float] The number of seconds from the given epoch to the given
405
+ # CCSDS day, milliseconds, and microseconds.
406
+ def self.ccsds2sec(day, ms, us, sec_epoch_jd = JULIAN_DATE_OF_CCSDS_EPOCH)
407
+ (self.ccsds2julian(day, ms, us) - sec_epoch_jd) * SEC_PER_DAY_FLOAT
408
+ end
409
+
410
+ # @param sec [Float] Number of seconds to convert
411
+ # @param sec_epoch_jd [Float] Epoch of seconds value
412
+ # @return [Array<day, ms, us>] CCSDS date
413
+ def self.sec2ccsds(sec, sec_epoch_jd = JULIAN_DATE_OF_CCSDS_EPOCH)
414
+ self.julian2ccsds((sec / SEC_PER_DAY_FLOAT) + sec_epoch_jd)
415
+ end
416
+
417
+ # @param year [Integer] Year
418
+ # @param day [Integer] Day of the year
419
+ # @param sec [Float] Seconds in the day
420
+ # @return [Array] [year, month, day, hour, minute, second, usec]
421
+ def self.yds2mdy(year, day, sec)
422
+ # Convert day of year (1-366) to day of month (1-31)
423
+ if self.leap_year?(year)
424
+ array = Time::LeapYearMonthDays
425
+ else
426
+ array = Time::CommonYearMonthDays
427
+ end
428
+
429
+ month = 1
430
+ array.each do |days|
431
+ if (day - days) >= 1
432
+ day -= days
433
+ month += 1
434
+ else
435
+ break
436
+ end
437
+ end
438
+
439
+ # Calculate hour of day (0-23)
440
+ hour = (sec / SEC_PER_HOUR).to_i
441
+ sec -= (hour * SEC_PER_HOUR).to_f
442
+
443
+ # Calculate minute of hour (0-59)
444
+ min = (sec / SEC_PER_MINUTE).to_i
445
+ sec -= (min * SEC_PER_MINUTE).to_f
446
+
447
+ # Calculate second of minute (0-60)
448
+ seconds = sec.to_i
449
+ sec -= seconds.to_f
450
+
451
+ # Calculate useconds of second (0-999999)
452
+ usec = (sec * 1000000.0).to_i
453
+
454
+ return [year, month, day, hour, min, seconds, usec]
455
+ end
456
+
457
+ # @param year [Integer] Year
458
+ # @param day [Integer] Day of the year
459
+ # @param sec [Integer] Seconds in the day
460
+ # @return [Float] Year, day, seconds converted to the Julian date
461
+ def self.yds2julian(year, day, sec)
462
+ year, month, day, hour, min, seconds, usec = self.yds2mdy(year, day, sec)
463
+ Time.mdy2julian(year, month, day, hour, min, seconds, usec)
464
+ end
465
+
466
+ # Ruby time objects cannot handle times before the Unix Epoch. Calculate a delta (in seconds) to be used
467
+ # when real epochs are before the Unix Epoch. Each received timestamp will be adjusted by this delta
468
+ # so a ruby time object can be used to parse the time.
469
+ # @param epoch [String] epoch is a string in the following format: "yyyy/mm/dd hh:mm:ss"
470
+ # @return [Float] unix_epohc_delta
471
+ def self.init_epoch_delta(epoch)
472
+ # UnixEpoch - Jan 1, 1970 00:00:00
473
+ unix_epoch = DateTime.new(1970, 1, 1, 0, 0, 0)
474
+
475
+ split_epoch = epoch.split
476
+ epoch_date = split_epoch[0].split("/")
477
+ epoch_time = split_epoch[1].split(":")
478
+
479
+ if epoch_date[0].to_i < 1970 then
480
+ # Calculate delta between epoch and unix epoch
481
+ real_epoch = DateTime.new(epoch_date[0].to_i, epoch_date[1].to_i, epoch_date[2].to_i, epoch_time[0].to_i, epoch_time[1].to_i, epoch_time[2].to_i)
482
+ day_delta = (unix_epoch - real_epoch).to_i
483
+ unix_epoch_delta = day_delta * 86400
484
+ if real_epoch.hour != 0 or real_epoch.min != 0 or real_epoch.sec != 0
485
+ hour_delta = 23 - real_epoch.hour
486
+ min_delta = 59 - real_epoch.min
487
+ sec_delta = 60 - real_epoch.sec
488
+ unix_epoch_delta += ((hour_delta * 3600) + (min_delta * 60) + sec_delta)
489
+ end
490
+ else
491
+ unix_epoch_delta = 0
492
+ end
493
+
494
+ unix_epoch_delta
495
+ end
496
+
497
+ def to_nsec_from_epoch
498
+ (self.tv_sec * NSEC_PER_SECOND) + self.tv_nsec
499
+ end
500
+
501
+ def self.from_nsec_from_epoch(nsec_from_epoch)
502
+ return nil if nsec_from_epoch.nil?
503
+
504
+ seconds = nsec_from_epoch / NSEC_PER_SECOND
505
+ nanoseconds = nsec_from_epoch % NSEC_PER_SECOND
506
+ Time.at(seconds, nanoseconds, :nsec)
507
+ end
508
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU 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
+ # This program is distributed in the hope that it will be useful,
12
+ # 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.
15
+
16
+ # Modified by OpenC3, Inc.
17
+ # All changes Copyright 2022, OpenC3, Inc.
18
+ # All Rights Reserved
19
+
20
+ require 'openc3/core_ext/array'
21
+ require 'openc3/core_ext/binding'
22
+ require 'openc3/core_ext/class'
23
+ require 'openc3/core_ext/openc3_io'
24
+ require 'openc3/core_ext/exception'
25
+ require 'openc3/core_ext/file'
26
+ require 'openc3/core_ext/hash'
27
+ require 'openc3/core_ext/io'
28
+ require 'openc3/core_ext/kernel'
29
+ require 'openc3/core_ext/math'
30
+ require 'openc3/core_ext/matrix'
31
+ require 'openc3/core_ext/range'
32
+ require 'openc3/core_ext/socket'
33
+ require 'openc3/core_ext/string'
34
+ require 'openc3/core_ext/stringio'
35
+ require 'openc3/core_ext/time'
36
+ require 'openc3/core_ext/objectspace'