class LIFX::LAN::TransportManager::LAN

Constants

DEFAULT_MESSAGE_RATE
DISCOVERY_INTERVAL
DISCOVERY_INTERVAL_WHEN_NO_SITES_FOUND
MESSAGE_RATE_1_2

Public Class Methods

new(bind_ip: '0.0.0.0', send_ip: Config.broadcast_ip, port: 56700) click to toggle source
Calls superclass method LIFX::LAN::TransportManager::Base::new
# File lib/lifx/lan/transport_manager/lan.rb, line 8
def initialize(bind_ip: '0.0.0.0', send_ip: Config.broadcast_ip, port: 56700)
  super
  @bind_ip   = bind_ip
  @send_ip   = send_ip
  @port      = port

  @sites = {}
  @threads = []
  @threads << initialize_timer_thread
  initialize_transport
  initialize_periodic_refresh
  initialize_message_rate_updater
end

Public Instance Methods

broadcast(message) click to toggle source
# File lib/lifx/lan/transport_manager/lan.rb, line 95
def broadcast(message)
  if !@transport.connected?
    create_broadcast_transport
  end
  @transport.write(message)
end
discover() click to toggle source
# File lib/lifx/lan/transport_manager/lan.rb, line 32
def discover
  stop_discovery
  @discovery_thread = Thread.start do
    @last_request_seen = Time.at(0)
    message = Message.new(path: ProtocolPath.new(tagged: true), payload: Protocol::Device::GetService.new)
    logger.info("Discovering gateways on #{@bind_ip}:#{@port}")
    loop do
      interval = @sites.empty? ?
        DISCOVERY_INTERVAL_WHEN_NO_SITES_FOUND :
        DISCOVERY_INTERVAL
      if Time.now - @last_request_seen > interval
        write(message)
      end
      sleep(interval / 2.0)
    end
  end
end
flush(**options) click to toggle source
# File lib/lifx/lan/transport_manager/lan.rb, line 22
def flush(**options)
  @sites.values.map do |site|
    Thread.start do
      site.flush(**options)
    end
  end.each(&:join)
end
gateway_connections() click to toggle source
# File lib/lifx/lan/transport_manager/lan.rb, line 110
def gateway_connections
  @sites.values.map(&:gateways).map(&:values).flatten
end
gateways() click to toggle source
# File lib/lifx/lan/transport_manager/lan.rb, line 106
def gateways
  @sites.values.map(&:gateways).map(&:keys).flatten.uniq.map { |id| context.lights.with_id(id) }.compact
end
message_rate() click to toggle source
# File lib/lifx/lan/transport_manager/lan.rb, line 114
def message_rate
  @message_rate || DEFAULT_MESSAGE_RATE
end
on_network?() click to toggle source
# File lib/lifx/lan/transport_manager/lan.rb, line 84
def on_network?
  if Socket.respond_to?(:getifaddrs) # Ruby 2.1+
    Socket.getifaddrs.any? { |ifaddr| ifaddr.broadaddr }
  else # Ruby 2.0
    Socket.ip_address_list.any? do |addrinfo|
      # Not entirely sure how to check if on a LAN with IPv6
      addrinfo.ipv4_private? || (addrinfo.respond_to?(:ipv6_unique_local?) && addrinfo.ipv6_unique_local?)
    end
  end
end
sites() click to toggle source
# File lib/lifx/lan/transport_manager/lan.rb, line 102
def sites
  @sites.dup
end
stop() click to toggle source
Calls superclass method LIFX::LAN::TransportManager::Base#stop
# File lib/lifx/lan/transport_manager/lan.rb, line 56
def stop
  super
  stop_discovery
  stop_timers
  @threads.each do |thr|
    thr.abort
  end
  @transport.close
  @sites.values.each do |site|
    site.stop
  end
end
stop_discovery() click to toggle source
# File lib/lifx/lan/transport_manager/lan.rb, line 50
def stop_discovery
  if @discovery_thread
    @discovery_thread.abort
  end
end
write(message) click to toggle source
# File lib/lifx/lan/transport_manager/lan.rb, line 69
def write(message)
  return unless on_network?
  if message.path.all_sites?
    broadcast(message)
  else
    site = @sites[message.path.site_id]
    if site
      site.write(message)
    else
      broadcast(message)
    end
  end
  @message_rate_timer.reset
end

Protected Instance Methods

create_broadcast_transport() click to toggle source
# File lib/lifx/lan/transport_manager/lan.rb, line 141
def create_broadcast_transport
  @transport = Transport::UDP.new(@send_ip, @port)
  @transport.add_observer(self, :message_received) do |message: nil, ip: nil, transport: nil|
    handle_broadcast_message(message, ip, @transport)
    notify_observers(:message_received, message: message, ip: ip, transport: transport)
  end
  @transport.listen(ip: @bind_ip)
end
handle_broadcast_message(message, ip, transport) click to toggle source
# File lib/lifx/lan/transport_manager/lan.rb, line 150
def handle_broadcast_message(message, ip, transport)
  return if message.nil?
  payload = message.payload
  case payload
  when Protocol::Device::StateService
    if !@sites.has_key?(message.path.site_id)
      @sites[message.path.site_id] = Site.new(id: message.path.site_id)
      @sites[message.path.site_id].add_observer(self, :message_received) do |**args|
        notify_observers(:message_received, **args)
      end
    end
    @sites[message.path.site_id].handle_message(message, ip, transport)
  when Protocol::Device::GetService
    @last_request_seen = Time.now
  end
end
initialize_message_rate_updater() click to toggle source
# File lib/lifx/lan/transport_manager/lan.rb, line 128
def initialize_message_rate_updater
  @message_rate_timer = timers.every(2) do
    @message_rate = MESSAGE_RATE_1_2
    gateway_connections.each do |connection|
      connection.set_message_rate(@message_rate)
    end
  end
end
initialize_periodic_refresh() click to toggle source
# File lib/lifx/lan/transport_manager/lan.rb, line 120
def initialize_periodic_refresh
  timers.every(10) do
    context.refresh(force: false)
  end
end
initialize_transport() click to toggle source
# File lib/lifx/lan/transport_manager/lan.rb, line 137
def initialize_transport
  create_broadcast_transport
end