openc3 5.20.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/bin/openc3cli +12 -120
  3. data/data/config/command_modifiers.yaml +13 -1
  4. data/data/config/interface_modifiers.yaml +21 -4
  5. data/data/config/item_modifiers.yaml +1 -1
  6. data/data/config/microservice.yaml +15 -2
  7. data/data/config/param_item_modifiers.yaml +1 -1
  8. data/data/config/parameter_modifiers.yaml +1 -1
  9. data/data/config/table_manager.yaml +2 -2
  10. data/data/config/target.yaml +11 -0
  11. data/data/config/telemetry_modifiers.yaml +17 -1
  12. data/data/config/tool.yaml +12 -0
  13. data/data/config/widgets.yaml +13 -17
  14. data/lib/openc3/accessors/form_accessor.rb +4 -3
  15. data/lib/openc3/accessors/html_accessor.rb +3 -3
  16. data/lib/openc3/accessors/http_accessor.rb +13 -13
  17. data/lib/openc3/accessors/xml_accessor.rb +16 -4
  18. data/lib/openc3/api/target_api.rb +0 -30
  19. data/lib/openc3/config/config_parser.rb +6 -3
  20. data/lib/openc3/core_ext/array.rb +0 -16
  21. data/lib/openc3/core_ext.rb +0 -1
  22. data/lib/openc3/interfaces/file_interface.rb +198 -0
  23. data/lib/openc3/interfaces/http_client_interface.rb +71 -39
  24. data/lib/openc3/interfaces/http_server_interface.rb +0 -7
  25. data/lib/openc3/interfaces/interface.rb +2 -0
  26. data/lib/openc3/interfaces/mqtt_interface.rb +32 -15
  27. data/lib/openc3/interfaces/mqtt_stream_interface.rb +19 -4
  28. data/lib/openc3/interfaces/protocols/crc_protocol.rb +7 -0
  29. data/lib/openc3/interfaces/serial_interface.rb +1 -0
  30. data/lib/openc3/interfaces.rb +2 -4
  31. data/lib/openc3/microservices/multi_microservice.rb +3 -3
  32. data/lib/openc3/migrations/20241208080000_no_critical_cmd.rb +31 -0
  33. data/lib/openc3/migrations/20241208080001_no_trigger_group.rb +46 -0
  34. data/lib/openc3/models/interface_model.rb +9 -3
  35. data/lib/openc3/models/microservice_model.rb +8 -1
  36. data/lib/openc3/models/plugin_model.rb +6 -1
  37. data/lib/openc3/models/python_package_model.rb +6 -1
  38. data/lib/openc3/models/reaction_model.rb +14 -10
  39. data/lib/openc3/models/scope_model.rb +60 -42
  40. data/lib/openc3/models/target_model.rb +17 -1
  41. data/lib/openc3/models/timeline_model.rb +17 -5
  42. data/lib/openc3/models/tool_model.rb +15 -3
  43. data/lib/openc3/models/trigger_group_model.rb +6 -3
  44. data/lib/openc3/operators/microservice_operator.rb +8 -0
  45. data/lib/openc3/packets/commands.rb +17 -6
  46. data/lib/openc3/packets/limits.rb +0 -12
  47. data/lib/openc3/packets/packet.rb +1 -1
  48. data/lib/openc3/packets/packet_item.rb +30 -36
  49. data/lib/openc3/packets/structure_item.rb +2 -2
  50. data/lib/openc3/script/script.rb +0 -10
  51. data/lib/openc3/script/web_socket_api.rb +2 -2
  52. data/lib/openc3/streams/mqtt_stream.rb +41 -33
  53. data/lib/openc3/streams/serial_stream.rb +27 -27
  54. data/lib/openc3/streams/stream.rb +17 -17
  55. data/lib/openc3/streams/tcpip_client_stream.rb +1 -1
  56. data/lib/openc3/streams/tcpip_socket_stream.rb +19 -19
  57. data/lib/openc3/system/system.rb +1 -1
  58. data/lib/openc3/system.rb +2 -3
  59. data/lib/openc3/tools/table_manager/table.rb +2 -2
  60. data/lib/openc3/tools/table_manager/table_parser.rb +1 -1
  61. data/lib/openc3/top_level.rb +0 -5
  62. data/lib/openc3/topics/command_decom_topic.rb +0 -7
  63. data/lib/openc3/utilities/bucket_utilities.rb +1 -1
  64. data/lib/openc3/utilities/cli_generator.rb +0 -1
  65. data/lib/openc3/version.rb +6 -6
  66. data/templates/plugin/README.md +1 -1
  67. data/templates/target/targets/TARGET/lib/target.rb +1 -1
  68. data/templates/tool_angular/package.json +8 -8
  69. data/templates/tool_angular/src/app/app.component.html +4 -13
  70. data/templates/tool_angular/src/app/app.component.scss +5 -13
  71. data/templates/tool_angular/src/app/app.component.ts +5 -4
  72. data/templates/tool_angular/src/app/custom-overlay-container.ts +2 -2
  73. data/templates/tool_angular/src/app/openc3-api.d.ts +1 -1
  74. data/templates/tool_angular/src/main.single-spa.ts +1 -1
  75. data/templates/tool_react/package.json +1 -0
  76. data/templates/tool_react/src/root.component.js +1 -1
  77. data/templates/tool_svelte/package.json +11 -9
  78. data/templates/tool_svelte/rollup.config.js +2 -0
  79. data/templates/tool_svelte/src/App.svelte +2 -2
  80. data/templates/tool_vue/eslint.config.mjs +68 -0
  81. data/templates/tool_vue/jsconfig.json +1 -1
  82. data/templates/tool_vue/package.json +26 -43
  83. data/templates/tool_vue/src/App.vue +3 -5
  84. data/templates/tool_vue/src/main.js +12 -23
  85. data/templates/tool_vue/src/router.js +19 -18
  86. data/templates/tool_vue/src/tools/tool_name/tool_name.vue +2 -2
  87. data/templates/tool_vue/vite.config.js +52 -0
  88. data/templates/widget/package.json +19 -26
  89. data/templates/widget/src/Widget.vue +13 -15
  90. data/templates/widget/vite.config.js +26 -0
  91. metadata +10 -41
  92. data/lib/openc3/core_ext/hash.rb +0 -40
  93. data/lib/openc3/core_ext/httpclient.rb +0 -11
  94. data/lib/openc3/interfaces/linc_interface.rb +0 -480
  95. data/lib/openc3/interfaces/protocols/override_protocol.rb +0 -4
  96. data/lib/openc3/microservices/critical_cmd_microservice.rb +0 -74
  97. data/lib/openc3/microservices/reaction_microservice.rb +0 -607
  98. data/lib/openc3/microservices/timeline_microservice.rb +0 -398
  99. data/lib/openc3/microservices/trigger_group_microservice.rb +0 -698
  100. data/lib/openc3/migrations/20230615000000_autonomic.rb +0 -86
  101. data/lib/openc3/migrations/20240915000000_activity_uuid.rb +0 -28
  102. data/lib/openc3/migrations/20241016000000_scope_critical_cmd.rb +0 -24
  103. data/lib/openc3/system/system_config.rb +0 -413
  104. data/templates/tool_svelte/src/services/api.js +0 -92
  105. data/templates/tool_svelte/src/services/axios.js +0 -85
  106. data/templates/tool_svelte/src/services/cable.js +0 -65
  107. data/templates/tool_svelte/src/services/config-parser.js +0 -198
  108. data/templates/tool_svelte/src/services/openc3-api.js +0 -606
  109. data/templates/tool_vue/.eslintrc.js +0 -43
  110. data/templates/tool_vue/babel.config.json +0 -11
  111. data/templates/tool_vue/vue.config.js +0 -38
  112. data/templates/widget/.eslintrc.js +0 -43
  113. data/templates/widget/babel.config.json +0 -11
  114. data/templates/widget/vue.config.js +0 -28
  115. /data/templates/tool_vue/{.prettierrc.js → .prettierrc.cjs} +0 -0
  116. /data/templates/widget/{.prettierrc.js → .prettierrc.cjs} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: afacc218fcbddf94eaf648df3232e9f6c99f9637fb0694cde932267542968d5e
4
- data.tar.gz: 1ce5bf3127b8b7ea3c1adae3de0a294f435302854bb08835d5fdb18a4b786804
3
+ metadata.gz: 9a54edc01e060c3a3d1163a1535491aca88770aa2cc0caba9d1300a2b450483d
4
+ data.tar.gz: a5bb46d276b36a51a742cfa383118cf6eb8cd866a3bb408f3daccfc69276a19e
5
5
  SHA512:
6
- metadata.gz: ad58ad437fb0f7391d33fef0bafdf6f0b670cb6f59b63f60f2f03bda7a65c06acf59cad85ba92069c79a505da0fe4c33d8fb928d9cd926e0c4a9be0d42ee20c9
7
- data.tar.gz: 503095241e1a8d34f71875abc4f1313c036470c86bb7627a3bd70b482281d03eeb6479d9a3109753b2f3b7927e1ceef49a62532197c5827f360ba66f23f4c4ff
6
+ metadata.gz: 3a7be413270a65c56781df9c8ffd4fe9a488c55d1e6e481ba6b043b94a6e762258fd7d7d6c02d7976bf05e6e84909fb032d9e4a569382888df1acb87e062bec9
7
+ data.tar.gz: e14b519af7d3f25a7668e37bfe7264d2ca766a4b2d0d654fe968a85be5809c5553a7dd0d8eeb60f674118c10a6f4be7851ec68df9ee07d7c3cd639cdc7b03d6a
data/bin/openc3cli CHANGED
@@ -47,15 +47,6 @@ require 'irb/completion'
47
47
 
48
48
  $redis_url = "redis://#{ENV['OPENC3_REDIS_HOSTNAME']}:#{ENV['OPENC3_REDIS_PORT']}"
49
49
 
50
- # Build the OpenStruct and OptionParser here as constants so we can use in methods
51
- MIGRATE_OPTIONS = OpenStruct.new
52
- MIGRATE_OPTIONS.all = false
53
- MIGRATE_PARSER = OptionParser.new do |opts|
54
- opts.banner = "cli migrate PLUGIN [TGT1...] # Create a OpenC3 plugin from existing COSMOS 4 targets"
55
- opts.on("-a", "--all", " Move all COSMOS 4 targets into a single OpenC3 plugin") do
56
- MIGRATE_OPTIONS.all = true
57
- end
58
- end
59
50
  ERROR_CODE = 1
60
51
 
61
52
  CLI_SCRIPT_ACTIONS = %w(help list run spawn)
@@ -82,7 +73,6 @@ def print_usage
82
73
  puts " cli list <SCOPE> # Lists installed plugins, SCOPE is DEFAULT if not given"
83
74
  puts " cli generate TYPE OPTIONS # Generate various COSMOS entities"
84
75
  puts " OPTIONS: --ruby or --python is required to specify the language in the generated code unless OPENC3_LANGUAGE is set"
85
- puts " #{MIGRATE_PARSER}"
86
76
  puts " cli bridge CONFIG_FILENAME # Run COSMOS host bridge"
87
77
  puts " cli bridgegem gem_name variable1=value1 variable2=value2 # Runs bridge using gem bridge.txt"
88
78
  puts " cli bridgesetup CONFIG_FILENAME # Create a default config file"
@@ -116,110 +106,6 @@ def check_environment
116
106
  end
117
107
  end
118
108
 
119
- def migrate(args)
120
- MIGRATE_PARSER.parse!(args)
121
- abort(MIGRATE_PARSER.to_s) if args.length == 0
122
- if MIGRATE_OPTIONS.all and args.length > 1
123
- puts "Only specify the plugin name when using --all"
124
- abort(MIGRATE_PARSER.to_s)
125
- end
126
- if !MIGRATE_OPTIONS.all and args.length < 2
127
- puts "Specify the individual target names when not using --all"
128
- abort(MIGRATE_PARSER.to_s)
129
- end
130
- if Dir.glob("config/targets/**/*").empty?
131
- puts "No targets found in config/targets/*"
132
- puts "Migrate must be run within an existing COSMOS configuration"
133
- abort(MIGRATE_PARSER.to_s)
134
- end
135
-
136
- ###############################################################
137
- # Create the framework for the plugin
138
- # NOTE: generate does a chdir to be inside the plugin directory
139
- ###############################################################
140
- plugin = args.shift
141
- OpenC3::CliGenerator.generate(['plugin', plugin])
142
-
143
- if MIGRATE_OPTIONS.all
144
- # Grab all target directories to match the command line input
145
- args = Dir.glob("../config/targets/*").map { |path| File.basename(path) }
146
- else
147
- # Ensure targets passed in on command line actually exist
148
- args.each do |target|
149
- path = File.join('..', 'config', 'targets', target)
150
- unless File.exist?(path)
151
- puts "Target #{path} does not exist!"
152
- abort(MIGRATE_PARSER.to_s)
153
- end
154
- end
155
- end
156
-
157
- # Overwrite plugin.txt with specified targets
158
- plugin = File.open('plugin.txt', 'w')
159
- FileUtils.mkdir 'targets'
160
- args.each do |target|
161
- puts "Migrating target #{target}"
162
- FileUtils.cp_r "../config/targets/#{target}", 'targets'
163
- plugin.puts "TARGET #{target} #{target}"
164
- end
165
- plugin.puts ""
166
-
167
- files = Dir.glob('../lib/*')
168
- files.concat(Dir.glob('../procedures/*'))
169
- unless files.empty?
170
- puts "Migrating /lib & /procedures to PROCEDURES target"
171
- FileUtils.cp_r '../lib', "targets/PROCEDURES"
172
- FileUtils.cp_r '../procedures', "targets/PROCEDURES"
173
- end
174
-
175
- # Migrate cmd_tlm_server.txt info to plugin.txt
176
- Dir.glob('targets/**/cmd_tlm_server*.txt') do |cmd_tlm_server_file|
177
- File.open(cmd_tlm_server_file) do |file|
178
- file.each do |line|
179
- next if line =~ /^\s*#/ # Ignore comments
180
- next if line.strip.empty? # Ignore empty lines
181
-
182
- # Convert TARGET to MAP_TARGET
183
- line.gsub!(/TARGET (\S+)/, 'MAP_TARGET \1')
184
- plugin.puts line
185
- end
186
- end
187
- plugin.puts ''
188
- end
189
-
190
- # Migrate target.txt
191
- Dir.glob('targets/**/target.txt') do |filename|
192
- file = File.read(filename)
193
- file.gsub!('LOG_RAW', 'LOG_STREAM')
194
- file.gsub!('AUTO_SCREEN_SUBSTITUTE', '')
195
- File.write(filename, file)
196
- end
197
-
198
- # Migrate some of the screens api
199
- Dir.glob('targets/**/screens/*') do |file|
200
- screen = File.read(file)
201
- screen.gsub!('cmd(', 'api.cmd(')
202
- screen.gsub!('cmd_no_checks(', 'api.cmd_no_checks(')
203
- screen.gsub!('cmd_no_range_check(', 'api.cmd_no_range_check(')
204
- screen.gsub!('cmd_no_hazardous_check(', 'api.cmd_no_hazardous_check(')
205
- screen.gsub!('get_named_widget(', 'screen.getNamedWidget(')
206
- lines = screen.split("\n")
207
- lines.map! do |line|
208
- if line.include?('Qt.')
209
- "# FIXME (no Qt): #{line.sub("<%", "< %").sub("%>", "% >")}"
210
- elsif line.include?('Cosmos::')
211
- "# FIXME (no Cosmos::): #{line.sub("<%", "< %").sub("%>", "% >")}"
212
- else
213
- line
214
- end
215
- end
216
- File.write(file, lines.join("\n"))
217
- end
218
-
219
- plugin.close
220
- puts "Plugin complete: #{File.expand_path('.')}" # Remember we're inside the plugin dir
221
- end
222
-
223
109
  def xtce_converter(args)
224
110
  options = {}
225
111
  option_parser = OptionParser.new do |opts|
@@ -619,16 +505,25 @@ def run_migrations(folder)
619
505
  end
620
506
 
621
507
  # Run each newly discovered migration unless brand_new
622
- folder = "/openc3/lib/openc3/migrations" unless folder
508
+ if !folder
509
+ folder = "/openc3/lib/openc3/migrations"
510
+ entries = Dir.entries(folder).map { |entry| File.join(folder, entry) }
511
+ folder = "/openc3-enterprise/lib/openc3-enterprise/migrations"
512
+ if File.exist?(folder)
513
+ entries.concat(Dir.entries(folder).map { |entry| File.join(folder, entry) })
514
+ end
515
+ entries = entries.sort() # run in alphabetical order
516
+ else
517
+ entries = Dir.entries(folder).sort
518
+ end
623
519
  migrations = OpenC3::MigrationModel.all
624
- entries = Dir.entries(folder).sort # run in alphabetical order
625
520
  entries.each do |entry|
626
521
  name = File.basename(entry)
627
522
  extension = File.extname(name)
628
523
  if extension == '.rb' and not migrations[name]
629
524
  unless brand_new
630
525
  puts "Running Migration: #{name}"
631
- require File.join(folder, entry)
526
+ require entry
632
527
  end
633
528
  OpenC3::MigrationModel.new(name: name).create
634
529
  end
@@ -869,9 +764,6 @@ if not ARGV[0].nil? # argument(s) given
869
764
  when 'generate'
870
765
  OpenC3::CliGenerator.generate(ARGV[1..-1])
871
766
 
872
- when 'migrate'
873
- migrate(ARGV[1..-1])
874
-
875
767
  when 'rubysloc'
876
768
  puts `ruby /openc3/bin/rubysloc #{ARGV[1..-1].join(' ')}`
877
769
 
@@ -165,7 +165,7 @@ HAZARDOUS:
165
165
  ACCESSOR:
166
166
  summary: Defines the class used to read and write raw values from the packet
167
167
  description: Defines the class that is used too read raw values from the packet. Defaults to BinaryAccessor.
168
- Provided accessors also include JsonAccessor, CborAccessor, HtmlAccessor, and XmlAccessor.
168
+ For more information see [Accessors](accessors).
169
169
  parameters:
170
170
  - name: Accessor Class Name
171
171
  required: true
@@ -278,6 +278,12 @@ VALIDATOR:
278
278
 
279
279
  require 'openc3/packets/command_validator'
280
280
  class CustomValidator < OpenC3::CommandValidator
281
+ # Both the pre_check and post_check are passed the command packet that was sent
282
+ # You can inspect the command in your checks as follows:
283
+ # packet.target_name => target name
284
+ # packet.packet_name => packet name (command name)
285
+ # packet.read("ITEM") => converted value
286
+ # packet.read("ITEM", :RAW) => raw value
281
287
  def pre_check(packet)
282
288
  if tlm("TGT PKT ITEM") == 0
283
289
  return [false, "TGT PKT ITEM is 0"]
@@ -297,6 +303,12 @@ VALIDATOR:
297
303
  Defined in custom_validator.py:
298
304
 
299
305
  class CustomValidator(CommandValidator):
306
+ # Both the pre_check and post_check are passed the command packet that was sent
307
+ # You can inspect the command in your checks as follows:
308
+ # packet.target_name => target name
309
+ # packet.packet_name => packet name (command name)
310
+ # packet.read("ITEM") => converted value
311
+ # packet.read("ITEM", :RAW) => raw value
300
312
  def pre_check(self, command):
301
313
  if tlm("TGT PKT ITEM") == 0:
302
314
  return [False, "TGT PKT ITEM is 0"]
@@ -153,7 +153,9 @@ OPTION:
153
153
  OPTION LISTEN_ADDRESS 127.0.0.1
154
154
  SECRET:
155
155
  summary: Define a secret needed by this interface
156
- description: Defines a secret for this interface and optionally assigns its value to an option
156
+ description:
157
+ Defines a secret for this interface and optionally assigns its value to an option.
158
+ For more information see [Admin Secrets](/docs/tools/admin#secrets).
157
159
  since: 5.3.0
158
160
  parameters:
159
161
  - name: Type
@@ -164,15 +166,19 @@ SECRET:
164
166
  values: .*
165
167
  - name: Secret Name
166
168
  required: true
167
- description: The name of the secret to retrieve
169
+ description:
170
+ The name of the secret to retrieve from the Admin / Secrets tab.
171
+ For more information see [Admin Secrets](/docs/tools/admin#secrets).
168
172
  values: .*
169
173
  - name: Environment Variable or File Path
170
174
  required: true
171
- description: Environment variable name or file path to store secret
175
+ description: Environment variable name or file path to store secret.
176
+ Note that if you use the Option Name to set an option to the secret value,
177
+ this value doesn't really matter as long as it is unique.
172
178
  values: .*
173
179
  - name: Option Name
174
180
  required: false
175
- description: Interface option to pass the secret value
181
+ description: Interface option to pass the secret value. This is the primary way to pass secrets to interfaces.
176
182
  values: .*
177
183
  - name: Secret Store Name
178
184
  required: false
@@ -252,3 +258,14 @@ ROUTE_PREFIX:
252
258
  values: .*
253
259
  example: |
254
260
  ROUTE_PREFIX /interface
261
+ SHARD:
262
+ summary: Operator shard to run target microservices on
263
+ description: Operator Shard. Only used if running multiple operator containers typically in Kubernetes
264
+ since: 6.0.0
265
+ parameters:
266
+ - name: Shard
267
+ required: false
268
+ description: Shard number starting from 0
269
+ values: \d+
270
+ example: |
271
+ SHARD 0
@@ -66,7 +66,7 @@ READ_CONVERSION:
66
66
  super().__init__()
67
67
  self.multiplier = float(multiplier)
68
68
  def call(self, value, packet, buffer):
69
- return value * multiplier
69
+ return value * self.multiplier
70
70
  parameters:
71
71
  - name: Class Filename
72
72
  required: true
@@ -115,7 +115,7 @@ MICROSERVICE:
115
115
  values: .+
116
116
  SECRET:
117
117
  summary: Define a secret needed by this microservice
118
- description: Defines a secret for this microservice
118
+ description: Defines a secret for this microservice. For more information see [Admin Secrets](/docs/tools/admin#secrets).
119
119
  since: 5.3.0
120
120
  parameters:
121
121
  - name: Type
@@ -126,7 +126,9 @@ MICROSERVICE:
126
126
  values: .*
127
127
  - name: Secret Name
128
128
  required: true
129
- description: The name of the secret to retrieve
129
+ description:
130
+ The name of the secret to retrieve from the Admin / Secrets tab.
131
+ For more information see [Admin Secrets](/docs/tools/admin#secrets).
130
132
  values: .*
131
133
  - name: Environment Variable or File Path
132
134
  required: true
@@ -160,3 +162,14 @@ MICROSERVICE:
160
162
  required: false
161
163
  description: Regex to match against filenames. If match, then no ERB processing
162
164
  values: .+
165
+ SHARD:
166
+ summary: Operator shard to run target microservices on
167
+ description: Operator Shard. Only used if running multiple operator containers typically in Kubernetes
168
+ since: 6.0.0
169
+ parameters:
170
+ - name: Shard
171
+ required: false
172
+ description: Shard number starting from 0
173
+ values: \d+
174
+ example: |
175
+ SHARD 0
@@ -52,7 +52,7 @@ OVERLAP:
52
52
  since: 4.4.1
53
53
  KEY:
54
54
  summary: Defines the key used to access this raw value in the packet.
55
- description: Keys are often JsonPath or XPath strings
55
+ description: Keys are often [JSONPath](https://en.wikipedia.org/wiki/JSONPath) or [XPath](https://en.wikipedia.org/wiki/XPath) strings
56
56
  example: KEY $.book.title
57
57
  parameters:
58
58
  - name: Key string
@@ -107,7 +107,7 @@ WRITE_CONVERSION:
107
107
  super().__init__()
108
108
  self.multiplier = float(multiplier)
109
109
  def call(self, value, packet, buffer):
110
- return value * multiplier
110
+ return value * self.multiplier
111
111
  parameters:
112
112
  - name: Class Filename
113
113
  required: true
@@ -53,7 +53,7 @@ TABLE:
53
53
  or a ROW_COLUMN table with identical rows containing different values.
54
54
  values:
55
55
  KEY_VALUE:
56
- summary: Table rows will be unique items (previously ONE_DIMENSIONAL, now deprecated)
56
+ summary: Table rows will be unique items
57
57
  parameters:
58
58
  - name: Description
59
59
  requires: true
@@ -61,7 +61,7 @@ TABLE:
61
61
  used in mouseover popups and status line information.
62
62
  values: "['\"].*['\"]"
63
63
  ROW_COLUMN:
64
- summary: Table rows will be identical with multiple columns (previously TWO_DIMENSIONAL, now deprecated)
64
+ summary: Table rows will be identical with multiple columns
65
65
  parameters:
66
66
  - name: Rows
67
67
  requires: true
@@ -196,3 +196,14 @@ TARGET:
196
196
  required: false
197
197
  description: Regex to match against filenames. If match, then no ERB processing
198
198
  values: .+
199
+ SHARD:
200
+ summary: Operator shard to run target microservices on
201
+ description: Operator Shard. Only used if running multiple operator containers typically in Kubernetes
202
+ since: 6.0.0
203
+ parameters:
204
+ - name: Shard
205
+ required: false
206
+ description: Shard number starting from 0
207
+ values: \d+
208
+ example: |
209
+ SHARD 0
@@ -165,13 +165,29 @@ HIDDEN:
165
165
  ACCESSOR:
166
166
  summary: Defines the class used to read and write raw values from the packet
167
167
  description: Defines the class that is used too read raw values from the packet. Defaults to BinaryAccessor.
168
- Provided accessors also include JsonAccessor, CborAccessor, HtmlAccessor, and XmlAccessor.
168
+ For more information see [Accessors](accessors).
169
169
  parameters:
170
170
  - name: Accessor Class Name
171
171
  required: true
172
172
  description: The name of the accessor class
173
173
  values: .+
174
174
  since: 5.0.10
175
+ TEMPLATE:
176
+ summary: Defines a template string used to pull telemetry values from a string buffer
177
+ parameters:
178
+ - name: Template
179
+ required: true
180
+ description: The template string which should be enclosed in quotes
181
+ values: "['\"].*['\"]"
182
+ since: 5.0.10
183
+ TEMPLATE_FILE:
184
+ summary: Defines a template file used to pull telemetry values from a string buffer
185
+ parameters:
186
+ - name: Template File Path
187
+ required: true
188
+ description: The relative path to the template file. Filename should generally start with an underscore.
189
+ values: .+
190
+ since: 5.0.10
175
191
  IGNORE_OVERLAP:
176
192
  summary: Ignores any packet items which overlap
177
193
  description: Packet items which overlap normally generate a warning unless each individual item has the OVERLAP keyword.
@@ -82,3 +82,15 @@ TOOL:
82
82
  required: false
83
83
  description: Regex to match against filenames. If match, then no ERB processing
84
84
  values: .+
85
+ IMPORT_MAP_ITEM:
86
+ summary: Add an item to the import map
87
+ since: 6.0.0
88
+ parameters:
89
+ - name: key
90
+ required: true
91
+ description: Import Map Key
92
+ values: .+
93
+ - name: value
94
+ required: true
95
+ description: Import Map Value
96
+ values: .+
@@ -173,14 +173,6 @@ Decoration Widgets:
173
173
  LABEL Over
174
174
  HORIZONTALLINE
175
175
  LABEL Under
176
- SECTIONHEADER:
177
- summary: DEPRECATED - Displays a label that is underlined with a horizontal line
178
- description: Use a VERTICALBOX or HORIZONTALBOX with title parameter instead of SECTIONHEADER
179
- parameters:
180
- - name: Text
181
- required: true
182
- description: Text to display
183
- values: .*
184
176
  TITLE:
185
177
  summary: Displays a large centered title on the screen
186
178
  parameters:
@@ -299,7 +291,7 @@ Telemetry Widgets:
299
291
  description: The type of the value to display. Default is CONVERTED.
300
292
  values: <%= %w(RAW CONVERTED FORMATTED WITH_UNITS) %>
301
293
  example: |
302
- BLOCK INST IMAGE IMAGE 400 130 "%02X" 4 4 "0x%08X:"
294
+ BLOCK INST IMAGE IMAGE 620 200 "%02X" 4 4 "0x%08X:"
303
295
  # FORMATFONTVALUE:
304
296
  # summary: Displays a box with a value printed inside
305
297
  # that is formatted by the specified string rather than by a format string given
@@ -377,6 +369,7 @@ Telemetry Widgets:
377
369
  values: .*
378
370
  example: |
379
371
  FORMATVALUE INST LATEST TIMESEC %012u CONVERTED 20
372
+ FORMATVALUE INST LATEST TEMP1 %.2f CONVERTED 20
380
373
  LABELLED:
381
374
  summary: Displays a LABEL followed by a LED
382
375
  parameters:
@@ -978,12 +971,6 @@ Telemetry Widgets:
978
971
  example: |
979
972
  LINEGRAPH INST HEALTH_STATUS TEMP1
980
973
  SETTING ITEM INST ADCS Q1 # Add additional item to graph
981
- LINEGRAPH INST HEALTH_STATUS TEMP2 RAW
982
- LINEGRAPH INST HEALTH_STATUS TEMP3 CONVERTED REDUCED_MINUTE MIN
983
- SETTING SIZE 600 500 # width height
984
- SETTING HISTORY 1h # load 1 hour of data into graph
985
- LINEGRAPH INST HEALTH_STATUS TEMP4
986
- SETTING HISTORY 30m # load 30 minutes of data into graph
987
974
  settings:
988
975
  # Inject the graph settings
989
976
  <%= MetaConfigParser.load('graph_settings.yaml').to_meta_config_yaml(8) %>
@@ -1232,7 +1219,6 @@ Telemetry Widgets:
1232
1219
  values: .*
1233
1220
  example: |
1234
1221
  TEXTBOX INST HEALTH_STATUS PACKET_TIMEFORMATTED 150 70
1235
- TEXTBOX INST HEALTH_STATUS PACKET_TIMEFORMATTED
1236
1222
  # TRENDBAR:
1237
1223
  # summary: Provides the same functionality as the LIMITSBAR
1238
1224
  # widget except that it also keeps a history of the telemetry item and
@@ -1401,10 +1387,20 @@ Interactive Widgets:
1401
1387
  required: true
1402
1388
  description: Text displayed next to the checkbox
1403
1389
  values: .+
1390
+ - name: Checked
1391
+ required: false
1392
+ description:
1393
+ Whether the initial state of the checkbox is checked (default = false).
1394
+ Do not give a value to make the checkbox unchecked.
1395
+ values: .+
1404
1396
  example: |
1405
- NAMED_WIDGET CHECK CHECKBUTTON 'Ignore Hazardous Checks'
1397
+ NAMED_WIDGET UNCHECKED CHECKBUTTON 'Default Unchecked'
1398
+ NAMED_WIDGET CHECK CHECKBUTTON 'Ignore Hazardous Checks' CHECKED
1406
1399
  BUTTON 'Send' 'screen.getNamedWidget("CHECK").checked() ? ' \
1407
1400
  'api.cmd_no_hazardous_check("INST CLEAR") : api.cmd("INST CLEAR")'
1401
+ # You can programmatically check or uncheck the checkbox
1402
+ BUTTON 'Check' 'screen.getNamedWidget("CHECK").value = true'
1403
+ BUTTON 'Uncheck' 'screen.getNamedWidget("CHECK").value = false'
1408
1404
  COMBOBOX:
1409
1405
  summary: Displays a drop down list of text items
1410
1406
  description:
@@ -26,11 +26,12 @@ module OpenC3
26
26
  value = nil
27
27
  ary.each do |key, ary_value|
28
28
  if key == item.key
29
+ # Handle the case of multiple values for the same key
30
+ # and build up an array of values
29
31
  if value
32
+ # Second time through value is not an Array yet
30
33
  if not Array === value
31
- value_temp = []
32
- value_temp << value
33
- value = value_temp
34
+ value = [value]
34
35
  end
35
36
  value << ary_value
36
37
  else
@@ -1,6 +1,6 @@
1
1
  # encoding: ascii-8bit
2
2
 
3
- # Copyright 2022 OpenC3, Inc.
3
+ # Copyright 2024 OpenC3, Inc.
4
4
  # All Rights Reserved.
5
5
  #
6
6
  # This program is free software; you can modify and/or redistribute it
@@ -13,7 +13,7 @@
13
13
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
14
  # GNU Affero General Public License for more details.
15
15
  #
16
- # This file may also be used under the terms of a commercial license
16
+ # This file may also be used under the terms of a commercial license
17
17
  # if purchased from OpenC3, Inc.
18
18
 
19
19
  require 'openc3/accessors/xml_accessor'
@@ -28,4 +28,4 @@ module OpenC3
28
28
  doc.to_html
29
29
  end
30
30
  end
31
- end
31
+ end
@@ -1,6 +1,6 @@
1
1
  # encoding: ascii-8bit
2
2
 
3
- # Copyright 2023 OpenC3, Inc.
3
+ # Copyright 2024 OpenC3, Inc.
4
4
  # All Rights Reserved.
5
5
  #
6
6
  # This program is free software; you can modify and/or redistribute it
@@ -50,10 +50,10 @@ module OpenC3
50
50
  return @packet.extra['HTTP_ERROR_PACKET']
51
51
  when /^HTTP_QUERY_/
52
52
  return nil unless @packet.extra
53
- if item.key
54
- query_name = item.key
53
+ if item.key =~ /^HTTP_QUERY_/
54
+ query_name = item_name[11..-1].downcase
55
55
  else
56
- query_name = item_name[11..-1]
56
+ query_name = item.key
57
57
  end
58
58
  queries = @packet.extra['HTTP_QUERIES']
59
59
  if queries
@@ -63,10 +63,10 @@ module OpenC3
63
63
  end
64
64
  when /^HTTP_HEADER_/
65
65
  return nil unless @packet.extra
66
- if item.key
67
- header_name = item.key
66
+ if item.key =~ /^HTTP_HEADER_/
67
+ header_name = item_name[12..-1].downcase
68
68
  else
69
- header_name = item_name[12..-1]
69
+ header_name = item.key
70
70
  end
71
71
  headers = @packet.extra['HTTP_HEADERS']
72
72
  if headers
@@ -99,19 +99,19 @@ module OpenC3
99
99
  @packet.extra['HTTP_ERROR_PACKET'] = value.to_s.upcase
100
100
  when /^HTTP_QUERY_/
101
101
  @packet.extra ||= {}
102
- if item.key
103
- query_name = item.key
102
+ if item.key =~ /^HTTP_QUERY_/
103
+ query_name = item_name[11..-1].downcase
104
104
  else
105
- query_name = item_name[11..-1]
105
+ query_name = item.key
106
106
  end
107
107
  queries = @packet.extra['HTTP_QUERIES'] ||= {}
108
108
  queries[query_name] = value.to_s
109
109
  when /^HTTP_HEADER_/
110
110
  @packet.extra ||= {}
111
- if item.key
112
- header_name = item.key
111
+ if item.key =~ /^HTTP_HEADER_/
112
+ header_name = item_name[12..-1].downcase
113
113
  else
114
- header_name = item_name[12..-1]
114
+ header_name = item.key
115
115
  end
116
116
  headers = @packet.extra['HTTP_HEADERS'] ||= {}
117
117
  headers[header_name] = value.to_s
@@ -1,6 +1,6 @@
1
1
  # encoding: ascii-8bit
2
2
 
3
- # Copyright 2022 OpenC3, Inc.
3
+ # Copyright 2024 OpenC3, Inc.
4
4
  # All Rights Reserved.
5
5
  #
6
6
  # This program is free software; you can modify and/or redistribute it
@@ -24,7 +24,13 @@ module OpenC3
24
24
  def self.read_item(item, buffer)
25
25
  return nil if item.data_type == :DERIVED
26
26
  doc = buffer_to_doc(buffer)
27
- return convert_to_type(doc.xpath(item.key).first.to_s, item)
27
+ doc_value = doc.xpath(item.key)
28
+ # Nokogiri returns a Nokogiri::XML::Text which responds to first
29
+ # unless they've applied some XPath functions to the result like normalize-space
30
+ if doc_value.respond_to?(:first)
31
+ doc_value = doc_value.first
32
+ end
33
+ return convert_to_type(doc_value.to_s, item)
28
34
  end
29
35
 
30
36
  def self.write_item(item, value, buffer)
@@ -43,7 +49,13 @@ module OpenC3
43
49
  if item.data_type == :DERIVED
44
50
  result[item.name] = nil
45
51
  else
46
- result[item.name] = convert_to_type(doc.xpath(item.key).first.to_s, item)
52
+ doc_value = doc.xpath(item.key)
53
+ # Nokogiri returns a Nokogiri::XML::Text which responds to first
54
+ # unless they've applied some XPath functions to the result like normalize-space
55
+ if doc_value.respond_to?(:first)
56
+ doc_value = doc_value.first
57
+ end
58
+ result[item.name] = convert_to_type(doc_value.to_s, item)
47
59
  end
48
60
  end
49
61
  return result
@@ -94,4 +106,4 @@ module OpenC3
94
106
  return true
95
107
  end
96
108
  end
97
- end
109
+ end