cosmos 3.7.1 → 3.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|