Module: AutomateEm

Defined in:
lib/automate-em/core/communicator.rb,
lib/automate-em.rb,
lib/automate-em/engine.rb,
lib/automate-em/status.rb,
lib/automate-em/version.rb,
lib/automate-em/constants.rb,
lib/automate-em/utilities.rb,
lib/automate-em/core/system.rb,
lib/automate-em/logic/logic.rb,
lib/automate-em/module_core.rb,
lib/automate-em/core/modules.rb,
lib/automate-em/device/device.rb,
lib/automate-em/service/service.rb,
lib/automate-em/interfaces/html5.rb,
lib/automate-em/core/resolver_pool.rb,
lib/automate-em/device/tcp_control.rb,
lib/automate-em/service/http_service.rb,
lib/automate-em/device/datagram_server.rb,
lib/automate-em/device/device_connection.rb

Overview

This contains the basic constructs required for serialised comms over TCP and UDP

Defined Under Namespace

Modules: Constants, DatagramServer, DeviceConnection, ModuleCore, Status, Utilities Classes: Communicator, DatagramBase, Device, DeviceModule, Engine, HttpService, JobProxy, Logic, LogicModule, Modules, ResolverJob, ResolverPool, ScheduleProxy, Service, ServiceModule, System

Constant Summary collapse

VERSION =
"0.0.4"

Class Method Summary collapse

Class Method Details

.bootObject



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/automate-em.rb', line 91

def self.boot
  
  #
  # System level logger
  #
  if Rails.env.production?
    System.logger = Logger.new(Rails.root.join('log/system.log').to_s, 10, 4194304)
  else
    System.logger = Logger.new(STDOUT)
  end
  System.logger.formatter = proc { |severity, datetime, progname, msg|
    "#{datetime.strftime("%d/%m/%Y @ %I:%M%p")} #{severity}: #{System} - #{msg}\n"
  }
  
  @@resolver = ResolverPool.new
  
  EventMachine.run do
    #
    # Enable the scheduling system
    #
    @@scheduler = Rufus::Scheduler.start_new
    
    EM.defer do
      System.logger.debug "Started with #{EM.get_max_timers} timers avaliable"
      System.logger.debug "Started with #{EM.threadpool_size} threads in pool"
    end
    
    #
    # Start the UDP server
    #
    EM.open_datagram_socket "0.0.0.0", Rails.configuration.automate.datagram_port, DatagramServer
    
    #
    # Load the system based on the database
    #
    ControlSystem.update_all(:active => false)
    ControlSystem.find_each do |controller|
      EM.defer do
        begin
          System.logger.debug "Booting #{controller.name}"
          result = System.start(controller, Rails.configuration.automate.log_level)
          if result == false
            #
            # TODO:: we need a class for handling failed starts
            #
            AutomateEm.print_error(AutomateEm::System.logger, e, {
              :message => "System #{controller.name} failed to start (gracefully). It is now offline",
              :level => Logger::WARN
            })
            controller.active = false
            controller.save
            @@scheduler.in '5m' do
              System.start(controller, Rails.configuration.automate.log_level)
            end
          end
        rescue => e
          AutomateEm.print_error(AutomateEm::System.logger, e, {
            :message => "System #{controller.name} threw an error whilst starting. It is now offline",
            :level => Logger::WARN
          })
          #
          # Mark as offline, do not retry and email
          #
          begin
            controller.active = false
            controller.save
            #
            # TODO:: email admin about failure
            #
          rescue => e
            AutomateEm.print_error(AutomateEm::System.logger, e, {
              :message => "Error marking system as offline",
              :level => Logger::ERROR
            })
          end
        end
      end
    end
    
    #
    # Emit connection counts for logging
    #
    @@scheduler.every '10m' do
      System.logger.info "There are #{EM.connection_count} connections to this server"
    end
    
    #
    # We should AutoLoad the interfaces as plugins rather than having them in the core
    #
    EM.add_timer(20) do
      System.start_websockets
    end
  end
end

.get_log_level(level) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/automate-em.rb', line 73

def self.get_log_level(level)
  if level.nil?
    return Logger::INFO
  else
    return case level.downcase.to_sym
      when :debug
        Logger::DEBUG
      when :warn
        Logger::WARN
      when :error
        Logger::ERROR
      else
        Logger::INFO
    end
  end
end

.load_paths=(paths) ⇒ Object



58
59
60
# File 'lib/automate-em.rb', line 58

def self.load_paths= (paths)
  @@load_paths = ([] << paths) # TODO:: this doesn't work
end


4
5
6
7
8
9
10
11
12
13
14
15
16
17
# File 'lib/automate-em/utilities.rb', line 4

def self.print_error(logger, e, options = {})

  begin
    level = options[:level] || Logger::INFO
    logger.add(level) do
      message = options[:message].nil? ? "" : "%p" % options[:message]
      message += "\n#{e.message}"
      e.backtrace.each {|line| message += "\n#{line}"}
      message
    end
  rescue
  end

end

.resolverObject



68
69
70
# File 'lib/automate-em.rb', line 68

def self.resolver
  @@resolver
end

.schedulerObject



63
64
65
# File 'lib/automate-em.rb', line 63

def self.scheduler
  @@scheduler
end