# encoding: ascii-8bit # Copyright 2022 Ball Aerospace & Technologies Corp. # All Rights Reserved. # # This program is free software; you can modify and/or redistribute it # under the terms of the GNU Affero General Public License # as published by the Free Software Foundation; version 3 with # attribution addendums as found in the LICENSE.txt # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # This program may also be used under the terms of a commercial or # enterprise edition license of COSMOS if purchased from the # copyright holder require 'cosmos' require 'json' require 'cosmos/config/config_parser' module Cosmos class JsonPacket attr_accessor :cmd_or_tlm attr_accessor :target_name attr_accessor :packet_name attr_accessor :packet_time attr_accessor :stored attr_accessor :json_hash def initialize(cmd_or_tlm, target_name, packet_name, time_nsec_from_epoch, stored, json_data) @cmd_or_tlm = cmd_or_tlm.intern @target_name = target_name @packet_name = packet_name @packet_time = ::Time.from_nsec_from_epoch(time_nsec_from_epoch) @stored = ConfigParser.handle_true_false(stored) @json_hash = JSON.parse(json_data) end # Read an item in the packet by name # # @param name [String] Name of the item to read - Should already by upcase # @param value_type (see #read_item) def read(name, value_type = :CONVERTED) if value_type == :WITH_UNITS value = @json_hash["#{name}__U"] return value if value end if value_type == :WITH_UNITS or value_type == :FORMATTED value = @json_hash["#{name}__F"] return value if value value = @json_hash["#{name}__C"] return value.to_s if value value = @json_hash[name] return value.to_s if value return nil end if value_type == :CONVERTED value = @json_hash["#{name}__C"] return value if value end value = @json_hash[name] return value if value end def read_with_limits_state(name, value_type = :CONVERTED) value = read(name, value_type) limits_state = @json_hash["#{name}__L"] limits_state.intern if limits_state return [value, limits_state] end # Read all items in the packet into an array of arrays # [[item name, item value], ...] # # @param value_type (see #read_item) def read_all(value_type = :CONVERTED, names = nil) result = {} names = read_all_names() unless names names.each do |name| result[name] = read(name, value_type) end return result end # Read all items in the packet into an array of arrays # [[item name, item value], [item limits state], ...] # # @param value_type (see #read_all) def read_all_with_limits_states(value_type = :CONVERTED, names = nil) result = {} names = read_all_names() unless names names.each do |name| result[name] = read_with_limits_state(name, value_type) end return result end # Read all the names of items in the packet # Note: This is not very efficient, ideally only call once for discovery purposes def read_all_names result = {} @json_hash.each do |key, value| result[key.split("__")[0]] = true end return result.keys end # Create a string that shows the name and value of each item in the packet # # @param value_type (see #read_item) # @param indent (see Structure#formatted) def formatted(value_type = :CONVERTED, names = nil, indent = 0) names = read_all_names() unless names indent_string = ' ' * indent string = '' names.each do |name| value = read(name, value_type) if String === value and value =~ File::NON_ASCII_PRINTABLE string << "#{indent_string}#{name}:\n" string << value.formatted(1, 16, ' ', indent + 2) else string << "#{indent_string}#{name}: #{value}\n" end end return string end end end