domotics-arduino 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
@@ -46,7 +46,12 @@ module Domotics
|
|
46
46
|
TIMER_5 = 5
|
47
47
|
def initialize(args = {})
|
48
48
|
# grab args from hash
|
49
|
-
|
49
|
+
@board_type = args[:board] || :mega
|
50
|
+
unless [:nano, :mega].include? @board_type
|
51
|
+
raise ArgumentError, 'Invalid board type. Use defaults.'
|
52
|
+
@board_type = :mega
|
53
|
+
end
|
54
|
+
case @board_type
|
50
55
|
when :nano
|
51
56
|
@port_str = args[:port] || "/dev/ttyUSB0"
|
52
57
|
@number_of_pins = 22
|
@@ -58,18 +63,17 @@ module Domotics
|
|
58
63
|
@number_of_pins = 70
|
59
64
|
@adc_pins = Array.new(16) { |index| 54+index }
|
60
65
|
@pwm_pins = Array.new(12) { |index| 2+index } + [44,45,46]
|
61
|
-
else
|
62
|
-
raise ArduinoError, 'Invalid board type.'
|
63
66
|
end
|
64
67
|
@logger = args[:logger] || Logger.new(STDERR)
|
65
68
|
# Not allow multiple command sends
|
66
69
|
@command_lock = Mutex.new
|
67
70
|
@reply = Queue.new
|
68
|
-
#
|
71
|
+
# connection
|
72
|
+
@board_lock = Mutex.new
|
69
73
|
@board = nil
|
70
74
|
@board_listener = nil
|
71
75
|
connect
|
72
|
-
super
|
76
|
+
super unless self.class.superclass == Object
|
73
77
|
end
|
74
78
|
|
75
79
|
# ---0--- SETPINMODE
|
@@ -168,20 +172,20 @@ module Domotics
|
|
168
172
|
end
|
169
173
|
|
170
174
|
def destroy
|
175
|
+
super if self.class.superclass != Object
|
171
176
|
@logger.info { "Destroy board connection..." }
|
172
177
|
@command_lock.synchronize do
|
173
178
|
@board_listener.exit if @board_listener and @board_listener.alive?
|
174
179
|
@board.close
|
175
180
|
end
|
176
181
|
@logger.info { "done." }
|
177
|
-
super if self.class.superclass != Object
|
178
182
|
end
|
179
183
|
|
180
184
|
private
|
181
185
|
|
182
186
|
# Default event handler simple prints event.
|
183
187
|
def event_handler(hash)
|
184
|
-
raise ArduinoError, hash[:event].inspect
|
188
|
+
#raise ArduinoError, hash[:event].inspect
|
185
189
|
end
|
186
190
|
|
187
191
|
# Send command directly to board
|
@@ -201,21 +205,35 @@ module Domotics
|
|
201
205
|
false
|
202
206
|
when Array
|
203
207
|
reply
|
208
|
+
when ArduinoError
|
209
|
+
raise reply
|
204
210
|
else
|
205
211
|
nil
|
206
212
|
end
|
207
213
|
end
|
208
214
|
end
|
215
|
+
rescue
|
216
|
+
@logger.error { "Timeout while sending command to board [#{@port_str}]." }
|
217
|
+
nil
|
209
218
|
end
|
210
219
|
# Listen for board replies and alarms
|
211
220
|
def listen
|
212
|
-
@
|
213
|
-
|
214
|
-
|
221
|
+
@board_lock.synchronize do
|
222
|
+
@board_listener.exit if @board_listener and @board_listener.alive?
|
223
|
+
@board_listener = Thread.new do
|
215
224
|
loop do
|
216
225
|
message = @board.gets
|
217
|
-
|
218
|
-
|
226
|
+
unless message # message nil - board disconected
|
227
|
+
if @command_lock.locked?
|
228
|
+
@reply.push ArduinoError.new("Board [#{@port_str}] i/o error.")
|
229
|
+
else
|
230
|
+
connect
|
231
|
+
@logger.error { "Board [#{@port_str}] i/o error." }
|
232
|
+
end
|
233
|
+
terminate
|
234
|
+
end
|
235
|
+
message = message.chomp.force_encoding("ISO-8859-1").split
|
236
|
+
p message.length
|
219
237
|
case message.length
|
220
238
|
when 1
|
221
239
|
@reply.push(message[0].to_i)
|
@@ -224,35 +242,25 @@ module Domotics
|
|
224
242
|
when 2
|
225
243
|
@reply.push(message.collect{ |m| m.to_i })
|
226
244
|
else
|
227
|
-
|
245
|
+
@reply.push ArduinoError.new("Invalid reply from board [#{@port_str}].") if @command_lock.locked?
|
246
|
+
terminate
|
228
247
|
end
|
229
248
|
end
|
230
|
-
rescue ArduinoError => e
|
231
|
-
# Continue to operate in new thread
|
232
|
-
Thread.new do
|
233
|
-
@logger.error e.message
|
234
|
-
# Release command lock
|
235
|
-
@reply.push(FAILREPRLY) if @command_lock.locked?
|
236
|
-
# Close board connection
|
237
|
-
@board.close
|
238
|
-
@logger.info "Try to restart board[#{@port_str}] in 2 seconds..."
|
239
|
-
sleep 2
|
240
|
-
connect
|
241
|
-
end
|
242
|
-
# Exit errored thread
|
243
|
-
@board_listener.exit
|
244
249
|
end
|
245
250
|
end
|
246
251
|
end
|
247
252
|
# Connect to board
|
248
253
|
def connect
|
249
|
-
@
|
254
|
+
@board.close if @board
|
255
|
+
# Release command lock
|
256
|
+
@reply.push(FAILREPRLY) if @command_lock.locked?
|
257
|
+
@logger.info { "Open serial connection to board [#{@port_str}]..." }
|
250
258
|
baudrate = 115200; databits = 8; stopbits = 1; parity = SerialPort::NONE
|
251
259
|
@board = SerialPort.new(@port_str, baudrate, databits, stopbits, parity)
|
252
260
|
@board.read_timeout = 0
|
253
261
|
@board.sync = true
|
254
262
|
@logger.info { "done." }
|
255
|
-
@logger.info { "Initializing board[#{@port_str}]..." }
|
263
|
+
@logger.info { "Initializing board [#{@port_str}]..." }
|
256
264
|
# Pin states and mods
|
257
265
|
@pin_mode = Array.new(@number_of_pins, INPUT)
|
258
266
|
@watch_list = Array.new(@number_of_pins, WATCHOFF)
|
@@ -262,20 +270,18 @@ module Domotics
|
|
262
270
|
sleep(2)
|
263
271
|
end
|
264
272
|
@logger.info { "done." }
|
265
|
-
@logger.info { "Starting board[#{@port_str}] listener..." }
|
273
|
+
@logger.info { "Starting board [#{@port_str}] listener..." }
|
266
274
|
listen
|
267
275
|
@logger.info { "done." }
|
268
|
-
@logger.info { "
|
269
|
-
|
270
|
-
@logger.info { "Checking connection with board[#{@port_str}]..." }
|
271
|
-
random = Random.new
|
272
|
-
a, b = 2.times.map { random.rand(0..9) }
|
276
|
+
@logger.info { "Checking connection with board [#{@port_str}]..." }
|
277
|
+
a, b = 2.times.map { rand (0..9) }
|
273
278
|
if send_command(ECHOREPLY, a, b) == [b, a]
|
274
279
|
@logger.info { "done." }
|
275
280
|
else
|
276
|
-
|
277
|
-
raise ArduinoError
|
281
|
+
raise ArduinoError, "Bad reply from board [#{@port_str}] (wrong firmware?)."
|
278
282
|
end
|
283
|
+
@logger.info { "Reset board [#{@port_str}] to defaults..." }
|
284
|
+
@logger.info { "done." } if send_command(DEFAULTS)
|
279
285
|
rescue Exception => e
|
280
286
|
@logger.error { e.message }
|
281
287
|
tries = tries || 0
|
@@ -285,8 +291,9 @@ module Domotics
|
|
285
291
|
sleep 2**tries
|
286
292
|
retry
|
287
293
|
end
|
288
|
-
@logger.error { "Board[#{@port_str}] malfunction. Automatic restart failed." }
|
294
|
+
@logger.error { "Board [#{@port_str}] malfunction. Automatic restart failed." }
|
289
295
|
event_handler :event => :malfunction
|
296
|
+
raise ArduinoError, "Board [#{@port_str}] malfunction. Automatic restart failed."
|
290
297
|
end
|
291
298
|
# Checks
|
292
299
|
def check_pin(pin)
|
data/test/board_emulator.rb
CHANGED
@@ -5,14 +5,27 @@ class BoardEmulator
|
|
5
5
|
success = Domotics::Arduino::ArduinoBase::SUCCESSREPRLY
|
6
6
|
@master, @slave = PTY.open
|
7
7
|
type = args[:type] || :normal
|
8
|
-
|
9
|
-
|
8
|
+
Thread.new do
|
9
|
+
case type
|
10
|
+
when :dead
|
11
|
+
terminate
|
12
|
+
when :crasy
|
13
|
+
loop do
|
14
|
+
@master.gets
|
15
|
+
ans = rand(4).times.map{ rand(10) }.join(' ')
|
16
|
+
@master.puts ans
|
17
|
+
end
|
18
|
+
when :disconnect
|
19
|
+
@master.gets
|
20
|
+
@slave.close
|
21
|
+
@master.close
|
22
|
+
else
|
10
23
|
loop do
|
11
24
|
raise unless message = @master.gets
|
12
25
|
command, pin, value = message.chomp.split(" ").map{ |m| m.to_i }
|
13
26
|
case command
|
14
27
|
when Domotics::Arduino::ArduinoBase::ECHOREPLY
|
15
|
-
@master.puts "#{value} #{pin}
|
28
|
+
@master.puts "#{value} #{pin}"
|
16
29
|
else
|
17
30
|
@master.puts success
|
18
31
|
end
|
data/test/test_arduino.rb
CHANGED
@@ -7,15 +7,28 @@ class ArduinoTestBoard
|
|
7
7
|
end
|
8
8
|
|
9
9
|
class ArduinoTest < Test::Unit::TestCase
|
10
|
-
def
|
11
|
-
|
12
|
-
def test_open_connection
|
13
|
-
assert brd = ArduinoTestBoard.new(port: BoardEmulator.new.port)
|
14
|
-
assert !brd.destroy
|
10
|
+
def asetup
|
11
|
+
@brd = ArduinoTestBoard.new(port: BoardEmulator.new.port)
|
15
12
|
end
|
16
13
|
def test_dead_board
|
17
14
|
assert_raise Domotics::Arduino::ArduinoError do
|
18
15
|
ArduinoTestBoard.new(port: BoardEmulator.new(type: :dead).port)
|
19
16
|
end
|
20
17
|
end
|
18
|
+
def test_crasy_board
|
19
|
+
assert_raise Domotics::Arduino::ArduinoError do
|
20
|
+
ArduinoTestBoard.new(port: BoardEmulator.new(type: :crasy).port)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
def test_disconnected_board
|
24
|
+
assert_raise Domotics::Arduino::ArduinoError do
|
25
|
+
ArduinoTestBoard.new(port: BoardEmulator.new(type: :disconnect).port)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
def atest_set_pin_mode
|
29
|
+
@brd
|
30
|
+
end
|
31
|
+
def ateardown
|
32
|
+
@brd.destroy
|
33
|
+
end
|
21
34
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: domotics-arduino
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-12-
|
12
|
+
date: 2013-12-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: serialport
|
@@ -73,7 +73,7 @@ files:
|
|
73
73
|
- Rakefile
|
74
74
|
- domotics-arduino.gemspec
|
75
75
|
- lib/domotics/arduino.rb
|
76
|
-
- lib/domotics/arduino/
|
76
|
+
- lib/domotics/arduino/arduino_base.rb
|
77
77
|
- lib/domotics/arduino/digital_pin.rb
|
78
78
|
- lib/domotics/arduino/digital_pin/nc_sensor.rb
|
79
79
|
- lib/domotics/arduino/digital_pin/no_sensor.rb
|
@@ -111,3 +111,4 @@ summary: Arduino part of Domotics
|
|
111
111
|
test_files:
|
112
112
|
- test/board_emulator.rb
|
113
113
|
- test/test_arduino.rb
|
114
|
+
has_rdoc:
|