tinkerforge 2.1.13 → 2.1.14

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.
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