plugins/slack_plugin.rb in ladder_drive-0.6.0 vs plugins/slack_plugin.rb in ladder_drive-0.6.1

- old
+ new

@@ -41,115 +41,141 @@ devices: M0-M2,M10 DOC require 'net/https' -def plugin_slack_init plc - @plugin_slack_config = load_plugin_config 'slack' - @plugin_slack_values = {} - @plugin_slack_times = {} - @plugin_slack_worker_queue = Queue.new +module LadderDrive +module Emulator - # collect comments - @plugin_slack_comments = {} - @plugin_slack_config[:device_comments].each do |k, v| - d = plc.device_by_name(k) - @plugin_slack_comments[d.name] = v if d - end if @plugin_slack_config[:device_comments] +class SlackPlugin < Plugin - Thread.start { - plugin_slack_worker_loop - } -end + def initialize plc + super #plc + return if disabled? -def plugin_slack_exec plc - return if @plugin_slack_config[:disable] + @values = {} + @times = {} + @worker_queue = Queue.new - @plugin_slack_config[:events].each do |event| - next unless event[:devices] - next unless event[:webhook_url] - begin + # collect comments + @comments = {} + config[:device_comments].each do |k, v| + d = plc.device_by_name(k) + @comments[d.name] = v if d + end if config[:device_comments] + setup + end - # gether values - devices = event[:devices].split(",").map{|e| e.split("-")}.map do |devs| - devs = devs.map{|d| plc.device_by_name d.strip} - d1 = devs.first - d2 = devs.last - d = d1 - [d2.number - d1.number + 1, 1].max.times.inject([]){|a, i| a << d1; d1 += 1; a} - end.flatten + def run_cycle plc + return if disabled? + return unless config[:events] - interval_triggered = false - now = Time.now - devices.each do |device| - triggered = false - v = nil - case event[:trigger][:type] - when "interval" - t = @plugin_slack_times[event.object_id] || now - triggered = t <= now - if triggered - interval_triggered = true - t += event[:trigger][:interval] || 300 - @plugin_slack_times[event.object_id] = t - end - v = device.send event[:value_type], event[:trigger][:text_length] || 8 - else - v = device.send event[:value_type], event[:text_length] || 8 - unless @plugin_slack_values[device.name] == v - @plugin_slack_values[device.name] = v - case event[:trigger][:type] - when "raise" - triggered = !!v - when "fall" - triggered = !v - else - triggered = true + config[:events].each do |event| + next unless event[:devices] + next unless event[:webhook_url] + begin + + # gether values + devices = event[:devices].split(",").map{|e| e.split("-")}.map do |devs| + devs = devs.map{|d| plc.device_by_name d.strip} + d1 = devs.first + d2 = devs.last + [d2.number - d1.number + 1, 1].max.times.inject([]){|a, i| a << d1; d1 += 1; a} + end.flatten + + interval_triggered = false + now = Time.now + devices.each do |device| + triggered = false + v = nil + case event[:trigger][:type] + when "interval" + t = @times[event.object_id] || now + triggered = t <= now + if triggered + interval_triggered = true + t += event[:trigger][:interval] || 300 + @times[event.object_id] = t end + v = device.send event[:value_type], event[:trigger][:text_length] || 8 + else + v = device.send event[:value_type], event[:text_length] || 8 + unless @values[device.name] == v + @values[device.name] = v + case event[:trigger][:type] + when "raise" + triggered = !!v + when "fall" + triggered = !v + else + triggered = true + end + end end - end - next unless triggered || interval_triggered + next unless triggered || interval_triggered - @plugin_slack_worker_queue.push event:event, - device_name:device.name, - value:v, - time: now + @worker_queue.push event:event, + device_name:device.name, + value:v, + time: now + end + rescue => e + p e end - rescue => e - p e end - end if @plugin_slack_config[:events] -end + end -def plugin_slack_worker_loop - while arg = @plugin_slack_worker_queue.pop - begin - event = arg[:event] - uri = URI.parse(event[:webhook_url]) - http = Net::HTTP.new(uri.host, uri.port) - http.use_ssl = true - http.verify_mode = OpenSSL::SSL::VERIFY_NONE + private - req = Net::HTTP::Post.new(uri.path) - req["Content-Type"] = "application/json" + def setup + Thread.start { + thread_proc + } + end - format = event[:format] || "__comment__ occured at __time__" - format = arg[:value] ? format[:raise] : format[:fall] unless format.is_a? String + def thread_proc + while arg = @worker_queue.pop + begin + event = arg[:event] + uri = URI.parse(event[:webhook_url]) + http = Net::HTTP.new(uri.host, uri.port) + http.use_ssl = true + http.verify_mode = OpenSSL::SSL::VERIFY_NONE - device_name = arg[:device_name] - comment = @plugin_slack_comments[device_name] || device_name - value = arg[:value].to_s - time = arg[:time].iso8601 + req = Net::HTTP::Post.new(uri.path) + req["Content-Type"] = "application/json" - payload = {text:format.gsub(/__device_comment__/, comment).gsub(/__value__/, value).gsub(/__time__/, time).gsub(/__device_name__/, device_name) - } - req.body = payload.to_json + format = event[:format] || "__comment__ occured at __time__" + format = arg[:value] ? format[:raise] : format[:fall] unless format.is_a? String - http.request(req) - rescue => e - # TODO: Resend if it fails. - p e + device_name = arg[:device_name] + comment = @comments[device_name] || device_name + value = arg[:value].to_s + time = arg[:time].iso8601 + + payload = {text:format.gsub(/__device_comment__/, comment).gsub(/__value__/, value).gsub(/__time__/, time).gsub(/__device_name__/, device_name) + } + req.body = payload.to_json + + http.request(req) + rescue => e + # TODO: Resend if it fails. + p e + end + end end - end + +end + +end +end + + +def plugin_slack_init plc + @slack_plugin = LadderDrive::Emulator::SlackPlugin.new plc +end + +def plugin_slack_exec plc + @slack_plugin.run_cycle plc end