cosmos 3.7.1 → 3.8.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.
- checksums.yaml +4 -4
- data/Manifest.txt +1 -0
- data/bin/xtce_converter +83 -0
- data/cosmos.gemspec +2 -0
- data/data/crc.txt +279 -279
- data/demo/config/data/crc.txt +171 -171
- data/demo/config/targets/INST/cmd_tlm/inst_tlm.txt +1 -1
- data/demo/config/targets/INST/lib/sim_inst.rb +17 -1
- data/demo/config/targets/INST/screens/hs.txt +4 -1
- data/demo/config/targets/INST/screens/limits.txt +13 -13
- data/install/config/data/crc.txt +113 -113
- data/lib/cosmos/conversions/conversion.rb +6 -0
- data/lib/cosmos/conversions/generic_conversion.rb +12 -0
- data/lib/cosmos/conversions/new_packet_log_conversion.rb +6 -0
- data/lib/cosmos/conversions/polynomial_conversion.rb +6 -0
- data/lib/cosmos/conversions/processor_conversion.rb +10 -0
- data/lib/cosmos/conversions/segmented_polynomial_conversion.rb +10 -0
- data/lib/cosmos/conversions/unix_time_conversion.rb +6 -0
- data/lib/cosmos/core_ext/string.rb +18 -5
- data/lib/cosmos/gui/line_graph/lines.rb +13 -12
- data/lib/cosmos/packets/limits_response.rb +4 -0
- data/lib/cosmos/packets/packet.rb +59 -8
- data/lib/cosmos/packets/packet_config.rb +679 -6
- data/lib/cosmos/packets/packet_item.rb +230 -0
- data/lib/cosmos/packets/parsers/packet_parser.rb +30 -22
- data/lib/cosmos/processors/new_packet_log_processor.rb +5 -0
- data/lib/cosmos/processors/processor.rb +5 -0
- data/lib/cosmos/processors/statistics_processor.rb +5 -0
- data/lib/cosmos/processors/watermark_processor.rb +5 -0
- data/lib/cosmos/script/extract.rb +1 -1
- data/lib/cosmos/tools/packet_viewer/packet_viewer.rb +7 -2
- data/lib/cosmos/tools/tlm_grapher/data_objects/housekeeping_data_object.rb +3 -1
- data/lib/cosmos/tools/tlm_grapher/data_objects/xy_data_object.rb +3 -1
- data/lib/cosmos/tools/tlm_viewer/widgets/limits_widget.rb +10 -0
- data/lib/cosmos/tools/tlm_viewer/widgets/limitsbar_widget.rb +14 -6
- data/lib/cosmos/tools/tlm_viewer/widgets/limitscolumn_widget.rb +14 -6
- data/lib/cosmos/tools/tlm_viewer/widgets/rangebar_widget.rb +14 -6
- data/lib/cosmos/tools/tlm_viewer/widgets/rangecolumn_widget.rb +14 -6
- data/lib/cosmos/utilities/simulated_target.rb +1 -0
- data/lib/cosmos/version.rb +5 -5
- metadata +18 -2
@@ -296,8 +296,238 @@ module Cosmos
|
|
296
296
|
hash
|
297
297
|
end
|
298
298
|
|
299
|
+
def to_config(cmd_or_tlm, default_endianness)
|
300
|
+
config = ''
|
301
|
+
if cmd_or_tlm == :TELEMETRY
|
302
|
+
if self.array_size
|
303
|
+
config << " ARRAY_ITEM #{self.name.to_s.quote_if_necessary} #{self.bit_offset} #{self.bit_size} #{self.data_type} #{self.array_size} \"#{self.description.to_s.gsub("\"", "'")}\""
|
304
|
+
elsif self.id_value
|
305
|
+
config << " ID_ITEM #{self.name.to_s.quote_if_necessary} #{self.bit_offset} #{self.bit_size} #{self.data_type} #{self.id_value} \"#{self.description.to_s.gsub("\"", "'")}\""
|
306
|
+
else
|
307
|
+
config << " ITEM #{self.name.to_s.quote_if_necessary} #{self.bit_offset} #{self.bit_size} #{self.data_type} \"#{self.description.to_s.gsub("\"", "'")}\""
|
308
|
+
end
|
309
|
+
else # :COMMAND
|
310
|
+
if self.array_size
|
311
|
+
config << " ARRAY_PARAMETER #{self.name.to_s.quote_if_necessary} #{self.bit_offset} #{self.bit_size} #{self.data_type} #{self.array_size} \"#{self.description.to_s.gsub("\"", "'")}\""
|
312
|
+
elsif self.id_value
|
313
|
+
if self.data_type == :BLOCK or self.data_type == :STRING
|
314
|
+
config << " ID_PARAMETER #{self.name.to_s.quote_if_necessary} #{self.bit_offset} #{self.bit_size} #{self.data_type} \"#{self.default}\" \"#{self.description.to_s.gsub("\"", "'")}\""
|
315
|
+
else
|
316
|
+
config << " ID_PARAMETER #{self.name.to_s.quote_if_necessary} #{self.bit_offset} #{self.bit_size} #{self.data_type} #{self.range.first} #{self.range.last} #{self.default} \"#{self.description.to_s.gsub("\"", "'")}\""
|
317
|
+
end
|
318
|
+
else
|
319
|
+
if self.data_type == :BLOCK or self.data_type == :STRING
|
320
|
+
config << " PARAMETER #{self.name.to_s.quote_if_necessary} #{self.bit_offset} #{self.bit_size} #{self.data_type} \"#{self.default}\" \"#{self.description.to_s.gsub("\"", "'")}\""
|
321
|
+
else
|
322
|
+
config << " PARAMETER #{self.name.to_s.quote_if_necessary} #{self.bit_offset} #{self.bit_size} #{self.data_type} #{self.range.first} #{self.range.last} #{self.default} \"#{self.description.to_s.gsub("\"", "'")}\""
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
326
|
+
config << " #{self.endianness}" if self.endianness != default_endianness
|
327
|
+
config << "\n"
|
328
|
+
|
329
|
+
config << " REQUIRED\n" if self.required
|
330
|
+
config << " FORMAT_STRING #{self.format_string.to_s.quote_if_necessary}\n" if self.format_string
|
331
|
+
config << " UNITS #{self.units_full.to_s.quote_if_necessary} #{self.units.to_s.quote_if_necessary}\n" if self.units
|
332
|
+
config << " OVERFLOW #{self.overflow}\n" if self.overflow != :ERROR
|
333
|
+
|
334
|
+
if @states
|
335
|
+
@states.each do |state_name, state_value|
|
336
|
+
config << " STATE #{state_name.to_s.quote_if_necessary} #{state_value.to_s.quote_if_necessary}"
|
337
|
+
if @hazardous and @hazardous[state_name]
|
338
|
+
config << " HAZARDOUS #{@hazardous[state_name].to_s.quote_if_necessary}"
|
339
|
+
end
|
340
|
+
if @state_colors and @state_colors[state_name]
|
341
|
+
config << " #{@state_colors[state_name]}"
|
342
|
+
end
|
343
|
+
config << "\n"
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
config << self.read_conversion.to_config(:READ) if self.read_conversion
|
348
|
+
config << self.write_conversion.to_config(:WRITE) if self.write_conversion
|
349
|
+
|
350
|
+
if self.limits
|
351
|
+
if self.limits.values
|
352
|
+
self.limits.values.each do |limits_set, limits_values|
|
353
|
+
config << " LIMITS #{limits_set} #{self.limits.persistence_setting} #{self.limits.enabled ? 'ENABLED' : 'DISABLED'} #{limits_values[0]} #{limits_values[1]} #{limits_values[2]} #{limits_values[3]} #{limits_values[4]} #{limits_values[5]}\n"
|
354
|
+
end
|
355
|
+
end
|
356
|
+
config << self.limits.response.to_config if self.limits.response
|
357
|
+
end
|
358
|
+
|
359
|
+
if @meta
|
360
|
+
@meta.each do |key, values|
|
361
|
+
config << " META #{key.to_s.quote_if_necessary} #{values.map {|a| a.to_s.quote_if_necessary}.join(" ")}\n"
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
config
|
366
|
+
end
|
367
|
+
|
368
|
+
def to_xtce_type(param_or_arg, xml)
|
369
|
+
# TODO: Arrays, Spline Conversions
|
370
|
+
case self.data_type
|
371
|
+
when :INT, :UINT
|
372
|
+
attrs = { :name => (self.name + '_Type') }
|
373
|
+
attrs[:initialValue] = self.default if self.default and !self.array_size
|
374
|
+
attrs[:shortDescription] = self.description if self.description
|
375
|
+
if @states and self.default and @states.key(self.default)
|
376
|
+
attrs[:initialValue] = @states.key(self.default) and !self.array_size
|
377
|
+
end
|
378
|
+
if self.data_type == :INT
|
379
|
+
signed = 'true'
|
380
|
+
encoding = 'twosCompliment'
|
381
|
+
else
|
382
|
+
signed = 'false'
|
383
|
+
encoding = 'unsigned'
|
384
|
+
end
|
385
|
+
if @states
|
386
|
+
xml['xtce'].send('Enumerated' + param_or_arg + 'Type', attrs) do
|
387
|
+
to_xtce_units(xml)
|
388
|
+
xml['xtce'].IntegerDataEncoding(:sizeInBits => self.bit_size, :encoding => encoding)
|
389
|
+
xml['xtce'].EnumerationList do
|
390
|
+
@states.each do |state_name, state_value|
|
391
|
+
xml['xtce'].Enumeration(:value => state_value, :label => state_name)
|
392
|
+
end
|
393
|
+
end
|
394
|
+
end
|
395
|
+
else
|
396
|
+
if (self.read_conversion and self.read_conversion.class == PolynomialConversion) or (self.write_conversion and self.write_conversion.class == PolynomialConversion)
|
397
|
+
type_string = 'Float' + param_or_arg + 'Type'
|
398
|
+
else
|
399
|
+
type_string = 'Integer' + param_or_arg + 'Type'
|
400
|
+
attrs[:signed] = signed
|
401
|
+
end
|
402
|
+
xml['xtce'].send(type_string, attrs) do
|
403
|
+
to_xtce_units(xml)
|
404
|
+
if (self.read_conversion and self.read_conversion.class == PolynomialConversion) or (self.write_conversion and self.write_conversion.class == PolynomialConversion)
|
405
|
+
xml['xtce'].IntegerDataEncoding(:sizeInBits => self.bit_size, :encoding => encoding) do
|
406
|
+
to_xtce_conversion(xml)
|
407
|
+
end
|
408
|
+
else
|
409
|
+
xml['xtce'].IntegerDataEncoding(:sizeInBits => self.bit_size, :encoding => encoding)
|
410
|
+
end
|
411
|
+
if self.limits
|
412
|
+
if self.limits.values
|
413
|
+
self.limits.values.each do |limits_set, limits_values|
|
414
|
+
if limits_set == :DEFAULT
|
415
|
+
xml['xtce'].DefaultAlarm do
|
416
|
+
xml['xtce'].StaticAlarmRanges do
|
417
|
+
xml['xtce'].WarningRange(:minInclusive => limits_values[1], :maxInclusive => limits_values[2])
|
418
|
+
xml['xtce'].CriticalRange(:minInclusive => limits_values[0], :maxInclusive => limits_values[3])
|
419
|
+
end
|
420
|
+
end
|
421
|
+
end
|
422
|
+
end
|
423
|
+
end
|
424
|
+
end
|
425
|
+
if self.range
|
426
|
+
xml['xtce'].ValidRange(:minInclusive => self.range.first, :maxInclusive => self.range.last)
|
427
|
+
end
|
428
|
+
end # Type
|
429
|
+
end # if @states
|
430
|
+
when :FLOAT
|
431
|
+
attrs = { :name => (self.name + '_Type'), :sizeInBits => self.bit_size }
|
432
|
+
attrs[:initialValue] = self.default if self.default and !self.array_size
|
433
|
+
attrs[:shortDescription] = self.description if self.description
|
434
|
+
xml['xtce'].send('Float' + param_or_arg + 'Type', attrs) do
|
435
|
+
to_xtce_units(xml)
|
436
|
+
if (self.read_conversion and self.read_conversion.class == PolynomialConversion) or (self.write_conversion and self.write_conversion.class == PolynomialConversion)
|
437
|
+
xml['xtce'].FloatDataEncoding(:sizeInBits => self.bit_size, :encoding => 'IEEE754_1985') do
|
438
|
+
to_xtce_conversion(xml)
|
439
|
+
end
|
440
|
+
else
|
441
|
+
xml['xtce'].FloatDataEncoding(:sizeInBits => self.bit_size, :encoding => 'IEEE754_1985')
|
442
|
+
end
|
443
|
+
|
444
|
+
if self.limits
|
445
|
+
if self.limits.values
|
446
|
+
self.limits.values.each do |limits_set, limits_values|
|
447
|
+
if limits_set == :DEFAULT
|
448
|
+
xml['xtce'].DefaultAlarm do
|
449
|
+
xml['xtce'].StaticAlarmRanges do
|
450
|
+
xml['xtce'].WarningRange(:minInclusive => limits_values[1], :maxInclusive => limits_values[2])
|
451
|
+
xml['xtce'].CriticalRange(:minInclusive => limits_values[0], :maxInclusive => limits_values[3])
|
452
|
+
end
|
453
|
+
end
|
454
|
+
end
|
455
|
+
end
|
456
|
+
end
|
457
|
+
end
|
458
|
+
|
459
|
+
if self.range
|
460
|
+
xml['xtce'].ValidRange(:minInclusive => self.range.first, :maxInclusive => self.range.last)
|
461
|
+
end
|
462
|
+
|
463
|
+
end # Type
|
464
|
+
when :STRING
|
465
|
+
# TODO: COSMOS Variably sized strings are not supported in XTCE
|
466
|
+
attrs = { :name => (self.name + '_Type'), :characterWidth => 8 }
|
467
|
+
attrs[:initialValue] = self.default if self.default and !self.array_size
|
468
|
+
attrs[:shortDescription] = self.description if self.description
|
469
|
+
xml['xtce'].send('String' + param_or_arg + 'Type', attrs) do
|
470
|
+
to_xtce_units(xml)
|
471
|
+
xml['xtce'].StringDataEncoding(:encoding => 'UTF-8') do
|
472
|
+
xml['xtce'].SizeInBits do
|
473
|
+
xml['xtce'].Fixed do
|
474
|
+
xml['xtce'].FixedValue(self.bit_size.to_s)
|
475
|
+
end
|
476
|
+
end
|
477
|
+
end
|
478
|
+
end
|
479
|
+
when :BLOCK
|
480
|
+
# TODO: COSMOS Variably sized blocks are not supported in XTCE
|
481
|
+
# TODO: Write string to hex method to support initial value
|
482
|
+
attrs = { :name => (self.name + '_Type') }
|
483
|
+
attrs[:shortDescription] = self.description if self.description
|
484
|
+
#attrs[:initialValue] = self.default if self.default and !self.array_size
|
485
|
+
xml['xtce'].send('Binary' + param_or_arg + 'Type', attrs) do
|
486
|
+
to_xtce_units(xml)
|
487
|
+
xml['xtce'].BinaryDataEncoding do
|
488
|
+
xml['xtce'].SizeInBits do
|
489
|
+
xml['xtce'].FixedValue(self.bit_size.to_s)
|
490
|
+
end
|
491
|
+
end
|
492
|
+
end
|
493
|
+
when :DERIVED
|
494
|
+
raise "DERIVED data type not supported in XTCE"
|
495
|
+
end
|
496
|
+
end
|
497
|
+
|
498
|
+
def to_xtce_item(param_or_arg, xml)
|
499
|
+
xml['xtce'].send(param_or_arg, :name => self.name, "#{param_or_arg.downcase}TypeRef" => self.name + '_Type')
|
500
|
+
end
|
501
|
+
|
299
502
|
protected
|
300
503
|
|
504
|
+
def to_xtce_units(xml)
|
505
|
+
if self.units
|
506
|
+
xml['xtce'].UnitSet do
|
507
|
+
xml['xtce'].Unit(self.units, :description => self.units_full)
|
508
|
+
end
|
509
|
+
else
|
510
|
+
xml['xtce'].UnitSet
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
514
|
+
def to_xtce_conversion(xml)
|
515
|
+
if self.read_conversion
|
516
|
+
conversion = self.read_conversion
|
517
|
+
else
|
518
|
+
conversion = self.write_conversion
|
519
|
+
end
|
520
|
+
if conversion and conversion.class == PolynomialConversion
|
521
|
+
xml['xtce'].DefaultCalibrator do
|
522
|
+
xml['xtce'].PolynomialCalibrator do
|
523
|
+
conversion.coeffs.each_with_index do |coeff, index|
|
524
|
+
xml['xtce'].Term(:coefficient => coeff, :exponent => index)
|
525
|
+
end
|
526
|
+
end
|
527
|
+
end
|
528
|
+
end
|
529
|
+
end
|
530
|
+
|
301
531
|
# Convert a value into the given data type
|
302
532
|
def convert(value, data_type)
|
303
533
|
case data_type
|
@@ -68,33 +68,15 @@ module Cosmos
|
|
68
68
|
|
69
69
|
def create_command(target_name, commands, warnings)
|
70
70
|
packet = create_packet(target_name)
|
71
|
-
|
72
|
-
warnings << warning if warning
|
73
|
-
commands[packet.target_name] ||= {}
|
74
|
-
packet
|
71
|
+
PacketParser.finish_create_command(packet, commands, warnings)
|
75
72
|
end
|
76
73
|
|
77
74
|
def create_telemetry(target_name, telemetry, latest_data, warnings)
|
78
75
|
packet = create_packet(target_name)
|
79
|
-
|
80
|
-
warnings << warning if warning
|
81
|
-
|
82
|
-
# Add received time packet items
|
83
|
-
item = packet.define_item('RECEIVED_TIMESECONDS', 0, 0, :DERIVED, nil, packet.default_endianness, :ERROR, '%0.6f', ReceivedTimeSecondsConversion.new)
|
84
|
-
item.description = 'COSMOS Received Time (UTC, Floating point, Unix epoch)'
|
85
|
-
item = packet.define_item('RECEIVED_TIMEFORMATTED', 0, 0, :DERIVED, nil, packet.default_endianness, :ERROR, nil, ReceivedTimeFormattedConversion.new)
|
86
|
-
item.description = 'COSMOS Received Time (Local time zone, Formatted string)'
|
87
|
-
item = packet.define_item('RECEIVED_COUNT', 0, 0, :DERIVED, nil, packet.default_endianness, :ERROR, nil, ReceivedCountConversion.new)
|
88
|
-
item.description = 'COSMOS packet received count'
|
89
|
-
|
90
|
-
unless telemetry[packet.target_name]
|
91
|
-
telemetry[packet.target_name] = {}
|
92
|
-
latest_data[packet.target_name] = {}
|
93
|
-
end
|
94
|
-
packet
|
76
|
+
PacketParser.finish_create_telemetry(packet, telemetry, latest_data, warnings)
|
95
77
|
end
|
96
78
|
|
97
|
-
private
|
79
|
+
#private
|
98
80
|
|
99
81
|
def create_packet(target_name)
|
100
82
|
params = @parser.parameters
|
@@ -108,7 +90,7 @@ module Cosmos
|
|
108
90
|
Packet.new(target_name, packet_name, endianness, description)
|
109
91
|
end
|
110
92
|
|
111
|
-
def check_for_duplicate(type, list, packet)
|
93
|
+
def self.check_for_duplicate(type, list, packet)
|
112
94
|
msg = nil
|
113
95
|
if list[packet.target_name]
|
114
96
|
if list[packet.target_name][packet.packet_name]
|
@@ -119,5 +101,31 @@ module Cosmos
|
|
119
101
|
msg
|
120
102
|
end
|
121
103
|
|
104
|
+
def self.finish_create_command(packet, commands, warnings)
|
105
|
+
warning = PacketParser.check_for_duplicate('Command', commands, packet)
|
106
|
+
warnings << warning if warning
|
107
|
+
commands[packet.target_name] ||= {}
|
108
|
+
packet
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.finish_create_telemetry(packet, telemetry, latest_data, warnings)
|
112
|
+
warning = PacketParser.check_for_duplicate('Telemetry', telemetry, packet)
|
113
|
+
warnings << warning if warning
|
114
|
+
|
115
|
+
# Add received time packet items
|
116
|
+
item = packet.define_item('RECEIVED_TIMESECONDS', 0, 0, :DERIVED, nil, packet.default_endianness, :ERROR, '%0.6f', ReceivedTimeSecondsConversion.new)
|
117
|
+
item.description = 'COSMOS Received Time (UTC, Floating point, Unix epoch)'
|
118
|
+
item = packet.define_item('RECEIVED_TIMEFORMATTED', 0, 0, :DERIVED, nil, packet.default_endianness, :ERROR, nil, ReceivedTimeFormattedConversion.new)
|
119
|
+
item.description = 'COSMOS Received Time (Local time zone, Formatted string)'
|
120
|
+
item = packet.define_item('RECEIVED_COUNT', 0, 0, :DERIVED, nil, packet.default_endianness, :ERROR, nil, ReceivedCountConversion.new)
|
121
|
+
item.description = 'COSMOS packet received count'
|
122
|
+
|
123
|
+
unless telemetry[packet.target_name]
|
124
|
+
telemetry[packet.target_name] = {}
|
125
|
+
latest_data[packet.target_name] = {}
|
126
|
+
end
|
127
|
+
packet
|
128
|
+
end
|
129
|
+
|
122
130
|
end
|
123
131
|
end # module Cosmos
|
@@ -29,6 +29,11 @@ module Cosmos
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
# Convert to configuration file string
|
33
|
+
def to_config
|
34
|
+
" PROCESSOR #{@name} #{self.class.name.to_s.class_name_to_filename} #{@packet_log_writer_name}\n"
|
35
|
+
end
|
36
|
+
|
32
37
|
end # class NewPacketLogProcessor
|
33
38
|
|
34
39
|
end # module Cosmos
|
@@ -60,6 +60,11 @@ module Cosmos
|
|
60
60
|
end
|
61
61
|
alias dup clone
|
62
62
|
|
63
|
+
# Convert to configuration file string
|
64
|
+
def to_config
|
65
|
+
" PROCESSOR #{@name} #{self.class.name.to_s.class_name_to_filename} #{@item_name} #{@samples_to_average} #{@value_type}\n"
|
66
|
+
end
|
67
|
+
|
63
68
|
end # class StatisticsProcessor
|
64
69
|
|
65
70
|
end # module Cosmos
|
@@ -39,6 +39,11 @@ module Cosmos
|
|
39
39
|
@results[:LOW_WATER] = nil
|
40
40
|
end
|
41
41
|
|
42
|
+
# Convert to configuration file string
|
43
|
+
def to_config
|
44
|
+
" PROCESSOR #{@name} #{self.class.name.to_s.class_name_to_filename} #{@item_name} #{@value_type}\n"
|
45
|
+
end
|
46
|
+
|
42
47
|
end # class WatermarkProcessor
|
43
48
|
|
44
49
|
end # module Cosmos
|
@@ -25,7 +25,7 @@ module Cosmos
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def extract_fields_from_cmd_text(text)
|
28
|
-
split_string = text.split(/\s
|
28
|
+
split_string = text.split(/\s+with\s+/i, 2)
|
29
29
|
raise "ERROR: 'with' must be followed by parameters : #{text}" if split_string.length == 1 and text =~ /\s*with\s*/i
|
30
30
|
|
31
31
|
# Extract target_name and cmd_name
|
@@ -35,7 +35,11 @@ module Cosmos
|
|
35
35
|
@tlm_thread = nil
|
36
36
|
@shutdown_tlm_thread = false
|
37
37
|
@mode = :WITH_UNITS
|
38
|
-
|
38
|
+
if options.rate
|
39
|
+
@polling_rate = options.rate
|
40
|
+
else
|
41
|
+
@polling_rate = 1.0
|
42
|
+
end
|
39
43
|
@colorblind = false
|
40
44
|
|
41
45
|
initialize_actions()
|
@@ -249,7 +253,7 @@ module Cosmos
|
|
249
253
|
end
|
250
254
|
|
251
255
|
def file_options
|
252
|
-
@polling_rate = Qt::InputDialog.getDouble(self, tr("Options"), tr("Polling Rate:"), @polling_rate, 0, 1000, 1, nil)
|
256
|
+
@polling_rate = Qt::InputDialog.getDouble(self, tr("Options"), tr("Polling Rate (sec):"), @polling_rate, 0, 1000, 1, nil)
|
253
257
|
end
|
254
258
|
|
255
259
|
def update_all
|
@@ -531,6 +535,7 @@ module Cosmos
|
|
531
535
|
end
|
532
536
|
options.packet = split
|
533
537
|
end
|
538
|
+
option_parser.on("-r", "--rate PERIOD", "Set the polling rate to PERIOD (unit seconds)") { |arg| options.rate = Float(arg) }
|
534
539
|
end
|
535
540
|
|
536
541
|
super(option_parser, options)
|
@@ -163,7 +163,9 @@ module Cosmos
|
|
163
163
|
# Bail on the values if they are NaN or nil as we can't graph them
|
164
164
|
return if x_value.nil? || y_value.nil? ||
|
165
165
|
(x_value.respond_to?(:nan?) && x_value.nan?) ||
|
166
|
-
(y_value.respond_to?(:nan?) && y_value.nan?)
|
166
|
+
(y_value.respond_to?(:nan?) && y_value.nan?) ||
|
167
|
+
(x_value.respond_to?(:infinite?) && x_value.infinite?) ||
|
168
|
+
(y_value.respond_to?(:infinite?) && y_value.infinite?)
|
167
169
|
@formatted_x_values << packet.read(@formatted_time_item_name) if @formatted_time_item_name
|
168
170
|
|
169
171
|
upper_index = nil
|
@@ -195,7 +195,9 @@ module Cosmos
|
|
195
195
|
# Bail on the values if they are NaN or nil as we can't graph them
|
196
196
|
return if x_value.nil? || y_value.nil? ||
|
197
197
|
(x_value.respond_to?(:nan?) && x_value.nan?) ||
|
198
|
-
(y_value.respond_to?(:nan?) && y_value.nan?)
|
198
|
+
(y_value.respond_to?(:nan?) && y_value.nan?) ||
|
199
|
+
(x_value.respond_to?(:infinite?) && x_value.infinite?) ||
|
200
|
+
(y_value.respond_to?(:infinite?) && y_value.infinite?)
|
199
201
|
|
200
202
|
time_value = packet.read(@time_item_name) if @time_item_name
|
201
203
|
|
@@ -34,6 +34,16 @@ module Cosmos
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def value=(data)
|
37
|
+
if String === data
|
38
|
+
substring = data[0..2]
|
39
|
+
if substring == "Inf".freeze
|
40
|
+
data = Float::INFINITY
|
41
|
+
elsif substring == "-In".freeze
|
42
|
+
data = -Float::INFINITY
|
43
|
+
elsif substring == "NaN".freeze
|
44
|
+
data = Float::NAN
|
45
|
+
end
|
46
|
+
end
|
37
47
|
@value = data.to_f
|
38
48
|
update()
|
39
49
|
end
|
@@ -81,12 +81,20 @@ module Cosmos
|
|
81
81
|
@low_value = red_low - 0.1 * @bar_scale
|
82
82
|
@high_value = red_high + 0.1 * @bar_scale
|
83
83
|
|
84
|
-
@
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
84
|
+
if @value.is_a?(Float) && (@value.infinite? || @value.nan?)
|
85
|
+
if @value.infinite? == 1
|
86
|
+
@line_pos = @bar_width + @x_pad
|
87
|
+
else
|
88
|
+
@line_pos = @x_pad
|
89
|
+
end
|
90
|
+
else
|
91
|
+
@line_pos = (@x_pad + (@value - @low_value) / @bar_scale * @bar_width).to_i
|
92
|
+
if @line_pos < @x_pad
|
93
|
+
@line_pos = @x_pad
|
94
|
+
end
|
95
|
+
if @line_pos > @x_pad + @bar_width
|
96
|
+
@line_pos = @bar_width + @x_pad
|
97
|
+
end
|
90
98
|
end
|
91
99
|
|
92
100
|
dc.addLineColor(@line_pos, @y_pad - 3, @line_pos, @y_pad + @bar_height + 3)
|