Class: Cosmos::Commands

Inherits:
Object show all
Defined in:
lib/cosmos/packets/commands.rb

Overview

Commands uses PacketConfig to parse the command and telemetry configuration files. It contains all the knowledge of which command packets exist in the system and how to access them. This class is the API layer which other classes use to access commands.

This should not be confused with the Api module which implements the JSON API that is used by tools when accessing the Server. The Api module always provides Ruby primatives where the PacketDefinition class can return actual Packet or PacketItem objects. While there are some overlapping methods between the two, these are separate interfaces into the system.

Constant Summary collapse

LATEST_PACKET_NAME =
'LATEST'.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ Commands

Returns a new instance of Commands.

Parameters:

  • config (PacketConfig)

    Packet configuration to use to access the commands



32
33
34
# File 'lib/cosmos/packets/commands.rb', line 32

def initialize(config)
  @config = config
end

Instance Attribute Details

#configObject

Returns the value of attribute config.



26
27
28
# File 'lib/cosmos/packets/commands.rb', line 26

def config
  @config
end

Instance Method Details

#allObject



287
288
289
# File 'lib/cosmos/packets/commands.rb', line 287

def all
  @config.commands
end

#build_cmd(target_name, packet_name, params = {}, range_checking = true, raw = false) ⇒ Object

Returns a copy of the specified command packet with the parameters initialzed to the given params values.

Parameters:

  • params (Hash<param_name=>param_value>) (defaults to: {})

    Parameter items to override in the given command.

  • range_checking (Boolean) (defaults to: true)

    Whether to perform range checking on the passed in parameters.

  • raw (Boolean) (defaults to: false)

    Indicates whether or not to run conversions on command parameters

  • target_name (String)

    The target name

  • packet_name (String)

    The packet name. Must be a defined packet name and not 'LATEST'.



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/cosmos/packets/commands.rb', line 128

def build_cmd(target_name, packet_name, params = {}, range_checking = true, raw = false)
  target_upcase = target_name.to_s.upcase
  packet_upcase = packet_name.to_s.upcase

  # Lookup the command and create a light weight copy
  command = packet(target_upcase, packet_upcase).clone

  # Set time, parameters, and restore defaults
  command.received_time = Time.now
  command.given_values = params
  command.restore_defaults
  command.raw = raw

  # Set any parameters
  given_item_names = []
  params.each do |item_name, value|
    item_upcase = item_name.to_s.upcase
    item = command.get_item(item_upcase)
    range_check_value = value

    # Convert from state to value if possible
    if item.states and item.states[value.to_s.upcase]
      range_check_value = item.states[value.to_s.upcase]
    end

    if range_checking
      range = item.range
      if range
        # Perform Range Check on command parameter
        if not range.include?(range_check_value)
          range_check_value = "'#{range_check_value}'" if String === range_check_value
          raise "Command parameter '#{target_upcase} #{packet_upcase} #{item_upcase}' = #{range_check_value} not in valid range of #{range.first} to #{range.last}"
        end
      end
    end

    # Update parameter in command
    if raw
      command.write(item_upcase, value, :RAW)
    else
      command.write(item_upcase, value, :CONVERTED)
    end

    given_item_names << item_upcase
  end # cmd_params.each

  # Script Runner could call this command with only some parameters
  # so make sure any required parameters were actually passed in.
  item_defs = command.items
  item_defs.each do |item_name, item_def|
    if item_def.required and not given_item_names.include? item_name
      raise "Required command parameter '#{target_upcase} #{packet_upcase} #{item_name}' not given"
    end
  end

  return command
end

#clear_countersObject



279
280
281
282
283
284
285
# File 'lib/cosmos/packets/commands.rb', line 279

def clear_counters
  @config.commands.each do |target_name, target_packets|
    target_packets.each do |packet_name, packet|
      packet.received_count = 0
    end
  end
end

#cmd_hazardous?(target_name, packet_name, params = {}) ⇒ Boolean

Returns whether the given command is hazardous. Commands are hazardous if they are marked hazardous overall or if any of their hardardous states are set. Thus any given parameter values are first applied to the command and then checked for hazardous states.

Parameters:

  • target_name (String)

    The target name

  • packet_name (String)

    The packet name. Must be a defined packet name and not 'LATEST'.

  • params (Hash<param_name=>param_value>) (defaults to: {})

    Parameter items to override in the given command.

Returns:

  • (Boolean)


233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/cosmos/packets/commands.rb', line 233

def cmd_hazardous?(target_name, packet_name, params = {})
  target_upcase = target_name.to_s.upcase
  packet_upcase = packet_name.to_s.upcase

  # Lookup the command
  command = packet(target_upcase, packet_upcase)

  # Overall command hazardous check
  return [true, command.hazardous_description] if command.hazardous

  # Create a light weight copy of command
  command = command.clone()
  # Set given command parameters and restore defaults
  command.given_values = params
  command.restore_defaults()

  # Set any parameters
  params.each do |item_name, value|
    item_upcase = item_name.to_s.upcase
    item = command.get_item(item_upcase)

    if item.states
      state_value = item.states[value.to_s.upcase]
      value = state_value if state_value
    end

    # Update parameter in command
    command.write(item_upcase, value)
  end

  # Check each item for hazardous states
  item_defs = command.items
  item_defs.each do |item_name, item_def|
    if item_def.hazardous
      state_name = command.read(item_name)
      # Nominally the command.read will return a valid state_name
      # If it doesn't, the if check will fail and we'll fall through to
      # the bottom where we return [false, nil] which means this
      # command is not hazardous.
      return [true, item_def.hazardous[state_name]] if item_def.hazardous[state_name]
    end
  end

  return [false, nil]
end

#format(packet, ignored_parameters = []) ⇒ Object

Formatted version of a command



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/cosmos/packets/commands.rb', line 187

def format(packet, ignored_parameters = [])
  first = true
  if packet.raw
    items = packet.read_all(:RAW)
    string = "cmd_raw('#{packet.target_name} #{packet.packet_name}"
  else
    items = packet.read_all(:FORMATTED)
    string = "cmd('#{packet.target_name} #{packet.packet_name}"
  end
  items.each do |item_name, item_value|
    unless ignored_parameters.include?(item_name)
      if first
        string << ' with '.freeze
        first = false
      else
        string << ', '.freeze
      end

      item = packet.get_item(item_name)
      if item.data_type ==:STRING or item.data_type == :BLOCK
        item_value = item_value.inspect
        if item_value.length > 256
          item_value = item_value[0..255] + '..."'.freeze
        end
        string << "#{item_name} #{item_value}"
      else
        if (Array === item_value) && (!packet.raw)
          string << "#{item_name} [#{item_value.join(", ")}]"
        else
          string << "#{item_name} #{item_value}"
        end
      end
    end
  end
  string << "')".freeze
  string
end

#identify(packet_data, target_names = nil) ⇒ Object

Identifies an unknown buffer of data as a defined command and sets the commands’s data to the given buffer. Identifying a command uses the fields marked as ID_PARAMETER to identify if the buffer passed represents the command defined. Incorrectly sized buffers are still processed but an error is logged.

Note: Subsequent requests for the command (using packet) will return an uninitialized copy of the command. Thus you must use the return value of this method.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/cosmos/packets/commands.rb', line 87

def identify(packet_data, target_names = nil)
  identified_packet = nil

  target_names = target_names() unless target_names

  target_names.each do |target_name|
    target_packets = nil
    begin
      target_packets = packets(target_name)
    rescue RuntimeError
      # No commands for this target
      next
    end

    # Iterate through the packets and see if any represent the buffer
    target_packets.each do |packet_name, packet|
      if (packet.identify?(packet_data))
        identified_packet = packet.clone
        identified_packet.received_time  = nil
        identified_packet.received_count = 0
        identified_packet.buffer = packet_data
        break
      end
    end

    break if identified_packet
  end

  return identified_packet
end

#packet(target_name, packet_name) ⇒ Packet

Returns The command packet for the given target and packet name.

Parameters:

  • target_name (String)

    The target name

  • packet_name (String)

    The packet name. Must be a defined packet name and not 'LATEST'.

Returns:

  • (Packet)

    The command packet for the given target and packet name



61
62
63
64
65
66
# File 'lib/cosmos/packets/commands.rb', line 61

def packet(target_name, packet_name)
  target_packets = packets(target_name)
  packet = target_packets[packet_name.to_s.upcase]
  raise "Command packet '#{target_name.to_s.upcase} #{packet_name.to_s.upcase}' does not exist" unless packet
  packet
end

#packets(target_name) ⇒ Hash<packet_name=>Packet>

Returns Hash of the command packets for the given target name keyed by the packet name.

Parameters:

  • target_name (String)

    The target name

Returns:

  • (Hash<packet_name=>Packet>)

    Hash of the command packets for the given target name keyed by the packet name



51
52
53
54
55
# File 'lib/cosmos/packets/commands.rb', line 51

def packets(target_name)
  target_packets = @config.commands[target_name.to_s.upcase]
  raise "Command target '#{target_name.to_s.upcase}' does not exist" unless target_packets
  target_packets
end

#params(target_name, packet_name) ⇒ Array<PacketItem>

Returns The command parameters for the given target and packet name.

Parameters:

  • target_name (String)

    The target name

  • packet_name (String)

    The packet name. Must be a defined packet name and not 'LATEST'.

Returns:

  • (Array<PacketItem>)

    The command parameters for the given target and packet name



71
72
73
# File 'lib/cosmos/packets/commands.rb', line 71

def params(target_name, packet_name)
  return packet(target_name, packet_name).sorted_items
end

#target_namesArray<String>

Returns The command target names (excluding UNKNOWN).

Returns:

  • (Array<String>)

    The command target names (excluding UNKNOWN)



42
43
44
45
46
# File 'lib/cosmos/packets/commands.rb', line 42

def target_names
  result = @config.commands.keys.sort
  result.delete('UNKNOWN'.freeze)
  return result
end

#warningsArray<String>

Returns Array of strings listing all the warnings that were created while parsing the configuration file.

Returns:

  • (Array<String>)

    Array of strings listing all the warnings that were created while parsing the configuration file.



37
38
39
# File 'lib/cosmos/packets/commands.rb', line 37

def warnings
  return @config.warnings
end