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
- case @board_type = args[:board] || :mega
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
- # Open connection
71
+ # connection
72
+ @board_lock = Mutex.new
69
73
  @board = nil
70
74
  @board_listener = nil
71
75
  connect
72
- super if self.class.superclass != Object
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
- @board_listener.exit if @board_listener
213
- @board_listener = Thread.new do
214
- begin
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
- raise ArduinoError, "Board[#{@port_str}] i/o error." unless message # message nil - board disconected
218
- message = message.force_encoding("ISO-8859-1").split
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
- raise ArduinoError, "Invalid reply from board[#{@port_str}]."
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
- @logger.info { "Open serial connection to board[#{@port_str}]..." }
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 { "Reset board[#{@port_str}] to defaults..." }
269
- @logger.info { "done." } if send_command(DEFAULTS)
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
- @logger.error { "Bad reply from board[#{@port_str}] (wrong firmware?)." }
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)
@@ -1,5 +1,5 @@
1
1
  module Domotics
2
2
  module Arduino
3
- VERSION = "0.1.2"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
@@ -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
- unless type == :dead
9
- Thread.new do
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}\n"
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 setup
11
- end
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.1.2
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 00:00:00.000000000 Z
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/arduino_serial.rb
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: