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/microservices/microservice'
@@ -30,9 +30,9 @@ require 'openc3/utilities/authentication'
30
30
  require 'openc3/script'
31
31
 
32
32
  module OpenC3
33
-
34
- # This should remain a thread safe implamentation. This is the in memory
35
- # cache that should mirror the database. This will update two hash
33
+
34
+ # This should remain a thread safe implamentation. This is the in memory
35
+ # cache that should mirror the database. This will update two hash
36
36
  # variables and will track triggers to lookup what triggers link to what
37
37
  # reactions.
38
38
  class ReactionBase
@@ -134,7 +134,7 @@ module OpenC3
134
134
  end
135
135
  reaction['triggers'].each do | trigger |
136
136
  trigger_name = trigger['name']
137
- @lookup_mutex.synchronize do
137
+ @lookup_mutex.synchronize do
138
138
  if @lookup[trigger_name].nil?
139
139
  @lookup[trigger_name] = [reaction_name]
140
140
  else
@@ -161,7 +161,7 @@ module OpenC3
161
161
  end
162
162
  reaction['triggers'].each do | trigger |
163
163
  trigger_name = trigger['name']
164
- @lookup_mutex.synchronize do
164
+ @lookup_mutex.synchronize do
165
165
  @lookup[trigger_name].delete(reaction_name)
166
166
  end
167
167
  end
@@ -205,7 +205,7 @@ module OpenC3
205
205
  end
206
206
 
207
207
  # Shared between the monitor thread and the manager thread to
208
- # share the resources.
208
+ # share the resources.
209
209
  class ReactionShare
210
210
 
211
211
  attr_reader :reaction_base, :queue_base, :snooze_base
@@ -226,22 +226,29 @@ module OpenC3
226
226
 
227
227
  attr_reader :name, :scope, :share
228
228
 
229
- def initialize(name:, scope:, share:, ident:)
229
+ def initialize(name:, logger:, scope:, share:, ident:)
230
230
  @name = name
231
+ @logger = logger
231
232
  @scope = scope
232
233
  @share = share
233
234
  @ident = ident
234
235
  @metric_output_time = 0
235
236
  @metric = Metric.new(microservice: @name, scope: @scope)
236
- @authentication = generate_auth()
237
237
  end
238
238
 
239
- # generate the auth object
240
- def generate_auth
241
- if ENV['OPENC3_API_USER'].nil? || ENV['OPENC3_API_CLIENT'].nil?
242
- return OpenC3Authentication.new()
239
+ def get_token(username)
240
+ if ENV['OPENC3_API_CLIENT'].nil?
241
+ return OpenC3Authentication.new().token
243
242
  else
244
- return OpenC3KeycloakAuthentication.new(ENV['OPENC3_KEYCLOAK_URL'])
243
+ # Check for offline access token
244
+ model = nil
245
+ model = OpenC3::OfflineAccessModel.get_model(name: username, scope: @scope) if username and username != ''
246
+ if model and model.offline_access_token
247
+ auth = OpenC3KeycloakAuthentication.new(ENV['OPENC3_KEYCLOAK_URL'])
248
+ return auth.get_token_from_refresh_token(model.offline_access_token)
249
+ else
250
+ return nil
251
+ end
245
252
  end
246
253
  end
247
254
 
@@ -250,7 +257,7 @@ module OpenC3
250
257
  end
251
258
 
252
259
  def run
253
- Logger.info "ReactionWorker-#{@ident} running"
260
+ @logger.info "ReactionWorker-#{@ident} running"
254
261
  loop do
255
262
  begin
256
263
  kind, data = @share.queue_base.queue.pop
@@ -267,10 +274,10 @@ module OpenC3
267
274
  @metric_output_time = current_time + 120
268
275
  end
269
276
  rescue StandardError => e
270
- Logger.error "ReactionWorker-#{@ident} failed to evaluate kind: #{kind} data: #{data}\n#{e.formatted}"
277
+ @logger.error "ReactionWorker-#{@ident} failed to evaluate kind: #{kind} data: #{data}\n#{e.formatted}"
271
278
  end
272
279
  end
273
- Logger.info "ReactionWorker-#{@ident} exiting"
280
+ @logger.info "ReactionWorker-#{@ident} exiting"
274
281
  end
275
282
 
276
283
  def process_enabled_trigger(data:)
@@ -304,22 +311,28 @@ module OpenC3
304
311
  end
305
312
 
306
313
  def run_command(reaction:, action:)
307
- Logger.debug "ReactionWorker-#{@ident} running reaction #{reaction.name}, command: '#{action['value']}' "
314
+ @logger.debug "ReactionWorker-#{@ident} running reaction #{reaction.name}, command: '#{action['value']}' "
308
315
  begin
309
- cmd_no_hazardous_check(action['value'], scope: @scope)
310
- Logger.info "ReactionWorker-#{@ident} #{reaction.name} command action complete, #{action['value']}"
316
+ username = reaction.username
317
+ token = get_token(username)
318
+ raise "No token available for username: #{username}" unless token
319
+ cmd_no_hazardous_check(action['value'], scope: @scope, token: token)
320
+ @logger.info "ReactionWorker-#{@ident} #{reaction.name} command action complete, #{action['value']}"
311
321
  rescue StandardError => e
312
- Logger.error "ReactionWorker-#{@ident} #{reaction.name} command action failed, #{action}\n#{e.message}"
322
+ @logger.error "ReactionWorker-#{@ident} #{reaction.name} command action failed, #{action}\n#{e.message}"
313
323
  end
314
324
  end
315
325
 
316
326
  def run_script(reaction:, action:)
317
- Logger.debug "ReactionWorker-#{@ident} running reaction #{reaction.name}, script: '#{action['value']}'"
327
+ @logger.debug "ReactionWorker-#{@ident} running reaction #{reaction.name}, script: '#{action['value']}'"
318
328
  begin
329
+ username = reaction.username
330
+ token = get_token(username)
331
+ raise "No token available for username: #{username}" unless token
319
332
  request = Net::HTTP::Post.new(
320
333
  "/script-api/scripts/#{action['value']}/run?scope=#{@scope}",
321
334
  'Content-Type' => 'application/json',
322
- 'Authorization' => @authentication.token()
335
+ 'Authorization' => token
323
336
  )
324
337
  request.body = JSON.generate({
325
338
  'scope' => @scope,
@@ -331,22 +344,23 @@ module OpenC3
331
344
  response = Net::HTTP.new(hostname, 2902).request(request)
332
345
  raise "failed to call #{hostname}, for script: #{action['value']}, response code: #{response.code}" if response.code != '200'
333
346
 
334
- Logger.info "ReactionWorker-#{@ident} #{reaction.name} script action complete, #{action['value']} => #{response.body}"
347
+ @logger.info "ReactionWorker-#{@ident} #{reaction.name} script action complete, #{action['value']} => #{response.body}"
335
348
  rescue StandardError => e
336
- Logger.error "ReactionWorker-#{@ident} #{reaction.name} script action failed, #{action}\n#{e.message}"
349
+ @logger.error "ReactionWorker-#{@ident} #{reaction.name} script action failed, #{action}\n#{e.message}"
337
350
  end
338
351
  end
339
352
  end
340
353
 
341
- # The reaction snooze manager starts a thread pool and keeps track of when a
354
+ # The reaction snooze manager starts a thread pool and keeps track of when a
342
355
  # reaction is activated and to evalute triggers when the snooze is complete.
343
356
  class ReactionSnoozeManager
344
357
  SNOOZE_METRIC_NAME = 'snooze_manager_duration_seconds'.freeze
345
358
 
346
359
  attr_reader :name, :scope, :share, :thread_pool
347
360
 
348
- def initialize(name:, scope:, share:)
361
+ def initialize(name:, logger:, scope:, share:)
349
362
  @name = name
363
+ @logger = logger
350
364
  @scope = scope
351
365
  @share = share
352
366
  @worker_count = 3
@@ -359,14 +373,14 @@ module OpenC3
359
373
  def generate_thread_pool()
360
374
  thread_pool = []
361
375
  @worker_count.times do | i |
362
- worker = ReactionWorker.new(name: @name, scope: @scope, share: @share, ident: i)
376
+ worker = ReactionWorker.new(name: @name, logger: @logger, scope: @scope, share: @share, ident: i)
363
377
  thread_pool << Thread.new { worker.run }
364
378
  end
365
379
  return thread_pool
366
380
  end
367
381
 
368
382
  def run
369
- Logger.info "ReactionSnoozeManager running"
383
+ @logger.info "ReactionSnoozeManager running"
370
384
  @thread_pool = generate_thread_pool()
371
385
  loop do
372
386
  begin
@@ -381,13 +395,13 @@ module OpenC3
381
395
  @metric_output_time = current_time + 120
382
396
  end
383
397
  rescue StandardError => e
384
- Logger.error "ReactionSnoozeManager failed to snooze reactions.\n#{e.formatted}"
398
+ @logger.error "ReactionSnoozeManager failed to snooze reactions.\n#{e.formatted}"
385
399
  end
386
400
  break if @cancel_thread
387
401
  sleep(1)
388
402
  break if @cancel_thread
389
403
  end
390
- Logger.info "ReactionSnoozeManager exiting"
404
+ @logger.info "ReactionSnoozeManager exiting"
391
405
  end
392
406
 
393
407
  def active_triggers(reaction:)
@@ -402,9 +416,9 @@ module OpenC3
402
416
  @share.reaction_base.get_snoozed.each do | reaction |
403
417
  time_difference = reaction.snoozed_until - current_time
404
418
  if time_difference <= 0 && @share.snooze_base.not_queued?(reaction: reaction)
405
- Logger.info "#{reaction.name} current: #{current_time}, vs #{reaction.snoozed_until}, #{time_difference}"
419
+ @logger.info "#{reaction.name} current: #{current_time}, vs #{reaction.snoozed_until}, #{time_difference}"
406
420
  unless reaction.review
407
- Logger.debug "#{reaction.name} review set to false, setting snoozed_until back to nil"
421
+ @logger.debug "#{reaction.name} review set to false, setting snoozed_until back to nil"
408
422
  @share.reaction_base.wake(name: reaction.name)
409
423
  next
410
424
  end
@@ -436,13 +450,13 @@ module OpenC3
436
450
  def initialize(*args)
437
451
  super(*args)
438
452
  @share = ReactionShare.new(scope: @scope)
439
- @manager = ReactionSnoozeManager.new(name: @name, scope: @scope, share: @share)
453
+ @manager = ReactionSnoozeManager.new(name: @name, logger: @logger, scope: @scope, share: @share)
440
454
  @manager_thread = nil
441
455
  @read_topic = true
442
456
  end
443
457
 
444
458
  def run
445
- Logger.info "ReactionMicroservice running"
459
+ @logger.info "ReactionMicroservice running"
446
460
  @manager_thread = Thread.new { @manager.run }
447
461
  loop do
448
462
  start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
@@ -455,7 +469,7 @@ module OpenC3
455
469
  block_for_updates()
456
470
  break if @cancel_thread
457
471
  end
458
- Logger.info "ReactionMicroservice exiting"
472
+ @logger.info "ReactionMicroservice exiting"
459
473
  end
460
474
 
461
475
  def topic_lookup_functions
@@ -491,45 +505,45 @@ module OpenC3
491
505
  while @read_topic
492
506
  begin
493
507
  AutonomicTopic.read_topics(@topics) do |_topic, _msg_id, msg_hash, _redis|
494
- Logger.debug "ReactionMicroservice block_for_updates: #{msg_hash.to_s}"
508
+ @logger.debug "ReactionMicroservice block_for_updates: #{msg_hash.to_s}"
495
509
  public_send(topic_lookup_functions[msg_hash['type']][msg_hash['kind']], msg_hash)
496
510
  end
497
511
  rescue StandardError => e
498
- Logger.error "ReactionMicroservice failed to read topics #{@topics}\n#{e.formatted}"
512
+ @logger.error "ReactionMicroservice failed to read topics #{@topics}\n#{e.formatted}"
499
513
  end
500
514
  end
501
515
  end
502
516
 
503
517
  def no_op(data)
504
- Logger.debug "ReactionMicroservice web socket event: #{data}"
518
+ @logger.debug "ReactionMicroservice web socket event: #{data}"
505
519
  end
506
520
 
507
521
  def refresh_event(data)
508
- Logger.debug "ReactionMicroservice web socket schedule refresh: #{data}"
522
+ @logger.debug "ReactionMicroservice web socket schedule refresh: #{data}"
509
523
  @read_topic = false
510
524
  end
511
525
 
512
- #
526
+ #
513
527
  def trigger_enabled_event(msg_hash)
514
- Logger.debug "ReactionMicroservice trigger event msg_hash: #{msg_hash}"
528
+ @logger.debug "ReactionMicroservice trigger event msg_hash: #{msg_hash}"
515
529
  @share.queue_base.enqueue(kind: 'trigger', data: JSON.parse(msg_hash['data'], :allow_nan => true, :create_additions => true))
516
530
  end
517
531
 
518
- # Add the reaction to the shared data.
532
+ # Add the reaction to the shared data.
519
533
  def reaction_created_event(msg_hash)
520
- Logger.debug "ReactionMicroservice reaction created msg_hash: #{msg_hash}"
534
+ @logger.debug "ReactionMicroservice reaction created msg_hash: #{msg_hash}"
521
535
  @share.reaction_base.add(reaction: JSON.parse(msg_hash['data'], :allow_nan => true, :create_additions => true))
522
536
  end
523
537
 
524
- # Update the reaction to the shared data.
538
+ # Update the reaction to the shared data.
525
539
  def reaction_updated_event(msg_hash)
526
- Logger.debug "ReactionMicroservice reaction updated msg_hash: #{msg_hash}"
540
+ @logger.debug "ReactionMicroservice reaction updated msg_hash: #{msg_hash}"
527
541
  @share.reaction_base.update(reaction: JSON.parse(msg_hash['data'], :allow_nan => true, :create_additions => true))
528
542
  end
529
543
 
530
544
  # Remove the reaction from the shared data
531
545
  def reaction_deleted_event(msg_hash)
532
- Logger.debug "ReactionMicroservice reaction deleted msg_hash: #{msg_hash}"
546
+ @logger.debug "ReactionMicroservice reaction deleted msg_hash: #{msg_hash}"
533
547
  @share.reaction_base.remove(reaction: JSON.parse(msg_hash['data'], :allow_nan => true, :create_additions => true))
534
548
  end
535
549
 
@@ -97,7 +97,7 @@ module OpenC3
97
97
  when 'BUFFER_DEPTH' # Buffer depth to write in time order
98
98
  @buffer_depth = option[1].to_i
99
99
  else
100
- Logger.error("Unknown option passed to microservice #{@name}: #{option}")
100
+ @logger.error("Unknown option passed to microservice #{@name}: #{option}")
101
101
  end
102
102
  end
103
103
  end
@@ -129,7 +129,7 @@ module OpenC3
129
129
  end
130
130
 
131
131
  def shutdown
132
- Logger.info("Shutting down reducer microservice: #{@name}")
132
+ @logger.info("Shutting down reducer microservice: #{@name}")
133
133
  @scheduler.shutdown(wait: SHUTDOWN_DELAY_SECS) if @scheduler
134
134
 
135
135
  # Make sure all the existing logs are properly closed down
@@ -193,6 +193,10 @@ module OpenC3
193
193
  def process_file(filename, type, entry_nanoseconds, file_nanoseconds)
194
194
  file = BucketFile.new(filename)
195
195
  file.retrieve
196
+ unless file.local_path
197
+ @logger.warn("Reducer Warning: #{filename}: Could not be retrieved")
198
+ return
199
+ end
196
200
 
197
201
  # Determine if we already have a PacketLogWriter created
198
202
  _, _, scope, target_name, _, rt_or_stored, _ = File.basename(filename).split('__')
@@ -271,66 +275,86 @@ module OpenC3
271
275
  if type == 'minute'
272
276
  # Update statistics for this packet's raw values
273
277
  state.raw_values.each do |key, value|
274
- reduced["#{key}__VALS"] ||= []
275
- reduced["#{key}__VALS"] << value
276
- reduced["#{key}__N"] ||= value
277
- reduced["#{key}__N"] = value if value < reduced["#{key}__N"]
278
- reduced["#{key}__X"] ||= value
279
- reduced["#{key}__X"] = value if value > reduced["#{key}__X"]
278
+ if value
279
+ reduced["#{key}__VALS"] ||= []
280
+ reduced["#{key}__VALS"] << value
281
+ reduced["#{key}__N"] ||= value
282
+ reduced["#{key}__N"] = value if value < reduced["#{key}__N"]
283
+ reduced["#{key}__X"] ||= value
284
+ reduced["#{key}__X"] = value if value > reduced["#{key}__X"]
285
+ end
280
286
  end
281
287
 
282
288
  # Update statistics for this packet's converted values
283
289
  state.converted_values.each do |key, value|
284
- reduced["#{key}__CVALS"] ||= []
285
- reduced["#{key}__CVALS"] << value
286
- reduced["#{key}__CN"] ||= value
287
- reduced["#{key}__CN"] = value if value < reduced["#{key}__CN"]
288
- reduced["#{key}__CX"] ||= value
289
- reduced["#{key}__CX"] = value if value > reduced["#{key}__CX"]
290
+ if value
291
+ reduced["#{key}__CVALS"] ||= []
292
+ reduced["#{key}__CVALS"] << value
293
+ reduced["#{key}__CN"] ||= value
294
+ reduced["#{key}__CN"] = value if value < reduced["#{key}__CN"]
295
+ reduced["#{key}__CX"] ||= value
296
+ reduced["#{key}__CX"] = value if value > reduced["#{key}__CX"]
297
+ end
290
298
  end
291
299
  else
292
300
  # Update statistics for this packet's raw values
293
301
  state.raw_max_values.each do |key, value|
294
- max_key = "#{key}__X"
295
- reduced[max_key] ||= value
296
- reduced[max_key] = value if value > reduced[max_key]
302
+ if value
303
+ max_key = "#{key}__X"
304
+ reduced[max_key] ||= value
305
+ reduced[max_key] = value if value > reduced[max_key]
306
+ end
297
307
  end
298
308
  state.raw_min_values.each do |key, value|
299
- min_key = "#{key}__N"
300
- reduced[min_key] ||= value
301
- reduced[min_key] = value if value < reduced[min_key]
309
+ if value
310
+ min_key = "#{key}__N"
311
+ reduced[min_key] ||= value
312
+ reduced[min_key] = value if value < reduced[min_key]
313
+ end
302
314
  end
303
315
  state.raw_avg_values.each do |key, value|
304
- avg_values_key = "#{key}__AVGVALS"
305
- reduced[avg_values_key] ||= []
306
- reduced[avg_values_key] << value
316
+ if value
317
+ avg_values_key = "#{key}__AVGVALS"
318
+ reduced[avg_values_key] ||= []
319
+ reduced[avg_values_key] << value
320
+ end
307
321
  end
308
322
  state.raw_stddev_values.each do |key, value|
309
- stddev_values_key = "#{key}__STDDEVVALS"
310
- reduced[stddev_values_key] ||= []
311
- reduced[stddev_values_key] << value
323
+ if value
324
+ stddev_values_key = "#{key}__STDDEVVALS"
325
+ reduced[stddev_values_key] ||= []
326
+ reduced[stddev_values_key] << value
327
+ end
312
328
  end
313
329
 
314
330
  # Update statistics for this packet's converted values
315
331
  state.converted_max_values.each do |key, value|
316
- max_key = "#{key}__CX"
317
- reduced[max_key] ||= value
318
- reduced[max_key] = value if value > reduced[max_key]
332
+ if value
333
+ max_key = "#{key}__CX"
334
+ reduced[max_key] ||= value
335
+ reduced[max_key] = value if value > reduced[max_key]
336
+ end
319
337
  end
320
338
  state.converted_min_values.each do |key, value|
321
- min_key = "#{key}__CN"
322
- reduced[min_key] ||= value
323
- reduced[min_key] = value if value < reduced[min_key]
339
+ if value
340
+ min_key = "#{key}__CN"
341
+ reduced[min_key] ||= value
342
+ reduced[min_key] = value if value < reduced[min_key]
343
+ end
324
344
  end
325
345
  state.converted_avg_values.each do |key, value|
326
- avg_values_key = "#{key}__CAVGVALS"
327
- reduced[avg_values_key] ||= []
328
- reduced[avg_values_key] << value
346
+ if value
347
+ avg_values_key = "#{key}__CAVGVALS"
348
+ reduced[avg_values_key] ||= []
349
+ reduced[avg_values_key] << value
350
+ end
329
351
  end
330
352
  state.converted_stddev_values.each do |key, value|
331
- stddev_values_key = "#{key}__CSTDDEVVALS"
332
- reduced[stddev_values_key] ||= []
333
- reduced[stddev_values_key] << value
353
+ if value
354
+ stddev_values_key = "#{key}__CSTDDEVVALS"
355
+ reduced[stddev_values_key] ||= []
356
+ reduced[stddev_values_key] << value
357
+ end
334
358
  end
335
359
 
336
360
  reduced["_NUM_SAMPLES__VALS"] ||= []
@@ -345,9 +369,9 @@ module OpenC3
345
369
  true
346
370
  rescue => e
347
371
  if file.local_path and File.exist?(file.local_path)
348
- Logger.error("Reducer Error: #{filename}: #{File.size(file.local_path)} bytes: \n#{e.formatted}")
372
+ @logger.error("Reducer Error: #{filename}: #{File.size(file.local_path)} bytes: \n#{e.formatted}")
349
373
  else
350
- Logger.error("Reducer Error: #{filename}: \n#{e.formatted}")
374
+ @logger.error("Reducer Error: #{filename}: \n#{e.formatted}")
351
375
  end
352
376
  false
353
377
  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/microservices/interface_microservice'
@@ -29,16 +29,16 @@ module OpenC3
29
29
  RouterStatusModel.set(@interface.as_json(:allow_nan => true), scope: @scope)
30
30
  if !packet.identified?
31
31
  # Need to identify so we can find the target
32
- identified_packet = System.commands.identify(packet.buffer(false), @target_names)
32
+ identified_packet = System.commands.identify(packet.buffer(false), @cmd_target_names)
33
33
  packet = identified_packet if identified_packet
34
34
  end
35
35
 
36
36
  begin
37
- RouterTopic.route_command(packet, @target_names, scope: @scope)
37
+ RouterTopic.route_command(packet, @cmd_target_names, scope: @scope)
38
38
  @count += 1
39
39
  rescue Exception => err
40
40
  @error = err
41
- Logger.error "Error routing command from #{@interface.name}\n#{err.formatted}"
41
+ @logger.error "Error routing command from #{@interface.name}\n#{err.formatted}"
42
42
  end
43
43
  end
44
44
  end
@@ -34,7 +34,7 @@ module OpenC3
34
34
  when 'CYCLE_SIZE' # Maximum size of a log file
35
35
  @cycle_size = option[1].to_i
36
36
  else
37
- Logger.error("Unknown option passed to microservice #{@name}: #{option}")
37
+ @logger.error("Unknown option passed to microservice #{@name}: #{option}")
38
38
  end
39
39
  end
40
40
 
@@ -78,7 +78,7 @@ module OpenC3
78
78
  @metric.add_sample(name: "log_duration_seconds", value: diff, labels: {})
79
79
  rescue => err
80
80
  @error = err
81
- Logger.error("#{@name} error: #{err.formatted}")
81
+ @logger.error("#{@name} error: #{err.formatted}")
82
82
  end
83
83
 
84
84
  def shutdown