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,586 @@
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/packets/structure_item'
21
+ require 'openc3/packets/packet_item_limits'
22
+ require 'openc3/conversions/conversion'
23
+ require 'openc3/io/json_rpc' # Includes needed as_json code
24
+
25
+ module OpenC3
26
+ # Maintains knowledge of an item in a Packet
27
+ class PacketItem < StructureItem
28
+ # @return [String] Printf-style string used to format the item
29
+ attr_reader :format_string
30
+
31
+ # Conversion instance used when reading the PacketItem
32
+ # @return [Conversion] Read conversion
33
+ attr_reader :read_conversion
34
+
35
+ # Conversion instance used when writing the PacketItem
36
+ # @return [Conversion] Write conversion
37
+ attr_reader :write_conversion
38
+
39
+ # The id_value type depends on the data_type of the PacketItem
40
+ # @return Value used to identify a packet
41
+ attr_reader :id_value
42
+
43
+ # States are used to convert from a numeric value to a String.
44
+ # @return [Hash] Item states given as STATE_NAME => VALUE
45
+ attr_reader :states
46
+
47
+ # @return [String] Description of the item
48
+ attr_reader :description
49
+
50
+ # Returns the fully spelled out units of the item. For example,
51
+ # if the item represents a voltage, this would return "Voltage".
52
+ # @return [String] Units of the item
53
+ attr_reader :units_full
54
+
55
+ # Returns the abbreviated units of the item. For example,
56
+ # if the item represents a voltage, this would return "V".
57
+ # @return [String] Abbreviated units of the item
58
+ attr_reader :units
59
+
60
+ # The default value type depends on the data_type of the PacketItem
61
+ # @return Default value for this item
62
+ attr_accessor :default
63
+
64
+ # The valid range of values for this item. Returns nil for items with
65
+ # data_type of :STRING or :BLOCK items.
66
+ # @return [Range] Valid range of values or nil
67
+ attr_reader :range
68
+
69
+ # @return [Boolean] Whether this item must be specified or can use its
70
+ # default value. true if it must be specified.
71
+ attr_accessor :required
72
+
73
+ # States that are hazardous for this item as well as their descriptions
74
+ # @return [Hash] Hazardous states given as STATE_NAME => DESCRIPTION. If no
75
+ # description was given the value will be nil.
76
+ attr_reader :hazardous
77
+
78
+ # Colors associated with states
79
+ # @return [Hash] State colors given as STATE_NAME => COLOR
80
+ attr_reader :state_colors
81
+
82
+ # The allowable state colors
83
+ STATE_COLORS = [:GREEN, :YELLOW, :RED]
84
+
85
+ # @return [PacketItemLimits] All information regarding limits for this PacketItem
86
+ attr_reader :limits
87
+
88
+ # (see StructureItem#initialize)
89
+ # It also initializes the attributes of the PacketItem.
90
+ def initialize(name, bit_offset, bit_size, data_type, endianness, array_size = nil, overflow = :ERROR)
91
+ super(name, bit_offset, bit_size, data_type, endianness, array_size, overflow)
92
+ @format_string = nil
93
+ @read_conversion = nil
94
+ @write_conversion = nil
95
+ @id_value = nil
96
+ @states = nil
97
+ @description = nil
98
+ @units_full = nil
99
+ @units = nil
100
+ @default = nil
101
+ @range = nil
102
+ @required = false
103
+ @hazardous = nil
104
+ @state_colors = nil
105
+ @limits = PacketItemLimits.new
106
+ @persistence_setting = 1
107
+ @persistence_count = 0
108
+ @meta = nil
109
+ end
110
+
111
+ def format_string=(format_string)
112
+ if format_string
113
+ raise ArgumentError, "#{@name}: format_string must be a String but is a #{format_string.class}" unless String === format_string
114
+ raise ArgumentError, "#{@name}: format_string invalid '#{format_string}'" unless /%.*(b|B|d|i|o|u|x|X|e|E|f|g|G|a|A|c|p|s|%)/.match?(format_string)
115
+
116
+ @format_string = format_string.clone.freeze
117
+ else
118
+ @format_string = nil
119
+ end
120
+ end
121
+
122
+ def read_conversion=(read_conversion)
123
+ if read_conversion
124
+ raise ArgumentError, "#{@name}: read_conversion must be a OpenC3::Conversion but is a #{read_conversion.class}" unless OpenC3::Conversion === read_conversion
125
+
126
+ @read_conversion = read_conversion.clone
127
+ else
128
+ @read_conversion = nil
129
+ end
130
+ end
131
+
132
+ def write_conversion=(write_conversion)
133
+ if write_conversion
134
+ raise ArgumentError, "#{@name}: write_conversion must be a OpenC3::Conversion but is a #{write_conversion.class}" unless OpenC3::Conversion === write_conversion
135
+
136
+ @write_conversion = write_conversion.clone
137
+ else
138
+ @write_conversion = nil
139
+ end
140
+ end
141
+
142
+ def id_value=(id_value)
143
+ if id_value
144
+ @id_value = convert(id_value, @data_type)
145
+ else
146
+ @id_value = nil
147
+ end
148
+ end
149
+
150
+ # Assignment operator for states to make sure it is a Hash with uppercase keys
151
+ def states=(states)
152
+ if states
153
+ raise ArgumentError, "#{@name}: states must be a Hash but is a #{states.class}" unless Hash === states
154
+
155
+ # Make sure all states are in upper case
156
+ upcase_states = {}
157
+ states.each do |key, value|
158
+ upcase_states[key.to_s.upcase] = value
159
+ end
160
+
161
+ @states = upcase_states
162
+ @state_colors ||= {}
163
+ else
164
+ @states = nil
165
+ end
166
+ end
167
+
168
+ def description=(description)
169
+ if description
170
+ raise ArgumentError, "#{@name}: description must be a String but is a #{description.class}" unless String === description
171
+
172
+ @description = description.to_utf8.freeze
173
+ else
174
+ @description = nil
175
+ end
176
+ end
177
+
178
+ def units_full=(units_full)
179
+ if units_full
180
+ raise ArgumentError, "#{@name}: units_full must be a String but is a #{units_full.class}" unless String === units_full
181
+
182
+ @units_full = units_full.clone.freeze
183
+ else
184
+ @units_full = nil
185
+ end
186
+ end
187
+
188
+ def units=(units)
189
+ if units
190
+ raise ArgumentError, "#{@name}: units must be a String but is a #{units.class}" unless String === units
191
+
192
+ @units = units.clone.freeze
193
+ else
194
+ @units = nil
195
+ end
196
+ end
197
+
198
+ def check_default_and_range_data_types
199
+ if @default and !@write_conversion
200
+ if @array_size
201
+ raise ArgumentError, "#{@name}: default must be an Array but is a #{default.class}" unless Array === @default
202
+ else
203
+ case data_type
204
+ when :INT, :UINT
205
+ raise ArgumentError, "#{@name}: default must be a Integer but is a #{@default.class}" unless Integer === @default
206
+
207
+ if @range
208
+ raise ArgumentError, "#{@name}: minimum must be a Integer but is a #{@range.first.class}" unless Integer === @range.first
209
+ raise ArgumentError, "#{@name}: maximum must be a Integer but is a #{@range.last.class}" unless Integer === @range.last
210
+ end
211
+ when :FLOAT
212
+ raise ArgumentError, "#{@name}: default must be a Float but is a #{@default.class}" unless Float === @default or Integer === @default
213
+
214
+ @default = @default.to_f
215
+ if @range
216
+ raise ArgumentError, "#{@name}: minimum must be a Float but is a #{@range.first.class}" unless Float === @range.first or Integer === @range.first
217
+ raise ArgumentError, "#{@name}: maximum must be a Float but is a #{@range.last.class}" unless Float === @range.last or Integer === @range.last
218
+
219
+ @range = ((@range.first.to_f)..(@range.last.to_f))
220
+ end
221
+ when :BLOCK, :STRING
222
+ raise ArgumentError, "#{@name}: default must be a String but is a #{@default.class}" unless String === @default
223
+
224
+ @default = @default.clone.freeze
225
+ end
226
+ end
227
+ end
228
+ end
229
+
230
+ def range=(range)
231
+ if range
232
+ raise ArgumentError, "#{@name}: range must be a Range but is a #{range.class}" unless Range === range
233
+
234
+ @range = range.clone.freeze
235
+ else
236
+ @range = nil
237
+ end
238
+ end
239
+
240
+ def hazardous=(hazardous)
241
+ if hazardous
242
+ raise ArgumentError, "#{@name}: hazardous must be a Hash but is a #{hazardous.class}" unless Hash === hazardous
243
+
244
+ @hazardous = hazardous.clone
245
+ else
246
+ @hazardous = nil
247
+ end
248
+ end
249
+
250
+ def state_colors=(state_colors)
251
+ if state_colors
252
+ raise ArgumentError, "#{@name}: state_colors must be a Hash but is a #{state_colors.class}" unless Hash === state_colors
253
+
254
+ @state_colors = state_colors.clone
255
+ else
256
+ @state_colors = nil
257
+ end
258
+ end
259
+
260
+ def limits=(limits)
261
+ if limits
262
+ raise ArgumentError, "#{@name}: limits must be a PacketItemLimits but is a #{limits.class}" unless PacketItemLimits === limits
263
+
264
+ @limits = limits.clone
265
+ else
266
+ @limits = nil
267
+ end
268
+ end
269
+
270
+ def meta
271
+ @meta ||= {}
272
+ end
273
+
274
+ def meta=(meta)
275
+ if meta
276
+ raise ArgumentError, "#{@name}: meta must be a Hash but is a #{meta.class}" unless Hash === meta
277
+
278
+ @meta = meta.clone
279
+ else
280
+ @meta = nil
281
+ end
282
+ end
283
+
284
+ # Make a light weight clone of this item
285
+ def clone
286
+ item = super()
287
+ item.format_string = self.format_string.clone if self.format_string
288
+ item.read_conversion = self.read_conversion.clone if self.read_conversion
289
+ item.write_conversion = self.write_conversion.clone if self.write_conversion
290
+ item.states = self.states.clone if self.states
291
+ item.description = self.description.clone if self.description
292
+ item.units_full = self.units_full.clone if self.units_full
293
+ item.units = self.units.clone if self.units
294
+ item.default = self.default.clone if self.default and String === self.default
295
+ item.hazardous = self.hazardous.clone if self.hazardous
296
+ item.state_colors = self.state_colors.clone if self.state_colors
297
+ item.limits = self.limits.clone if self.limits
298
+ item.meta = self.meta.clone if @meta
299
+ item
300
+ end
301
+ alias dup clone
302
+
303
+ def to_hash
304
+ hash = super()
305
+ hash['format_string'] = self.format_string
306
+ if self.read_conversion
307
+ hash['read_conversion'] = self.read_conversion.to_s
308
+ else
309
+ hash['read_conversion'] = nil
310
+ end
311
+ if self.write_conversion
312
+ hash['write_conversion'] = self.write_conversion.to_s
313
+ else
314
+ hash['write_conversion'] = nil
315
+ end
316
+ hash['id_value'] = self.id_value
317
+ hash['states'] = self.states
318
+ hash['description'] = self.description
319
+ hash['units_full'] = self.units_full
320
+ hash['units'] = self.units
321
+ hash['default'] = self.default
322
+ hash['range'] = self.range
323
+ hash['required'] = self.required
324
+ hash['hazardous'] = self.hazardous
325
+ hash['state_colors'] = self.state_colors
326
+ hash['limits'] = self.limits.to_hash
327
+ hash['meta'] = nil
328
+ hash['meta'] = @meta if @meta
329
+ hash
330
+ end
331
+
332
+ def calculate_range
333
+ first = range.first
334
+ last = range.last
335
+ if data_type == :FLOAT
336
+ if bit_size == 32
337
+ if range.first == -3.402823e38
338
+ first = 'MIN'
339
+ end
340
+ if range.last == 3.402823e38
341
+ last = 'MAX'
342
+ end
343
+ else
344
+ if range.first == -Float::MAX
345
+ first = 'MIN'
346
+ end
347
+ if range.last == Float::MAX
348
+ last = 'MAX'
349
+ end
350
+ end
351
+ end
352
+ return [first, last]
353
+ end
354
+
355
+ def to_config(cmd_or_tlm, default_endianness)
356
+ config = ''
357
+ if cmd_or_tlm == :TELEMETRY
358
+ if self.array_size
359
+ config << " ARRAY_ITEM #{self.name.to_s.quote_if_necessary} #{self.bit_offset} #{self.bit_size} #{self.data_type} #{self.array_size} \"#{self.description.to_s.gsub("\"", "'")}\""
360
+ elsif self.id_value
361
+ id_value = self.id_value
362
+ if self.data_type == :BLOCK || self.data_type == :STRING
363
+ unless self.id_value.is_printable?
364
+ id_value = "0x" + self.id_value.simple_formatted
365
+ else
366
+ id_value = "\"#{self.id_value}\""
367
+ end
368
+ end
369
+ config << " ID_ITEM #{self.name.to_s.quote_if_necessary} #{self.bit_offset} #{self.bit_size} #{self.data_type} #{id_value} \"#{self.description.to_s.gsub("\"", "'")}\""
370
+ else
371
+ config << " ITEM #{self.name.to_s.quote_if_necessary} #{self.bit_offset} #{self.bit_size} #{self.data_type} \"#{self.description.to_s.gsub("\"", "'")}\""
372
+ end
373
+ else # :COMMAND
374
+ if self.array_size
375
+ config << " ARRAY_PARAMETER #{self.name.to_s.quote_if_necessary} #{self.bit_offset} #{self.bit_size} #{self.data_type} #{self.array_size} \"#{self.description.to_s.gsub("\"", "'")}\""
376
+ else
377
+ config << parameter_config()
378
+ end
379
+ end
380
+ config << " #{self.endianness}" if self.endianness != default_endianness && self.data_type != :STRING && self.data_type != :BLOCK
381
+ config << "\n"
382
+
383
+ config << " REQUIRED\n" if self.required
384
+ config << " FORMAT_STRING #{self.format_string.to_s.quote_if_necessary}\n" if self.format_string
385
+ config << " UNITS #{self.units_full.to_s.quote_if_necessary} #{self.units.to_s.quote_if_necessary}\n" if self.units
386
+ config << " OVERFLOW #{self.overflow}\n" if self.overflow != :ERROR
387
+
388
+ if @states
389
+ @states.each do |state_name, state_value|
390
+ config << " STATE #{state_name.to_s.quote_if_necessary} #{state_value.to_s.quote_if_necessary}"
391
+ if @hazardous and @hazardous[state_name]
392
+ config << " HAZARDOUS #{@hazardous[state_name].to_s.quote_if_necessary}"
393
+ end
394
+ if @state_colors and @state_colors[state_name]
395
+ config << " #{@state_colors[state_name]}"
396
+ end
397
+ config << "\n"
398
+ end
399
+ end
400
+
401
+ config << self.read_conversion.to_config(:READ) if self.read_conversion
402
+ config << self.write_conversion.to_config(:WRITE) if self.write_conversion
403
+
404
+ if self.limits
405
+ if self.limits.values
406
+ self.limits.values.each do |limits_set, limits_values|
407
+ config << " LIMITS #{limits_set} #{self.limits.persistence_setting} #{self.limits.enabled ? 'ENABLED' : 'DISABLED'} #{limits_values[0]} #{limits_values[1]} #{limits_values[2]} #{limits_values[3]}"
408
+ if limits_values[4] && limits_values[5]
409
+ config << " #{limits_values[4]} #{limits_values[5]}\n"
410
+ else
411
+ config << "\n"
412
+ end
413
+ end
414
+ end
415
+ config << self.limits.response.to_config if self.limits.response
416
+ end
417
+
418
+ if @meta
419
+ @meta.each do |key, values|
420
+ config << " META #{key.to_s.quote_if_necessary} #{values.map { |a| a.to_s.quote_if_necessary }.join(" ")}\n"
421
+ end
422
+ end
423
+
424
+ config
425
+ end
426
+
427
+ def as_json(*a)
428
+ config = {}
429
+ config['name'] = self.name
430
+ config['bit_offset'] = self.bit_offset
431
+ config['bit_size'] = self.bit_size
432
+ config['data_type'] = self.data_type.to_s
433
+ config['array_size'] = self.array_size if self.array_size
434
+ config['description'] = self.description
435
+ config['id_value'] = self.id_value.as_json(*a) if self.id_value
436
+ if @default
437
+ config['default'] = @default.as_json(*a)
438
+ end
439
+ if self.range
440
+ config['minimum'] = self.range.first.as_json(*a)
441
+ config['maximum'] = self.range.last.as_json(*a)
442
+ end
443
+ config['endianness'] = self.endianness.to_s
444
+ config['required'] = self.required
445
+ config['format_string'] = self.format_string if self.format_string
446
+ if self.units
447
+ config['units'] = self.units
448
+ config['units_full'] = self.units_full
449
+ end
450
+ config['overflow'] = self.overflow.to_s
451
+ if @states
452
+ states = {}
453
+ config['states'] = states
454
+ @states.each do |state_name, state_value|
455
+ state = {}
456
+ states[state_name] = state
457
+ state['value'] = state_value.as_json(*a)
458
+ state['hazardous'] = @hazardous[state_name] if @hazardous and @hazardous[state_name]
459
+ state['color'] = @state_colors[state_name].to_s if @state_colors and @state_colors[state_name]
460
+ end
461
+ end
462
+
463
+ config['read_conversion'] = self.read_conversion.as_json(*a) if self.read_conversion
464
+ config['write_conversion'] = self.write_conversion.as_json(*a) if self.write_conversion
465
+
466
+ if self.limits
467
+ if self.limits.values
468
+ config['limits'] ||= {}
469
+ config['limits']['persistence_setting'] = self.limits.persistence_setting
470
+ config['limits']['enabled'] = true if self.limits.enabled
471
+ self.limits.values.each do |limits_set, limits_values|
472
+ limits = {}
473
+ limits['red_low'] = limits_values[0]
474
+ limits['yellow_low'] = limits_values[1]
475
+ limits['yellow_high'] = limits_values[2]
476
+ limits['red_high'] = limits_values[3]
477
+ limits['green_low'] = limits_values[4] if limits_values[4]
478
+ limits['green_high'] = limits_values[5] if limits_values[5]
479
+ config['limits'][limits_set] = limits
480
+ end
481
+ end
482
+ config['limits_response'] = self.limits.response.as_json(*a) if self.limits.response
483
+ end
484
+
485
+ config['meta'] = @meta if @meta
486
+ config
487
+ end
488
+
489
+ def self.from_json(hash)
490
+ # Convert strings to symbols
491
+ endianness = hash['endianness'] ? hash['endianness'].intern : nil
492
+ data_type = hash['data_type'] ? hash['data_type'].intern : nil
493
+ overflow = hash['overflow'] ? hash['overflow'].intern : nil
494
+ item = PacketItem.new(hash['name'], hash['bit_offset'], hash['bit_size'],
495
+ data_type, endianness, hash['array_size'], overflow)
496
+ item.description = hash['description']
497
+ item.id_value = hash['id_value']
498
+ item.default = hash['default']
499
+ item.range = (hash['minimum']..hash['maximum']) if hash['minimum'] && hash['maximum']
500
+ item.required = hash['required']
501
+ item.format_string = hash['format_string']
502
+ item.units = hash['units']
503
+ item.units_full = hash['units_full']
504
+ if hash['states']
505
+ item.states = {}
506
+ item.hazardous = {}
507
+ item.state_colors = {}
508
+ hash['states'].each do |state_name, state|
509
+ item.states[state_name] = state['value']
510
+ item.hazardous[state_name] = state['hazardous']
511
+ item.state_colors[state_name] = state['color'].to_sym if state['color']
512
+ end
513
+ end
514
+ # Recreate OpenC3 built-in conversions
515
+ if hash['read_conversion']
516
+ begin
517
+ item.read_conversion = OpenC3::const_get(hash['read_conversion']['class']).new(*hash['read_conversion']['params'])
518
+ rescue => error
519
+ Logger.instance.error "#{item.name} read_conversion of #{hash['read_conversion']} could not be instantiated due to #{error}"
520
+ end
521
+ end
522
+ if hash['write_conversion']
523
+ begin
524
+ item.write_conversion = OpenC3::const_get(hash['write_conversion']['class']).new(*hash['write_conversion']['params'])
525
+ rescue => error
526
+ Logger.instance.error "#{item.name} write_conversion of #{hash['write_conversion']} could not be instantiated due to #{error}"
527
+ end
528
+ end
529
+
530
+ if hash['limits']
531
+ item.limits = PacketItemLimits.new
532
+ # Delete these keys so the only ones left are limits sets
533
+ item.limits.persistence_setting = hash['limits'].delete('persistence_setting')
534
+ item.limits.enabled = true if hash['limits'].delete('enabled')
535
+ values = {}
536
+ hash['limits'].each do |set, items|
537
+ values[set.to_sym] = [items['red_low'], items['yellow_low'], items['yellow_high'], items['red_high']]
538
+ values[set.to_sym].concat([items['green_low'], items['green_high']]) if items['green_low'] && items['green_high']
539
+ end
540
+ item.limits.values = values
541
+ end
542
+ item.meta = hash['meta']
543
+ item
544
+ end
545
+
546
+ protected
547
+
548
+ def parameter_config
549
+ if @id_value
550
+ value = @id_value
551
+ config = " ID_PARAMETER "
552
+ else
553
+ value = @default
554
+ config = " PARAMETER "
555
+ end
556
+ config << "#{@name.to_s.quote_if_necessary} #{@bit_offset} #{@bit_size} #{@data_type} "
557
+
558
+ if @data_type == :BLOCK || @data_type == :STRING
559
+ unless value.is_printable?
560
+ val_string = "0x" + value.simple_formatted
561
+ else
562
+ val_string = "\"#{value}\""
563
+ end
564
+ else
565
+ first, last = calculate_range()
566
+ config << "#{first} #{last} "
567
+ val_string = value.to_s
568
+ end
569
+ config << "#{val_string} \"#{@description.to_s.gsub("\"", "'")}\""
570
+ end
571
+
572
+ # Convert a value into the given data type
573
+ def convert(value, data_type)
574
+ case data_type
575
+ when :INT, :UINT
576
+ Integer(value)
577
+ when :FLOAT
578
+ Float(value)
579
+ when :STRING, :BLOCK
580
+ value.to_s.freeze
581
+ end
582
+ rescue
583
+ raise ArgumentError, "#{@name}: Invalid value: #{value} for data type: #{data_type}"
584
+ end
585
+ end
586
+ end