cosmos 5.0.2 → 5.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/cosmos +183 -42
- data/data/config/microservice.yaml +47 -35
- data/data/config/plugins.yaml +10 -147
- data/data/config/target.yaml +70 -0
- data/data/config/tool.yaml +37 -31
- data/ext/cosmos/ext/cosmos_io/cosmos_io.c +14 -14
- data/ext/cosmos/ext/packet/packet.c +3 -3
- data/ext/cosmos/ext/structure/structure.c +31 -31
- data/lib/cosmos/api/api.rb +1 -25
- data/lib/cosmos/api/cmd_api.rb +17 -6
- data/lib/cosmos/api/config_api.rb +10 -4
- data/lib/cosmos/api/limits_api.rb +1 -1
- data/lib/cosmos/api/settings_api.rb +19 -7
- data/lib/cosmos/api/target_api.rb +2 -2
- data/lib/cosmos/api/tlm_api.rb +65 -41
- data/lib/cosmos/config/config_parser.rb +19 -22
- data/lib/cosmos/config/meta_config_parser.rb +1 -1
- data/lib/cosmos/conversions/generic_conversion.rb +2 -2
- data/lib/cosmos/conversions/polynomial_conversion.rb +5 -8
- data/lib/cosmos/conversions/segmented_polynomial_conversion.rb +26 -9
- data/lib/cosmos/io/json_drb.rb +5 -1
- data/lib/cosmos/logs/log_writer.rb +78 -29
- data/lib/cosmos/microservices/cleanup_microservice.rb +28 -29
- data/lib/cosmos/microservices/decom_microservice.rb +1 -1
- data/lib/cosmos/microservices/interface_microservice.rb +0 -16
- data/lib/cosmos/microservices/microservice.rb +3 -3
- data/lib/cosmos/microservices/reducer_microservice.rb +12 -10
- data/lib/cosmos/models/cvt_model.rb +6 -6
- data/lib/cosmos/models/gem_model.rb +9 -3
- data/lib/cosmos/models/info_model.rb +1 -1
- data/lib/cosmos/models/interface_model.rb +16 -7
- data/lib/cosmos/models/interface_status_model.rb +1 -1
- data/lib/cosmos/models/metadata_model.rb +69 -219
- data/lib/cosmos/models/metric_model.rb +2 -2
- data/lib/cosmos/models/microservice_model.rb +7 -4
- data/lib/cosmos/models/microservice_status_model.rb +1 -1
- data/lib/cosmos/models/model.rb +23 -16
- data/lib/cosmos/models/note_model.rb +122 -0
- data/lib/cosmos/models/ping_model.rb +2 -1
- data/lib/cosmos/models/plugin_model.rb +108 -48
- data/lib/cosmos/models/process_status_model.rb +1 -1
- data/lib/cosmos/models/scope_model.rb +10 -25
- data/lib/cosmos/models/settings_model.rb +55 -0
- data/lib/cosmos/models/sorted_model.rb +167 -0
- data/lib/cosmos/models/target_model.rb +143 -27
- data/lib/cosmos/models/tool_config_model.rb +38 -0
- data/lib/cosmos/models/tool_model.rb +9 -9
- data/lib/cosmos/models/widget_model.rb +11 -11
- data/lib/cosmos/operators/microservice_operator.rb +2 -1
- data/lib/cosmos/packets/packet.rb +24 -1
- data/lib/cosmos/packets/packet_config.rb +2 -2
- data/lib/cosmos/packets/packet_item.rb +57 -0
- data/lib/cosmos/packets/packet_item_limits.rb +14 -2
- data/lib/cosmos/packets/parsers/packet_item_parser.rb +1 -1
- data/lib/cosmos/packets/parsers/packet_parser.rb +1 -1
- data/lib/cosmos/packets/parsers/xtce_parser.rb +1 -1
- data/lib/cosmos/packets/structure.rb +30 -33
- data/lib/cosmos/packets/structure_item.rb +10 -1
- data/lib/cosmos/script/api_shared.rb +30 -25
- data/lib/cosmos/script/calendar.rb +37 -15
- data/lib/cosmos/script/commands.rb +5 -7
- data/lib/cosmos/script/script.rb +19 -39
- data/lib/cosmos/script/storage.rb +92 -105
- data/lib/cosmos/system/system.rb +2 -1
- data/lib/cosmos/tools/table_manager/table_config.rb +16 -1
- data/lib/cosmos/tools/table_manager/table_item.rb +1 -1
- data/lib/cosmos/tools/table_manager/table_manager_core.rb +213 -309
- data/lib/cosmos/top_level.rb +5 -1
- data/lib/cosmos/topics/autonomic_topic.rb +2 -2
- data/lib/cosmos/topics/calendar_topic.rb +1 -1
- data/lib/cosmos/topics/command_decom_topic.rb +35 -1
- data/lib/cosmos/topics/command_topic.rb +6 -4
- data/lib/cosmos/topics/config_topic.rb +68 -0
- data/lib/cosmos/topics/interface_topic.rb +8 -8
- data/lib/cosmos/topics/limits_event_topic.rb +5 -3
- data/lib/cosmos/topics/notifications_topic.rb +1 -1
- data/lib/cosmos/topics/router_topic.rb +9 -9
- data/lib/cosmos/topics/telemetry_decom_topic.rb +5 -1
- data/lib/cosmos/topics/telemetry_topic.rb +1 -1
- data/lib/cosmos/topics/timeline_topic.rb +1 -1
- data/lib/cosmos/topics/topic.rb +23 -8
- data/lib/cosmos/utilities/logger.rb +4 -3
- data/lib/cosmos/utilities/metric.rb +32 -26
- data/lib/cosmos/utilities/s3.rb +61 -0
- data/lib/cosmos/utilities/s3_file_cache.rb +12 -6
- data/lib/cosmos/utilities/store.rb +1 -0
- data/lib/cosmos/utilities/store_autoload.rb +25 -134
- data/lib/cosmos/version.rb +5 -4
- data/templates/plugin-template/plugin.gemspec +0 -2
- metadata +12 -10
- data/bin/xtce_converter +0 -92
- data/lib/cosmos/models/narrative_model.rb +0 -280
@@ -39,7 +39,7 @@ module Cosmos
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def convert_microservice_to_process_definition(microservice_name, microservice_config)
|
42
|
-
process_definition = ["ruby", "plugin_microservice.rb"
|
42
|
+
process_definition = ["ruby", "plugin_microservice.rb"]
|
43
43
|
work_dir = "/cosmos/lib/cosmos/microservices"
|
44
44
|
env = microservice_config["env"].dup
|
45
45
|
if microservice_config["needs_dependencies"]
|
@@ -47,6 +47,7 @@ module Cosmos
|
|
47
47
|
else
|
48
48
|
env['GEM_HOME'] = nil
|
49
49
|
end
|
50
|
+
env['COSMOS_MICROSERVICE_NAME'] = microservice_name
|
50
51
|
container = microservice_config["container"]
|
51
52
|
scope = microservice_name.split("__")[0]
|
52
53
|
return process_definition, work_dir, env, scope, container
|
@@ -98,7 +98,7 @@ module Cosmos
|
|
98
98
|
# @param buffer [String] String buffer to hold the packet data
|
99
99
|
# @param item_class [Class] Class used to instantiate items (Must be a
|
100
100
|
# subclass of PacketItem)
|
101
|
-
def initialize(target_name, packet_name, default_endianness = :BIG_ENDIAN, description = nil, buffer =
|
101
|
+
def initialize(target_name, packet_name, default_endianness = :BIG_ENDIAN, description = nil, buffer = nil, item_class = PacketItem)
|
102
102
|
super(default_endianness, buffer, item_class)
|
103
103
|
# Explictly call the defined setter methods
|
104
104
|
self.target_name = target_name
|
@@ -445,6 +445,11 @@ module Cosmos
|
|
445
445
|
@meta ||= {}
|
446
446
|
end
|
447
447
|
|
448
|
+
# Sets packet specific metadata
|
449
|
+
def meta=(meta)
|
450
|
+
@meta = meta
|
451
|
+
end
|
452
|
+
|
448
453
|
# Indicates if the packet has been identified
|
449
454
|
# @return [TrueClass or FalseClass]
|
450
455
|
def identified?
|
@@ -1009,6 +1014,24 @@ module Cosmos
|
|
1009
1014
|
config
|
1010
1015
|
end
|
1011
1016
|
|
1017
|
+
def self.from_json(hash)
|
1018
|
+
endianness = hash['endianness'] ? hash['endianness'].intern : nil # Convert to symbol
|
1019
|
+
packet = Packet.new(hash['target_name'], hash['packet_name'], endianness, hash['description'])
|
1020
|
+
packet.short_buffer_allowed = hash['short_buffer_allowed']
|
1021
|
+
packet.hazardous = hash['hazardous']
|
1022
|
+
packet.hazardous_description = hash['hazardous_description']
|
1023
|
+
packet.messages_disabled = hash['messages_disabled']
|
1024
|
+
packet.disabled = hash['disabled']
|
1025
|
+
packet.hidden = hash['hidden']
|
1026
|
+
# packet.stale is read only
|
1027
|
+
packet.meta = hash['meta']
|
1028
|
+
# Can't convert processors
|
1029
|
+
hash['items'].each do |item|
|
1030
|
+
packet.define(PacketItem.from_json(item))
|
1031
|
+
end
|
1032
|
+
packet
|
1033
|
+
end
|
1034
|
+
|
1012
1035
|
protected
|
1013
1036
|
|
1014
1037
|
# Performs packet specific processing on the packet.
|
@@ -463,8 +463,8 @@ module Cosmos
|
|
463
463
|
when 'POLY_READ_CONVERSION', 'POLY_WRITE_CONVERSION'
|
464
464
|
usage = "#{keyword} <C0> <C1> <C2> ..."
|
465
465
|
parser.verify_num_parameters(1, nil, usage)
|
466
|
-
@current_item.read_conversion = PolynomialConversion.new(params) if keyword.include? "READ"
|
467
|
-
@current_item.write_conversion = PolynomialConversion.new(params) if keyword.include? "WRITE"
|
466
|
+
@current_item.read_conversion = PolynomialConversion.new(*params) if keyword.include? "READ"
|
467
|
+
@current_item.write_conversion = PolynomialConversion.new(*params) if keyword.include? "WRITE"
|
468
468
|
|
469
469
|
# Apply a segmented polynomial conversion to the current item
|
470
470
|
# after it is read from the telemetry packet
|
@@ -486,6 +486,63 @@ module Cosmos
|
|
486
486
|
config
|
487
487
|
end
|
488
488
|
|
489
|
+
def self.from_json(hash)
|
490
|
+
# Convert strings to symbols
|
491
|
+
endianness = hash['endianness'] ? hash['endianness'].intern : nil
|
492
|
+
data_type = hash['data_type'] ? hash['data_type'].intern : nil
|
493
|
+
overflow = hash['overflow'] ? hash['overflow'].intern : nil
|
494
|
+
item = PacketItem.new(hash['name'], hash['bit_offset'], hash['bit_size'],
|
495
|
+
data_type, endianness, hash['array_size'], overflow)
|
496
|
+
item.description = hash['description']
|
497
|
+
item.id_value = hash['id_value']
|
498
|
+
item.default = hash['default']
|
499
|
+
item.range = (hash['minimum']..hash['maximum']) if hash['minimum'] && hash['maximum']
|
500
|
+
item.required = hash['required']
|
501
|
+
item.format_string = hash['format_string']
|
502
|
+
item.units = hash['units']
|
503
|
+
item.units_full = hash['units_full']
|
504
|
+
if hash['states']
|
505
|
+
item.states = {}
|
506
|
+
item.hazardous = {}
|
507
|
+
item.state_colors = {}
|
508
|
+
hash['states'].each do |state_name, state|
|
509
|
+
item.states[state_name] = state['value']
|
510
|
+
item.hazardous[state_name] = state['hazardous']
|
511
|
+
item.state_colors[state_name] = state['color'].to_sym if state['color']
|
512
|
+
end
|
513
|
+
end
|
514
|
+
# Recreate COSMOS built-in conversions
|
515
|
+
if hash['read_conversion']
|
516
|
+
begin
|
517
|
+
item.read_conversion = Cosmos::const_get(hash['read_conversion']['class']).new(*hash['read_conversion']['params'])
|
518
|
+
rescue => error
|
519
|
+
Logger.instance.error "#{item.name} read_conversion of #{hash['read_conversion']} could not be instantiated due to #{error}"
|
520
|
+
end
|
521
|
+
end
|
522
|
+
if hash['write_conversion']
|
523
|
+
begin
|
524
|
+
item.write_conversion = Cosmos::const_get(hash['write_conversion']['class']).new(*hash['write_conversion']['params'])
|
525
|
+
rescue => error
|
526
|
+
Logger.instance.error "#{item.name} write_conversion of #{hash['write_conversion']} could not be instantiated due to #{error}"
|
527
|
+
end
|
528
|
+
end
|
529
|
+
|
530
|
+
if hash['limits']
|
531
|
+
item.limits = PacketItemLimits.new
|
532
|
+
# Delete these keys so the only ones left are limits sets
|
533
|
+
item.limits.persistence_setting = hash['limits'].delete('persistence_setting')
|
534
|
+
item.limits.enabled = true if hash['limits'].delete('enabled')
|
535
|
+
values = {}
|
536
|
+
hash['limits'].each do |set, items|
|
537
|
+
values[set.to_sym] = [items['red_low'], items['yellow_low'], items['yellow_high'], items['red_high']]
|
538
|
+
values[set.to_sym].concat([items['green_low'], items['green_high']]) if items['green_low'] && items['green_high']
|
539
|
+
end
|
540
|
+
item.limits.values = values
|
541
|
+
end
|
542
|
+
item.meta = hash['meta']
|
543
|
+
item
|
544
|
+
end
|
545
|
+
|
489
546
|
protected
|
490
547
|
|
491
548
|
def parameter_config
|
@@ -132,7 +132,7 @@ module Cosmos
|
|
132
132
|
end
|
133
133
|
alias dup clone
|
134
134
|
|
135
|
-
def
|
135
|
+
def as_json
|
136
136
|
hash = {}
|
137
137
|
hash['values'] = self.values
|
138
138
|
hash['enabled'] = self.enabled
|
@@ -146,5 +146,17 @@ module Cosmos
|
|
146
146
|
hash['persistence_count'] = self.persistence_count
|
147
147
|
hash
|
148
148
|
end
|
149
|
+
|
150
|
+
def self.from_json(hash)
|
151
|
+
limits = PacketItemLimits.new
|
152
|
+
limits.values = hash['values'].transform_keys(&:to_sym) if hash['values']
|
153
|
+
limits.enabled = hash['enabled']
|
154
|
+
limits.state = hash['state'] ? hash['state'].to_sym : nil
|
155
|
+
# Can't recreate a LimitsResponse class
|
156
|
+
# limits.response = hash['response']
|
157
|
+
limits.persistence_setting = hash['persistence_setting'] if hash['persistence_setting']
|
158
|
+
limits.persistence_count = hash['persistence_count'] if hash['persistence_count']
|
159
|
+
limits
|
160
|
+
end
|
149
161
|
end
|
150
|
-
end
|
162
|
+
end
|
@@ -56,7 +56,7 @@ module Cosmos
|
|
56
56
|
max_options = @usage.count("<")
|
57
57
|
# The last two options (description and endianness) are optional
|
58
58
|
@parser.verify_num_parameters(max_options - 2, max_options, @usage)
|
59
|
-
@parser.
|
59
|
+
@parser.verify_parameter_naming(1) # Item name is the 1st parameter
|
60
60
|
end
|
61
61
|
|
62
62
|
def create_packet_item(packet, cmd_or_tlm)
|
@@ -72,7 +72,7 @@ module Cosmos
|
|
72
72
|
def verify_parameters
|
73
73
|
@usage = "#{@parser.keyword} <TARGET NAME> <PACKET NAME> <ENDIANNESS: BIG_ENDIAN/LITTLE_ENDIAN> <DESCRIPTION (Optional)>"
|
74
74
|
@parser.verify_num_parameters(3, 4, @usage)
|
75
|
-
@parser.
|
75
|
+
@parser.verify_parameter_naming(2) # Packet name is the 2nd parameter
|
76
76
|
end
|
77
77
|
|
78
78
|
def create_command(target_name, commands, warnings)
|
@@ -293,7 +293,7 @@ module Cosmos
|
|
293
293
|
xtce_recurse_element(element) do |block_element|
|
294
294
|
if block_element.name == 'Term'
|
295
295
|
exponent = Float(block_element['exponent']).to_i
|
296
|
-
@current_type.conversion ||= PolynomialConversion.new(
|
296
|
+
@current_type.conversion ||= PolynomialConversion.new()
|
297
297
|
@current_type.conversion.coeffs[exponent] = Float(block_element['coefficient'])
|
298
298
|
@current_type.conversion.coeffs.each_with_index do |value, index|
|
299
299
|
@current_type.conversion.coeffs[index] = 0.0 if value.nil?
|
@@ -66,7 +66,7 @@ module Cosmos
|
|
66
66
|
# @param buffer [String] Buffer used to store the structure
|
67
67
|
# @param item_class [Class] Class used to instantiate new structure items.
|
68
68
|
# Must be StructureItem or one of its subclasses.
|
69
|
-
def initialize(default_endianness = BinaryAccessor::HOST_ENDIANNESS, buffer =
|
69
|
+
def initialize(default_endianness = BinaryAccessor::HOST_ENDIANNESS, buffer = nil, item_class = StructureItem)
|
70
70
|
if (default_endianness == :BIG_ENDIAN) || (default_endianness == :LITTLE_ENDIAN)
|
71
71
|
@default_endianness = default_endianness
|
72
72
|
if buffer
|
@@ -102,14 +102,11 @@ module Cosmos
|
|
102
102
|
def read_item(item, value_type = :RAW, buffer = @buffer)
|
103
103
|
return nil if item.data_type == :DERIVED
|
104
104
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
else
|
109
|
-
return BinaryAccessor.read(item.bit_offset, item.bit_size, item.data_type, buffer, item.endianness)
|
110
|
-
end
|
105
|
+
buffer = allocate_buffer_if_needed() unless buffer
|
106
|
+
if item.array_size
|
107
|
+
return BinaryAccessor.read_array(item.bit_offset, item.bit_size, item.data_type, item.array_size, buffer, item.endianness)
|
111
108
|
else
|
112
|
-
|
109
|
+
return BinaryAccessor.read(item.bit_offset, item.bit_size, item.data_type, buffer, item.endianness)
|
113
110
|
end
|
114
111
|
end
|
115
112
|
|
@@ -117,9 +114,8 @@ module Cosmos
|
|
117
114
|
#
|
118
115
|
# @return [Integer] Size of the buffer in bytes
|
119
116
|
def length
|
120
|
-
|
121
|
-
|
122
|
-
return 0
|
117
|
+
allocate_buffer_if_needed()
|
118
|
+
return @buffer.length
|
123
119
|
end
|
124
120
|
|
125
121
|
# Resize the buffer at least the defined length of the structure
|
@@ -129,12 +125,23 @@ module Cosmos
|
|
129
125
|
if @buffer.length < @defined_length
|
130
126
|
@buffer << (ZERO_STRING * (@defined_length - @buffer.length))
|
131
127
|
end
|
128
|
+
else
|
129
|
+
allocate_buffer_if_needed()
|
132
130
|
end
|
133
131
|
|
134
132
|
return self
|
135
133
|
end
|
136
134
|
end
|
137
135
|
|
136
|
+
# Allocate a buffer if not available
|
137
|
+
def allocate_buffer_if_needed
|
138
|
+
unless @buffer
|
139
|
+
@buffer = ZERO_STRING * @defined_length
|
140
|
+
@buffer.force_encoding(ASCII_8BIT_STRING)
|
141
|
+
end
|
142
|
+
return @buffer
|
143
|
+
end
|
144
|
+
|
138
145
|
# Indicates if any items have been defined for this structure
|
139
146
|
# @return [TrueClass or FalseClass]
|
140
147
|
def defined?
|
@@ -340,14 +347,11 @@ module Cosmos
|
|
340
347
|
# parameter to check whether to perform conversions on the item.
|
341
348
|
# @param buffer [String] The binary buffer to write the value to
|
342
349
|
def write_item(item, value, value_type = :RAW, buffer = @buffer)
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
else
|
347
|
-
BinaryAccessor.write(value, item.bit_offset, item.bit_size, item.data_type, buffer, item.endianness, item.overflow)
|
348
|
-
end
|
350
|
+
buffer = allocate_buffer_if_needed() unless buffer
|
351
|
+
if item.array_size
|
352
|
+
BinaryAccessor.write_array(value, item.bit_offset, item.bit_size, item.data_type, item.array_size, buffer, item.endianness, item.overflow)
|
349
353
|
else
|
350
|
-
|
354
|
+
BinaryAccessor.write(value, item.bit_offset, item.bit_size, item.data_type, buffer, item.endianness, item.overflow)
|
351
355
|
end
|
352
356
|
end
|
353
357
|
|
@@ -432,14 +436,11 @@ module Cosmos
|
|
432
436
|
# @param copy [TrueClass/FalseClass] Whether to copy the buffer
|
433
437
|
# @return [String] Data buffer backing the structure
|
434
438
|
def buffer(copy = true)
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
else
|
439
|
-
return @buffer
|
440
|
-
end
|
439
|
+
local_buffer = allocate_buffer_if_needed()
|
440
|
+
if copy
|
441
|
+
return local_buffer.dup
|
441
442
|
else
|
442
|
-
return
|
443
|
+
return local_buffer
|
443
444
|
end
|
444
445
|
end
|
445
446
|
|
@@ -525,15 +526,11 @@ module Cosmos
|
|
525
526
|
module MethodMissing
|
526
527
|
# Method missing provides reading/writing item values as if they were methods to the class
|
527
528
|
def method_missing(name, value = nil)
|
528
|
-
if
|
529
|
-
|
530
|
-
|
531
|
-
return write(name.to_s[0..-2], value)
|
532
|
-
else
|
533
|
-
return read(name.to_s)
|
534
|
-
end
|
529
|
+
if value
|
530
|
+
# Strip off the equals sign before looking up the item
|
531
|
+
return write(name.to_s[0..-2], value)
|
535
532
|
else
|
536
|
-
|
533
|
+
return read(name.to_s)
|
537
534
|
end
|
538
535
|
end
|
539
536
|
end
|
@@ -292,7 +292,16 @@ module Cosmos
|
|
292
292
|
end
|
293
293
|
alias dup clone
|
294
294
|
|
295
|
-
def
|
295
|
+
def self.from_json(hash)
|
296
|
+
# Convert strings to symbols
|
297
|
+
endianness = hash['endianness'] ? hash['endianness'].intern : nil
|
298
|
+
data_type = hash['data_type'] ? hash['data_type'].intern : nil
|
299
|
+
overflow = hash['overflow'] ? hash['overflow'].intern : nil
|
300
|
+
StructureItem.new(hash['name'], hash['bit_offset'], hash['bit_size'], data_type,
|
301
|
+
endianness, hash['array_size'], overflow)
|
302
|
+
end
|
303
|
+
|
304
|
+
def as_json
|
296
305
|
hash = {}
|
297
306
|
hash['name'] = self.name
|
298
307
|
hash['bit_offset'] = self.bit_offset
|
@@ -300,10 +300,10 @@ module Cosmos
|
|
300
300
|
#
|
301
301
|
# @param args [String|Array<String>] See the description for calling style
|
302
302
|
# @param type [Symbol] Telemetry type, :RAW, :CONVERTED (default), :FORMATTED, or :WITH_UNITS
|
303
|
-
def wait_check(*args, type: :CONVERTED, scope: $cosmos_scope, token: $cosmos_token)
|
303
|
+
def wait_check(*args, type: :CONVERTED, scope: $cosmos_scope, token: $cosmos_token, &block)
|
304
304
|
target_name, packet_name, item_name, comparison_to_eval, timeout, polling_rate = _wait_check_process_args(args, scope: scope, token: token)
|
305
305
|
start_time = Time.now.sys
|
306
|
-
success, value = cosmos_script_wait_implementation(target_name, packet_name, item_name, type, comparison_to_eval, timeout, polling_rate, scope: scope, token: token)
|
306
|
+
success, value = cosmos_script_wait_implementation(target_name, packet_name, item_name, type, comparison_to_eval, timeout, polling_rate, scope: scope, token: token, &block)
|
307
307
|
time = Time.now.sys - start_time
|
308
308
|
check_str = "CHECK: #{_upcase(target_name, packet_name, item_name)} #{comparison_to_eval}"
|
309
309
|
with_value_str = "with value == #{value} after waiting #{time} seconds"
|
@@ -321,8 +321,8 @@ module Cosmos
|
|
321
321
|
end
|
322
322
|
|
323
323
|
# @deprecated use wait_check with type: :RAW
|
324
|
-
def wait_check_raw(*args, scope: $cosmos_scope, token: $cosmos_token)
|
325
|
-
wait_check(*args, type: :RAW, scope: scope, token: token)
|
324
|
+
def wait_check_raw(*args, scope: $cosmos_scope, token: $cosmos_token, &block)
|
325
|
+
wait_check(*args, type: :RAW, scope: scope, token: token, &block)
|
326
326
|
end
|
327
327
|
|
328
328
|
# Wait for the value of a telmetry item to be within a tolerance of a value
|
@@ -334,7 +334,7 @@ module Cosmos
|
|
334
334
|
#
|
335
335
|
# @param args [String|Array<String>] See the description for calling style
|
336
336
|
# @param type [Symbol] Telemetry type, :RAW or :CONVERTED (default)
|
337
|
-
def wait_check_tolerance(*args, type: :CONVERTED, scope: $cosmos_scope, token: $cosmos_token)
|
337
|
+
def wait_check_tolerance(*args, type: :CONVERTED, scope: $cosmos_scope, token: $cosmos_token, &block)
|
338
338
|
raise "Invalid type '#{type}' for wait_check_tolerance" unless %i(RAW CONVERTED).include?(type)
|
339
339
|
|
340
340
|
target_name, packet_name, item_name, expected_value, tolerance, timeout, polling_rate = _wait_tolerance_process_args(args, scope: scope, token: token)
|
@@ -343,7 +343,7 @@ module Cosmos
|
|
343
343
|
if value.is_a?(Array)
|
344
344
|
expected_value, tolerance = array_tolerance_process_args(value.size, expected_value, tolerance, 'wait_check_tolerance', scope: scope, token: token)
|
345
345
|
|
346
|
-
success, value = cosmos_script_wait_implementation_array_tolerance(value.size, target_name, packet_name, item_name, type, expected_value, tolerance, timeout, polling_rate, scope: scope, token: token)
|
346
|
+
success, value = cosmos_script_wait_implementation_array_tolerance(value.size, target_name, packet_name, item_name, type, expected_value, tolerance, timeout, polling_rate, scope: scope, token: token, &block)
|
347
347
|
time = Time.now.sys - start_time
|
348
348
|
|
349
349
|
message = ""
|
@@ -388,8 +388,8 @@ module Cosmos
|
|
388
388
|
end
|
389
389
|
|
390
390
|
# @deprecated Use wait_check_tolerance with type: :RAW
|
391
|
-
def wait_check_tolerance_raw(*args, scope: $cosmos_scope, token: $cosmos_token)
|
392
|
-
wait_check_tolerance(*args, type: :RAW, scope: scope, token: token)
|
391
|
+
def wait_check_tolerance_raw(*args, scope: $cosmos_scope, token: $cosmos_token, &block)
|
392
|
+
wait_check_tolerance(*args, type: :RAW, scope: scope, token: token, &block)
|
393
393
|
end
|
394
394
|
|
395
395
|
# Wait on an expression to be true. On a timeout, the script will pause.
|
@@ -397,12 +397,12 @@ module Cosmos
|
|
397
397
|
timeout,
|
398
398
|
polling_rate = DEFAULT_TLM_POLLING_RATE,
|
399
399
|
context = nil,
|
400
|
-
scope: $cosmos_scope, token: $cosmos_token)
|
400
|
+
scope: $cosmos_scope, token: $cosmos_token, &block)
|
401
401
|
start_time = Time.now.sys
|
402
402
|
success = cosmos_script_wait_implementation_expression(exp_to_eval,
|
403
403
|
timeout,
|
404
404
|
polling_rate,
|
405
|
-
context, scope: scope, token: token)
|
405
|
+
context, scope: scope, token: token, &block)
|
406
406
|
time = Time.now.sys - start_time
|
407
407
|
if success
|
408
408
|
Logger.info "CHECK: #{exp_to_eval} is TRUE after waiting #{time} seconds"
|
@@ -691,15 +691,20 @@ module Cosmos
|
|
691
691
|
return [target_name, packet_name, item_name, comparison_to_eval, timeout, polling_rate]
|
692
692
|
end
|
693
693
|
|
694
|
-
def _cosmos_script_wait_implementation(target_name, packet_name, item_name, value_type, timeout, polling_rate, scope: $cosmos_scope, token: $cosmos_token)
|
694
|
+
def _cosmos_script_wait_implementation(target_name, packet_name, item_name, value_type, timeout, polling_rate, exp_to_eval, scope: $cosmos_scope, token: $cosmos_token, &block)
|
695
695
|
end_time = Time.now.sys + timeout
|
696
|
-
exp_to_eval = yield
|
697
696
|
|
698
697
|
while true
|
699
698
|
work_start = Time.now.sys
|
700
699
|
value = tlm(target_name, packet_name, item_name, type: value_type, scope: scope, token: token)
|
701
|
-
if
|
702
|
-
|
700
|
+
if not block.nil?
|
701
|
+
if block.call(value)
|
702
|
+
return true, value
|
703
|
+
end
|
704
|
+
else
|
705
|
+
if eval(exp_to_eval)
|
706
|
+
return true, value
|
707
|
+
end
|
703
708
|
end
|
704
709
|
break if Time.now.sys >= end_time
|
705
710
|
|
@@ -724,25 +729,25 @@ module Cosmos
|
|
724
729
|
end
|
725
730
|
|
726
731
|
# Wait for a converted telemetry item to pass a comparison
|
727
|
-
def cosmos_script_wait_implementation(target_name, packet_name, item_name, value_type, comparison_to_eval, timeout, polling_rate = DEFAULT_TLM_POLLING_RATE, scope: $cosmos_scope, token: $cosmos_token)
|
728
|
-
|
729
|
-
"value " + comparison_to_eval
|
732
|
+
def cosmos_script_wait_implementation(target_name, packet_name, item_name, value_type, comparison_to_eval, timeout, polling_rate = DEFAULT_TLM_POLLING_RATE, scope: $cosmos_scope, token: $cosmos_token, &block)
|
733
|
+
if comparison_to_eval
|
734
|
+
exp_to_eval = "value " + comparison_to_eval
|
735
|
+
else
|
736
|
+
exp_to_eval = nil
|
730
737
|
end
|
738
|
+
_cosmos_script_wait_implementation(target_name, packet_name, item_name, value_type, timeout, polling_rate, exp_to_eval, scope: scope, token: token, &block)
|
731
739
|
end
|
732
740
|
|
733
|
-
def cosmos_script_wait_implementation_tolerance(target_name, packet_name, item_name, value_type, expected_value, tolerance, timeout, polling_rate = DEFAULT_TLM_POLLING_RATE, scope: $cosmos_scope, token: $cosmos_token)
|
734
|
-
|
735
|
-
|
736
|
-
end
|
741
|
+
def cosmos_script_wait_implementation_tolerance(target_name, packet_name, item_name, value_type, expected_value, tolerance, timeout, polling_rate = DEFAULT_TLM_POLLING_RATE, scope: $cosmos_scope, token: $cosmos_token, &block)
|
742
|
+
exp_to_eval = "((#{expected_value} - #{tolerance})..(#{expected_value} + #{tolerance})).include? value"
|
743
|
+
_cosmos_script_wait_implementation(target_name, packet_name, item_name, value_type, timeout, polling_rate, exp_to_eval, scope: scope, token: token, &block)
|
737
744
|
end
|
738
745
|
|
739
|
-
def cosmos_script_wait_implementation_array_tolerance(array_size, target_name, packet_name, item_name, value_type, expected_value, tolerance, timeout, polling_rate = DEFAULT_TLM_POLLING_RATE, scope: $cosmos_scope, token: $cosmos_token)
|
746
|
+
def cosmos_script_wait_implementation_array_tolerance(array_size, target_name, packet_name, item_name, value_type, expected_value, tolerance, timeout, polling_rate = DEFAULT_TLM_POLLING_RATE, scope: $cosmos_scope, token: $cosmos_token, &block)
|
740
747
|
statements = []
|
741
748
|
array_size.times { |i| statements << "(((#{expected_value[i]} - #{tolerance[i]})..(#{expected_value[i]} + #{tolerance[i]})).include? value[#{i}])" }
|
742
749
|
exp_to_eval = statements.join(" && ")
|
743
|
-
_cosmos_script_wait_implementation(target_name, packet_name, item_name, value_type, timeout, polling_rate, scope: scope, token: token)
|
744
|
-
exp_to_eval
|
745
|
-
end
|
750
|
+
_cosmos_script_wait_implementation(target_name, packet_name, item_name, value_type, timeout, polling_rate, exp_to_eval, scope: scope, token: token, &block)
|
746
751
|
end
|
747
752
|
|
748
753
|
# Wait on an expression to be true.
|
@@ -18,6 +18,7 @@
|
|
18
18
|
# copyright holder
|
19
19
|
|
20
20
|
require 'cosmos/script/extract'
|
21
|
+
require 'time'
|
21
22
|
|
22
23
|
module Cosmos
|
23
24
|
module Script
|
@@ -25,38 +26,59 @@ module Cosmos
|
|
25
26
|
|
26
27
|
private
|
27
28
|
|
28
|
-
#
|
29
|
+
# Gets the current metadata
|
29
30
|
#
|
30
|
-
# @param target [String] Target to set metadata on
|
31
31
|
# @return The result of the method call.
|
32
|
-
def get_metadata(
|
33
|
-
|
34
|
-
response = $api_server.request('get', endpoint)
|
32
|
+
def get_metadata()
|
33
|
+
response = $api_server.request('get', "/cosmos-api/metadata/latest")
|
35
34
|
return nil if response.nil? || response.code != 200
|
36
35
|
return JSON.parse(response.body)
|
37
36
|
end
|
38
37
|
|
39
|
-
# Sets the metadata
|
38
|
+
# Sets the metadata
|
40
39
|
#
|
41
|
-
# @param target [String] Target to set metadata on
|
42
40
|
# @param metadata [Hash<Symbol, Variable>] A hash of metadata
|
43
|
-
# @param color [String] Events color to show on Calendar tool
|
44
|
-
# @param start
|
41
|
+
# @param color [String] Events color to show on Calendar tool, if nil will be blue
|
42
|
+
# @param start [Time] Metadata time value, if nil will be current time
|
45
43
|
# @return The result of the method call.
|
46
|
-
def set_metadata(
|
44
|
+
def set_metadata(metadata, color: nil, start: nil)
|
45
|
+
unless metadata.is_a?(Hash)
|
46
|
+
raise "metadata must be a Hash: #{metadata} is a #{metadata.class}"
|
47
|
+
end
|
47
48
|
color = color.nil? ? '#003784' : color
|
48
|
-
data = {:
|
49
|
-
data[:start] = start unless start.nil?
|
49
|
+
data = { color: color, metadata: metadata }
|
50
|
+
data[:start] = start.iso8601 unless start.nil?
|
50
51
|
response = $api_server.request('post', '/cosmos-api/metadata', data: data, json: true)
|
51
52
|
return nil if response.nil? || response.code != 201
|
52
53
|
return JSON.parse(response.body)
|
53
54
|
end
|
54
55
|
|
55
|
-
#
|
56
|
+
# Updates the metadata
|
56
57
|
#
|
57
|
-
|
58
|
-
|
58
|
+
# @param metadata [Hash<Symbol, Variable>] A hash of metadata
|
59
|
+
# @param color [String] Events color to show on Calendar tool, if nil will be blue
|
60
|
+
# @param start [Integer] Metadata time value as integer seconds from epoch
|
61
|
+
# @return The result of the method call.
|
62
|
+
def update_metadata(metadata, color: nil, start: nil)
|
63
|
+
unless metadata.is_a?(Hash)
|
64
|
+
raise "metadata must be a Hash: #{metadata} is a #{metadata.class}"
|
65
|
+
end
|
66
|
+
color = color.nil? ? '#003784' : color
|
67
|
+
if start == nil
|
68
|
+
existing = get_metadata()
|
69
|
+
start = existing['start']
|
70
|
+
metadata = existing['metadata'].merge(metadata)
|
71
|
+
end
|
72
|
+
data = { :color => color, :metadata => metadata }
|
73
|
+
data[:start] = Time.at(start).iso8601
|
74
|
+
response = $api_server.request('put', "/cosmos-api/metadata/#{start}", data: data, json: true)
|
75
|
+
return nil if response.nil? || response.code != 201
|
76
|
+
return JSON.parse(response.body)
|
59
77
|
end
|
60
78
|
|
79
|
+
# Requests the metadata from the user for a target
|
80
|
+
def input_metadata(*args, **kwargs)
|
81
|
+
raise StandardError "can only be used in Script Runner"
|
82
|
+
end
|
61
83
|
end
|
62
84
|
end
|
@@ -112,13 +112,11 @@ module Cosmos
|
|
112
112
|
target_name, cmd_name, cmd_params = $api_server.method_missing(cmd, *args)
|
113
113
|
_log_cmd(target_name, cmd_name, cmd_params, raw, no_range, no_hazardous)
|
114
114
|
rescue HazardousError => e
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
retry unless prompt_for_script_abort()
|
121
|
-
end
|
115
|
+
# This opens a prompt at which point they can cancel and stop the script
|
116
|
+
# or say Yes and send the command. Thus we don't care about the return value.
|
117
|
+
prompt_for_hazardous(e.target_name, e.cmd_name, e.hazardous_description)
|
118
|
+
target_name, cmd_name, cmd_params = $api_server.method_missing(cmd_no_hazardous, *args)
|
119
|
+
_log_cmd(target_name, cmd_name, cmd_params, raw, no_range, no_hazardous)
|
122
120
|
end
|
123
121
|
end
|
124
122
|
end
|
data/lib/cosmos/script/script.rb
CHANGED
@@ -129,58 +129,38 @@ module Cosmos
|
|
129
129
|
message_box(string, *items, **options)
|
130
130
|
end
|
131
131
|
|
132
|
-
def _file_dialog(
|
132
|
+
def _file_dialog(title, message, filter:)
|
133
133
|
answer = ''
|
134
|
-
|
135
|
-
if
|
136
|
-
|
137
|
-
|
138
|
-
files.select! { |f| File.directory? f }
|
139
|
-
end
|
134
|
+
path = "./*"
|
135
|
+
path += filter if filter
|
136
|
+
files = Dir[path]
|
137
|
+
files.select! { |f| !File.directory? f }
|
140
138
|
while answer.empty?
|
141
|
-
print
|
139
|
+
print "#{title}\n#{message}\n#{files.join("\n")}\n<Type file name>:"
|
142
140
|
answer = gets
|
143
141
|
answer.chomp!
|
144
142
|
end
|
145
143
|
return answer
|
146
144
|
end
|
147
145
|
|
148
|
-
def
|
149
|
-
_file_dialog(
|
150
|
-
end
|
151
|
-
|
152
|
-
def open_file_dialog(directory, message = "Open File", filter = "*")
|
153
|
-
_file_dialog(message, directory, filter)
|
154
|
-
end
|
155
|
-
|
156
|
-
def open_files_dialog(directory, message = "Open File(s)", filter = "*")
|
157
|
-
_file_dialog(message, directory, filter)
|
146
|
+
def open_file_dialog(title, message = "Open File", filter:)
|
147
|
+
_file_dialog(title, message, filter)
|
158
148
|
end
|
159
149
|
|
160
|
-
def
|
161
|
-
_file_dialog(
|
150
|
+
def open_files_dialog(title, message = "Open File(s)", filter:)
|
151
|
+
_file_dialog(title, message, filter)
|
162
152
|
end
|
163
153
|
|
164
154
|
def prompt_for_hazardous(target_name, cmd_name, hazardous_description)
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
def prompt_for_script_abort
|
178
|
-
print "Stop running script? (y,n): "
|
179
|
-
answer = gets.chomp
|
180
|
-
if answer.downcase == 'y'
|
181
|
-
exit
|
182
|
-
else
|
183
|
-
return false # Not aborted - Retry
|
155
|
+
loop do
|
156
|
+
message = "Warning: Command #{target_name} #{cmd_name} is Hazardous. "
|
157
|
+
message << "\n#{hazardous_description}\n" if hazardous_description
|
158
|
+
message << "Send? (y): "
|
159
|
+
print message
|
160
|
+
answer = gets.chomp
|
161
|
+
if answer.downcase == 'y'
|
162
|
+
return true
|
163
|
+
end
|
184
164
|
end
|
185
165
|
end
|
186
166
|
|