Class: OpenC3::Commands
- Includes:
- CmdLog
- Defined in:
- lib/openc3/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 primitives where the PacketConfig 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
-
#config ⇒ Object
Returns the value of attribute config.
Instance Method Summary collapse
- #all ⇒ Object
-
#build_cmd(target_name, packet_name, params = {}, range_checking = true, raw = false, check_required_params = true) ⇒ Object
Returns a copy of the specified command packet with the parameters initialized to the given params values.
- #build_cmd_output_string(target_name, cmd_name, cmd_params, raw = false, packet) ⇒ Object
-
#cmd_hazardous?(target_name, packet_name, params = {}) ⇒ Boolean
Returns whether the given command is hazardous.
-
#cmd_pkt_hazardous?(command) ⇒ Boolean
Returns whether the given command is hazardous.
- #cmd_subpacket_unique_id_mode(target_name) ⇒ Object
- #cmd_unique_id_mode(target_name) ⇒ Object
- #dynamic_add_packet(packet, affect_ids: false) ⇒ Object
-
#format(packet, ignored_parameters = []) ⇒ Object
Formatted version of a command.
-
#identify(packet_data, target_names = nil, subpackets: false) ⇒ Object
Identifies an unknown buffer of data as a defined command and sets the commands’s data to the given buffer.
-
#initialize(config) ⇒ Commands
constructor
A new instance of Commands.
-
#packet(target_name, packet_name) ⇒ Packet
The command packet for the given target and packet name.
-
#packets(target_name) ⇒ Hash<packet_name=>Packet>
Hash of the command packets for the given target name keyed by the packet name.
-
#params(target_name, packet_name) ⇒ Array<PacketItem>
The command parameters for the given target and packet name.
-
#target_names ⇒ Array<String>
The command target names (excluding UNKNOWN).
-
#warnings ⇒ Array<String>
Array of strings listing all the warnings that were created while parsing the configuration file.
Methods included from CmdLog
Constructor Details
#initialize(config) ⇒ Commands
Returns a new instance of Commands.
43 44 45 |
# File 'lib/openc3/packets/commands.rb', line 43 def initialize(config) @config = config end |
Instance Attribute Details
#config ⇒ Object
Returns the value of attribute config.
37 38 39 |
# File 'lib/openc3/packets/commands.rb', line 37 def config @config end |
Instance Method Details
#all ⇒ Object
278 279 280 |
# File 'lib/openc3/packets/commands.rb', line 278 def all @config.commands end |
#build_cmd(target_name, packet_name, params = {}, range_checking = true, raw = false, check_required_params = true) ⇒ Object
Returns a copy of the specified command packet with the parameters initialized to the given params values.
Note: this method does not increment received_count and it should be incremented externally if needed.
184 185 186 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 |
# File 'lib/openc3/packets/commands.rb', line 184 def build_cmd(target_name, packet_name, params = {}, range_checking = true, raw = false, check_required_params = true) target_upcase = target_name.to_s.upcase packet_upcase = packet_name.to_s.upcase # Lookup the command directly - avoid redundant upcase in packet()/packets() target_packets = @config.commands[target_upcase] raise "Command target '#{target_upcase}' does not exist" unless target_packets pkt = target_packets[packet_upcase] raise "Command packet '#{target_upcase} #{packet_upcase}' does not exist" unless pkt # Use deep_copy to avoid shared item modifications affecting the template # This is critical for variable_bit_size items where handle_write_variable_bit_size # modifies item.bit_offset and item.array_size during writes command = pkt.deep_copy # Restore the command's buffer to a zeroed string of defined length # This will undo any side effects from earlier commands that may have altered the size # of the buffer command.buffer = "\x00" * command.defined_length # Set time, parameters, and restore defaults command.received_time = Time.now.sys command.stored = false command.extra = nil command.given_values = params command.restore_defaults(command.buffer(false), params.keys) command.raw = raw given_item_names = set_parameters(command, params, range_checking) check_required_params(command, given_item_names) if check_required_params return command end |
#build_cmd_output_string(target_name, cmd_name, cmd_params, raw = false, packet) ⇒ Object
230 231 232 233 234 235 236 237 |
# File 'lib/openc3/packets/commands.rb', line 230 def build_cmd_output_string(target_name, cmd_name, cmd_params, raw = false, packet) method_name = raw ? "cmd_raw" : "cmd" target_name = 'UNKNOWN' unless target_name cmd_name = 'UNKNOWN' unless cmd_name packet_hash = packet ? packet.as_json : {} _build_cmd_output_string(method_name, target_name, cmd_name, cmd_params, packet_hash) 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.
272 273 274 275 276 |
# File 'lib/openc3/packets/commands.rb', line 272 def cmd_hazardous?(target_name, packet_name, params = {}) # Build a command without range checking, perform conversions, and don't # check required parameters since we're not actually using the command. cmd_pkt_hazardous?(build_cmd(target_name, packet_name, params, false, false, false)) end |
#cmd_pkt_hazardous?(command) ⇒ 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.
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
# File 'lib/openc3/packets/commands.rb', line 245 def cmd_pkt_hazardous?(command) return [true, command.hazardous_description] if command.hazardous # 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 |
#cmd_subpacket_unique_id_mode(target_name) ⇒ Object
290 291 292 |
# File 'lib/openc3/packets/commands.rb', line 290 def cmd_subpacket_unique_id_mode(target_name) return @config.cmd_subpacket_unique_id_mode[target_name.upcase] end |
#cmd_unique_id_mode(target_name) ⇒ Object
286 287 288 |
# File 'lib/openc3/packets/commands.rb', line 286 def cmd_unique_id_mode(target_name) return @config.cmd_unique_id_mode[target_name.upcase] end |
#dynamic_add_packet(packet, affect_ids: false) ⇒ Object
282 283 284 |
# File 'lib/openc3/packets/commands.rb', line 282 def dynamic_add_packet(packet, affect_ids: false) @config.dynamic_add_packet(packet, :COMMAND, affect_ids: affect_ids) end |
#format(packet, ignored_parameters = []) ⇒ Object
Formatted version of a command
218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/openc3/packets/commands.rb', line 218 def format(packet, ignored_parameters = []) if packet.raw items = packet.read_all(:RAW) raw = true else items = packet.read_all(:FORMATTED) raw = false end items.delete_if { |item_name, _item_value| ignored_parameters.include?(item_name) } return build_cmd_output_string(packet.target_name, packet.packet_name, items, raw, packet) end |
#identify(packet_data, target_names = nil, subpackets: false) ⇒ 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.
Note: this method does not increment received_count and it should be incremented externally if needed.
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 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 |
# File 'lib/openc3/packets/commands.rb', line 103 def identify(packet_data, target_names = nil, subpackets: false) identified_packet = nil target_names = target_names() unless target_names target_names.each do |target_name| target_name = target_name.to_s.upcase target_packets = nil begin target_packets = packets(target_name) rescue RuntimeError # No commands for this target next end if (not subpackets and System.commands.cmd_unique_id_mode(target_name)) or (subpackets and System.commands.cmd_subpacket_unique_id_mode(target_name)) # Iterate through the packets and see if any represent the buffer target_packets.each do |_packet_name, packet| if subpackets next unless packet.subpacket else next if packet.subpacket end if packet.identify?(packet_data) # Handles virtual identified_packet = packet break end end else # Do a hash lookup to quickly identify the packet packet = nil target_packets.each do |_packet_name, target_packet| next if target_packet.virtual if subpackets next unless target_packet.subpacket else next if target_packet.subpacket end packet = target_packet break end if packet key = packet.read_id_values(packet_data) if subpackets hash = @config.cmd_subpacket_id_value_hash[target_name] else hash = @config.cmd_id_value_hash[target_name] end identified_packet = hash[key] identified_packet = hash['CATCHALL'.freeze] unless identified_packet end end if identified_packet identified_packet = identified_packet.clone identified_packet.received_time = nil identified_packet.stored = false identified_packet.extra = nil identified_packet.buffer = packet_data break end end return identified_packet end |
#packet(target_name, packet_name) ⇒ Packet
Returns The command packet for the given target and packet name.
73 74 75 76 77 78 79 |
# File 'lib/openc3/packets/commands.rb', line 73 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.
62 63 64 65 66 67 |
# File 'lib/openc3/packets/commands.rb', line 62 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.
84 85 86 |
# File 'lib/openc3/packets/commands.rb', line 84 def params(target_name, packet_name) return packet(target_name, packet_name).sorted_items end |