#!/usr/bin/env ruby # # huec - Philips (friends of) hue command-line utility # # Hued is Copyright © 2011 Paul van Tilburg # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 2 of the License, or (at your # option) any later version. require "hued/version" require "huey" require "logger" require "optparse" require "pp" require "pry" require "rainbow" include Huey def status_line(blb) mode = [] if blb.reachable on_off = blb.on ? Rainbow("on").bright.green : Rainbow("off").red case blb.colormode when "xy" mode << "xy: #{blb.xy.inspect}" when "hs" mode << "hue: #{blb.hue}" << "sat: #{blb.sat}" when "ct" mode << "ct: #{blb.ct}" end mode << "bri: #{blb.bri}" else on_off = Rainbow("unreachable").bright.red end line = "%2d: %-30s (%-12s" % [blb.id, blb.name, on_off, mode] if mode.empty? line += ")" else line += ", #{mode.join(', ')})" end return line end def prompt_status Huey::Bulb.all.map do |blb| if blb.reachable blb.on ? Rainbow("o").bright.green : Rainbow("o").red else Rainbow("x").bright.red end end.join end def lights Huey::Bulb.all.each do |blb| puts status_line(blb) end true end def groups Huey::Group.all.each do |grp| puts "#{grp.id}: #{grp.name} (#{grp.bulbs.map(&:id).join(', ')})" end true end def events events_cfg = File.join(@options[:config_dir], "events.yml") Huey::Event.import(events_cfg).each_with_index do |ev, idx| puts "#{idx + 1}: #{ev.name}" end true end def scenes @scenes = {} scenes_cfg = File.join(@options[:config_dir], "scenes.yml") YAML.load_file(scenes_cfg).each_with_index do |(name, entry), idx| puts "#{idx + 1}: #{name}" @scenes[name] = entry.map do |ev_options| # Keys should be symbols options = ev_options.inject({}) { |opts, (k, v)| opts[k.to_sym] = v; opts } event = Huey::Event.new(options) event.actions["on"] = true if event.actions["on"].nil? event end end true end def refresh! Huey::Bulb.all.each do |blb| blb.reload puts status_line(blb) end true end def get(*names_or_ids) names_or_ids.map do |name_or_id| blb = Huey::Bulb.find(name_or_id) puts status_line(blb) true end end def set(*names_or_ids, opts) blb = nil names_or_ids.map do |name_or_id| blb = Huey::Bulb.find(name_or_id) blb.update(opts) end rescue Huey::Errors::BulbOff blb.update(on: true) retry rescue Huey::Errors::Error => e puts "Error: #{e.message}" end def getgrp(*names_or_ids) names_or_ids.map do |name_or_id| Huey::Group.find(name_or_id).each do |blb| puts status_line(blb) end true end end def setgrp(*names_or_ids, opts) names_or_ids.map do |name_or_id| grp = Huey::Group.find(name_or_id) grp.update(opts) end end def event(name_or_id) ev = case name_or_id when Fixnum Huey::Event.all[name_or_id - 1] when String Huey::Event.find(name_or_id) end ev.execute end def scene(name_or_id) sc = case name_or_id when Fixnum @scenes.values[name_or_id - 1] when String @scenes[name_or_id] end sc.map { |ev| ev.execute } end def alert(*names_or_ids) names_or_ids.map do |name_or_id| blb = Huey::Bulb.find(name_or_id) blb.alert! end end def off(*names_or_ids) set(*names_or_ids, on: false) end def on(*names_or_ids) set(*names_or_ids, on: true) end def commands puts < "config"} opt_parser = OptionParser.new do |opts| opts.banner = "Usage: huec [options]" opts.separator "" opts.on("-c", "--config-dir [CONFDIR] ", "set an alternative configuration directory") do |cd| @options[:config_dir] = cd end opts.on("--hue-debug", "log hue bridge communication output") do @options[:hue_debug] = true end opts.on_tail("-h", "--help", "show this help message") do puts opts exit end opts.on_tail("-v", "--version", "show version") do puts "Hued version #{Hued::VERSION}" exit end end begin opt_parser.parse! rescue OptionParser::InvalidOption => e warn e.message abort opt_parser.to_s end puts "Starting huec #{Hued::VERSION}..." bridge_cfg = YAML.load_file(File.join(@options[:config_dir], "bridge.yml")) Huey.configure do |cfg| cfg.hue_ip = bridge_cfg["ip"] cfg.uuid = bridge_cfg["user"] end Huey.logger.level = @options[:hue_debug] ? Logger::DEBUG : Logger::FATAL puts "Configured bridge connection" puts "Discovering lights..." lights puts puts "Discovering groups..." groups puts puts "Loading events..." events puts puts "Loading scenes..." scenes puts puts "All done!" puts "Use 'commands' to see a list of additional commands to pry's." puts Pry.config.prompt = proc { "#{prompt_status}> " } binding.pry(quiet: true)