tinkerforge 2.1.13 → 2.1.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/lib/tinkerforge/brick_dc.rb +122 -34
  2. data/lib/tinkerforge/brick_imu.rb +135 -49
  3. data/lib/tinkerforge/brick_imu_v2.rb +137 -54
  4. data/lib/tinkerforge/brick_master.rb +206 -120
  5. data/lib/tinkerforge/brick_red.rb +64 -69
  6. data/lib/tinkerforge/brick_servo.rb +133 -44
  7. data/lib/tinkerforge/brick_silent_stepper.rb +151 -65
  8. data/lib/tinkerforge/brick_stepper.rb +139 -51
  9. data/lib/tinkerforge/bricklet_accelerometer.rb +17 -18
  10. data/lib/tinkerforge/bricklet_ambient_light.rb +16 -19
  11. data/lib/tinkerforge/bricklet_ambient_light_v2.rb +13 -14
  12. data/lib/tinkerforge/bricklet_analog_in.rb +20 -23
  13. data/lib/tinkerforge/bricklet_analog_in_v2.rb +18 -21
  14. data/lib/tinkerforge/bricklet_analog_out.rb +8 -7
  15. data/lib/tinkerforge/bricklet_analog_out_v2.rb +7 -6
  16. data/lib/tinkerforge/bricklet_barometer.rb +21 -24
  17. data/lib/tinkerforge/bricklet_can.rb +14 -14
  18. data/lib/tinkerforge/bricklet_co2.rb +11 -12
  19. data/lib/tinkerforge/bricklet_color.rb +22 -25
  20. data/lib/tinkerforge/bricklet_current12.rb +18 -22
  21. data/lib/tinkerforge/bricklet_current25.rb +18 -22
  22. data/lib/tinkerforge/bricklet_distance_ir.rb +18 -21
  23. data/lib/tinkerforge/bricklet_distance_us.rb +13 -14
  24. data/lib/tinkerforge/bricklet_dual_button.rb +8 -8
  25. data/lib/tinkerforge/bricklet_dual_relay.rb +9 -9
  26. data/lib/tinkerforge/bricklet_dust_detector.rb +13 -14
  27. data/lib/tinkerforge/bricklet_gps.rb +21 -25
  28. data/lib/tinkerforge/bricklet_gps_v2.rb +56 -41
  29. data/lib/tinkerforge/bricklet_hall_effect.rb +13 -13
  30. data/lib/tinkerforge/bricklet_humidity.rb +16 -19
  31. data/lib/tinkerforge/bricklet_industrial_analog_out.rb +13 -12
  32. data/lib/tinkerforge/bricklet_industrial_digital_in_4.rb +15 -15
  33. data/lib/tinkerforge/bricklet_industrial_digital_out_4.rb +12 -12
  34. data/lib/tinkerforge/bricklet_industrial_dual_0_20ma.rb +13 -14
  35. data/lib/tinkerforge/bricklet_industrial_dual_analog_in.rb +16 -17
  36. data/lib/tinkerforge/bricklet_industrial_quad_relay.rb +12 -12
  37. data/lib/tinkerforge/bricklet_io16.rb +18 -19
  38. data/lib/tinkerforge/bricklet_io4.rb +18 -19
  39. data/lib/tinkerforge/bricklet_joystick.rb +18 -23
  40. data/lib/tinkerforge/bricklet_laser_range_finder.rb +26 -29
  41. data/lib/tinkerforge/bricklet_lcd_16x2.rb +14 -15
  42. data/lib/tinkerforge/bricklet_lcd_20x4.rb +18 -19
  43. data/lib/tinkerforge/bricklet_led_strip.rb +20 -20
  44. data/lib/tinkerforge/bricklet_line.rb +11 -12
  45. data/lib/tinkerforge/bricklet_linear_poti.rb +16 -19
  46. data/lib/tinkerforge/bricklet_load_cell.rb +20 -21
  47. data/lib/tinkerforge/bricklet_moisture.rb +13 -14
  48. data/lib/tinkerforge/bricklet_motion_detector.rb +7 -8
  49. data/lib/tinkerforge/bricklet_multi_touch.rb +10 -10
  50. data/lib/tinkerforge/bricklet_nfc_rfid.rb +11 -11
  51. data/lib/tinkerforge/bricklet_oled_128x64.rb +10 -9
  52. data/lib/tinkerforge/bricklet_oled_64x48.rb +10 -9
  53. data/lib/tinkerforge/bricklet_piezo_buzzer.rb +6 -7
  54. data/lib/tinkerforge/bricklet_piezo_speaker.rb +7 -8
  55. data/lib/tinkerforge/bricklet_ptc.rb +23 -26
  56. data/lib/tinkerforge/bricklet_real_time_clock.rb +13 -14
  57. data/lib/tinkerforge/bricklet_remote_switch.rb +12 -12
  58. data/lib/tinkerforge/bricklet_rgb_led.rb +6 -5
  59. data/lib/tinkerforge/bricklet_rotary_encoder.rb +12 -15
  60. data/lib/tinkerforge/bricklet_rotary_poti.rb +16 -19
  61. data/lib/tinkerforge/bricklet_rs232.rb +12 -13
  62. data/lib/tinkerforge/bricklet_rs485.rb +1373 -0
  63. data/lib/tinkerforge/bricklet_segment_display_4x7.rb +8 -8
  64. data/lib/tinkerforge/bricklet_solid_state_relay.rb +8 -8
  65. data/lib/tinkerforge/bricklet_sound_intensity.rb +11 -12
  66. data/lib/tinkerforge/bricklet_temperature.rb +13 -14
  67. data/lib/tinkerforge/bricklet_temperature_ir.rb +18 -21
  68. data/lib/tinkerforge/bricklet_thermocouple.rb +14 -16
  69. data/lib/tinkerforge/bricklet_tilt.rb +8 -8
  70. data/lib/tinkerforge/bricklet_uv_light.rb +11 -12
  71. data/lib/tinkerforge/bricklet_voltage.rb +16 -19
  72. data/lib/tinkerforge/bricklet_voltage_current.rb +25 -30
  73. data/lib/tinkerforge/ip_connection.rb +207 -138
  74. data/lib/tinkerforge/version.rb +1 -1
  75. metadata +3 -2
@@ -52,156 +52,163 @@ module Tinkerforge
52
52
  class NotSupportedException < TinkerforgeException
53
53
  end
54
54
 
55
- def pack(unpacked, format)
56
- data = ''
57
- format.split(' ').each do |f|
58
- if f.length > 1
59
- f0 = f[0, 1]
60
- f1 = f[1..-1]
61
- r = []
62
-
63
- if f0 == '?'
64
- n1 = (Integer(f1) / 8.0).ceil
65
- r = Array.new(n1, 0)
66
-
67
- unpacked[0].each_with_index do |b, i|
68
- if b
69
- r[i / 8] |= 1 << (i % 8)
55
+ class StreamOutOfSyncException < TinkerforgeException
56
+ end
57
+
58
+ class Packer
59
+ def self.pack(unpacked, format)
60
+ data = ''
61
+
62
+ format.split(' ').each do |f|
63
+ if f.length > 1
64
+ f0 = f[0, 1]
65
+ f1 = f[1..-1]
66
+ r = []
67
+
68
+ if f0 == '?'
69
+ n1 = (Integer(f1) / 8.0).ceil
70
+ r = Array.new(n1, 0)
71
+
72
+ unpacked[0].each_with_index do |b, i|
73
+ if b
74
+ r[i / 8] |= 1 << (i % 8)
75
+ end
70
76
  end
71
- end
72
77
 
73
- data += r.pack "C#{n1}"
74
- elsif f0 == 'k'
75
- unpacked[0].each { |c| r << c.ord }
76
- data += r.pack "c#{f1}"
77
- else
78
- r = unpacked[0]
79
- if ['s', 'S', 'l', 'L', 'q', 'Q'].count(f0) > 0
80
- data += r.pack "#{f0}<#{f1}"
81
- elsif f0 == 'Z'
82
- data += [r].pack "#{f0}#{f1}"
78
+ data += r.pack "C#{n1}"
79
+ elsif f0 == 'k'
80
+ unpacked[0].each { |c| r << c.ord }
81
+ data += r.pack "c#{f1}"
83
82
  else
84
- data += r.pack "#{f0}#{f1}"
83
+ r = unpacked[0]
84
+ if ['s', 'S', 'l', 'L', 'q', 'Q'].count(f0) > 0
85
+ data += r.pack "#{f0}<#{f1}"
86
+ elsif f0 == 'Z'
87
+ data += [r].pack "#{f0}#{f1}"
88
+ else
89
+ data += r.pack "#{f0}#{f1}"
90
+ end
85
91
  end
86
- end
87
- else
88
- if f == '?'
89
- r = [unpacked[0] ? 1 : 0]
90
- data += r.pack 'C'
91
- elsif f == 'k'
92
- r = [unpacked[0].ord]
93
- data += r.pack 'c'
94
92
  else
95
- r = [unpacked[0]]
96
- if ['s', 'S', 'l', 'L', 'q', 'Q'].count(f) > 0
97
- data += r.pack "#{f}<"
93
+ if f == '?'
94
+ r = [unpacked[0] ? 1 : 0]
95
+ data += r.pack 'C'
96
+ elsif f == 'k'
97
+ r = [unpacked[0].ord]
98
+ data += r.pack 'c'
98
99
  else
99
- data += r.pack f
100
+ r = [unpacked[0]]
101
+ if ['s', 'S', 'l', 'L', 'q', 'Q'].count(f) > 0
102
+ data += r.pack "#{f}<"
103
+ else
104
+ data += r.pack f
105
+ end
100
106
  end
101
107
  end
108
+
109
+ unpacked = unpacked.drop 1
102
110
  end
103
111
 
104
- unpacked = unpacked.drop 1
112
+ data
105
113
  end
106
114
 
107
- data
108
- end
115
+ def self.unpack(data, format)
116
+ unpacked = []
109
117
 
110
- def unpack(data, format)
111
- unpacked = []
112
- format.split(' ').each do |f|
113
- if f.length > 1
114
- f0 = f[0, 1]
115
- f1 = f[1..-1]
116
- u = []
117
-
118
- if f0 == '?'
119
- r = data.unpack "C#{f1}a*"
120
- data = r[-1]
121
- r.delete_at(-1)
122
-
123
- for i in 0..Integer(f1) - 1
124
- u << ((r[i / 8] & (1 << (i % 8))) != 0)
125
- end
126
- elsif f0 == 'k'
127
- r = data.unpack "c#{f1}a*"
128
- data = r[-1]
129
- r.delete_at(-1)
130
- r.each { |c| u << c.chr }
131
- else
132
- if ['s', 'S', 'l', 'L', 'q', 'Q'].count(f0) > 0
133
- r = data.unpack "#{f}<a*"
118
+ format.split(' ').each do |f|
119
+ if f.length > 1
120
+ f0 = f[0, 1]
121
+ f1 = f[1..-1]
122
+ u = []
123
+
124
+ if f0 == '?'
125
+ r = data.unpack "C#{f1}a*"
126
+ data = r[-1]
127
+ r.delete_at(-1)
128
+
129
+ for i in 0..Integer(f1) - 1
130
+ u << ((r[i / 8] & (1 << (i % 8))) != 0)
131
+ end
132
+ elsif f0 == 'k'
133
+ r = data.unpack "c#{f1}a*"
134
+ data = r[-1]
135
+ r.delete_at(-1)
136
+ r.each { |c| u << c.chr }
134
137
  else
135
- r = data.unpack "#{f}a*"
138
+ if ['s', 'S', 'l', 'L', 'q', 'Q'].count(f0) > 0
139
+ r = data.unpack "#{f}<a*"
140
+ else
141
+ r = data.unpack "#{f}a*"
142
+ end
143
+ data = r[-1]
144
+ r.delete_at(-1)
145
+ r.each { |k| u << k }
136
146
  end
137
- data = r[-1]
138
- r.delete_at(-1)
139
- r.each { |k| u << k }
140
- end
141
147
 
142
- if u.length == 1
143
- u = u[0]
144
- end
148
+ if u.length == 1
149
+ u = u[0]
150
+ end
145
151
 
146
- unpacked << u
147
- else
148
- r = []
149
- u = nil
150
-
151
- if f == '?'
152
- r = data.unpack "Ca*"
153
- u = r[0] != 0
154
- elsif f == 'k'
155
- r = data.unpack "ca*"
156
- u = r[0].chr
152
+ unpacked << u
157
153
  else
158
- if ['s', 'q', 'l', 'L', 'S', 'Q'].count(f) > 0
159
- r = data.unpack "#{f}<a*"
154
+ r = []
155
+ u = nil
156
+
157
+ if f == '?'
158
+ r = data.unpack "Ca*"
159
+ u = r[0] != 0
160
+ elsif f == 'k'
161
+ r = data.unpack "ca*"
162
+ u = r[0].chr
160
163
  else
161
- r = data.unpack "#{f}a*"
164
+ if ['s', 'q', 'l', 'L', 'S', 'Q'].count(f) > 0
165
+ r = data.unpack "#{f}<a*"
166
+ else
167
+ r = data.unpack "#{f}a*"
168
+ end
169
+ u = r[0]
162
170
  end
163
- u = r[0]
164
- end
165
171
 
166
- data = r[1]
167
- unpacked << u
172
+ data = r[1]
173
+ unpacked << u
174
+ end
168
175
  end
169
- end
170
176
 
171
- unpacked
172
- end
177
+ unpacked
178
+ end
173
179
 
174
- def get_uid_from_data(data)
175
- data[0, 4].unpack('L<')[0]
176
- end
180
+ def self.get_uid_from_data(data)
181
+ data[0, 4].unpack('L<')[0]
182
+ end
177
183
 
178
- def get_length_from_data(data)
179
- data[4, 1].unpack('C')[0]
180
- end
184
+ def self.get_length_from_data(data)
185
+ data[4, 1].unpack('C')[0]
186
+ end
181
187
 
182
- def get_function_id_from_data(data)
183
- data[5, 1].unpack('C')[0]
184
- end
188
+ def self.get_function_id_from_data(data)
189
+ data[5, 1].unpack('C')[0]
190
+ end
185
191
 
186
- def get_sequence_number_from_data(data)
187
- (data[6, 1].unpack('C')[0] >> 4) & 0x0F
188
- end
192
+ def self.get_sequence_number_from_data(data)
193
+ (data[6, 1].unpack('C')[0] >> 4) & 0x0F
194
+ end
189
195
 
190
- def get_error_code_from_data(data)
191
- (data[7, 1].unpack('C')[0] >> 6) & 0x03
196
+ def self.get_error_code_from_data(data)
197
+ (data[7, 1].unpack('C')[0] >> 6) & 0x03
198
+ end
192
199
  end
193
200
 
194
201
  class Device
195
202
  RESPONSE_EXPECTED_INVALID_FUNCTION_ID = 0
196
203
  RESPONSE_EXPECTED_ALWAYS_TRUE = 1 # getter
197
- RESPONSE_EXPECTED_ALWAYS_FALSE = 2 # callback
198
- RESPONSE_EXPECTED_TRUE = 3 # setter
199
- RESPONSE_EXPECTED_FALSE = 4 # setter, default
204
+ RESPONSE_EXPECTED_TRUE = 2 # setter
205
+ RESPONSE_EXPECTED_FALSE = 3 # setter, default
200
206
 
201
207
  attr_accessor :uid
202
208
  attr_accessor :expected_response_function_id
203
209
  attr_accessor :expected_response_sequence_number
204
210
  attr_accessor :callback_formats
211
+ attr_accessor :high_level_callbacks
205
212
  attr_accessor :registered_callbacks
206
213
 
207
214
  # Creates the device object with the unique device ID <tt>uid</tt> and adds
@@ -228,8 +235,6 @@ module Tinkerforge
228
235
  @request_mutex = Mutex.new
229
236
 
230
237
  @response_expected = Array.new(256, RESPONSE_EXPECTED_INVALID_FUNCTION_ID)
231
- @response_expected[IPConnection::FUNCTION_ENUMERATE] = RESPONSE_EXPECTED_ALWAYS_FALSE
232
- @response_expected[IPConnection::CALLBACK_ENUMERATE] = RESPONSE_EXPECTED_ALWAYS_FALSE
233
238
 
234
239
  @expected_response_function_id = 0
235
240
  @expected_response_sequence_number = 0
@@ -238,7 +243,10 @@ module Tinkerforge
238
243
  @response_condition = ConditionVariable.new
239
244
  @response_queue = Queue.new
240
245
 
246
+ @stream_mutex = Mutex.new
247
+
241
248
  @callback_formats = {}
249
+ @high_level_callbacks = {}
242
250
  @registered_callbacks = {}
243
251
 
244
252
  @ipcon.devices[@uid] = self # FIXME: use a weakref here
@@ -287,8 +295,7 @@ module Tinkerforge
287
295
  # Changes the response expected flag of the function specified by the
288
296
  # <tt>function_id</tt> parameter. This flag can only be changed for setter
289
297
  # (default value: <tt>false</tt>) and callback configuration functions
290
- # (default value: <tt>true</tt>). For getter functions it is always enabled
291
- # and callbacks it is always disabled.
298
+ # (default value: <tt>true</tt>). For getter functions it is always enabled.
292
299
  #
293
300
  # Enabling the response expected flag for a setter function allows to
294
301
  # detect timeouts and other error conditions calls of this setter as
@@ -306,8 +313,7 @@ module Tinkerforge
306
313
  raise ArgumentError, "Invalid function ID #{function_id}"
307
314
  end
308
315
 
309
- if flag == RESPONSE_EXPECTED_ALWAYS_TRUE or \
310
- flag == RESPONSE_EXPECTED_ALWAYS_FALSE
316
+ if flag == RESPONSE_EXPECTED_ALWAYS_TRUE
311
317
  raise ArgumentError, "Response Expected flag cannot be changed for function ID #{function_id}"
312
318
  end
313
319
 
@@ -341,7 +347,7 @@ module Tinkerforge
341
347
  response = nil
342
348
 
343
349
  if request_data.length > 0
344
- payload = pack request_data, request_format
350
+ payload = Packer.pack request_data, request_format
345
351
  else
346
352
  payload = ''
347
353
  end
@@ -363,8 +369,8 @@ module Tinkerforge
363
369
  while true
364
370
  packet = dequeue_response "Did not receive response in time for function ID #{function_id}"
365
371
 
366
- if function_id == get_function_id_from_data(packet) and \
367
- sequence_number == get_sequence_number_from_data(packet)
372
+ if function_id == Packer.get_function_id_from_data(packet) and \
373
+ sequence_number == Packer.get_sequence_number_from_data(packet)
368
374
  # ignore old responses that arrived after the timeout expired, but before setting
369
375
  # expected_response_function_id and expected_response_sequence_number back to None
370
376
  break
@@ -376,7 +382,7 @@ module Tinkerforge
376
382
  end
377
383
  }
378
384
 
379
- error_code = get_error_code_from_data(packet)
385
+ error_code = Packer.get_error_code_from_data packet
380
386
 
381
387
  if error_code == 0
382
388
  # no error
@@ -389,7 +395,7 @@ module Tinkerforge
389
395
  end
390
396
 
391
397
  if response_length > 0
392
- response = unpack packet[8..-1], response_format
398
+ response = Packer.unpack packet[8..-1], response_format
393
399
 
394
400
  if response.length == 1
395
401
  response = response[0]
@@ -460,11 +466,11 @@ module Tinkerforge
460
466
  end
461
467
 
462
468
  def get_authentication_nonce
463
- send_request(FUNCTION_GET_AUTHENTICATION_NONCE, [], '', 4, 'C4')
469
+ send_request FUNCTION_GET_AUTHENTICATION_NONCE, [], '', 4, 'C4'
464
470
  end
465
471
 
466
472
  def authenticate(client_nonce, digest)
467
- send_request(FUNCTION_AUTHENTICATE, [client_nonce, digest], 'C4 C20', 0, '')
473
+ send_request FUNCTION_AUTHENTICATE, [client_nonce, digest], 'C4 C20', 0, ''
468
474
  end
469
475
  end
470
476
 
@@ -611,11 +617,11 @@ module Tinkerforge
611
617
  end
612
618
 
613
619
  server_nonce = @brickd.get_authentication_nonce
614
- client_nonce = unpack(pack([@next_authentication_nonce], 'L'), 'C4')[0]
620
+ client_nonce = Packer.unpack(Packer.pack([@next_authentication_nonce], 'L'), 'C4')[0]
615
621
  @next_authentication_nonce += 1
616
- nonce_bytes = pack [server_nonce, client_nonce], 'C4 C4'
622
+ nonce_bytes = Packer.pack [server_nonce, client_nonce], 'C4 C4'
617
623
  digest_bytes = OpenSSL::HMAC.digest 'sha1', secret, nonce_bytes
618
- digest = unpack(digest_bytes, 'C20')[0]
624
+ digest = Packer.unpack(digest_bytes, 'C20')[0]
619
625
 
620
626
  @brickd.authenticate client_nonce, digest
621
627
  }
@@ -731,7 +737,7 @@ module Tinkerforge
731
737
  end
732
738
 
733
739
  sequence_number_and_options = (sequence_number << 4) | (r_bit << 3)
734
- header = pack [uid, length, function_id, sequence_number_and_options, 0], 'L C C C C'
740
+ header = Packer.pack [uid, length, function_id, sequence_number_and_options, 0], 'L C C C C'
735
741
 
736
742
  [header, response_expected, sequence_number]
737
743
  end
@@ -907,7 +913,7 @@ module Tinkerforge
907
913
  break
908
914
  end
909
915
 
910
- length = get_length_from_data pending_data
916
+ length = Packer.get_length_from_data pending_data
911
917
 
912
918
  if pending_data.length < length
913
919
  # Wait for complete packet
@@ -989,18 +995,80 @@ module Tinkerforge
989
995
 
990
996
  # internal
991
997
  def dispatch_packet(packet)
992
- uid = get_uid_from_data packet
993
- function_id = get_function_id_from_data packet
998
+ uid = Packer.get_uid_from_data packet
999
+ function_id = Packer.get_function_id_from_data packet
994
1000
 
995
1001
  if function_id == CALLBACK_ENUMERATE and \
996
1002
  @registered_callbacks.has_key? CALLBACK_ENUMERATE
997
- payload = unpack packet[8..-1], 'Z8 Z8 k C3 C3 S C'
1003
+ payload = Packer.unpack packet[8..-1], 'Z8 Z8 k C3 C3 S C'
998
1004
  @registered_callbacks[CALLBACK_ENUMERATE].call(*payload)
999
1005
  elsif @devices.has_key? uid
1000
1006
  device = @devices[uid]
1001
1007
 
1008
+ if device.high_level_callbacks.has_key?(-function_id)
1009
+ hlcb = device.high_level_callbacks[-function_id] # [roles, options, data]
1010
+ payload = Packer.unpack packet[8..-1], device.callback_formats[function_id]
1011
+ has_data = false
1012
+ data = nil
1013
+
1014
+ if hlcb[1]['fixed_length'] != nil
1015
+ length = hlcb[1]['fixed_length']
1016
+ else
1017
+ length = payload[hlcb[0].index 'stream_length']
1018
+ end
1019
+
1020
+ if not hlcb[1]['single_chunk']
1021
+ chunk_offset = payload[hlcb[0].index 'stream_chunk_offset']
1022
+ else
1023
+ chunk_offset = 0
1024
+ end
1025
+
1026
+ chunk_data = payload[hlcb[0].index 'stream_chunk_data']
1027
+
1028
+ if hlcb[2] == nil # no stream in-progress
1029
+ if chunk_offset == 0 # stream starts
1030
+ hlcb[2] = chunk_data
1031
+
1032
+ if hlcb[2].length >= length # stream complete
1033
+ has_data = true
1034
+ data = hlcb[2][0, length]
1035
+ hlcb[2] = nil
1036
+ else # ignore tail of current stream, wait for next stream start
1037
+ end
1038
+ else # stream in-progress
1039
+ if chunk_offset != hlcb[2].length # stream out-of-sync
1040
+ has_data = true
1041
+ data = nil
1042
+ hlcb[2] = nil
1043
+ else # stream in-sync
1044
+ hlcb[2] += chunk_data
1045
+
1046
+ if hlcb[2].length >= length # stream complete
1047
+ has_data = true
1048
+ data = hlcb[2][0, length]
1049
+ hlcb[2] = nil
1050
+ end
1051
+ end
1052
+ end
1053
+
1054
+ if has_data and device.registered_callbacks.has_key?(-function_id)
1055
+ result = []
1056
+
1057
+ hlcb[0].zip(payload).each do |role, value|
1058
+ if role == 'stream_chunk_data'
1059
+ result << data
1060
+ elsif role == nil
1061
+ result << value
1062
+ end
1063
+ end
1064
+
1065
+ device.registered_callbacks[-function_id].call(*result)
1066
+ end
1067
+ end
1068
+ end
1069
+
1002
1070
  if device.registered_callbacks.has_key? function_id
1003
- payload = unpack packet[8..-1], device.callback_formats[function_id]
1071
+ payload = Packer.unpack packet[8..-1], device.callback_formats[function_id]
1004
1072
  device.registered_callbacks[function_id].call(*payload)
1005
1073
  end
1006
1074
  end
@@ -1084,9 +1152,9 @@ module Tinkerforge
1084
1152
  def handle_response(packet)
1085
1153
  @disconnect_probe_flag = false
1086
1154
 
1087
- uid = get_uid_from_data packet
1088
- function_id = get_function_id_from_data packet
1089
- sequence_number = get_sequence_number_from_data packet
1155
+ uid = Packer.get_uid_from_data packet
1156
+ function_id = Packer.get_function_id_from_data packet
1157
+ sequence_number = Packer.get_sequence_number_from_data packet
1090
1158
 
1091
1159
  if sequence_number == 0 and function_id == CALLBACK_ENUMERATE
1092
1160
  if @registered_callbacks.has_key? CALLBACK_ENUMERATE
@@ -1096,7 +1164,8 @@ module Tinkerforge
1096
1164
  device = @devices[uid]
1097
1165
 
1098
1166
  if sequence_number == 0
1099
- if device.registered_callbacks.has_key? function_id
1167
+ if device.registered_callbacks.has_key? function_id or \
1168
+ device.high_level_callbacks.has_key?(-function_id)
1100
1169
  @callback.queue.push [QUEUE_KIND_PACKET, packet]
1101
1170
  end
1102
1171
  elsif device.expected_response_function_id == function_id and \
@@ -1,4 +1,4 @@
1
1
 
2
2
  module Tinkerforge
3
- VERSION = '2.1.13'
3
+ VERSION = '2.1.14'
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tinkerforge
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.13
4
+ version: 2.1.14
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: 2017-05-11 00:00:00.000000000 Z
12
+ date: 2017-07-27 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description:
15
15
  email: matthias@tinkerforge.com
@@ -78,6 +78,7 @@ files:
78
78
  - lib/tinkerforge/bricklet_temperature_ir.rb
79
79
  - lib/tinkerforge/bricklet_dual_button.rb
80
80
  - lib/tinkerforge/brick_silent_stepper.rb
81
+ - lib/tinkerforge/bricklet_rs485.rb
81
82
  - lib/tinkerforge/bricklet_load_cell.rb
82
83
  - lib/tinkerforge/bricklet_segment_display_4x7.rb
83
84
  - lib/tinkerforge/bricklet_distance_us.rb