# # Copyright (c) 201 ITO SOFT DESIGN Inc. # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. dir = Dir.pwd $:.unshift dir unless $:.include? dir require 'active_support' require 'active_support/core_ext' require 'erb' require 'plugin_trigger_state' module PlcPlugins #def self.included(klass) # load_plugins #end private def plugins @plugins ||= [] end def load_plugins return unless plugins.empty? seen = {} Dir.glob("plugins/*_plugin.rb").each do |plugin_path| name = File.basename plugin_path, "_plugin.rb" next if seen[name] seen[name] = true require plugin_path.gsub(/\.rb$/, "") plugins << name end init_plugins end def init_plugins send_message_plugins "init", self end def exec_plugins send_message_plugins "exec", self end def send_message_plugins method, arg plugins.each do |plugin| msg = "plugin_#{plugin}_#{method}" unless arg send msg if Object.respond_to?(msg, true) else send msg, arg if Object.respond_to?(msg, true) end end end end module LadderDrive module Emulator class Plugin attr_reader :plc attr_reader :config class << self def devices_with_plc_from_str plc, dev_str dev_str.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 end def device_names_with_plc_from_str plc, dev_str devices_with_plc_from_str.map{|d| d.name} end end def devices_with_plc_from_str plc, dev_str self.class.devices_with_plc_from_str plc, dev_str end def device_names_with_plc_from_str plc, dev_str self.class.device_names_with_plc_from_str plc, dev_str end def initialize plc @config = load_config @plc = plc @device_states = {} @trigger_states = {} end def name @name ||= self.class.name.split(":").last.underscore.scan(/(.*)_plugin$/).first.first end def disabled? config.empty? || config[:disable] end def run_cycle plc return false unless self.plc == plc end def triggered? trigger_config state = trigger_state_for trigger_config state.reset state.update state.triggered? end def trigger_state_for trigger_config @trigger_states[trigger_config.object_id] ||= PluginTriggerState.new(plc, trigger_config) end private def load_config h = {} path = File.join("config", "plugins", "#{name}.yml") if File.exist?(path) erb = ERB.new File.read(path) h = YAML.load(erb.result(binding)) h = JSON.parse(h.to_json, symbolize_names: true) end h end end end end