openc3 5.17.1 → 5.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +7 -4
  3. data/bin/cstol_converter +14 -14
  4. data/bin/openc3cli +190 -8
  5. data/data/config/_interfaces.yaml +5 -5
  6. data/data/config/command_modifiers.yaml +59 -0
  7. data/data/config/interface_modifiers.yaml +19 -9
  8. data/data/config/item_modifiers.yaml +34 -26
  9. data/data/config/microservice.yaml +4 -1
  10. data/data/config/param_item_modifiers.yaml +17 -1
  11. data/data/config/parameter_modifiers.yaml +30 -13
  12. data/data/config/plugins.yaml +9 -5
  13. data/data/config/screen.yaml +9 -9
  14. data/data/config/table_manager.yaml +2 -2
  15. data/data/config/telemetry_modifiers.yaml +9 -4
  16. data/data/config/tool.yaml +4 -1
  17. data/data/config/widgets.yaml +44 -17
  18. data/ext/openc3/ext/config_parser/config_parser.c +1 -1
  19. data/ext/openc3/ext/packet/packet.c +7 -1
  20. data/ext/openc3/ext/platform/platform.c +3 -3
  21. data/ext/openc3/ext/structure/structure.c +56 -76
  22. data/lib/openc3/accessors/accessor.rb +1 -0
  23. data/lib/openc3/accessors/binary_accessor.rb +174 -15
  24. data/lib/openc3/accessors/form_accessor.rb +2 -2
  25. data/lib/openc3/accessors/http_accessor.rb +1 -1
  26. data/lib/openc3/accessors/json_accessor.rb +6 -4
  27. data/lib/openc3/accessors/template_accessor.rb +6 -9
  28. data/lib/openc3/accessors/xml_accessor.rb +1 -1
  29. data/lib/openc3/api/cmd_api.rb +72 -44
  30. data/lib/openc3/api/config_api.rb +10 -10
  31. data/lib/openc3/api/interface_api.rb +28 -21
  32. data/lib/openc3/api/limits_api.rb +30 -30
  33. data/lib/openc3/api/metrics_api.rb +3 -3
  34. data/lib/openc3/api/offline_access_api.rb +5 -5
  35. data/lib/openc3/api/router_api.rb +25 -19
  36. data/lib/openc3/api/settings_api.rb +10 -10
  37. data/lib/openc3/api/stash_api.rb +10 -10
  38. data/lib/openc3/api/target_api.rb +10 -10
  39. data/lib/openc3/api/tlm_api.rb +44 -44
  40. data/lib/openc3/config/config_parser.rb +1 -1
  41. data/lib/openc3/conversions/bit_reverse_conversion.rb +60 -0
  42. data/lib/openc3/conversions/ip_read_conversion.rb +59 -0
  43. data/lib/openc3/conversions/ip_write_conversion.rb +61 -0
  44. data/lib/openc3/conversions/object_read_conversion.rb +88 -0
  45. data/lib/openc3/conversions/object_write_conversion.rb +38 -0
  46. data/lib/openc3/conversions/segmented_polynomial_conversion.rb +7 -7
  47. data/lib/openc3/conversions.rb +6 -1
  48. data/lib/openc3/core_ext/array.rb +5 -5
  49. data/lib/openc3/core_ext/exception.rb +9 -2
  50. data/lib/openc3/core_ext/string.rb +2 -2
  51. data/lib/openc3/interfaces/http_server_interface.rb +1 -0
  52. data/lib/openc3/interfaces/interface.rb +1 -1
  53. data/lib/openc3/interfaces/linc_interface.rb +3 -3
  54. data/lib/openc3/io/json_api.rb +11 -6
  55. data/lib/openc3/io/json_drb.rb +19 -21
  56. data/lib/openc3/io/json_rpc.rb +15 -14
  57. data/lib/openc3/logs/buffered_packet_log_writer.rb +3 -3
  58. data/lib/openc3/logs/log_writer.rb +7 -8
  59. data/lib/openc3/logs/packet_log_writer.rb +7 -7
  60. data/lib/openc3/logs/text_log_writer.rb +4 -4
  61. data/lib/openc3/microservices/decom_microservice.rb +19 -4
  62. data/lib/openc3/microservices/interface_microservice.rb +41 -3
  63. data/lib/openc3/microservices/microservice.rb +11 -11
  64. data/lib/openc3/microservices/reaction_microservice.rb +2 -2
  65. data/lib/openc3/microservices/scope_cleanup_microservice.rb +1 -1
  66. data/lib/openc3/microservices/timeline_microservice.rb +70 -45
  67. data/lib/openc3/microservices/trigger_group_microservice.rb +3 -3
  68. data/lib/openc3/migrations/20240915000000_activity_uuid.rb +28 -0
  69. data/lib/openc3/models/activity_model.rb +124 -92
  70. data/lib/openc3/models/auth_model.rb +31 -2
  71. data/lib/openc3/models/cvt_model.rb +11 -5
  72. data/lib/openc3/models/gem_model.rb +8 -8
  73. data/lib/openc3/models/plugin_model.rb +3 -3
  74. data/lib/openc3/models/reducer_model.rb +2 -2
  75. data/lib/openc3/models/scope_model.rb +45 -14
  76. data/lib/openc3/models/sorted_model.rb +5 -5
  77. data/lib/openc3/models/target_model.rb +7 -4
  78. data/lib/openc3/models/tool_config_model.rb +1 -1
  79. data/lib/openc3/models/tool_model.rb +4 -4
  80. data/lib/openc3/models/widget_model.rb +11 -5
  81. data/lib/openc3/operators/microservice_operator.rb +2 -2
  82. data/lib/openc3/operators/operator.rb +14 -12
  83. data/lib/openc3/packets/command_validator.rb +48 -0
  84. data/lib/openc3/packets/commands.rb +6 -14
  85. data/lib/openc3/packets/packet.rb +49 -16
  86. data/lib/openc3/packets/packet_config.rb +47 -25
  87. data/lib/openc3/packets/packet_item.rb +5 -0
  88. data/lib/openc3/packets/parsers/packet_parser.rb +3 -3
  89. data/lib/openc3/packets/structure.rb +87 -15
  90. data/lib/openc3/packets/structure_item.rb +76 -53
  91. data/lib/openc3/packets/telemetry.rb +6 -27
  92. data/lib/openc3/script/api_shared.rb +7 -5
  93. data/lib/openc3/script/calendar.rb +2 -2
  94. data/lib/openc3/script/commands.rb +6 -4
  95. data/lib/openc3/script/extract.rb +5 -3
  96. data/lib/openc3/script/metadata.rb +2 -2
  97. data/lib/openc3/script/suite.rb +17 -17
  98. data/lib/openc3/script/web_socket_api.rb +11 -0
  99. data/lib/openc3/streams/serial_stream.rb +2 -3
  100. data/lib/openc3/streams/stream.rb +2 -2
  101. data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +10 -10
  102. data/lib/openc3/tools/table_manager/table_manager_core.rb +11 -11
  103. data/lib/openc3/tools/table_manager/table_parser.rb +2 -3
  104. data/lib/openc3/topics/command_decom_topic.rb +2 -1
  105. data/lib/openc3/topics/command_topic.rb +3 -3
  106. data/lib/openc3/topics/decom_interface_topic.rb +4 -3
  107. data/lib/openc3/topics/system_events_topic.rb +40 -0
  108. data/lib/openc3/topics/telemetry_decom_topic.rb +1 -1
  109. data/lib/openc3/utilities/authentication.rb +2 -1
  110. data/lib/openc3/utilities/authorization.rb +4 -3
  111. data/lib/openc3/utilities/cli_generator.rb +15 -8
  112. data/lib/openc3/utilities/cosmos_rails_formatter.rb +60 -0
  113. data/lib/openc3/utilities/crc.rb +6 -6
  114. data/lib/openc3/utilities/local_mode.rb +2 -1
  115. data/lib/openc3/utilities/logger.rb +44 -34
  116. data/lib/openc3/utilities/metric.rb +1 -2
  117. data/lib/openc3/utilities/quaternion.rb +18 -18
  118. data/lib/openc3/utilities/target_file.rb +4 -4
  119. data/lib/openc3/version.rb +6 -6
  120. data/lib/openc3/win32/win32_main.rb +2 -2
  121. data/templates/tool_angular/package.json +22 -22
  122. data/templates/tool_react/package.json +13 -13
  123. data/templates/tool_svelte/package.json +14 -14
  124. data/templates/tool_svelte/src/services/openc3-api.js +17 -17
  125. data/templates/tool_vue/package.json +13 -13
  126. data/templates/widget/package.json +11 -12
  127. data/templates/widget/src/Widget.vue +0 -1
  128. metadata +25 -2
@@ -14,7 +14,7 @@
14
14
  # GNU Affero General Public License for more details.
15
15
 
16
16
  # Modified by OpenC3, Inc.
17
- # All changes Copyright 2022, OpenC3, Inc.
17
+ # All changes Copyright 2024, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
20
  # This file may also be used under the terms of a commercial license
@@ -26,6 +26,18 @@ require 'openc3/models/plugin_model'
26
26
  require 'openc3/models/microservice_model'
27
27
  require 'openc3/models/setting_model'
28
28
  require 'openc3/models/trigger_group_model'
29
+ require 'openc3/topics/system_events_topic'
30
+
31
+ begin
32
+ require 'openc3-enterprise/models/cmd_authority_model'
33
+ rescue LoadError
34
+ # Stub out the Enterprise CmdAuthorityModel to do nothing
35
+ class CmdAuthorityModel
36
+ def self.names(scope:)
37
+ []
38
+ end
39
+ end
40
+ end
29
41
 
30
42
  module OpenC3
31
43
  class ScopeModel < Model
@@ -37,9 +49,13 @@ module OpenC3
37
49
  attr_accessor :text_log_retain_time
38
50
  attr_accessor :tool_log_retain_time
39
51
  attr_accessor :cleanup_poll_time
52
+ attr_accessor :command_authority
40
53
 
41
54
  # NOTE: The following three class methods are used by the ModelController
42
55
  # and are reimplemented to enable various Model class methods to work
56
+ #
57
+ # The scope keyword is given to support the ModelController method signature
58
+ # even though it is not used
43
59
  def self.get(name:, scope: nil)
44
60
  super(PRIMARY_KEY, name: name)
45
61
  end
@@ -52,13 +68,13 @@ module OpenC3
52
68
  super(PRIMARY_KEY)
53
69
  end
54
70
 
55
- def self.from_json(json, scope: nil)
71
+ def self.from_json(json)
56
72
  json = JSON.parse(json, :allow_nan => true, :create_additions => true) if String === json
57
73
  raise "json data is nil" if json.nil?
58
- self.new(**json.transform_keys(&:to_sym), scope: scope)
74
+ self.new(**json.transform_keys(&:to_sym))
59
75
  end
60
76
 
61
- def self.get_model(name:, scope: nil)
77
+ def self.get_model(name:)
62
78
  json = get(name: name)
63
79
  if json
64
80
  return from_json(json)
@@ -73,18 +89,15 @@ module OpenC3
73
89
  text_log_retain_time: nil,
74
90
  tool_log_retain_time: nil,
75
91
  cleanup_poll_time: 900,
76
- updated_at: nil,
77
- scope: nil
92
+ command_authority: false,
93
+ updated_at: nil
78
94
  )
79
95
  super(
80
96
  PRIMARY_KEY,
81
97
  name: name,
82
- text_log_cycle_time: text_log_cycle_time,
83
- text_log_cycle_size: text_log_cycle_size,
84
- text_log_retain_time: text_log_retain_time,
85
- tool_log_retain_time: tool_log_retain_time,
86
- cleanup_poll_time: cleanup_poll_time,
87
98
  updated_at: updated_at,
99
+ # This sets the @scope variable which is sort of redundant for the ScopeModel
100
+ # (since its the same as @name) but every model has a @scope
88
101
  scope: name
89
102
  )
90
103
  @text_log_cycle_time = text_log_cycle_time
@@ -92,21 +105,34 @@ module OpenC3
92
105
  @text_log_retain_time = text_log_retain_time
93
106
  @tool_log_retain_time = tool_log_retain_time
94
107
  @cleanup_poll_time = cleanup_poll_time
108
+ @command_authority = command_authority
95
109
  @children = []
96
110
  end
97
111
 
98
112
  def create(update: false, force: false, queued: false)
99
- # Ensure there are no "." in the scope name - prevents gems accidently becoming scope names
113
+ # Ensure there are no "." in the scope name - prevents gems accidentally becoming scope names
100
114
  raise "Invalid scope name: #{@name}" if @name !~ /^[a-zA-Z0-9_-]+$/
101
115
  @name = @name.upcase
116
+ @scope = @name # Ensure @scope matches @name
102
117
  super(update: update, force: force, queued: queued)
118
+
119
+ # If we're updating the scope and disabling command_authority
120
+ # then we clear out all the existing values so it comes up fresh
121
+ if update and @command_authority == false
122
+ CmdAuthorityModel.names(scope: @name).each do |auth_name|
123
+ model = CmdAuthorityModel.get_model(name: auth_name, scope: @name)
124
+ model.destroy if model
125
+ end
126
+ end
127
+
128
+ SystemEventsTopic.write(:scope, as_json())
103
129
  end
104
130
 
105
131
  def destroy
106
132
  if @name != 'DEFAULT'
107
133
  # Remove all the plugins for this scope
108
134
  plugins = PluginModel.get_all_models(scope: @name)
109
- plugins.each do |plugin_name, plugin|
135
+ plugins.each do |_plugin_name, plugin|
110
136
  plugin.destroy
111
137
  end
112
138
  super()
@@ -115,7 +141,7 @@ module OpenC3
115
141
  end
116
142
  end
117
143
 
118
- def as_json(*a)
144
+ def as_json(*_a)
119
145
  { 'name' => @name,
120
146
  'updated_at' => @updated_at,
121
147
  'text_log_cycle_time' => @text_log_cycle_time,
@@ -123,6 +149,7 @@ module OpenC3
123
149
  'text_log_retain_time' => @text_log_retain_time,
124
150
  'tool_log_retain_time' => @tool_log_retain_time,
125
151
  'cleanup_poll_time' => @cleanup_poll_time,
152
+ 'command_authority' => @command_authority,
126
153
  }
127
154
  end
128
155
 
@@ -276,6 +303,10 @@ module OpenC3
276
303
  end
277
304
 
278
305
  def undeploy
306
+ # Delete UNKNOWN target
307
+ target = TargetModel.get_model(name: "UNKNOWN", scope: @scope)
308
+ target.destroy
309
+
279
310
  model = MicroserviceModel.get_model(name: "#{@scope}__SCOPEMULTI__#{@scope}", scope: @scope)
280
311
  model.destroy if model
281
312
  model = MicroserviceModel.get_model(name: "#{@scope}__SCOPECLEANUP__#{@scope}", scope: @scope)
@@ -14,7 +14,7 @@
14
14
  # GNU Affero General Public License for more details.
15
15
 
16
16
  # Modified by OpenC3, Inc.
17
- # All changes Copyright 2023, OpenC3, Inc.
17
+ # All changes Copyright 2024, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
20
  # This file may also be used under the terms of a commercial license
@@ -34,15 +34,15 @@ module OpenC3
34
34
  class SortedOverlapError < SortedError; end
35
35
 
36
36
  class SortedModel < Model
37
- SORTED_TYPE = 'sorted'.freeze # To be overriden by base class
38
- PRIMARY_KEY = '__SORTED'.freeze # To be overriden by base class
37
+ SORTED_TYPE = 'sorted'.freeze # To be overridden by base class
38
+ PRIMARY_KEY = '__SORTED'.freeze # To be overridden by base class
39
39
 
40
- # MUST be overriden by any subclasses
40
+ # MUST be overridden by any subclasses
41
41
  def self.pk(scope)
42
42
  return "#{scope}#{PRIMARY_KEY}"
43
43
  end
44
44
 
45
- # MUST be overriden by any subclasses
45
+ # MUST be overridden by any subclasses
46
46
  def self.notify(scope:, kind:, start:, stop: nil)
47
47
  # Do nothing by default
48
48
  end
@@ -109,7 +109,7 @@ module OpenC3
109
109
  modified_targets = Bucket.getClient().list_files(bucket: ENV['OPENC3_CONFIG_BUCKET'], path: "DEFAULT/targets_modified/", only_directories: true)
110
110
  modified_targets.each do |target_name|
111
111
  # A target could have been deleted without removing the modified files
112
- # Thus we have to check for the existance of the target_name key
112
+ # Thus we have to check for the existence of the target_name key
113
113
  if targets.has_key?(target_name)
114
114
  targets[target_name]['modified'] = true
115
115
  end
@@ -250,7 +250,7 @@ module OpenC3
250
250
  (items - found_items).each do |item|
251
251
  not_found << "'#{target_name} #{packet_name} #{item}'"
252
252
  end
253
- # 'does not exist' not gramatically correct but we use it in every other exception
253
+ # 'does not exist' not grammatically correct but we use it in every other exception
254
254
  raise "Item(s) #{not_found.join(', ')} does not exist"
255
255
  end
256
256
  found
@@ -660,7 +660,10 @@ module OpenC3
660
660
  Store.del(item_map_key)
661
661
  @@item_map_cache[@name] = nil
662
662
 
663
- ConfigTopic.write({ kind: 'deleted', type: 'target', name: @name, plugin: @plugin }, scope: @scope)
663
+ topic = { kind: 'deleted', type: 'target', name: @name }
664
+ # The UNKNOWN target doesn't have an associated plugin
665
+ topic[:plugin] = @plugin if @plugin
666
+ ConfigTopic.write(topic, scope: @scope)
664
667
  rescue Exception => e
665
668
  Logger.error("Error undeploying target model #{@name} in scope #{@scope} due to #{e}")
666
669
  end
@@ -1118,7 +1121,7 @@ module OpenC3
1118
1121
  end
1119
1122
  end
1120
1123
  # If there are any topics (packets) left over that haven't been
1121
- # explictly handled above, spawn another microservice
1124
+ # explicitly handled above, spawn another microservice
1122
1125
  if all_topics.length > 0
1123
1126
  instance = nil
1124
1127
  instance = deploy_count unless deploy_count == 0
@@ -25,7 +25,7 @@ require 'openc3/utilities/local_mode'
25
25
  module OpenC3
26
26
  class ToolConfigModel
27
27
  def self.config_tool_names(scope: $openc3_scope)
28
- cursor, keys = Store.scan(0, match: "#{scope}__config__*", type: 'hash', count: 100)
28
+ _, keys = Store.scan(0, match: "#{scope}__config__*", type: 'hash', count: 100)
29
29
  # Just return the tool name that is used in the other APIs
30
30
  return keys.map! { |key| key.split('__')[2] }.sort
31
31
  end
@@ -96,7 +96,7 @@ module OpenC3
96
96
  def self.set_position(name:, position:, scope:)
97
97
  moving = from_json(get(name: name, scope: scope), scope: scope)
98
98
  old_pos = moving.position
99
- new_pos = Integer(position)
99
+ new_pos = position
100
100
  direction = :down
101
101
  if (old_pos == new_pos)
102
102
  return # we're not doing anything
@@ -225,7 +225,7 @@ module OpenC3
225
225
  @shown = ConfigParser.handle_true_false(parameters[0])
226
226
  when 'POSITION'
227
227
  parser.verify_num_parameters(1, 1, "POSITION <value>")
228
- @position = parameters[0].to_i
228
+ @position = parameters[0].to_f
229
229
  when 'DISABLE_ERB'
230
230
  # 0 to unlimited parameters
231
231
  @disable_erb ||= []
@@ -274,8 +274,8 @@ module OpenC3
274
274
  ConfigTopic.write({ kind: 'deleted', type: 'tool', name: @folder_name, plugin: @plugin }, scope: @scope)
275
275
  end
276
276
  end
277
- rescue Exception => error
278
- Logger.error("Error undeploying tool model #{@name} in scope #{@scope} due to #{error}")
277
+ rescue Exception => e
278
+ Logger.error("Error undeploying tool model #{@name} in scope #{@scope} due to #{e}")
279
279
  end
280
280
 
281
281
  ##################################################
@@ -73,9 +73,11 @@ module OpenC3
73
73
  def self.handle_config(parser, keyword, parameters, plugin: nil, needs_dependencies: false, scope:)
74
74
  case keyword
75
75
  when 'WIDGET'
76
- parser.verify_num_parameters(1, 2, "WIDGET <Name> <Label>")
76
+ parser.verify_num_parameters(1, 3, "WIDGET <Name> <Label> <Select Items (true/false)>")
77
77
  # Label is optional and if it doesn't exist nil is fine
78
- return self.new(name: parameters[0], plugin: plugin, label: parameters[1], needs_dependencies: needs_dependencies, scope: scope)
78
+ # Select Items is optional and if it doesn't exist nil is fine
79
+ items = ConfigParser.handle_true_false_nil(parameters[2])
80
+ return self.new(name: parameters[0], plugin: plugin, label: parameters[1], items: items, needs_dependencies: needs_dependencies, scope: scope)
79
81
  else
80
82
  raise ConfigParser::Error.new(parser, "Unknown keyword and parameters for Widget: #{keyword} #{parameters.join(" ")}")
81
83
  end
@@ -87,6 +89,7 @@ module OpenC3
87
89
  updated_at: nil,
88
90
  plugin: nil,
89
91
  label: nil,
92
+ items: false,
90
93
  needs_dependencies: false,
91
94
  disable_erb: nil,
92
95
  scope:
@@ -96,6 +99,8 @@ module OpenC3
96
99
  @filename = @full_name + '.umd.min.js'
97
100
  @bucket_key = 'widgets/' + @full_name + '/' + @filename
98
101
  @label = label
102
+ # Ensure items is a boolean because it could be nil
103
+ @items = items ? true : false
99
104
  @needs_dependencies = needs_dependencies
100
105
  @disable_erb = disable_erb
101
106
  end
@@ -106,8 +111,9 @@ module OpenC3
106
111
  'updated_at' => @updated_at,
107
112
  'plugin' => @plugin,
108
113
  'label' => @label,
114
+ 'items' => @items,
109
115
  'needs_dependencies' => @needs_dependencies,
110
- 'disable_erb' => @disable_erb
116
+ 'disable_erb' => @disable_erb,
111
117
  }
112
118
  end
113
119
 
@@ -155,8 +161,8 @@ module OpenC3
155
161
  bucket = Bucket.getClient()
156
162
  bucket.delete_object(bucket: ENV['OPENC3_TOOLS_BUCKET'], key: @bucket_key)
157
163
  bucket.delete_object(bucket: ENV['OPENC3_TOOLS_BUCKET'], key: @bucket_key + '.map')
158
- rescue Exception => error
159
- Logger.error("Error undeploying widget model #{@name} in scope #{@scope} due to #{error}")
164
+ rescue Exception => e
165
+ Logger.error("Error undeploying widget model #{@name} in scope #{@scope} due to #{e}")
160
166
  end
161
167
  end
162
168
  end
@@ -14,7 +14,7 @@
14
14
  # GNU Affero General Public License for more details.
15
15
 
16
16
  # Modified by OpenC3, Inc.
17
- # All changes Copyright 2022, OpenC3, Inc.
17
+ # All changes Copyright 2024, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
20
  # This file may also be used under the terms of a commercial license
@@ -186,7 +186,7 @@ module OpenC3
186
186
  end
187
187
  end
188
188
 
189
- @removed_microservices.each do |microservice_name, microservice_config|
189
+ @removed_microservices.each do |microservice_name, _microservice_config|
190
190
  process = @processes[microservice_name]
191
191
  @processes.delete(microservice_name)
192
192
  @removed_processes[microservice_name] = process
@@ -105,7 +105,7 @@ module OpenC3
105
105
  def cmd_line
106
106
  # In ProcessManager processes, the process_definition is the actual thing run
107
107
  # e.g. OpenC3::ProcessManager.instance.spawn(["ruby", "/openc3/bin/openc3cli", "load", ...])
108
- # However, if the MicroserviceOperator is spawning the proceses it sets
108
+ # However, if the MicroserviceOperator is spawning the processes it sets
109
109
  # process_definition = ["ruby", "plugin_microservice.rb"]
110
110
  # which then calls exec(*@config["cmd"]) to actually run
111
111
  # So check if the @config['cmd'] is defined to give the user more info in the log
@@ -127,7 +127,7 @@ module OpenC3
127
127
  # @process.io.inherit!
128
128
  @process.cwd = @work_dir
129
129
  # Spawned process should not be controlled by same Bundler constraints as spawning process
130
- ENV.each do |key, value|
130
+ ENV.each do |key, _value|
131
131
  if key =~ /^BUNDLER/
132
132
  @process.environment[key] = nil
133
133
  end
@@ -195,12 +195,14 @@ module OpenC3
195
195
  if @process
196
196
  stdout = @process.io.stdout.extract
197
197
  if stdout.length > 0
198
- STDOUT.puts "STDOUT #{stdout.length} bytes from #{cmd_line()}:"
198
+ message = "STDOUT #{stdout.length} bytes from #{cmd_line()}:"
199
+ STDOUT.puts Logger.build_log_data(Logger::INFO_LEVEL, message, user: nil, type: OpenC3::Logger::LOG, url: nil).as_json(:allow_nan => true).to_json(:allow_nan => true)
199
200
  STDOUT.puts stdout
200
201
  end
201
202
  stderr = @process.io.stderr.extract
202
203
  if stderr.length > 0
203
- STDERR.puts "STDERR #{stderr.length} bytes from #{cmd_line()}:"
204
+ message = "STDERR #{stderr.length} bytes from #{cmd_line()}:"
205
+ STDERR.puts Logger.build_log_data(Logger::ERROR_LEVEL, message, user: nil, type: OpenC3::Logger::LOG, url: nil).as_json(:allow_nan => true).to_json(:allow_nan => true)
204
206
  STDERR.puts stderr
205
207
  end
206
208
  end
@@ -265,7 +267,7 @@ module OpenC3
265
267
  if @new_processes.length > 0
266
268
  # Start all the processes
267
269
  Logger.info("#{self.class} starting each new process...")
268
- @new_processes.each { |name, p| p.start }
270
+ @new_processes.each { |_name, p| p.start }
269
271
  @new_processes = {}
270
272
  end
271
273
  end
@@ -278,7 +280,7 @@ module OpenC3
278
280
  shutdown_processes(@changed_processes)
279
281
  break if @shutdown
280
282
 
281
- @changed_processes.each { |name, p| p.start }
283
+ @changed_processes.each { |_name, p| p.start }
282
284
  @changed_processes = {}
283
285
  end
284
286
  end
@@ -296,7 +298,7 @@ module OpenC3
296
298
 
297
299
  def respawn_dead
298
300
  @mutex.synchronize do
299
- @processes.each do |name, p|
301
+ @processes.each do |_name, p|
300
302
  break if @shutdown
301
303
  p.output_increment
302
304
  unless p.alive?
@@ -314,7 +316,7 @@ module OpenC3
314
316
  processes = processes.dup
315
317
 
316
318
  Logger.info("Commanding soft stops...")
317
- processes.each { |name, p| p.soft_stop }
319
+ processes.each { |_name, p| p.soft_stop }
318
320
  start_time = Time.now
319
321
  # Allow sufficient time for processes to shutdown cleanly
320
322
  while (Time.now - start_time) < PROCESS_SHUTDOWN_SECONDS
@@ -322,21 +324,21 @@ module OpenC3
322
324
  processes.each do |name, p|
323
325
  unless p.alive?
324
326
  processes_to_remove << name
325
- Logger.info("Soft stop process successful: #{p.cmd_line}", scope: p.scope)
327
+ Logger.debug("Soft stop process successful: #{p.cmd_line}", scope: p.scope)
326
328
  end
327
329
  end
328
330
  processes_to_remove.each do |name|
329
331
  processes.delete(name)
330
332
  end
331
333
  if processes.length <= 0
332
- Logger.info("Soft stop all successful")
334
+ Logger.debug("Soft stop all successful")
333
335
  break
334
336
  end
335
337
  sleep(0.1)
336
338
  end
337
339
  if processes.length > 0
338
- Logger.info("Commanding hard stops...")
339
- processes.each { |name, p| p.hard_stop }
340
+ Logger.debug("Commanding hard stops...")
341
+ processes.each { |_name, p| p.hard_stop }
340
342
  end
341
343
  end
342
344
 
@@ -0,0 +1,48 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2024 OpenC3, Inc.
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
+ # This file may also be used under the terms of a commercial license
17
+ # if purchased from OpenC3, Inc.
18
+
19
+ # This file implements a class to handle command validation
20
+
21
+ require 'openc3/api/api'
22
+
23
+ module OpenC3
24
+ # This class defines methods which are called when a command is sent.
25
+ # This class must be subclassed and the pre_check or
26
+ # post_check methods implemented. Do NOT use this class directly.
27
+ class CommandValidator
28
+ attr_reader :args
29
+ include Api
30
+
31
+ def initialize(command = nil)
32
+ @command = command
33
+ @args = []
34
+ end
35
+
36
+ def pre_check(command)
37
+ # Return true to indicate Success, false to indicate Failure,
38
+ # and nil to indicate Unknown. The second value is the optional message.
39
+ return [true, nil]
40
+ end
41
+
42
+ def post_check(command)
43
+ # Return true to indicate Success, false to indicate Failure,
44
+ # and nil to indicate Unknown. The second value is the optional message.
45
+ return [true, nil]
46
+ end
47
+ end
48
+ end
@@ -30,7 +30,7 @@ module OpenC3
30
30
  #
31
31
  # This should not be confused with the Api module which implements the JSON
32
32
  # API that is used by tools when accessing the Server. The Api module always
33
- # provides Ruby primatives where the PacketConfig class can return actual
33
+ # provides Ruby primitives where the PacketConfig class can return actual
34
34
  # Packet or PacketItem objects. While there are some overlapping methods between
35
35
  # the two, these are separate interfaces into the system.
36
36
  class Commands
@@ -115,7 +115,7 @@ module OpenC3
115
115
  target = System.targets[target_name]
116
116
  if target and target.cmd_unique_id_mode
117
117
  # Iterate through the packets and see if any represent the buffer
118
- target_packets.each do |packet_name, packet|
118
+ target_packets.each do |_packet_name, packet|
119
119
  if packet.identify?(packet_data)
120
120
  identified_packet = packet
121
121
  break
@@ -147,7 +147,7 @@ module OpenC3
147
147
  end
148
148
 
149
149
  # Returns a copy of the specified command packet with the parameters
150
- # initialzed to the given params values.
150
+ # initialized to the given params values.
151
151
  #
152
152
  # @param target_name (see #packet)
153
153
  # @param packet_name (see #packet)
@@ -195,7 +195,7 @@ module OpenC3
195
195
  items = packet.read_all(:FORMATTED)
196
196
  raw = false
197
197
  end
198
- items.delete_if { |item_name, item_value| ignored_parameters.include?(item_name) }
198
+ items.delete_if { |item_name, _item_value| ignored_parameters.include?(item_name) }
199
199
  return build_cmd_output_string(packet.target_name, packet.packet_name, items, raw)
200
200
  end
201
201
 
@@ -207,7 +207,7 @@ module OpenC3
207
207
  end
208
208
  target_name = 'UNKNOWN' unless target_name
209
209
  cmd_name = 'UNKNOWN' unless cmd_name
210
- output_string << target_name + ' ' + cmd_name
210
+ output_string << (target_name + ' ' + cmd_name)
211
211
  if cmd_params.nil? or cmd_params.empty?
212
212
  output_string << '")'
213
213
  else
@@ -247,7 +247,7 @@ module OpenC3
247
247
  params << "#{key} #{value}"
248
248
  end
249
249
  params = params.join(", ")
250
- output_string << ' with ' + params + '")'
250
+ output_string << (' with ' + params + '")')
251
251
  end
252
252
  return output_string
253
253
  end
@@ -291,14 +291,6 @@ module OpenC3
291
291
  cmd_pkt_hazardous?(build_cmd(target_name, packet_name, params, false, false, false))
292
292
  end
293
293
 
294
- def clear_counters
295
- @config.commands.each do |target_name, target_packets|
296
- target_packets.each do |packet_name, packet|
297
- packet.received_count = 0
298
- end
299
- end
300
- end
301
-
302
294
  def all
303
295
  @config.commands
304
296
  end