openc3 5.14.0 → 5.14.1

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.

Potentially problematic release.


This version of openc3 might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2b009f636dd8566127001ad9ee48972d584fb03baaf88389646048e7231dc54b
4
- data.tar.gz: 0ce2ff7aad089eba4794f4f15075bcf5e3087632f776eb76127c80af5256bda6
3
+ metadata.gz: 459b654a51a4d3b984681eb1b25165039e95d0a22c68e08973fc3539beee1b5c
4
+ data.tar.gz: cf6975c07ab38342228401d84a01f1ee672f4a74b7c2a697f2dc893aecfb4b3e
5
5
  SHA512:
6
- metadata.gz: 1d87b341b985cca628485419b0406b449289364497e4061024d0407551920fc8f62529fb35897761a1ae471c838cf2ce38d706fcf84eea4960abdd24a7608af5
7
- data.tar.gz: '0758dfda18babfc4c47f870efe074e5a6bbd371aee1ba2a362f3d851791f20c2f5955e7f144972198a461a314b0a2a334c02d8191c7387503c30a11d8bd53c50'
6
+ metadata.gz: 8368bda2e80639021df632271a972a5a716a8db380eb23dd4375d3334d10ca3001a5a33d9017caeeff684804338d4ba36a2adc180d1656f843d20440560d47ab
7
+ data.tar.gz: 195a9f6a3e4dbbadb1ed219765f627e1dd3cf96f9fd14a21e7891ea24e5cef6847eefb644ae8cfcbd15a894a32f0c23fc10bf405b9b2c3011553411f14f58b42
@@ -45,6 +45,7 @@ module OpenC3
45
45
  end
46
46
 
47
47
  def run
48
+ setup_microservice_topic()
48
49
  while true
49
50
  break if @cancel_thread
50
51
 
@@ -52,8 +53,9 @@ module OpenC3
52
53
  OpenC3.in_span("read_topics") do
53
54
  Topic.read_topics(@topics) do |topic, msg_id, msg_hash, redis|
54
55
  break if @cancel_thread
55
-
56
- if topic =~ /__DECOMINTERFACE/
56
+ if topic == @microservice_topic
57
+ microservice_cmd(topic, msg_id, msg_hash, redis)
58
+ elsif topic =~ /__DECOMINTERFACE/
57
59
  if msg_hash.key?('inject_tlm')
58
60
  handle_inject_tlm(msg_hash['inject_tlm'])
59
61
  next
@@ -62,12 +62,17 @@ module OpenC3
62
62
 
63
63
  def run
64
64
  setup_plws()
65
+ setup_microservice_topic()
65
66
  while true
66
67
  break if @cancel_thread
67
68
 
68
69
  Topic.read_topics(@topics) do |topic, msg_id, msg_hash, redis|
69
70
  break if @cancel_thread
70
- log_data(topic, msg_id, msg_hash, redis)
71
+ if topic == @microservice_topic
72
+ microservice_cmd(topic, msg_id, msg_hash, redis)
73
+ else
74
+ log_data(topic, msg_id, msg_hash, redis)
75
+ end
71
76
  @count += 1
72
77
  @metric.set(name: 'log_total', value: @count, type: 'counter')
73
78
  end
@@ -116,6 +116,7 @@ module OpenC3
116
116
  end
117
117
  @logger.info("Microservice initialized with config:\n#{@config}")
118
118
  @topics ||= []
119
+ @microservice_topic = "MICROSERVICE__#{@name}"
119
120
 
120
121
  # Get configuration for any targets
121
122
  @target_names = @config["target_names"]
@@ -210,5 +211,32 @@ module OpenC3
210
211
  @logger.info("Shutting down microservice complete: #{@name}")
211
212
  @shutdown_complete = true
212
213
  end
214
+
215
+ def setup_microservice_topic
216
+ @topics.append(@microservice_topic)
217
+ Thread.current[:topic_offsets] ||= {}
218
+ topic_offsets = Thread.current[:topic_offsets]
219
+ topic_offsets[@microservice_topic] = "0-0" # Always get all available
220
+ end
221
+
222
+ # Returns if the command was handled
223
+ def microservice_cmd(topic, msg_id, msg_hash, redis)
224
+ command = msg_hash['command']
225
+ case command
226
+ when 'ADD_TOPICS'
227
+ topics = JSON.parse(msg_hash['topics'])
228
+ if topics and Array === topics
229
+ topics.each do |new_topic|
230
+ @topics << new_topic unless @topics.include?(new_topic)
231
+ end
232
+ else
233
+ raise "Invalid topics given to microservice_cmd: #{topics}"
234
+ end
235
+ Topic.trim_topic(topic, msg_id)
236
+ return true
237
+ end
238
+ Topic.trim_topic(topic, msg_id)
239
+ return false
240
+ end
213
241
  end
214
242
  end
@@ -43,6 +43,7 @@ module OpenC3
43
43
  attr_accessor :secrets
44
44
  attr_accessor :prefix
45
45
  attr_accessor :disable_erb
46
+ attr_accessor :ignore_changes
46
47
 
47
48
  # NOTE: The following three class methods are used by the ModelController
48
49
  # and are reimplemented to enable various Model class methods to work
@@ -103,6 +104,7 @@ module OpenC3
103
104
  secrets: [],
104
105
  prefix: nil,
105
106
  disable_erb: nil,
107
+ ignore_changes: nil,
106
108
  scope:
107
109
  )
108
110
  parts = name.split("__")
@@ -128,6 +130,7 @@ module OpenC3
128
130
  @secrets = secrets
129
131
  @prefix = prefix
130
132
  @disable_erb = disable_erb
133
+ @ignore_changes = ignore_changes
131
134
  @bucket = Bucket.getClient()
132
135
  end
133
136
 
@@ -149,7 +152,8 @@ module OpenC3
149
152
  'needs_dependencies' => @needs_dependencies,
150
153
  'secrets' => @secrets.as_json(*a),
151
154
  'prefix' => @prefix,
152
- 'disable_erb' => @disable_erb
155
+ 'disable_erb' => @disable_erb,
156
+ 'ignore_changes' => @ignore_changes
153
157
  }
154
158
  end
155
159
 
@@ -342,7 +342,7 @@ module OpenC3
342
342
  raise message
343
343
  end
344
344
  rescue Exception => error
345
- Logger.error("Error undeploying plugin model #{@name} in scope #{@scope} due to: #{error}")
345
+ Logger.error("Error undeploying plugin model #{@name} in scope #{@scope} due to: #{error.formatted}")
346
346
  ensure
347
347
  # Double check everything is gone
348
348
  found = []
@@ -869,6 +869,42 @@ module OpenC3
869
869
  )
870
870
  end
871
871
  end
872
+
873
+ # Inform microservices of new topics
874
+ # Need to tell loggers to log, and decom to decom
875
+ # We do this for no downtime
876
+ raw_topics = []
877
+ decom_topics = []
878
+ packets.each do |packet|
879
+ if cmd_or_tlm == :TELEMETRY
880
+ raw_topics << "#{@scope}__TELEMETRY__{#{@name}}__#{packet.packet_name.upcase}"
881
+ decom_topics << "#{@scope}__DECOM__{#{@name}}__#{packet.packet_name.upcase}"
882
+ else
883
+ raw_topics << "#{@scope}__COMMAND__{#{@name}}__#{packet.packet_name.upcase}"
884
+ decom_topics << "#{@scope}__DECOMCMD__{#{@name}}__#{packet.packet_name.upcase}"
885
+ end
886
+ end
887
+ if cmd_or_tlm == :TELEMETRY
888
+ Topic.write_topic("MICROSERVICE__#{@scope}__PACKETLOG__#{@name}", {'command' => 'ADD_TOPICS', 'topics' => raw_topics.as_json.to_json})
889
+ add_topics_to_microservice("#{@scope}__PACKETLOG__#{@name}", raw_topics)
890
+ Topic.write_topic("MICROSERVICE__#{@scope}__DECOMLOG__#{@name}", {'command' => 'ADD_TOPICS', 'topics' => decom_topics.as_json.to_json})
891
+ add_topics_to_microservice("#{@scope}__DECOMLOG__#{@name}", decom_topics)
892
+ Topic.write_topic("MICROSERVICE__#{@scope}__DECOM__#{@name}", {'command' => 'ADD_TOPICS', 'topics' => raw_topics.as_json.to_json})
893
+ add_topics_to_microservice("#{@scope}__DECOM__#{@name}", raw_topics)
894
+ else
895
+ Topic.write_topic("MICROSERVICE__#{@scope}__COMMANDLOG__#{@name}", {'command' => 'ADD_TOPICS', 'topics' => raw_topics.as_json.to_json})
896
+ add_topics_to_microservice("#{@scope}__COMMANDLOG__#{@name}", raw_topics)
897
+ Topic.write_topic("MICROSERVICE__#{@scope}__DECOMCMDLOG__#{@name}", {'command' => 'ADD_TOPICS', 'topics' => decom_topics.as_json.to_json})
898
+ add_topics_to_microservice("#{@scope}__DECOMCMDLOG__#{@name}", decom_topics)
899
+ end
900
+ end
901
+
902
+ def add_topics_to_microservice(microservice_name, topics)
903
+ model = MicroserviceModel.get_model(name: microservice_name, scope: @scope)
904
+ model.topics.concat(topics)
905
+ model.topics.uniq!
906
+ model.ignore_changes = true # Don't restart the microservice right now
907
+ model.update
872
908
  end
873
909
 
874
910
  def deploy_commmandlog_microservice(gem_path, variables, topics, instance = nil, parent = nil)
@@ -1109,7 +1145,6 @@ module OpenC3
1109
1145
  decom_command_topic_list = []
1110
1146
  packet_topic_list = []
1111
1147
  decom_topic_list = []
1112
- reduced_topic_list = []
1113
1148
  begin
1114
1149
  system.commands.packets(@name).each do |packet_name, packet|
1115
1150
  command_topic_list << "#{@scope}__COMMAND__{#{@name}}__#{packet_name}"
@@ -1122,9 +1157,6 @@ module OpenC3
1122
1157
  system.telemetry.packets(@name).each do |packet_name, packet|
1123
1158
  packet_topic_list << "#{@scope}__TELEMETRY__{#{@name}}__#{packet_name}"
1124
1159
  decom_topic_list << "#{@scope}__DECOM__{#{@name}}__#{packet_name}"
1125
- reduced_topic_list << "#{@scope}__REDUCED_MINUTE__{#{@name}}__#{packet_name}"
1126
- reduced_topic_list << "#{@scope}__REDUCED_HOUR__{#{@name}}__#{packet_name}"
1127
- reduced_topic_list << "#{@scope}__REDUCED_DAY__{#{@name}}__#{packet_name}"
1128
1160
  end
1129
1161
  rescue
1130
1162
  # No telemetry packets for this target
@@ -98,28 +98,30 @@ module OpenC3
98
98
  previous_parent = @previous_microservices[microservice_name]['parent']
99
99
  if @previous_microservices[microservice_name] != microservice_config
100
100
  # CHANGED
101
- scope = microservice_name.split("__")[0]
102
- Logger.info("Changed microservice detected: #{microservice_name}\nWas: #{@previous_microservices[microservice_name]}\nIs: #{microservice_config}", scope: scope)
103
- if parent or previous_parent
104
- if parent == previous_parent
105
- # Same Parent - Respawn parent
106
- @changed_microservices[parent] = @microservices[parent] if @microservices[parent] and @previous_microservices[parent]
107
- elsif parent and previous_parent
108
- # Parent changed - Respawn both parents
109
- @changed_microservices[parent] = @microservices[parent] if @microservices[parent] and @previous_microservices[parent]
110
- @changed_microservices[previous_parent] = @microservices[previous_parent] if @microservices[previous_parent] and @previous_microservices[previous_parent]
111
- elsif parent
112
- # Moved under a parent - Respawn parent and kill standalone
113
- @changed_microservices[parent] = @microservices[parent] if @microservices[parent] and @previous_microservices[parent]
114
- @removed_microservices[microservice_name] = microservice_config
115
- else # previous_parent
116
- # Moved to standalone - Respawn previous parent and make new
117
- @changed_microservices[previous_parent] = @microservices[previous_parent] if @microservices[previous_parent] and @previous_microservices[previous_parent]
118
- @new_microservices[microservice_name] = microservice_config
101
+ if not microservice_config['ignore_changes']
102
+ scope = microservice_name.split("__")[0]
103
+ Logger.info("Changed microservice detected: #{microservice_name}\nWas: #{@previous_microservices[microservice_name]}\nIs: #{microservice_config}", scope: scope)
104
+ if parent or previous_parent
105
+ if parent == previous_parent
106
+ # Same Parent - Respawn parent
107
+ @changed_microservices[parent] = @microservices[parent] if @microservices[parent] and @previous_microservices[parent]
108
+ elsif parent and previous_parent
109
+ # Parent changed - Respawn both parents
110
+ @changed_microservices[parent] = @microservices[parent] if @microservices[parent] and @previous_microservices[parent]
111
+ @changed_microservices[previous_parent] = @microservices[previous_parent] if @microservices[previous_parent] and @previous_microservices[previous_parent]
112
+ elsif parent
113
+ # Moved under a parent - Respawn parent and kill standalone
114
+ @changed_microservices[parent] = @microservices[parent] if @microservices[parent] and @previous_microservices[parent]
115
+ @removed_microservices[microservice_name] = microservice_config
116
+ else # previous_parent
117
+ # Moved to standalone - Respawn previous parent and make new
118
+ @changed_microservices[previous_parent] = @microservices[previous_parent] if @microservices[previous_parent] and @previous_microservices[previous_parent]
119
+ @new_microservices[microservice_name] = microservice_config
120
+ end
121
+ else
122
+ # Respawn regular microservice
123
+ @changed_microservices[microservice_name] = microservice_config
119
124
  end
120
- else
121
- # Respawn regular microservice
122
- @changed_microservices[microservice_name] = microservice_config
123
125
  end
124
126
  end
125
127
  else
@@ -303,6 +303,10 @@ module OpenC3
303
303
  @config.commands
304
304
  end
305
305
 
306
+ def dynamic_add_packet(packet, affect_ids: false)
307
+ @config.dynamic_add_packet(packet, :COMMAND, affect_ids: affect_ids)
308
+ end
309
+
306
310
  protected
307
311
 
308
312
  def set_parameters(command, params, range_checking)
@@ -315,30 +315,60 @@ module OpenC3
315
315
  hash = @cmd_id_value_hash[@current_packet.target_name]
316
316
  hash = {} unless hash
317
317
  @cmd_id_value_hash[@current_packet.target_name] = hash
318
- update_id_value_hash(hash)
318
+ update_id_value_hash(@current_packet, hash)
319
319
  else
320
320
  @telemetry[@current_packet.target_name][@current_packet.packet_name] = @current_packet
321
321
  hash = @tlm_id_value_hash[@current_packet.target_name]
322
322
  hash = {} unless hash
323
323
  @tlm_id_value_hash[@current_packet.target_name] = hash
324
- update_id_value_hash(hash)
324
+ update_id_value_hash(@current_packet, hash)
325
325
  end
326
326
  @current_packet = nil
327
327
  @current_item = nil
328
328
  end
329
329
  end
330
330
 
331
+ def dynamic_add_packet(packet, cmd_or_tlm = :TELEMETRY, affect_ids: false)
332
+ if cmd_or_tlm == :COMMAND
333
+ @commands[packet.target_name][packet.packet_name] = packet
334
+
335
+ if affect_ids
336
+ hash = @cmd_id_value_hash[packet.target_name]
337
+ hash = {} unless hash
338
+ @cmd_id_value_hash[packet.target_name] = hash
339
+ update_id_value_hash(packet, hash)
340
+ end
341
+ else
342
+ @telemetry[packet.target_name][packet.packet_name] = packet
343
+
344
+ # Update latest_data lookup for telemetry
345
+ packet.sorted_items.each do |item|
346
+ target_latest_data = @latest_data[packet.target_name]
347
+ target_latest_data[item.name] ||= []
348
+ latest_data_packets = target_latest_data[item.name]
349
+ latest_data_packets << packet unless latest_data_packets.include?(packet)
350
+ end
351
+
352
+ if affect_ids
353
+ hash = @tlm_id_value_hash[packet.target_name]
354
+ hash = {} unless hash
355
+ @tlm_id_value_hash[packet.target_name] = hash
356
+ update_id_value_hash(packet, hash)
357
+ end
358
+ end
359
+ end
360
+
331
361
  protected
332
362
 
333
- def update_id_value_hash(hash)
334
- if @current_packet.id_items.length > 0
363
+ def update_id_value_hash(packet, hash)
364
+ if packet.id_items.length > 0
335
365
  key = []
336
- @current_packet.id_items.each do |item|
366
+ packet.id_items.each do |item|
337
367
  key << item.id_value
338
368
  end
339
- hash[key] = @current_packet
369
+ hash[key] = packet
340
370
  else
341
- hash['CATCHALL'.freeze] = @current_packet
371
+ hash['CATCHALL'.freeze] = packet
342
372
  end
343
373
  end
344
374
 
@@ -442,5 +442,9 @@ module OpenC3
442
442
  def all
443
443
  @config.telemetry
444
444
  end
445
+
446
+ def dynamic_add_packet(packet, affect_ids: false)
447
+ @config.dynamic_add_packet(packet, :TELEMETRY, affect_ids: affect_ids)
448
+ end
445
449
  end # class Telemetry
446
450
  end
@@ -60,6 +60,9 @@ module OpenC3
60
60
  # The current limits set
61
61
  @@limits_set = nil
62
62
 
63
+ # Callbacks to call once @@instance is created
64
+ @@post_instance_callbacks = []
65
+
63
66
  # @return [Symbol] The current limits_set of the system returned from Redis
64
67
  def self.limits_set
65
68
  unless @@limits_set
@@ -72,6 +75,14 @@ module OpenC3
72
75
  @@limits_set = value.to_s.intern
73
76
  end
74
77
 
78
+ def self.add_post_instance_callback(callback)
79
+ if @@instance
80
+ callback.call()
81
+ else
82
+ @@post_instance_callbacks << callback
83
+ end
84
+ end
85
+
75
86
  def self.setup_targets(target_names, base_dir, scope:)
76
87
  # Nothing to do if there are no targets
77
88
  return if target_names.nil? or target_names.length == 0
@@ -121,11 +132,30 @@ module OpenC3
121
132
  raise "System.instance parameters are required on first call" unless target_names and target_config_dir
122
133
 
123
134
  @@instance_mutex.synchronize do
135
+ return @@instance if @@instance
124
136
  @@instance ||= self.new(target_names, target_config_dir)
137
+ @@post_instance_callbacks.each do |callback|
138
+ callback.call
139
+ end
125
140
  return @@instance
126
141
  end
127
142
  end
128
143
 
144
+ # Dynamically add packets to the system instance
145
+ #
146
+ # @param dynamic_packets [Array of packets]
147
+ # @param cmd_or_tlm [Symbol] :COMMAND or :TELEMETRY
148
+ # @param affect_ids [Boolean] Whether to affect packet id lookup or not
149
+ def self.dynamic_update(dynamic_packets, cmd_or_tlm = :TELEMETRY, affect_ids: false)
150
+ dynamic_packets.each do |packet|
151
+ if cmd_or_tlm == :TELEMETRY
152
+ @@instance.telemetry.dynamic_add_packet(packet, affect_ids: affect_ids)
153
+ else
154
+ @@instance.commands.dynamic_add_packet(packet, affect_ids: affect_ids)
155
+ end
156
+ end
157
+ end
158
+
129
159
  # Create a new System object.
130
160
  #
131
161
  # @param target_names [Array of target names]
@@ -1,14 +1,14 @@
1
1
  # encoding: ascii-8bit
2
2
 
3
- OPENC3_VERSION = '5.14.0'
3
+ OPENC3_VERSION = '5.14.1'
4
4
  module OpenC3
5
5
  module Version
6
6
  MAJOR = '5'
7
7
  MINOR = '14'
8
- PATCH = '0'
8
+ PATCH = '1'
9
9
  OTHER = ''
10
- BUILD = 'dd31e4853fa50ed08ee3100e43e75849617d0a47'
10
+ BUILD = '902e54e502f6070c58183746a7db21a50e7b5263'
11
11
  end
12
- VERSION = '5.14.0'
13
- GEM_VERSION = '5.14.0'
12
+ VERSION = '5.14.1'
13
+ GEM_VERSION = '5.14.1'
14
14
  end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "<%= tool_name %>",
3
- "version": "5.14.0",
3
+ "version": "5.14.1",
4
4
  "scripts": {
5
5
  "ng": "ng",
6
6
  "start": "ng serve",
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "private": true,
14
14
  "dependencies": {
15
- "@openc3/tool-common": "5.14.0",
15
+ "@openc3/tool-common": "5.14.1",
16
16
  "@angular/animations": "^17.0.8",
17
17
  "@angular/cdk": "^17.0.4",
18
18
  "@angular/common": "^17.0.8",
@@ -11,7 +11,7 @@
11
11
  "smui-theme": "smui-theme compile build/smui.css -i src/theme"
12
12
  },
13
13
  "dependencies": {
14
- "@openc3/tool-common": "5.14.0",
14
+ "@openc3/tool-common": "5.14.1",
15
15
  "@astrouxds/astro-web-components": "7.20.0",
16
16
  "@smui/button": "^7.0.0-beta.16",
17
17
  "@smui/card": "^7.0.0-beta.16",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "<%= tool_name %>",
3
- "version": "5.14.0",
3
+ "version": "5.14.1",
4
4
  "private": true,
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -11,7 +11,7 @@
11
11
  "test:components": "vue-cli-service test:components"
12
12
  },
13
13
  "dependencies": {
14
- "@openc3/tool-common": "5.14.0",
14
+ "@openc3/tool-common": "5.14.1",
15
15
  "@astrouxds/astro-web-components": "7.20.0",
16
16
  "axios": "1.6.5",
17
17
  "date-fns": "2.30.0",
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "widget",
3
- "version": "5.14.0",
3
+ "version": "5.14.1",
4
4
  "private": true,
5
5
  "scripts": {
6
6
  "build": "vue-cli-service build --target lib --dest tools/widgets/<%= widget_name %> --formats umd-min <%= widget_path %> --name <%= widget_name %>"
7
7
  },
8
8
  "dependencies": {
9
- "@openc3/tool-common": "5.14.0",
9
+ "@openc3/tool-common": "5.14.1",
10
10
  "@astrouxds/astro-web-components": "7.20.0",
11
11
  "vue": "2.7.16",
12
12
  "vuetify": "2.7.1"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openc3
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.14.0
4
+ version: 5.14.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Melton
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-01-18 00:00:00.000000000 Z
12
+ date: 2024-01-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler