openc3 5.20.0 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
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