farmbot-serial 0.3.0 → 0.3.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 63d4f03cfdeea5d307b9e4d5b9f3abff6e9c3127
4
- data.tar.gz: 8d9afbc6a329232d9119fb792bab37b620025cfc
3
+ metadata.gz: 7218c2ba0e30dadcc95541989c77a39c7cb45983
4
+ data.tar.gz: 8cf08101df89cc74f18f0e78ed5fbe9f81a00d13
5
5
  SHA512:
6
- metadata.gz: 5b9aced9e498a880f65c3a1977f76f2ea7d5c38a03065f6cffebe5a5ad4648a3e9d3967f89cabf8b3651e44962e5af30b5f4beaf9ce40d052bd6842b993dc764
7
- data.tar.gz: d6f3071f68e53b750a82af089125700cf6d6e6e2aafe4df1320fe7c9ba948a11200512a10bbb781fe08244add31a3afc8fc6862aaed6bca3bc8aeb444fb30d53
6
+ metadata.gz: 8c1c83d20b6c46fba884cdc3b39ecd502ef7e6ffe243cd0e214296f120702c98ec29350d980b02daddad9a34f87e8bef1d004b7fc0a659b5ddf0ca49124e0ebc
7
+ data.tar.gz: c71840a5bac1d79eb389c9b7f772529b4154df7e4a0e60529ab427aca79a75c8de2297b83e79726568dddbba23736f2a71d6702339baae07884aa783e27cbc76
data/lib/arduino.rb CHANGED
@@ -68,6 +68,10 @@ module FB
68
68
  end
69
69
  end
70
70
 
71
+ def next_cmd
72
+ outbound_queue.first
73
+ end
74
+
71
75
  def pop_gcode_off_queue
72
76
  gcode = @outbound_queue.pop
73
77
  if gcode.is_a?(FB::Gcode)
@@ -83,7 +87,7 @@ module FB
83
87
  def start_event_listeners
84
88
  status.onchange { |diff| @onchange.call(diff) if @onchange }
85
89
  inbound_queue.subscribe do |gcodes|
86
- gcodes.each do |gcode|
90
+ Array(gcodes).each do |gcode|
87
91
  parse_incoming(gcode)
88
92
  @onmessage.call(gcode) if @onmessage
89
93
  end
@@ -17,8 +17,9 @@ module FB
17
17
 
18
18
  def move_relative(x: 0, y: 0, z: 0, s: 100)
19
19
  write do
20
- # TODO: At some point, I will need to figure out why this is double
21
- # firing. In the meantime, the fix is to use `||=` instead of `=`
20
+ # REMEBER: YOU NEVER WANT TO MUTATE VARIABLES HERE. If you mutate vars
21
+ # in a block, it will result in the return value getting incremented
22
+ # every time the value is read. For this reason, we use ||= and not =.
22
23
  x1 ||= [(bot.current_position.x + (x || 0)), 0].max
23
24
  y1 ||= [(bot.current_position.y + (y || 0)), 0].max
24
25
  z1 ||= [(bot.current_position.z + (z || 0)), 0].max
@@ -28,6 +29,9 @@ module FB
28
29
  end
29
30
 
30
31
  def move_absolute(x: 0, y: 0, z: 0, s: 100)
32
+ x = [x.to_i, 0].max
33
+ y = [y.to_i, 0].max
34
+ z = [z.to_i, 0].max
31
35
  write { "G00 X#{x} Y#{y} Z#{z}" }
32
36
  end
33
37
 
@@ -20,11 +20,7 @@ module FB
20
20
  def []=(register, value)
21
21
  transaction do
22
22
  register = register.upcase.to_sym
23
- if @info.members.include?(register)
24
- @info[register] = value
25
- else
26
- bot.log "Ignoring attempt to set unknown status value: #{register}"
27
- end
23
+ @info[register] = value if @info.members.include?(register)
28
24
  end
29
25
  end
30
26
 
@@ -14,6 +14,7 @@ module FB
14
14
 
15
15
  # Why `def self::new()`? it was defined that way in the parent class,
16
16
  # therefore, I can't call super in #initialize().
17
+ #:nocov:
17
18
  def self::new(com = COM_PORT, conf = OPTIONS)
18
19
  super
19
20
  end
@@ -3,5 +3,6 @@ require_relative "fake_serial_port"
3
3
 
4
4
  class FakeArduino < FB::Arduino
5
5
  def initialize(serial_port: FakeSerialPort.new, logger: FakeLogger.new)
6
+ super
6
7
  end
7
8
  end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+
3
+ describe FB::ArduinoEventMachine do
4
+
5
+ let(:handler) { FB::OutgoingHandler.new(FakeArduino.new) }
6
+ let(:bot) { handler.bot }
7
+ it 'initializes' do
8
+ handler
9
+ expect(handler.bot).to be_kind_of(FB::Arduino)
10
+ end
11
+
12
+ it 'emergency_stop()s' do
13
+ 10.times { handler.move_relative(x: 1) }
14
+
15
+ handler.emergency_stop
16
+
17
+ expect(bot.outbound_queue.length).to eq(0)
18
+ expect(bot.status[:LAST]).to eq(:emergency_stop)
19
+ expect(bot.serial_port.message).to eq('E')
20
+ end
21
+
22
+ it 'adjusts relative movements to bots position RIGHT NOW' do
23
+ handler.move_relative(x: 1, y: 2, z: 3)
24
+ expect(bot.next_cmd.to_s).to eq("G0 X1 Y2 Z3")
25
+ [:x, :y, :z].each { |pos| bot.status[pos] = 3 }
26
+ expect(bot.next_cmd.to_s).to eq("G0 X4 Y5 Z6")
27
+ end
28
+
29
+ it 'never goes behind the 0 line' do
30
+ handler.move_relative(x: -999, y: -999, z: -999)
31
+ expect(bot.outbound_queue.first.value_of(:x)).to eq(0)
32
+ expect(bot.outbound_queue.first.value_of(:y)).to eq(0)
33
+ expect(bot.outbound_queue.first.value_of(:z)).to eq(0)
34
+ end
35
+
36
+ it 'Moves absolute' do
37
+ [:x, :y, :z].each { |pos| bot.status[pos] = 300 }
38
+ handler.move_absolute(x: 5, y: 6, z: 7)
39
+ expect(bot.next_cmd.to_s).to eq("G0 X5 Y6 Z7")
40
+ handler.move_absolute(x: 7, y: 8, z: 9)
41
+ expect(bot.next_cmd.to_s).to eq("G0 X7 Y8 Z9")
42
+ end
43
+
44
+ it 'Never goes farther than 0 when moving absolute' do
45
+ handler.move_absolute(x: -987, y: -654, z: -321)
46
+ expect(bot.next_cmd.to_s).to eq("G0 X0 Y0 Z0")
47
+ end
48
+
49
+ it 'homes x, y, z, all' do
50
+ handler.home_x
51
+ expect(bot.next_cmd.to_s).to eq("F11")
52
+ handler.home_y
53
+ expect(bot.next_cmd.to_s).to eq("F12")
54
+ handler.home_z
55
+ expect(bot.next_cmd.to_s).to eq("F13")
56
+ handler.home_all
57
+ expect(bot.next_cmd.to_s).to eq("G28")
58
+ end
59
+
60
+ it 'reads / writes parameters' do
61
+ handler.read_parameter(0)
62
+ expect(bot.next_cmd.to_s).to eq("F21 P0")
63
+ handler.write_parameter(0, 1)
64
+ expect(bot.next_cmd.to_s).to eq("F22 P0 V1")
65
+ end
66
+
67
+ it 'reads status' do
68
+ handler.read_status(0)
69
+ expect(bot.next_cmd.to_s).to eq("F31 P0")
70
+ end
71
+
72
+ it 'writes to a pin' do
73
+ handler.pin_write(pin: 0, value: 1, mode: 3)
74
+ expect(bot.next_cmd.to_s).to eq("F41 P0 V1 M3")
75
+ end
76
+ end
@@ -36,5 +36,20 @@ describe FB::IncomingHandler do
36
36
  expect(status[:busy]).to eq(1)
37
37
  expect(@diff).to eq(:BUSY => 1)
38
38
  end
39
+
40
+ it 'Updates status registers directly from GCode' do
41
+ command = FB::Gcode.new { "A1 X88 Y77 Z66" }
42
+ status.gcode_update(command)
43
+ expect(status[:x]).to eq(88)
44
+ expect(status[:y]).to eq(77)
45
+ expect(status[:z]).to eq(66)
46
+ end
47
+
48
+ it 'reads known and unknow pin values' do
49
+ status.set_pin(1, 1)
50
+ expect(status.pin(1)).to eq(:on)
51
+ expect(status.pin(2)).to eq(:unknown)
52
+ end
53
+
39
54
  end
40
55
 
@@ -3,18 +3,19 @@ require 'spec_helper'
3
3
  describe FB::Arduino do
4
4
  let(:logger) { FakeLogger.new }
5
5
  let(:serial_port) { FakeSerialPort.new }
6
+ let(:command) { FB::Gcode.new { 'A1 B2 C3' } }
6
7
  let(:bot) do
7
8
  FB::Arduino.new(serial_port: serial_port, logger: logger)
8
9
  end
9
10
 
10
11
 
11
- it "logs" do
12
+ it 'logs' do
12
13
  bot.log 'Hello, world!'
13
14
  expect(logger.message).to eq('Hello, world!')
14
15
  end
15
16
 
16
17
 
17
- it "initializes" do
18
+ it 'initializes' do
18
19
  expect(bot).to be_kind_of(FB::Arduino)
19
20
  expect(bot.serial_port).to be_kind_of(FakeSerialPort)
20
21
  expect(bot.logger).to be_kind_of(StringIO)
@@ -25,17 +26,17 @@ describe FB::Arduino do
25
26
  end
26
27
 
27
28
  it 'prints to the logger object' do
28
- bot.log "Hello, World!"
29
- expect(logger.message).to eq("Hello, World!")
29
+ bot.log 'Hello, World!'
30
+ expect(logger.message).to eq('Hello, World!')
30
31
  end
31
32
 
32
33
  it 'writes to outbound command queue' do
33
- bot.write("A1 B2 C3")
34
- expect(bot.outbound_queue).to include("A1 B2 C3")
34
+ bot.write('A1 B2 C3')
35
+ expect(bot.outbound_queue).to include('A1 B2 C3')
35
36
  end
36
37
 
37
- it "sets change/message/close callbacks" do
38
- yowza = ->{ bot.log "QQQ" }
38
+ it 'sets change/message/close callbacks' do
39
+ yowza = ->{ bot.log 'QQQ' }
39
40
  bot.onmessage(&yowza)
40
41
  bot.onclose(&yowza)
41
42
  bot.onchange(&yowza)
@@ -44,16 +45,16 @@ describe FB::Arduino do
44
45
  expect(bot.instance_variable_get(:@onchange)).to be(yowza)
45
46
  end
46
47
 
47
- it "calls onclose callback via disconnect()" do
48
+ it 'calls onclose callback via disconnect()' do
48
49
  calls = []
49
- bot.onclose { calls << "Hey!" }
50
+ bot.onclose { calls << 'Hey!' }
50
51
  bot.disconnect
51
- expect(logger.message).to eq("Connection to device lost")
52
+ expect(logger.message).to eq('Connection to device lost')
52
53
  expect(calls.length).to eq(1)
53
- expect(calls).to include("Hey!")
54
+ expect(calls).to include('Hey!')
54
55
  end
55
56
 
56
- it "reports current_position" do
57
+ it 'reports current_position' do
57
58
  bot.status[:x] = 1
58
59
  bot.status[:y] = 2
59
60
  bot.status[:z] = 3
@@ -62,15 +63,38 @@ describe FB::Arduino do
62
63
  expect(bot.current_position.z).to eq(3)
63
64
  end
64
65
 
65
- it "pops gcode off queue" do
66
- command = FB::Gcode.new { "A1 B2 C3" }
66
+ it 'pops gcode off queue' do
67
67
  bot.outbound_queue.push(command)
68
68
  expect(bot.outbound_queue.length).to eq(1)
69
69
  within_event_loop { bot.pop_gcode_off_queue }
70
70
  expect(bot.outbound_queue.length).to eq(0)
71
- expect(serial_port.message).to eq("A1 B2 C3")
71
+ expect(serial_port.message).to eq('A1 B2 C3')
72
72
  expect(bot.status.ready?).to be_falsey
73
73
  expect(bot.status[:last]).to eq(:unknown)
74
74
  end
75
- end
76
75
 
76
+ it 'starts event listeners' do
77
+ called_onmessage = 0
78
+ called_onchange = 0
79
+ bot.inbound_queue.push(command)
80
+
81
+ bot.onmessage do |msg|
82
+ called_onmessage += 1
83
+ bot.status[:X] = 33
84
+ end
85
+
86
+ bot.onchange do |diff|
87
+ called_onchange += 1
88
+ end
89
+
90
+ within_event_loop { bot }
91
+
92
+ expect(called_onmessage).to eq(1)
93
+ expect(called_onchange).to eq(1)
94
+ end
95
+
96
+ it 'Flips out if a message is not a GCode object.' do
97
+ bot.inbound_queue.push "I don't think so!"
98
+ expect { bot.pop_gcode_off_queue }.to raise_error(TypeError)
99
+ end
100
+ end
data/spec/spec_helper.rb CHANGED
@@ -15,9 +15,9 @@ end
15
15
 
16
16
  # This is used for testing things that require an event loop. Once run, you can
17
17
  # observe / make assertions on side effects.
18
- def within_event_loop
18
+ def within_event_loop(ticks_remaining = 1)
19
19
  EM.run do
20
+ EventMachine::PeriodicTimer.new(0.1) { EM.stop }
20
21
  yield
21
- EM.next_tick { EM.stop }
22
22
  end
23
23
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: farmbot-serial
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Evers
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-04-23 00:00:00.000000000 Z
12
+ date: 2015-04-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -134,6 +134,7 @@ files:
134
134
  - spec/fakes/fake_logger.rb
135
135
  - spec/fakes/fake_serial_port.rb
136
136
  - spec/lib/arduino/event_machine_spec.rb
137
+ - spec/lib/arduino/outgoing_handler_spec.rb
137
138
  - spec/lib/arduino/status_spec.rb
138
139
  - spec/lib/arduino_spec.rb
139
140
  - spec/lib/gcode_spec.rb
@@ -167,7 +168,9 @@ test_files:
167
168
  - spec/fakes/fake_logger.rb
168
169
  - spec/fakes/fake_serial_port.rb
169
170
  - spec/lib/arduino/event_machine_spec.rb
171
+ - spec/lib/arduino/outgoing_handler_spec.rb
170
172
  - spec/lib/arduino/status_spec.rb
171
173
  - spec/lib/arduino_spec.rb
172
174
  - spec/lib/gcode_spec.rb
173
175
  - spec/spec_helper.rb
176
+ has_rdoc: