openc3 5.1.1 → 5.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/openc3cli +48 -9
- data/data/config/interface_modifiers.yaml +14 -0
- data/data/config/parameter_modifiers.yaml +5 -3
- data/data/config/screen.yaml +12 -8
- data/data/config/target.yaml +33 -0
- data/ext/openc3/ext/config_parser/config_parser.c +66 -63
- data/ext/openc3/ext/packet/packet.c +1 -4
- data/lib/openc3/api/README.md +5 -0
- data/lib/openc3/api/api.rb +3 -1
- data/lib/openc3/api/cmd_api.rb +43 -112
- data/lib/openc3/api/interface_api.rb +3 -3
- data/lib/openc3/api/offline_access_api.rb +78 -0
- data/lib/openc3/api/settings_api.rb +3 -1
- data/lib/openc3/api/stash_api.rb +63 -0
- data/lib/openc3/api/target_api.rb +4 -5
- data/lib/openc3/config/config_parser.rb +47 -47
- data/lib/openc3/interfaces/interface.rb +11 -1
- data/lib/openc3/interfaces/protocols/burst_protocol.rb +30 -16
- data/lib/openc3/interfaces/protocols/fixed_protocol.rb +8 -2
- data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +2 -2
- data/lib/openc3/interfaces/protocols/override_protocol.rb +2 -2
- data/lib/openc3/interfaces/tcpip_server_interface.rb +3 -1
- data/lib/openc3/io/json_api_object.rb +30 -9
- data/lib/openc3/io/json_drb.rb +6 -1
- data/lib/openc3/io/json_drb_object.rb +18 -9
- data/lib/openc3/io/json_rpc.rb +5 -3
- data/lib/openc3/logs/buffered_packet_log_writer.rb +1 -1
- data/lib/openc3/logs/log_writer.rb +8 -2
- data/lib/openc3/microservices/cleanup_microservice.rb +3 -3
- data/lib/openc3/microservices/decom_microservice.rb +8 -8
- data/lib/openc3/microservices/interface_microservice.rb +86 -71
- data/lib/openc3/microservices/log_microservice.rb +5 -3
- data/lib/openc3/microservices/microservice.rb +18 -14
- data/lib/openc3/microservices/multi_microservice.rb +62 -0
- data/lib/openc3/microservices/periodic_microservice.rb +58 -0
- data/lib/openc3/microservices/reaction_microservice.rb +61 -47
- data/lib/openc3/microservices/reducer_microservice.rb +64 -40
- data/lib/openc3/microservices/router_microservice.rb +4 -4
- data/lib/openc3/microservices/text_log_microservice.rb +2 -2
- data/lib/openc3/microservices/timeline_microservice.rb +44 -30
- data/lib/openc3/microservices/trigger_group_microservice.rb +39 -36
- data/lib/openc3/migrations/20221202214600_add_target_names.rb +30 -0
- data/lib/openc3/migrations/20221210174900_convert_to_multi.rb +65 -0
- data/lib/openc3/models/cvt_model.rb +1 -1
- data/lib/openc3/models/gem_model.rb +24 -20
- data/lib/openc3/models/interface_model.rb +69 -35
- data/lib/openc3/models/metadata_model.rb +1 -1
- data/lib/openc3/models/microservice_model.rb +7 -24
- data/lib/openc3/models/migration_model.rb +52 -0
- data/lib/openc3/models/model.rb +2 -7
- data/lib/openc3/models/note_model.rb +1 -1
- data/lib/openc3/models/offline_access_model.rb +55 -0
- data/lib/openc3/models/plugin_model.rb +12 -3
- data/lib/openc3/models/reaction_model.rb +6 -2
- data/lib/openc3/models/scope_model.rb +89 -13
- data/lib/openc3/models/settings_model.rb +1 -1
- data/lib/openc3/models/stash_model.rb +53 -0
- data/lib/openc3/models/target_model.rb +301 -130
- data/lib/openc3/models/tool_model.rb +1 -12
- data/lib/openc3/models/widget_model.rb +1 -6
- data/lib/openc3/operators/microservice_operator.rb +45 -6
- data/lib/openc3/operators/operator.rb +27 -5
- data/lib/openc3/packets/commands.rb +1 -25
- data/lib/openc3/packets/limits.rb +0 -75
- data/lib/openc3/packets/packet.rb +0 -28
- data/lib/openc3/packets/packet_item.rb +23 -0
- data/lib/openc3/packets/packet_item_limits.rb +2 -2
- data/lib/openc3/packets/parsers/state_parser.rb +10 -6
- data/lib/openc3/packets/telemetry.rb +1 -45
- data/lib/openc3/script/commands.rb +41 -71
- data/lib/openc3/script/extract.rb +15 -1
- data/lib/openc3/script/{calendar.rb → metadata.rb} +42 -17
- data/lib/openc3/script/script.rb +13 -5
- data/lib/openc3/script/storage.rb +3 -1
- data/lib/openc3/system/system.rb +19 -17
- data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +4 -4
- data/lib/openc3/top_level.rb +3 -3
- data/lib/openc3/topics/command_decom_topic.rb +2 -2
- data/lib/openc3/topics/command_topic.rb +7 -6
- data/lib/openc3/topics/interface_topic.rb +2 -2
- data/lib/openc3/topics/router_topic.rb +1 -1
- data/lib/openc3/topics/telemetry_topic.rb +2 -1
- data/lib/openc3/utilities/authentication.rb +35 -14
- data/lib/openc3/utilities/aws_bucket.rb +4 -3
- data/lib/openc3/utilities/bucket.rb +4 -2
- data/lib/openc3/utilities/bucket_file_cache.rb +3 -8
- data/lib/openc3/utilities/bucket_utilities.rb +77 -15
- data/lib/openc3/utilities/local_mode.rb +12 -9
- data/lib/openc3/utilities/logger.rb +17 -9
- data/lib/openc3/utilities/message_log.rb +6 -5
- data/lib/openc3/utilities/migration.rb +22 -0
- data/lib/openc3/utilities/store_autoload.rb +7 -5
- data/lib/openc3/utilities/target_file.rb +9 -7
- data/lib/openc3/version.rb +6 -6
- data/lib/openc3.rb +2 -1
- 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
|
-
|
240
|
-
|
241
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
277
|
+
@logger.error "ReactionWorker-#{@ident} failed to evaluate kind: #{kind} data: #{data}\n#{e.formatted}"
|
271
278
|
end
|
272
279
|
end
|
273
|
-
|
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
|
-
|
314
|
+
@logger.debug "ReactionWorker-#{@ident} running reaction #{reaction.name}, command: '#{action['value']}' "
|
308
315
|
begin
|
309
|
-
|
310
|
-
|
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
|
-
|
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
|
-
|
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' =>
|
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
|
-
|
347
|
+
@logger.info "ReactionWorker-#{@ident} #{reaction.name} script action complete, #{action['value']} => #{response.body}"
|
335
348
|
rescue StandardError => e
|
336
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
419
|
+
@logger.info "#{reaction.name} current: #{current_time}, vs #{reaction.snoozed_until}, #{time_difference}"
|
406
420
|
unless reaction.review
|
407
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
518
|
+
@logger.debug "ReactionMicroservice web socket event: #{data}"
|
505
519
|
end
|
506
520
|
|
507
521
|
def refresh_event(data)
|
508
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
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
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
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
|
-
|
295
|
-
|
296
|
-
|
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
|
-
|
300
|
-
|
301
|
-
|
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
|
-
|
305
|
-
|
306
|
-
|
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
|
-
|
310
|
-
|
311
|
-
|
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
|
-
|
317
|
-
|
318
|
-
|
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
|
-
|
322
|
-
|
323
|
-
|
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
|
-
|
327
|
-
|
328
|
-
|
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
|
-
|
332
|
-
|
333
|
-
|
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
|
-
|
372
|
+
@logger.error("Reducer Error: #{filename}: #{File.size(file.local_path)} bytes: \n#{e.formatted}")
|
349
373
|
else
|
350
|
-
|
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), @
|
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, @
|
37
|
+
RouterTopic.route_command(packet, @cmd_target_names, scope: @scope)
|
38
38
|
@count += 1
|
39
39
|
rescue Exception => err
|
40
40
|
@error = err
|
41
|
-
|
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
|
-
|
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
|
-
|
81
|
+
@logger.error("#{@name} error: #{err.formatted}")
|
82
82
|
end
|
83
83
|
|
84
84
|
def shutdown
|