domotics-arduino 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: