cosmos 3.1.2 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/Manifest.txt +17 -1
  4. data/autohotkey/tools/test_runner2.ahk +1 -0
  5. data/autohotkey/tools/tlm_grapher.ahk +13 -1
  6. data/data/crc.txt +39 -30
  7. data/demo/config/data/crc.txt +3 -3
  8. data/demo/config/targets/TEMPLATED/lib/templated_interface.rb +3 -1
  9. data/demo/config/tools/cmd_tlm_server/cmd_tlm_server.txt +7 -1
  10. data/demo/config/tools/cmd_tlm_server/cmd_tlm_server2.txt +6 -1
  11. data/lib/cosmos.rb +2 -2
  12. data/lib/cosmos/gui/dialogs/about_dialog.rb +18 -5
  13. data/lib/cosmos/gui/dialogs/tlm_details_dialog.rb +0 -7
  14. data/lib/cosmos/gui/line_graph/overview_graph.rb +12 -2
  15. data/lib/cosmos/gui/utilities/script_module_gui.rb +11 -3
  16. data/lib/cosmos/interfaces/interface.rb +12 -0
  17. data/lib/cosmos/interfaces/stream_interface.rb +1 -21
  18. data/lib/cosmos/interfaces/tcpip_server_interface.rb +10 -0
  19. data/lib/cosmos/io/json_drb_object.rb +75 -56
  20. data/lib/cosmos/io/tcpip_server.rb +1 -11
  21. data/lib/cosmos/packet_logs.rb +1 -0
  22. data/lib/cosmos/packet_logs/ccsds_log_reader.rb +103 -0
  23. data/lib/cosmos/packets/packet.rb +70 -1
  24. data/lib/cosmos/packets/packet_config.rb +59 -611
  25. data/lib/cosmos/packets/parsers/format_string_parser.rb +58 -0
  26. data/lib/cosmos/packets/parsers/limits_parser.rb +146 -0
  27. data/lib/cosmos/packets/parsers/limits_response_parser.rb +52 -0
  28. data/lib/cosmos/packets/parsers/macro_parser.rb +116 -0
  29. data/lib/cosmos/packets/parsers/packet_item_parser.rb +215 -0
  30. data/lib/cosmos/packets/parsers/packet_parser.rb +123 -0
  31. data/lib/cosmos/packets/parsers/processor_parser.rb +63 -0
  32. data/lib/cosmos/packets/parsers/state_parser.rb +116 -0
  33. data/lib/cosmos/packets/structure.rb +59 -22
  34. data/lib/cosmos/packets/structure_item.rb +1 -1
  35. data/lib/cosmos/script/script.rb +4 -5
  36. data/lib/cosmos/streams/serial_stream.rb +5 -0
  37. data/lib/cosmos/streams/stream.rb +8 -2
  38. data/lib/cosmos/streams/stream_protocol.rb +1 -0
  39. data/lib/cosmos/streams/tcpip_client_stream.rb +37 -7
  40. data/lib/cosmos/streams/tcpip_socket_stream.rb +9 -6
  41. data/lib/cosmos/system/target.rb +3 -6
  42. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +57 -48
  43. data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +7 -3
  44. data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +1 -1
  45. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_realtime_thread.rb +7 -1
  46. data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +1 -2
  47. data/lib/cosmos/top_level.rb +22 -11
  48. data/lib/cosmos/utilities/message_log.rb +14 -9
  49. data/lib/cosmos/version.rb +5 -5
  50. data/spec/interfaces/cmd_tlm_server_interface_spec.rb +16 -16
  51. data/spec/interfaces/linc_interface_spec.rb +3 -0
  52. data/spec/interfaces/tcpip_client_interface_spec.rb +1 -0
  53. data/spec/interfaces/tcpip_server_interface_spec.rb +9 -0
  54. data/spec/io/json_drb_object_spec.rb +1 -1
  55. data/spec/io/serial_driver_spec.rb +0 -1
  56. data/spec/packet_logs/packet_log_writer_spec.rb +5 -3
  57. data/spec/packets/packet_config_spec.rb +22 -837
  58. data/spec/packets/packet_item_spec.rb +10 -10
  59. data/spec/packets/packet_spec.rb +239 -1
  60. data/spec/packets/parsers/format_string_parser_spec.rb +122 -0
  61. data/spec/packets/parsers/limits_parser_spec.rb +282 -0
  62. data/spec/packets/parsers/limits_response_parser_spec.rb +149 -0
  63. data/spec/packets/parsers/macro_parser_spec.rb +184 -0
  64. data/spec/packets/parsers/packet_item_parser_spec.rb +306 -0
  65. data/spec/packets/parsers/packet_parser_spec.rb +99 -0
  66. data/spec/packets/parsers/processor_parser_spec.rb +114 -0
  67. data/spec/packets/parsers/state_parser_spec.rb +156 -0
  68. data/spec/packets/structure_item_spec.rb +14 -14
  69. data/spec/packets/structure_spec.rb +162 -16
  70. data/spec/streams/fixed_stream_protocol_spec.rb +7 -4
  71. data/spec/streams/length_stream_protocol_spec.rb +3 -0
  72. data/spec/streams/preidentified_stream_protocol_spec.rb +3 -0
  73. data/spec/streams/serial_stream_spec.rb +12 -0
  74. data/spec/streams/stream_protocol_spec.rb +14 -0
  75. data/spec/streams/stream_spec.rb +1 -0
  76. data/spec/streams/tcpip_client_stream_spec.rb +3 -0
  77. data/spec/streams/tcpip_socket_stream_spec.rb +15 -3
  78. data/spec/streams/template_stream_protocol_spec.rb +5 -0
  79. data/spec/streams/terminated_stream_protocol_spec.rb +4 -0
  80. data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +21 -1
  81. data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +1 -1
  82. data/spec/tools/cmd_tlm_server/interfaces_spec.rb +1 -1
  83. metadata +19 -3
@@ -0,0 +1,123 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2014 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU General Public License
8
+ # as published by the Free Software Foundation; version 3 with
9
+ # attribution addendums as found in the LICENSE.txt
10
+
11
+ require 'cosmos/packets/packet'
12
+
13
+ module Cosmos
14
+
15
+ class PacketParser
16
+ # @param parser [ConfigParser] Configuration parser
17
+ # @param target_name [String] The name of the target to create the packet
18
+ # under. If the target name is 'SYSTEM' the keyword parameter will be
19
+ # used instead of this parameter.
20
+ # @param commands [Hash] Hash of the currently defined commands
21
+ # @param warnings [Array<String>] Any warning strings generated while
22
+ # parsing this command will be appened to this array
23
+ def self.parse_command(parser, target_name, commands, warnings)
24
+ parser = PacketParser.new(parser)
25
+ parser.verify_parameters()
26
+ parser.create_command(target_name, commands, warnings)
27
+ end
28
+
29
+ # @param parser [ConfigParser] Configuration parser
30
+ # @param target_name [String] The name of the target to create the packet
31
+ # under. If the target name is 'SYSTEM' the keyword parameter will be
32
+ # used instead of this parameter.
33
+ # @param telemetry [Hash] Hash of the currently defined telemetry packets
34
+ # @param latest_data [Hash<String=>Hash<String=>Array(Packet)>>] Hash of hashes keyed
35
+ # first by the target name and then by the item name. This results in an
36
+ # array of packets containing that target and item. This structure is
37
+ # used to perform lookups when the packet and item are known but the
38
+ # packet is not.
39
+ # @param warnings [Array<String>] Any warning strings generated while
40
+ # parsing this command will be appened to this array
41
+ def self.parse_telemetry(parser, target_name, telemetry, latest_data, warnings)
42
+ parser = PacketParser.new(parser)
43
+ parser.verify_parameters()
44
+ parser.create_telemetry(target_name, telemetry, latest_data, warnings)
45
+ end
46
+
47
+ # @param packet [Packet] Packet to check all default and range items for
48
+ # appropriate data types. Only applicable to COMMAND packets.
49
+ def self.check_item_data_types(packet)
50
+ packet.sorted_items.each do |item|
51
+ item.check_default_and_range_data_types()
52
+ end
53
+ rescue => err
54
+ # Add the target name and packet name to the error message so the user
55
+ # can debug where the error occurred
56
+ raise $!, "#{packet.target_name} #{packet.packet_name} #{$!}", $!.backtrace
57
+ end
58
+
59
+ # @param parser [ConfigParser] Configuration parser
60
+ def initialize(parser)
61
+ @parser = parser
62
+ end
63
+
64
+ def verify_parameters
65
+ @usage = "#{@parser.keyword} <TARGET NAME> <PACKET NAME> <ENDIANNESS: BIG_ENDIAN/LITTLE_ENDIAN> <DESCRIPTION (Optional)>"
66
+ @parser.verify_num_parameters(3, 4, @usage)
67
+ end
68
+
69
+ def create_command(target_name, commands, warnings)
70
+ packet = create_packet(target_name)
71
+ warning = check_for_duplicate('Command', commands, packet)
72
+ warnings << warning if warning
73
+ commands[packet.target_name] ||= {}
74
+ packet
75
+ end
76
+
77
+ def create_telemetry(target_name, telemetry, latest_data, warnings)
78
+ packet = create_packet(target_name)
79
+ warning = check_for_duplicate('Telemetry', telemetry, packet)
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
95
+ end
96
+
97
+ private
98
+
99
+ def create_packet(target_name)
100
+ params = @parser.parameters
101
+ target_name = params[0].to_s.upcase if target_name == 'SYSTEM'
102
+ packet_name = params[1].to_s.upcase
103
+ endianness = params[2].to_s.upcase.to_sym
104
+ description = params[3].to_s
105
+ if endianness != :BIG_ENDIAN and endianness != :LITTLE_ENDIAN
106
+ raise @parser.error("Invalid endianness #{params[2]}. Must be BIG_ENDIAN or LITTLE_ENDIAN.", @usage)
107
+ end
108
+ Packet.new(target_name, packet_name, endianness, description)
109
+ end
110
+
111
+ def check_for_duplicate(type, list, packet)
112
+ msg = nil
113
+ if list[packet.target_name]
114
+ if list[packet.target_name][packet.packet_name]
115
+ msg = "#{type} Packet #{packet.target_name} #{packet.packet_name} redefined."
116
+ Logger.instance.warn msg
117
+ end
118
+ end
119
+ msg
120
+ end
121
+
122
+ end
123
+ end # module Cosmos
@@ -0,0 +1,63 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2014 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU General Public License
8
+ # as published by the Free Software Foundation; version 3 with
9
+ # attribution addendums as found in the LICENSE.txt
10
+
11
+ require 'cosmos/processors'
12
+
13
+ module Cosmos
14
+
15
+ class ProcessorParser
16
+ # @param parser [ConfigParser] Configuration parser
17
+ # @param packet [Packet] The current packet
18
+ # @param cmd_or_tlm [String] Whether this is a command or telemetry packet
19
+ def self.parse(parser, packet, cmd_or_tlm)
20
+ @parser = ProcessorParser.new(parser)
21
+ @parser.verify_parameters(cmd_or_tlm)
22
+ @parser.create_processor(packet)
23
+ end
24
+
25
+ # @param parser [ConfigParser] Configuration parser
26
+ def initialize(parser)
27
+ @parser = parser
28
+ end
29
+
30
+ # @param cmd_or_tlm [String] Whether this is a command or telemetry packet
31
+ def verify_parameters(cmd_or_tlm)
32
+ if cmd_or_tlm == PacketConfig::COMMAND
33
+ raise @parser.error("PROCESSOR only applies to telemetry packets")
34
+ end
35
+ @usage = "PROCESSOR <PROCESSOR NAME> <PROCESSOR CLASS FILENAME> <PROCESSOR SPECIFIC OPTIONS>"
36
+ @parser.verify_num_parameters(2, nil, @usage)
37
+ end
38
+
39
+ # @param packet [Packet] The packet the processor should be added to
40
+ def create_processor(packet)
41
+ # require should be performed in target.txt
42
+ klass = @parser.parameters[1].filename_to_class_name.to_class
43
+ raise @parser.error("#{@parser.parameters[1].filename_to_class_name} class not found. Did you require the file in target.txt?", @usage) unless klass
44
+ if @parser.parameters[2]
45
+ processor = klass.new(*@parser.parameters[2..(@parser.parameters.length - 1)])
46
+ else
47
+ processor = klass.new
48
+ end
49
+ raise ArgumentError, "processor must be a Cosmos::Processor but is a #{processor.class}" unless Cosmos::Processor === processor
50
+ processor.name = get_processor_name()
51
+ packet.processors[processor.name] = processor
52
+ rescue Exception => err
53
+ raise @parser.error(err, @usage)
54
+ end
55
+
56
+ private
57
+
58
+ def get_processor_name
59
+ @parser.parameters[0].to_s.upcase
60
+ end
61
+
62
+ end
63
+ end # module Cosmos
@@ -0,0 +1,116 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2014 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU General Public License
8
+ # as published by the Free Software Foundation; version 3 with
9
+ # attribution addendums as found in the LICENSE.txt
10
+
11
+ require 'cosmos/packets/packet_item'
12
+
13
+ module Cosmos
14
+
15
+ class StateParser
16
+ # @param parser [ConfigParser] Configuration parser
17
+ # @param packet [Packet] The current packet
18
+ # @param cmd_or_tlm [String] Whether this is a command or telemetry packet
19
+ # @param item [PacketItem] The packet item to create states on
20
+ # @param warnings [Array<String>] Array of string warnings which will be
21
+ # appended with any warnings found when parsing the limits
22
+ def self.parse(parser, packet, cmd_or_tlm, item, warnings)
23
+ @parser = StateParser.new(parser)
24
+ @parser.verify_parameters(cmd_or_tlm)
25
+ @parser.create_state(packet, cmd_or_tlm, item, warnings)
26
+ end
27
+
28
+ # @param parser [ConfigParser] Configuration parser
29
+ def initialize(parser)
30
+ @parser = parser
31
+ end
32
+
33
+ # @param cmd_or_tlm [String] Whether this is a command or telemetry packet
34
+ def verify_parameters(cmd_or_tlm)
35
+ @usage = "STATE <STATE NAME> <STATE VALUE> "
36
+ if cmd_or_tlm == PacketConfig::COMMAND
37
+ @usage << "<HAZARDOUS (Optional)> <Hazardous Description (Optional)>"
38
+ @parser.verify_num_parameters(2, 4, @usage)
39
+ else
40
+ @usage << "<COLOR: GREEN/YELLOW/RED (Optional)>"
41
+ @parser.verify_num_parameters(2, 3, @usage)
42
+ end
43
+ end
44
+
45
+ # @param packet [Packet] The current packet
46
+ # @param cmd_or_tlm [String] Whether this is a command or telemetry packet
47
+ # @param item [PacketItem] The packet item to create states on
48
+ # @param warnings [Array<String>] Array of string warnings which will be
49
+ # appended with any warnings found when parsing the limits
50
+ def create_state(packet, cmd_or_tlm, item, warnings)
51
+ item.states ||= {}
52
+
53
+ state_name = get_state_name()
54
+ check_for_duplicate_states(item, warnings)
55
+ item.states[state_name] = get_state_value(item.data_type)
56
+ parse_additional_parameters(packet, cmd_or_tlm, item)
57
+ end
58
+
59
+ private
60
+
61
+ def get_state_name
62
+ @parser.parameters[0].upcase
63
+ end
64
+
65
+ def get_state_value(data_type)
66
+ if data_type == :STRING || data_type == :BLOCK
67
+ @parser.parameters[1]
68
+ else
69
+ @parser.parameters[1].convert_to_value
70
+ end
71
+ end
72
+
73
+ def check_for_duplicate_states(item, warnings)
74
+ if item.states[get_state_name()]
75
+ msg = "Duplicate state defined on line #{@parser.line_number}: #{@parser.line}"
76
+ Logger.instance.warn(msg)
77
+ warnings << msg
78
+ end
79
+ end
80
+
81
+ def parse_additional_parameters(packet, cmd_or_tlm, item)
82
+ return unless @parser.parameters.length > 2
83
+
84
+ if cmd_or_tlm == PacketConfig::COMMAND
85
+ get_hazardous(item)
86
+ else
87
+ get_state_colors(item)
88
+ packet.update_limits_items_cache
89
+ end
90
+ end
91
+
92
+ def get_hazardous(item)
93
+ if @parser.parameters[2].upcase == 'HAZARDOUS'
94
+ item.hazardous ||= {}
95
+ if @parser.parameters[3]
96
+ item.hazardous[get_state_name()] = @parser.parameters[3]
97
+ else
98
+ item.hazardous[get_state_name()] = ""
99
+ end
100
+ else
101
+ raise @parser.error("HAZARDOUS expected as third parameter for this line.", @usage)
102
+ end
103
+ end
104
+
105
+ def get_state_colors(item)
106
+ color = @parser.parameters[2].upcase.to_sym
107
+ unless PacketItem::STATE_COLORS.include? color
108
+ raise @parser.error("Invalid state color #{color}. Must be one of #{PacketItem::STATE_COLORS.join(' ')}.", @usage)
109
+ end
110
+ item.limits.enabled = true
111
+ item.state_colors ||= {}
112
+ item.state_colors[get_state_name()] = color
113
+ end
114
+
115
+ end
116
+ end # module Cosmos
@@ -66,6 +66,20 @@ module Cosmos
66
66
  @sorted_items.length > 0
67
67
  end
68
68
 
69
+ # Rename an existing item
70
+ #
71
+ # @param item_name [String] Name of the currently defined item
72
+ # @param new_item_name [String] New name for the item
73
+ def rename_item(item_name, new_item_name)
74
+ item = get_item(item_name)
75
+ item.name = new_item_name
76
+ @items.delete(item_name)
77
+ @items[new_item_name] = item
78
+ # Since @sorted_items contains the actual item reference it is
79
+ # updated when we set the item.name
80
+ item
81
+ end
82
+
69
83
  # Define an item in the structure. This creates a new instance of the
70
84
  # item_class as given in the constructor and adds it to the items hash. It
71
85
  # also resizes the buffer to accomodate the new item.
@@ -89,12 +103,20 @@ module Cosmos
89
103
 
90
104
  # Create the item
91
105
  item = @item_class.new(name_upcase, bit_offset, bit_size, data_type, endianness, array_size, overflow)
106
+ define(item)
107
+ end
92
108
 
109
+ # Adds the given item to the items hash. It also resizes the buffer to
110
+ # accomodate the new item.
111
+ #
112
+ # @param item [StructureItem] The structure item to add
113
+ # @return [StrutureItem] The struture item defined
114
+ def define(item)
93
115
  # Handle Overwriting Existing Item
94
- if @items[name_upcase]
116
+ if @items[item.name]
95
117
  item_index = nil
96
118
  @sorted_items.each_with_index do |sorted_item, index|
97
- if sorted_item.name == name_upcase
119
+ if sorted_item.name == item.name
98
120
  item_index = index
99
121
  break
100
122
  end
@@ -117,9 +139,9 @@ module Cosmos
117
139
  end
118
140
 
119
141
  # Add to the overall hash of defined items
120
- @items[name_upcase] = item
142
+ @items[item.name] = item
121
143
  # Update fixed size knowledge
122
- @fixed_size = false if ((data_type != :DERIVED and bit_size <= 0) or (array_size and array_size <= 0))
144
+ @fixed_size = false if ((item.data_type != :DERIVED and item.bit_size <= 0) or (item.array_size and item.array_size <= 0))
123
145
 
124
146
  # Recalculate the overall defined length of the structure
125
147
  update_needed = false
@@ -178,6 +200,17 @@ module Cosmos
178
200
  return define_item(name, @defined_length_bits, bit_size, data_type, array_size, endianness, overflow)
179
201
  end
180
202
 
203
+ # Adds an item at the end of the structure. It adds the item to the items
204
+ # hash and resizes the buffer to accomodate the new item.
205
+ #
206
+ # @param item (see #define)
207
+ # @return (see #define)
208
+ def append(item)
209
+ raise ArgumentError, "Can't append an item after a variably sized item" if !@fixed_size
210
+ item.bit_offset = @defined_length_bits
211
+ return define(item)
212
+ end
213
+
181
214
  # @param name [String] Name of the item to look up in the items Hash
182
215
  # @return [StructureItem] StructureItem or one of its subclasses
183
216
  def get_item(name)
@@ -329,6 +362,28 @@ module Cosmos
329
362
  end
330
363
  end
331
364
 
365
+ # Make a light weight clone of this structure. This only creates a new buffer
366
+ # of data. The defined structure items are the same.
367
+ #
368
+ # @return [Structure] A copy of the current structure with a new underlying
369
+ # buffer of data
370
+ def clone
371
+ structure = super()
372
+ # Use instance_variable_set since we have overriden buffer= to do
373
+ # additional work that isn't neccessary here
374
+ structure.instance_variable_set("@buffer", @buffer.clone) if @buffer
375
+ return structure
376
+ end
377
+ alias dup clone
378
+
379
+ # Enable the ability to read and write item values as if they were methods
380
+ # to the class
381
+ def enable_method_missing
382
+ extend(MethodMissing)
383
+ end
384
+
385
+ protected
386
+
332
387
  # Take the structure mutex to ensure the buffer does not change while you perform activities
333
388
  def synchronize
334
389
  @mutex ||= Mutex.new
@@ -365,24 +420,6 @@ module Cosmos
365
420
  end
366
421
  end
367
422
 
368
- # Make a light weight clone of this structure. This only creates a new buffer
369
- # of data. The defined structure items are the same.
370
- #
371
- # @return [Structure] A copy of the current structure with a new underlying
372
- # buffer of data
373
- def clone
374
- structure = super()
375
- @buffer = @buffer.clone if @buffer # Deep Copy @buffer
376
- return structure
377
- end
378
- alias dup clone
379
-
380
- def enable_method_missing
381
- extend(MethodMissing)
382
- end
383
-
384
- protected
385
-
386
423
  module MethodMissing
387
424
  # Method missing provides reading/writing item values as if they were methods to the class
388
425
  def method_missing(name, value = nil)
@@ -89,7 +89,7 @@ module Cosmos
89
89
  raise ArgumentError, "name must be a String but is a #{name.class}" unless String === name
90
90
  raise ArgumentError, "name must contain at least one character" if name.empty?
91
91
 
92
- @name = name.clone.freeze
92
+ @name = name.upcase.clone.freeze
93
93
  verify_overall() if @structure_item_constructed
94
94
  end
95
95
 
@@ -438,7 +438,7 @@ module Cosmos
438
438
  script_runner.script_set_status(message) if script_runner
439
439
  end
440
440
 
441
- def ask_string(question, allow_blank = false)
441
+ def ask_string(question, allow_blank = false, password = false)
442
442
  answer = ''
443
443
  while answer.empty?
444
444
  print question + " "
@@ -449,8 +449,8 @@ module Cosmos
449
449
  return answer
450
450
  end
451
451
 
452
- def ask(question, allow_blank = false)
453
- string = ask_string(question, allow_blank)
452
+ def ask(question, allow_blank = false, password = false)
453
+ string = ask_string(question, allow_blank, password)
454
454
  value = string.convert_to_value
455
455
  return value
456
456
  end
@@ -1504,8 +1504,7 @@ module Cosmos
1504
1504
  end
1505
1505
 
1506
1506
  def shutdown_cmd_tlm
1507
- script_disconnect()
1508
- $cmd_tlm_server = nil
1507
+ $cmd_tlm_server.shutdown if $cmd_tlm_server && !$cmd_tlm_disconnect
1509
1508
  end
1510
1509
 
1511
1510
  end # module Script