diff --git a/hued b/hued index 6e84845..5ee6668 100755 --- a/hued +++ b/hued @@ -150,6 +150,9 @@ class Hued def initialize(options = {}) @options = options + @ctime = Hash.new(Time.now) + + # Set up the logger @log = Logger.new($stdout) @log.progname = "hued" @log.level = options[:debug] ? Logger::DEBUG : Logger::INFO @@ -204,37 +207,41 @@ class Hued end def load - @log.info "Loading events..." - @events = Huey::Event.import("events.yml") - @events.each do |event| - event.actions["on"] = true if event.actions["on"].nil? - @log.info "* Loaded event: #{event.name}" - end - @log.info "Loaded #{@events.count} event#{"s" unless @events.count == 1}" - - @log.info "Loading scenes..." - @scenes = {} - YAML.load_file("scenes.yml").each do |name, entry| - @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 + [:events, :scenes].each do |items| + if File.exist? "#{items}.yml" + @log.info "Loading #{items}..." + send("load_#{items}") end - Scenes[name] = @scenes[name] - @log.info "* Loaded scene: #{name}" end - @log.info "Loaded #{@scenes.count} scene#{"s" unless @scenes.count == 1}" - @log.info "Loading rules" - @rules = YAML.load_file("rules.yml").map do |name, entry| - Rule.new(name, @log, entry) - end - @rules.each do |rule| - @log.info "* Loaded rule: #{rule.name}" + # Treat rules separately, we cannot start without it + if File.exist? "rules.yml" + @log.info "Loading rules" + load_rules + else + @log.error "Cannot find required file: rules.yml, aborting!" + exit 1 + end + end + + def reload + @log.debug "Checking if events/scenes/rules need to be reloaded..." + @reload_rules = false + [:events, :scenes].each do |items| + if File.exist?("#{items}.yml") and + File.ctime("#{items}.yml") > @ctime[items] + @log.info "Reloading events..." + send("load_#{items}") + # Rules may depend on events/scenes, reload the rules too! + @reload_rules = true + end + end + + if File.exist?("rules.yml") and + (@reload_rules or File.ctime("rules.yml") > @ctime[:rules]) + @log.info "Reloading rules..." + send("load_rules") end - @log.info "Loaded #{@rules.count} rule#{"s" unless @rules.count == 1}" end def execute @@ -277,6 +284,47 @@ class Hued @log.info "Shutting down..." end + ####### + private + + def load_events + @ctime[:events] = File.ctime("events.yml") + @events = Huey::Event.import("events.yml") + @events.each do |event| + event.actions["on"] = true if event.actions["on"].nil? + @log.info "* Loaded event: #{event.name}" + end + @log.info "Loaded #{@events.count} event#{"s" unless @events.count == 1}" + end + + def load_scenes + @ctime[:scenes] = File.ctime "scenes.yml" + @scenes = {} + YAML.load_file("scenes.yml").each do |name, entry| + @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 + Scenes[name] = @scenes[name] + @log.info "* Loaded scene: #{name}" + end + @log.info "Loaded #{@scenes.count} scene#{"s" unless @scenes.count == 1}" + end + + def load_rules + @ctime[:rules] = File.ctime "rules.yml" + @rules = YAML.load_file("rules.yml").map do |name, entry| + Rule.new(name, @log, entry) + end + @rules.each do |rule| + @log.info "* Loaded rule: #{rule.name}" + end + @log.info "Loaded #{@rules.count} rule#{"s" unless @rules.count == 1}" + end + end # class Hued # Option parsing