#!/usr/bin/env ruby require "gli" require "lifx_dash" include GLI::App LOGGER = Logger.new(STDOUT) CONFIG = LifxDash::Configuration.new program_desc "Toggle LIFX lights with an Amazon Dash button" version LifxDash::VERSION subcommand_option_handling :normal arguments :strict desc "Set (and persist) default options for commands" long_desc "Use config to set default values for the command options, these will be saved to: ~/.lifx_dash.rc.yml and used as defaults. They can still be overridden with any arguments passed on the command line." skips_pre command :config do |c| c.desc "Show the config file" c.switch [:s, :show] c.action do |_global_options, options, _args| if options["show"] CONFIG.show else CONFIG.configure end end end desc "Listen for Dash button presses on the network and show packet information" long_desc "Monitor the sepcified network interface for any Dash button ARP packets and log the device MAC address to stdout. Wait for the network to quiet down, before pressing the button, since other devices may respond with ARP packets of their own when you press. Take care to choose the MAC address from the ARP packet that occurs only once from a single MAC address." command :snoop do |c| c.desc "Network Interface" c.default_value CONFIG["iface"] || "en0" c.flag [:i, :iface] c.action do |_global_options, options, _args| LifxDash::Snoop.new(options["iface"]).run end end desc "Listen for a Dash button press, and the toggle selected lights" long_desc "Monitor the sepcified network interface, filtered by a Dash button MAC address. If a valid ARP packet is detected, the LIFX lights (identified by the selector) will be toggled using the LIFX HTTP API (v1). You can optionally pass a LIFX bulb selector (the bulb ID), or choose to daemonize the `monitor` process. You can get a free LIFX API token from here: https://cloud.lifx.com/settings If running as a daemon (-d switch), this command will log to: #{LifxDash::Daemonizer::LOG_FILE} by default. Use the --log-file flag to overrride this location." command :monitor do |c| c.desc "Dash button MAC address" c.default_value CONFIG["mac-address"] c.flag [:m, :"mac-address"] c.desc "LIFX HTTP API Token" c.default_value CONFIG["token"] c.flag [:t, :token] c.desc "LIFX Bulb Selector" c.default_value CONFIG["selector"] || "all" c.flag [:s, :selector] c.desc "Network Interface" c.default_value CONFIG["iface"] || "en0" c.flag [:i, :iface] c.desc "Log file location (when running as a daemon)" c.default_value CONFIG["log-file"] || LifxDash::Daemonizer::LOG_FILE c.flag [:l, :"log-file"] c.desc "Dameonize the monitor process" c.switch [:d, :daemonize] c.action do |_global_options, options, _args| help_now!("a valid Dash button MAC address option (-m) is required: use `lifx_dash snoop -i #{options["iface"]}` to find it") unless options["mac-address"] help_now!("a valid LIFX API Token option (-t) is required: get one from https://cloud.lifx.com/settings") unless options["token"] if options["daemonize"] LifxDash::Daemonizer.start(options["log-file"]) end LifxDash::Monitor.new( iface: options["iface"], token: options["token"], mac: options["mac-address"], selector: options["selector"] ).run end end pre do |_global_options, _command, options, _args| # check user has root access for packet sniffing if Process.euid.zero? true else help_now!("sudo required: you must be a root user to capture packets on #{options["iface"]}") end end exit run(ARGV)