openc3 5.1.1 → 5.2.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 (97) hide show
  1. checksums.yaml +4 -4
  2. data/bin/openc3cli +48 -9
  3. data/data/config/interface_modifiers.yaml +14 -0
  4. data/data/config/parameter_modifiers.yaml +5 -3
  5. data/data/config/screen.yaml +12 -8
  6. data/data/config/target.yaml +33 -0
  7. data/ext/openc3/ext/config_parser/config_parser.c +66 -63
  8. data/ext/openc3/ext/packet/packet.c +1 -4
  9. data/lib/openc3/api/README.md +5 -0
  10. data/lib/openc3/api/api.rb +3 -1
  11. data/lib/openc3/api/cmd_api.rb +43 -112
  12. data/lib/openc3/api/interface_api.rb +3 -3
  13. data/lib/openc3/api/offline_access_api.rb +78 -0
  14. data/lib/openc3/api/settings_api.rb +3 -1
  15. data/lib/openc3/api/stash_api.rb +63 -0
  16. data/lib/openc3/api/target_api.rb +4 -5
  17. data/lib/openc3/config/config_parser.rb +47 -47
  18. data/lib/openc3/interfaces/interface.rb +11 -1
  19. data/lib/openc3/interfaces/protocols/burst_protocol.rb +30 -16
  20. data/lib/openc3/interfaces/protocols/fixed_protocol.rb +8 -2
  21. data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +2 -2
  22. data/lib/openc3/interfaces/protocols/override_protocol.rb +2 -2
  23. data/lib/openc3/interfaces/tcpip_server_interface.rb +3 -1
  24. data/lib/openc3/io/json_api_object.rb +30 -9
  25. data/lib/openc3/io/json_drb.rb +6 -1
  26. data/lib/openc3/io/json_drb_object.rb +18 -9
  27. data/lib/openc3/io/json_rpc.rb +5 -3
  28. data/lib/openc3/logs/buffered_packet_log_writer.rb +1 -1
  29. data/lib/openc3/logs/log_writer.rb +8 -2
  30. data/lib/openc3/microservices/cleanup_microservice.rb +3 -3
  31. data/lib/openc3/microservices/decom_microservice.rb +8 -8
  32. data/lib/openc3/microservices/interface_microservice.rb +86 -71
  33. data/lib/openc3/microservices/log_microservice.rb +5 -3
  34. data/lib/openc3/microservices/microservice.rb +18 -14
  35. data/lib/openc3/microservices/multi_microservice.rb +62 -0
  36. data/lib/openc3/microservices/periodic_microservice.rb +58 -0
  37. data/lib/openc3/microservices/reaction_microservice.rb +61 -47
  38. data/lib/openc3/microservices/reducer_microservice.rb +64 -40
  39. data/lib/openc3/microservices/router_microservice.rb +4 -4
  40. data/lib/openc3/microservices/text_log_microservice.rb +2 -2
  41. data/lib/openc3/microservices/timeline_microservice.rb +44 -30
  42. data/lib/openc3/microservices/trigger_group_microservice.rb +39 -36
  43. data/lib/openc3/migrations/20221202214600_add_target_names.rb +30 -0
  44. data/lib/openc3/migrations/20221210174900_convert_to_multi.rb +65 -0
  45. data/lib/openc3/models/cvt_model.rb +1 -1
  46. data/lib/openc3/models/gem_model.rb +24 -20
  47. data/lib/openc3/models/interface_model.rb +69 -35
  48. data/lib/openc3/models/metadata_model.rb +1 -1
  49. data/lib/openc3/models/microservice_model.rb +7 -24
  50. data/lib/openc3/models/migration_model.rb +52 -0
  51. data/lib/openc3/models/model.rb +2 -7
  52. data/lib/openc3/models/note_model.rb +1 -1
  53. data/lib/openc3/models/offline_access_model.rb +55 -0
  54. data/lib/openc3/models/plugin_model.rb +12 -3
  55. data/lib/openc3/models/reaction_model.rb +6 -2
  56. data/lib/openc3/models/scope_model.rb +89 -13
  57. data/lib/openc3/models/settings_model.rb +1 -1
  58. data/lib/openc3/models/stash_model.rb +53 -0
  59. data/lib/openc3/models/target_model.rb +301 -130
  60. data/lib/openc3/models/tool_model.rb +1 -12
  61. data/lib/openc3/models/widget_model.rb +1 -6
  62. data/lib/openc3/operators/microservice_operator.rb +45 -6
  63. data/lib/openc3/operators/operator.rb +27 -5
  64. data/lib/openc3/packets/commands.rb +1 -25
  65. data/lib/openc3/packets/limits.rb +0 -75
  66. data/lib/openc3/packets/packet.rb +0 -28
  67. data/lib/openc3/packets/packet_item.rb +23 -0
  68. data/lib/openc3/packets/packet_item_limits.rb +2 -2
  69. data/lib/openc3/packets/parsers/state_parser.rb +10 -6
  70. data/lib/openc3/packets/telemetry.rb +1 -45
  71. data/lib/openc3/script/commands.rb +41 -71
  72. data/lib/openc3/script/extract.rb +15 -1
  73. data/lib/openc3/script/{calendar.rb → metadata.rb} +42 -17
  74. data/lib/openc3/script/script.rb +13 -5
  75. data/lib/openc3/script/storage.rb +3 -1
  76. data/lib/openc3/system/system.rb +19 -17
  77. data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +4 -4
  78. data/lib/openc3/top_level.rb +3 -3
  79. data/lib/openc3/topics/command_decom_topic.rb +2 -2
  80. data/lib/openc3/topics/command_topic.rb +7 -6
  81. data/lib/openc3/topics/interface_topic.rb +2 -2
  82. data/lib/openc3/topics/router_topic.rb +1 -1
  83. data/lib/openc3/topics/telemetry_topic.rb +2 -1
  84. data/lib/openc3/utilities/authentication.rb +35 -14
  85. data/lib/openc3/utilities/aws_bucket.rb +4 -3
  86. data/lib/openc3/utilities/bucket.rb +4 -2
  87. data/lib/openc3/utilities/bucket_file_cache.rb +3 -8
  88. data/lib/openc3/utilities/bucket_utilities.rb +77 -15
  89. data/lib/openc3/utilities/local_mode.rb +12 -9
  90. data/lib/openc3/utilities/logger.rb +17 -9
  91. data/lib/openc3/utilities/message_log.rb +6 -5
  92. data/lib/openc3/utilities/migration.rb +22 -0
  93. data/lib/openc3/utilities/store_autoload.rb +7 -5
  94. data/lib/openc3/utilities/target_file.rb +9 -7
  95. data/lib/openc3/version.rb +6 -6
  96. data/lib/openc3.rb +2 -1
  97. metadata +14 -3
@@ -17,7 +17,7 @@
17
17
  # All changes Copyright 2022, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
- # This file may also be used under the terms of a commercial license
20
+ # This file may also be used under the terms of a commercial license
21
21
  # if purchased from OpenC3, Inc.
22
22
 
23
23
  require 'openc3'
@@ -64,27 +64,65 @@ module OpenC3
64
64
  # Detect new and changed microservices
65
65
  @new_microservices = {}
66
66
  @changed_microservices = {}
67
+ @removed_microservices = {}
67
68
  @microservices.each do |microservice_name, microservice_config|
69
+ parent = microservice_config['parent']
68
70
  if @previous_microservices[microservice_name]
71
+ previous_parent = @previous_microservices[microservice_name]['parent']
69
72
  if @previous_microservices[microservice_name] != microservice_config
73
+ # CHANGED
70
74
  scope = microservice_name.split("__")[0]
71
75
  Logger.info("Changed microservice detected: #{microservice_name}\nWas: #{@previous_microservices[microservice_name]}\nIs: #{microservice_config}", scope: scope)
72
- @changed_microservices[microservice_name] = microservice_config
76
+ if parent or previous_parent
77
+ if parent == previous_parent
78
+ # Same Parent - Respawn parent
79
+ @changed_microservices[parent] = @microservices[parent] if @microservices[parent] and @previous_microservices[parent]
80
+ elsif parent and previous_parent
81
+ # Parent changed - Respawn both parents
82
+ @changed_microservices[parent] = @microservices[parent] if @microservices[parent] and @previous_microservices[parent]
83
+ @changed_microservices[previous_parent] = @microservices[previous_parent] if @microservices[previous_parent] and @previous_microservices[previous_parent]
84
+ elsif parent
85
+ # Moved under a parent - Respawn parent and kill standalone
86
+ @changed_microservices[parent] = @microservices[parent] if @microservices[parent] and @previous_microservices[parent]
87
+ @removed_microservices[microservice_name] = microservice_config
88
+ else # previous_parent
89
+ # Moved to standalone - Respawn previous parent and make new
90
+ @changed_microservices[previous_parent] = @microservices[previous_parent] if @microservices[previous_parent] and @previous_microservices[previous_parent]
91
+ @new_microservices[microservice_name] = microservice_config
92
+ end
93
+ else
94
+ # Respawn regular microservice
95
+ @changed_microservices[microservice_name] = microservice_config
96
+ end
73
97
  end
74
98
  else
99
+ # NEW
75
100
  scope = microservice_name.split("__")[0]
76
101
  Logger.info("New microservice detected: #{microservice_name}", scope: scope)
77
- @new_microservices[microservice_name] = microservice_config
102
+ if parent
103
+ # Respawn parent
104
+ @changed_microservices[parent] = @microservices[parent] if @microservices[parent] and @previous_microservices[parent]
105
+ else
106
+ # New process be spawned
107
+ @new_microservices[microservice_name] = microservice_config
108
+ end
78
109
  end
79
110
  end
80
111
 
81
112
  # Detect removed microservices
82
- @removed_microservices = {}
83
113
  @previous_microservices.each do |microservice_name, microservice_config|
114
+ previous_parent = microservice_config['parent']
84
115
  unless @microservices[microservice_name]
116
+ # REMOVED
85
117
  scope = microservice_name.split("__")[0]
86
118
  Logger.info("Removed microservice detected: #{microservice_name}", scope: scope)
87
- @removed_microservices[microservice_name] = microservice_config
119
+ if previous_parent
120
+ # Respawn previous parent
121
+ @changed_microservices[previous_parent] = @microservices[previous_parent] if @microservices[previous_parent] and @previous_microservices[previous_parent]
122
+ else
123
+ # Regular process to be removed
124
+ @removed_microservices[microservice_name] = microservice_config
125
+ end
88
126
  end
89
127
  end
90
128
 
@@ -109,7 +147,8 @@ module OpenC3
109
147
  process.new_temp_dir = nil
110
148
  process.env = env
111
149
  @changed_processes[microservice_name] = process
112
- else # TODO: How is this even possible?
150
+ else
151
+ # This shouldn't be possible, but still needs to be handled
113
152
  Logger.error("Changed microservice #{microservice_name} does not exist. Creating new...", scope: scope)
114
153
  process = OperatorProcess.new(cmd_array, work_dir: work_dir, env: env, scope: scope, container: container, config: microservice_config)
115
154
  @new_processes[microservice_name] = process
@@ -225,12 +225,11 @@ module OpenC3
225
225
  @@instance = nil
226
226
 
227
227
  CYCLE_TIME = 5.0 # cycle time to check for new microservices
228
+ PROCESS_SHUTDOWN_SECONDS = 5.0
228
229
 
229
230
  def initialize
230
231
  Logger.level = Logger::INFO
231
- # TODO: This is pretty generic. Can we pass in more information to help identify the operator?
232
232
  Logger.microservice_name = 'MicroserviceOperator'
233
- Logger.tag = "operator.log"
234
233
 
235
234
  OperatorProcess.setup()
236
235
  @cycle_time = (ENV['OPERATOR_CYCLE_TIME'] and ENV['OPERATOR_CYCLE_TIME'].to_f) || CYCLE_TIME # time in seconds
@@ -305,9 +304,31 @@ module OpenC3
305
304
  end
306
305
 
307
306
  def shutdown_processes(processes)
307
+ Logger.info("Commanding soft stops...")
308
308
  processes.each { |name, p| p.soft_stop }
309
- sleep(4) # TODO: This is an arbitrary sleep of 4s ...
310
- processes.each { |name, p| p.hard_stop }
309
+ start_time = Time.now
310
+ # Allow sufficient time for processes to shutdown cleanly
311
+ while (Time.now - start_time) < PROCESS_SHUTDOWN_SECONDS
312
+ processes_to_remove = []
313
+ processes.each do |name, p|
314
+ unless p.alive?
315
+ processes_to_remove << name
316
+ Logger.info("Soft stop process successful: #{p.cmd_line}", scope: p.scope)
317
+ end
318
+ end
319
+ processes_to_remove.each do |name|
320
+ processes.delete(name)
321
+ end
322
+ if processes.length <= 0
323
+ Logger.info("Soft stop all successful")
324
+ break
325
+ end
326
+ sleep(0.1)
327
+ end
328
+ if processes.length > 0
329
+ Logger.info("Commanding hard stops...")
330
+ processes.each { |name, p| p.hard_stop }
331
+ end
311
332
  end
312
333
 
313
334
  def run
@@ -317,6 +338,7 @@ module OpenC3
317
338
  @mutex.synchronize do
318
339
  Logger.info("Shutting down processes...")
319
340
  shutdown_processes(@processes)
341
+ Logger.info("Shutting down processes complete")
320
342
  @shutdown_complete = true
321
343
  end
322
344
  end
@@ -337,7 +359,7 @@ module OpenC3
337
359
 
338
360
  loop do
339
361
  break if @shutdown_complete
340
- sleep(1)
362
+ sleep(0.1)
341
363
  end
342
364
  ensure
343
365
  Logger.info("#{self.class} shutdown complete")
@@ -17,7 +17,7 @@
17
17
  # All changes Copyright 2022, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
- # This file may also be used under the terms of a commercial license
20
+ # This file may also be used under the terms of a commercial license
21
21
  # if purchased from OpenC3, Inc.
22
22
 
23
23
  require 'openc3/packets/packet_config'
@@ -297,30 +297,6 @@ module OpenC3
297
297
  end
298
298
  end
299
299
 
300
- # Returns an array with a "TARGET_NAME PACKET_NAME" string for every command in the system (PACKET_NAME == command name)
301
- def all_packet_strings(include_hidden = false, splash = nil)
302
- strings = []
303
- tnames = target_names()
304
- total = tnames.length.to_f
305
- tnames.each_with_index do |target_name, index|
306
- if splash
307
- splash.message = "Processing #{target_name} command"
308
- splash.progress = index / total
309
- end
310
-
311
- # TODO: This wasn't being used ... should it be
312
- # ignored_items = System.targets[target_name].ignored_items
313
-
314
- packets(target_name).each do |command_name, packet|
315
- # We don't audit against hidden or disabled packets/commands
316
- next if !include_hidden and (packet.hidden || packet.disabled)
317
-
318
- strings << "#{target_name} #{command_name}"
319
- end
320
- end
321
- strings
322
- end
323
-
324
300
  def all
325
301
  @config.commands
326
302
  end
@@ -62,86 +62,11 @@ module OpenC3
62
62
  return items
63
63
  end
64
64
 
65
- # @param ignored_items [Array<Array<String, String, String>>] Items to ignore from the consideration
66
- # @return [Symbol] The overall limits state for the system
67
- def overall_limits_state(ignored_items = nil)
68
- overall = :GREEN
69
- limits_packet_stale = false
70
- items_out_of_limits = []
71
- # Note: If anything with limits is stale then overall limits state cannot be green or blue
72
- @config.telemetry.each do |target_name, target_packets|
73
- target_packets.each do |packet_name, packet|
74
- if packet.stale && !packet.limits_items.empty?
75
- if ignored_items
76
- all_ignored = true
77
- packet.limits_items.each do |item|
78
- all_ignored = false unless includes_item?(ignored_items, target_name, packet_name, item.name)
79
- end
80
- else
81
- all_ignored = false
82
- end
83
- limits_packet_stale = true unless all_ignored
84
- end
85
- items_out_of_limits.concat(packet.out_of_limits)
86
- end
87
- end
88
- items_out_of_limits.each do |target_name, packet_name, item_name, limits_state|
89
- next if ignored_items && includes_item?(ignored_items, target_name, packet_name, item_name)
90
-
91
- case overall
92
- # If our overall state is currently blue or green we can go to any state
93
- when :BLUE, :GREEN, :GREEN_HIGH, :GREEN_LOW
94
- overall = limits_state
95
- # If our overal state is yellow we can only go higher to red
96
- when :YELLOW, :YELLOW_HIGH, :YELLOW_LOW
97
- if limits_state == :RED || limits_state == :RED_HIGH || limits_state == :RED_LOW
98
- overall = limits_state
99
- break # Red is as high as we go so no need to look for more
100
- end
101
- end
102
- end
103
- overall = :GREEN if overall == :GREEN_HIGH || overall == :GREEN_LOW || overall == :BLUE
104
- overall = :YELLOW if overall == :YELLOW_HIGH || overall == :YELLOW_LOW
105
- overall = :RED if overall == :RED_HIGH || overall == :RED_LOW
106
- overall = :STALE if (overall == :GREEN || overall == :BLUE) && limits_packet_stale
107
- return overall
108
- end
109
-
110
65
  # @return [Hash(String, Array)] The defined limits groups
111
66
  def groups
112
67
  return @config.limits_groups
113
68
  end
114
69
 
115
- # Enables limit checking for all the items in the given group.
116
- #
117
- # @param group_name [String] Name of the group to enable
118
- def enable_group(group_name)
119
- group_upcase = group_name.to_s.upcase
120
- limits_group = @config.limits_groups[group_upcase]
121
- if limits_group
122
- limits_group.each do |target_name, packet_name, item_name|
123
- enable(target_name, packet_name, item_name)
124
- end
125
- else
126
- raise "LIMITS_GROUP #{group_upcase} undefined. Ensure your telemetry definition contains the line: LIMITS_GROUP #{group_upcase}"
127
- end
128
- end
129
-
130
- # Disables limit checking for all the items in the given group.
131
- #
132
- # @param group_name [String] Name of the group to disable
133
- def disable_group(group_name)
134
- group_upcase = group_name.to_s.upcase
135
- limits_group = @config.limits_groups[group_upcase]
136
- if limits_group
137
- limits_group.each do |target_name, packet_name, item_name|
138
- disable(target_name, packet_name, item_name)
139
- end
140
- else
141
- raise "LIMITS_GROUP #{group_upcase} undefined. Ensure your telemetry definition contains the line: LIMITS_GROUP #{group_upcase}"
142
- end
143
- end
144
-
145
70
  # Checks whether the limits are enabled for the specified item
146
71
  #
147
72
  # @param target_name [String] The target name
@@ -62,9 +62,6 @@ module OpenC3
62
62
  # @return [Hash<Item Name, Value>] Given values when constructing the packet
63
63
  attr_reader :given_values
64
64
 
65
- # @return [Boolean] Flag indicating if the packet is stale (hasn't been received recently)
66
- attr_reader :stale
67
-
68
65
  # @return [Boolean] Whether or not this is a 'raw' packet
69
66
  attr_accessor :raw
70
67
 
@@ -119,7 +116,6 @@ module OpenC3
119
116
  @given_values = nil
120
117
  @limits_items = nil
121
118
  @processors = nil
122
- @stale = true
123
119
  @limits_change_callback = nil
124
120
  @read_conversion_cache = nil
125
121
  @raw = nil
@@ -896,13 +892,6 @@ module OpenC3
896
892
  return items
897
893
  end
898
894
 
899
- # Set the limits state for all items to the given state
900
- #
901
- # @param state [Symbol] Must be one of PacketItemLimits::LIMITS_STATES
902
- def set_all_limits_states(state)
903
- @sorted_items.each { |item| item.limits.state = state }
904
- end
905
-
906
895
  # Check all the items in the packet against their defined limits. Update
907
896
  # their internal limits state and persistence and call the
908
897
  # limits_change_callback as necessary.
@@ -912,14 +901,6 @@ module OpenC3
912
901
  # @param ignore_persistence [Boolean] Whether to ignore persistence when
913
902
  # checking for out of limits
914
903
  def check_limits(limits_set = :DEFAULT, ignore_persistence = false)
915
- # If check_limits is being called, then a new packet has arrived and
916
- # this packet is no longer stale
917
- # Stored telemetry doesn't affect the current value table and such doesn't affect stale
918
- if @stale and !@stored
919
- @stale = false
920
- set_all_limits_states(nil)
921
- end
922
-
923
904
  return unless @limits_items
924
905
 
925
906
  @limits_items.each do |item|
@@ -937,13 +918,6 @@ module OpenC3
937
918
  end
938
919
  end
939
920
 
940
- # Sets the overall packet stale state to true and sets each packet item
941
- # limits state to :STALE.
942
- def set_stale
943
- @stale = true
944
- set_all_limits_states(:STALE)
945
- end
946
-
947
921
  # Reset temporary packet data
948
922
  # This includes packet received time, received count, and processor state
949
923
  def reset
@@ -1063,7 +1037,6 @@ module OpenC3
1063
1037
  config['messages_disabled'] = true if @messages_disabled
1064
1038
  config['disabled'] = true if @disabled
1065
1039
  config['hidden'] = true if @hidden
1066
- config['stale'] = true if @stale
1067
1040
  config['accessor'] = @accessor.to_s
1068
1041
  config['template'] = Base64.encode64(@template) if @template
1069
1042
 
@@ -1103,7 +1076,6 @@ module OpenC3
1103
1076
  packet.messages_disabled = hash['messages_disabled']
1104
1077
  packet.disabled = hash['disabled']
1105
1078
  packet.hidden = hash['hidden']
1106
- # packet.stale is read only
1107
1079
  if hash['accessor']
1108
1080
  begin
1109
1081
  packet.accessor = OpenC3::const_get(hash['accessor'])
@@ -78,6 +78,10 @@ module OpenC3
78
78
  # description was given the value will be nil.
79
79
  attr_reader :hazardous
80
80
 
81
+ # @return [Hash] Whether or not messages should be printed for this state.
82
+ # Given as STATE_NAME => true / false.
83
+ attr_accessor :messages_disabled
84
+
81
85
  # Colors associated with states
82
86
  # @return [Hash] State colors given as STATE_NAME => COLOR
83
87
  attr_reader :state_colors
@@ -104,6 +108,7 @@ module OpenC3
104
108
  @range = nil
105
109
  @required = false
106
110
  @hazardous = nil
111
+ @messages_disabled = nil
107
112
  @state_colors = nil
108
113
  @limits = PacketItemLimits.new
109
114
  @persistence_setting = 1
@@ -250,6 +255,16 @@ module OpenC3
250
255
  end
251
256
  end
252
257
 
258
+ def messages_disabled=(messages_disabled)
259
+ if messages_disabled
260
+ raise ArgumentError, "#{@name}: messages_disabled must be a Hash but is a #{messages_disabled.class}" unless Hash === messages_disabled
261
+
262
+ @messages_disabled = messages_disabled.clone
263
+ else
264
+ @messages_disabled = nil
265
+ end
266
+ end
267
+
253
268
  def state_colors=(state_colors)
254
269
  if state_colors
255
270
  raise ArgumentError, "#{@name}: state_colors must be a Hash but is a #{state_colors.class}" unless Hash === state_colors
@@ -296,6 +311,7 @@ module OpenC3
296
311
  item.units = self.units.clone if self.units
297
312
  item.default = self.default.clone if self.default and String === self.default
298
313
  item.hazardous = self.hazardous.clone if self.hazardous
314
+ item.messages_disabled = self.messages_disabled.clone if self.messages_disabled
299
315
  item.state_colors = self.state_colors.clone if self.state_colors
300
316
  item.limits = self.limits.clone if self.limits
301
317
  item.meta = self.meta.clone if @meta
@@ -325,6 +341,7 @@ module OpenC3
325
341
  hash['range'] = self.range
326
342
  hash['required'] = self.required
327
343
  hash['hazardous'] = self.hazardous
344
+ hash['messages_disabled'] = self.messages_disabled
328
345
  hash['state_colors'] = self.state_colors
329
346
  hash['limits'] = self.limits.to_hash
330
347
  hash['meta'] = nil
@@ -394,6 +411,9 @@ module OpenC3
394
411
  if @hazardous and @hazardous[state_name]
395
412
  config << " HAZARDOUS #{@hazardous[state_name].to_s.quote_if_necessary}"
396
413
  end
414
+ if @messages_disabled and @messages_disabled[state_name]
415
+ config << " DISABLE_MESSAGES"
416
+ end
397
417
  if @state_colors and @state_colors[state_name]
398
418
  config << " #{@state_colors[state_name]}"
399
419
  end
@@ -459,6 +479,7 @@ module OpenC3
459
479
  states[state_name] = state
460
480
  state['value'] = state_value.as_json(*a)
461
481
  state['hazardous'] = @hazardous[state_name] if @hazardous and @hazardous[state_name]
482
+ state['messages_disabled'] = @messages_disabled[state_name] if @messages_disabled and @messages_disabled[state_name]
462
483
  state['color'] = @state_colors[state_name].to_s if @state_colors and @state_colors[state_name]
463
484
  end
464
485
  end
@@ -509,10 +530,12 @@ module OpenC3
509
530
  if hash['states']
510
531
  item.states = {}
511
532
  item.hazardous = {}
533
+ item.messages_disabled = {}
512
534
  item.state_colors = {}
513
535
  hash['states'].each do |state_name, state|
514
536
  item.states[state_name] = state['value']
515
537
  item.hazardous[state_name] = state['hazardous']
538
+ item.messages_disabled[state_name] = state['messages_disabled']
516
539
  item.state_colors[state_name] = state['color'].to_sym if state['color']
517
540
  end
518
541
  end
@@ -17,7 +17,7 @@
17
17
  # All changes Copyright 2022, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
- # This file may also be used under the terms of a commercial license
20
+ # This file may also be used under the terms of a commercial license
21
21
  # if purchased from OpenC3, Inc.
22
22
 
23
23
  require 'openc3/packets/limits_response'
@@ -71,7 +71,7 @@ module OpenC3
71
71
  def initialize
72
72
  @values = nil
73
73
  @enabled = false
74
- @state = :STALE
74
+ @state = nil
75
75
  @response = nil
76
76
  @persistence_setting = 1
77
77
  @persistence_count = 0
@@ -17,7 +17,7 @@
17
17
  # All changes Copyright 2022, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
- # This file may also be used under the terms of a commercial license
20
+ # This file may also be used under the terms of a commercial license
21
21
  # if purchased from OpenC3, Inc.
22
22
 
23
23
  require 'openc3/packets/packet_item'
@@ -48,7 +48,7 @@ module OpenC3
48
48
  def verify_parameters(cmd_or_tlm)
49
49
  @usage = "STATE <STATE NAME> <STATE VALUE> "
50
50
  if cmd_or_tlm == PacketConfig::COMMAND
51
- @usage << "<HAZARDOUS (Optional)> <Hazardous Description (Optional)>"
51
+ @usage << "<HAZARDOUS / DISABLE_MESSAGES (Optional)> <Hazardous Description (Optional)>"
52
52
  @parser.verify_num_parameters(2, 4, @usage)
53
53
  else
54
54
  @usage << "<COLOR: GREEN/YELLOW/RED (Optional)>"
@@ -96,23 +96,27 @@ module OpenC3
96
96
  return unless @parser.parameters.length > 2
97
97
 
98
98
  if cmd_or_tlm == PacketConfig::COMMAND
99
- get_hazardous(item)
99
+ get_hazardous_or_disable_messages(item)
100
100
  else
101
101
  get_state_colors(item)
102
102
  packet.update_limits_items_cache(item)
103
103
  end
104
104
  end
105
105
 
106
- def get_hazardous(item)
107
- if @parser.parameters[2].upcase == 'HAZARDOUS'
106
+ def get_hazardous_or_disable_messages(item)
107
+ case @parser.parameters[2].upcase
108
+ when 'HAZARDOUS'
108
109
  item.hazardous ||= {}
109
110
  if @parser.parameters[3]
110
111
  item.hazardous[get_state_name()] = @parser.parameters[3]
111
112
  else
112
113
  item.hazardous[get_state_name()] = ""
113
114
  end
115
+ when 'DISABLE_MESSAGES'
116
+ item.messages_disabled ||= {}
117
+ item.messages_disabled[get_state_name()] = true
114
118
  else
115
- raise @parser.error("HAZARDOUS expected as third parameter for this line.", @usage)
119
+ raise @parser.error("HAZARDOUS or DISABLE_MESSAGES expected as third parameter for this line.", @usage)
116
120
  end
117
121
  end
118
122
 
@@ -17,7 +17,7 @@
17
17
  # All changes Copyright 2022, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
- # This file may also be used under the terms of a commercial license
20
+ # This file may also be used under the terms of a commercial license
21
21
  # if purchased from OpenC3, Inc.
22
22
 
23
23
  require 'openc3/packets/packet_config'
@@ -372,50 +372,6 @@ module OpenC3
372
372
  end
373
373
  end
374
374
 
375
- # Iterates through all the telemetry packets and marks them stale if they
376
- # haven't been received for over the System.staleness_seconds value.
377
- #
378
- # @return [Array(Packet)] Array of the stale packets
379
- def check_stale
380
- stale = []
381
- time = Time.now.sys
382
- @config.telemetry.each do |target_name, target_packets|
383
- target_packets.each do |packet_name, packet|
384
- if packet.received_time and (!packet.stale) and (time - packet.received_time > System.staleness_seconds)
385
- packet.set_stale
386
- stale << packet
387
- end
388
- end
389
- end
390
- stale
391
- end
392
-
393
- # @param with_limits_only [Boolean] Return only the stale packets
394
- # that have limits items and thus affect the overall limits
395
- # state of the system
396
- # @param target [String] Target name or nil for all targets
397
- # @return [Array(Packet)] Array of the stale packets
398
- def stale(with_limits_only = false, target = nil)
399
- if target && !target_names.include?(target)
400
- raise "Telemetry target '#{target.upcase}' does not exist"
401
- end
402
-
403
- stale = []
404
- @config.telemetry.each do |target_name, target_packets|
405
- next if target && target != target_name
406
- next if target_name == 'UNKNOWN'
407
-
408
- target_packets.each do |packet_name, packet|
409
- if packet.stale
410
- next if with_limits_only && packet.limits_items.empty?
411
-
412
- stale << packet
413
- end
414
- end
415
- end
416
- stale
417
- end
418
-
419
375
  # Clears the received_count value on every packet in every target
420
376
  def clear_counters
421
377
  @config.telemetry.each do |target_name, target_packets|