class LIFX::LAN::Message

@api private

Constants

PROTOCOL_VERSION

Attributes

path[RW]
payload[RW]

Public Class Methods

message_type_for_id(type_id) click to toggle source
# File lib/lifx/lan/message.rb, line 64
def message_type_for_id(type_id)
  Protocol::TYPE_ID_TO_CLASS[type_id]
end
new(*args) click to toggle source
# File lib/lifx/lan/message.rb, line 93
def initialize(*args)
  if args.count == 3
    @path, @message, @payload = args
  elsif (hash = args.first).is_a?(Hash)
    path = hash.delete(:path) || ProtocolPath.new
    payload = hash.delete(:payload)

    check_valid_fields!(hash)

    @message = Protocol::Message.new(hash)
    self.payload = payload
    self.path = path
    @message.tagged = path.tagged? if path
  else
    @message = Protocol::Message.new
  end
  @message.msg_size = @message.num_bytes
  @message.protocol = PROTOCOL_VERSION
rescue => ex
  raise MessageError.new("Unable to initialize message with args: #{args.inspect} - #{ex}")
end
type_id_for_message_class(klass) click to toggle source
# File lib/lifx/lan/message.rb, line 68
def type_id_for_message_class(klass)
  Protocol::CLASS_TO_TYPE_ID[klass]
end
unpack(data) click to toggle source
# File lib/lifx/lan/message.rb, line 25
def unpack(data)
  raise InvalidFrame if data.length < 2

  header = Protocol::Header.read(data)
  raise UnsupportedProtocolVersion.new("Expected #{PROTOCOL_VERSION} but got #{header.protocol} instead") if header.protocol != PROTOCOL_VERSION
  raise NotAddressableFrame if header.addressable == 0

  message = Protocol::Message.read(data)
  path = ProtocolPath.new(raw_site: message.raw_site, raw_target: message.raw_target, tagged: message.tagged)
  payload_class = message_type_for_id(message.type_.snapshot)
  if payload_class.nil?
    if Config.log_invalid_messages
      logger.error("Message.unpack: Unrecognised payload ID: #{message.type_}")
      logger.error("Message.unpack: Message: #{message}")
    end
    return nil # FIXME
    raise UnmappedPayload.new("Unrecognised payload ID: #{message.type_}")
  end
  begin
    payload = payload_class.read(message.payload)
  rescue => ex
    if message.raw_site == "\x00" * 6
      logger.info("Message.unpack: Ignoring malformed message from virgin bulb")
    else
      if Config.log_invalid_messages
        logger.error("Message.unpack: Exception while unpacking payload of type #{payload_class}: #{ex}")
        logger.error("Message.unpack: Data: #{data.inspect}")
      end
    end
  end
  new(path, message, payload)
rescue => ex
  if Config.log_invalid_messages
    logger.debug("Message.unpack: Exception while unpacking #{data.inspect}")
    logger.debug("Message.unpack: #{ex} - #{ex.backtrace.join("\n")}")
  end
  raise ex
end
valid_fields() click to toggle source
# File lib/lifx/lan/message.rb, line 72
def valid_fields
  @valid_fields ||= Protocol::Message.new.field_names.map(&:to_sym)
end

Public Instance Methods

inspect()
Alias for: to_s
pack() click to toggle source
# File lib/lifx/lan/message.rb, line 125
def pack
  raise NoPayload if !payload
  @message.raw_site = path.raw_site
  @message.raw_target = path.raw_target
  @message.tagged = path.tagged?
  @message.msg_size = @message.num_bytes
  @message.pack
end
payload=(payload) click to toggle source
# File lib/lifx/lan/message.rb, line 115
def payload=(payload)
  @payload = payload
  type_id = self.class.type_id_for_message_class(payload.class)
  if type_id.nil?
    raise UnmappedPayload.new("Unmapped payload class #{payload.class}")
  end
  @message.type_ = type_id
  @message.payload = payload.pack
end
to_hex() click to toggle source
# File lib/lifx/lan/message.rb, line 152
def to_hex
  pack.each_byte.map { |b| b.to_s(16).rjust(2, '0') }.join
end
to_s() click to toggle source
# File lib/lifx/lan/message.rb, line 134
def to_s
  hash = {site: path.site_id}
  if path.tagged?
    hash[:tags] = path.tag_ids
    hash[:tags] = 'all' if hash[:tags].empty?
  else
    hash[:device] = path.device_id
  end
  hash[:type_] = payload.class.to_s.sub('LIFX::Protocol::', '')
  hash[:addressable] = addressable? ? 'true' : 'false'
  hash[:tagged] = path.tagged? ? 'true' : 'false'
  hash[:at_time] = @message.at_time if @message.at_time && @message.at_time > 0
  hash[:protocol] = protocol
  hash[:payload] = payload.snapshot if payload
  attrs = hash.map { |k, v| "#{k}=#{v}" }.join(' ')
  %Q{#<LIFX::LAN::Message #{attrs}>}
end
Also aliased as: inspect

Protected Instance Methods

check_valid_fields!(hash) click to toggle source
# File lib/lifx/lan/message.rb, line 160
def check_valid_fields!(hash)
  invalid_fields = hash.keys - self.class.valid_fields
  if invalid_fields.count > 0
    raise InvalidFields.new("Invalid fields for Message: #{invalid_fields.join(', ')}")
  end
end