Implement events/scenes/rules reloading

* Store change time when loading
* On reload, check if a file exists and whether it is newer
* Fail if the rules file cannot be loaded
* Reload the rules file if the events/scenes file has been reloaded
  (This is needed because rules might depend on new or updated
  events/scenes)
This commit is contained in:
Paul van Tilburg 2014-11-15 22:22:04 +01:00
parent ee95693976
commit 24c95f417a
1 changed files with 75 additions and 27 deletions

102
hued
View File

@ -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