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