tinkerforge 2.1.13 → 2.1.14
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/tinkerforge/brick_dc.rb +122 -34
- data/lib/tinkerforge/brick_imu.rb +135 -49
- data/lib/tinkerforge/brick_imu_v2.rb +137 -54
- data/lib/tinkerforge/brick_master.rb +206 -120
- data/lib/tinkerforge/brick_red.rb +64 -69
- data/lib/tinkerforge/brick_servo.rb +133 -44
- data/lib/tinkerforge/brick_silent_stepper.rb +151 -65
- data/lib/tinkerforge/brick_stepper.rb +139 -51
- data/lib/tinkerforge/bricklet_accelerometer.rb +17 -18
- data/lib/tinkerforge/bricklet_ambient_light.rb +16 -19
- data/lib/tinkerforge/bricklet_ambient_light_v2.rb +13 -14
- data/lib/tinkerforge/bricklet_analog_in.rb +20 -23
- data/lib/tinkerforge/bricklet_analog_in_v2.rb +18 -21
- data/lib/tinkerforge/bricklet_analog_out.rb +8 -7
- data/lib/tinkerforge/bricklet_analog_out_v2.rb +7 -6
- data/lib/tinkerforge/bricklet_barometer.rb +21 -24
- data/lib/tinkerforge/bricklet_can.rb +14 -14
- data/lib/tinkerforge/bricklet_co2.rb +11 -12
- data/lib/tinkerforge/bricklet_color.rb +22 -25
- data/lib/tinkerforge/bricklet_current12.rb +18 -22
- data/lib/tinkerforge/bricklet_current25.rb +18 -22
- data/lib/tinkerforge/bricklet_distance_ir.rb +18 -21
- data/lib/tinkerforge/bricklet_distance_us.rb +13 -14
- data/lib/tinkerforge/bricklet_dual_button.rb +8 -8
- data/lib/tinkerforge/bricklet_dual_relay.rb +9 -9
- data/lib/tinkerforge/bricklet_dust_detector.rb +13 -14
- data/lib/tinkerforge/bricklet_gps.rb +21 -25
- data/lib/tinkerforge/bricklet_gps_v2.rb +56 -41
- data/lib/tinkerforge/bricklet_hall_effect.rb +13 -13
- data/lib/tinkerforge/bricklet_humidity.rb +16 -19
- data/lib/tinkerforge/bricklet_industrial_analog_out.rb +13 -12
- data/lib/tinkerforge/bricklet_industrial_digital_in_4.rb +15 -15
- data/lib/tinkerforge/bricklet_industrial_digital_out_4.rb +12 -12
- data/lib/tinkerforge/bricklet_industrial_dual_0_20ma.rb +13 -14
- data/lib/tinkerforge/bricklet_industrial_dual_analog_in.rb +16 -17
- data/lib/tinkerforge/bricklet_industrial_quad_relay.rb +12 -12
- data/lib/tinkerforge/bricklet_io16.rb +18 -19
- data/lib/tinkerforge/bricklet_io4.rb +18 -19
- data/lib/tinkerforge/bricklet_joystick.rb +18 -23
- data/lib/tinkerforge/bricklet_laser_range_finder.rb +26 -29
- data/lib/tinkerforge/bricklet_lcd_16x2.rb +14 -15
- data/lib/tinkerforge/bricklet_lcd_20x4.rb +18 -19
- data/lib/tinkerforge/bricklet_led_strip.rb +20 -20
- data/lib/tinkerforge/bricklet_line.rb +11 -12
- data/lib/tinkerforge/bricklet_linear_poti.rb +16 -19
- data/lib/tinkerforge/bricklet_load_cell.rb +20 -21
- data/lib/tinkerforge/bricklet_moisture.rb +13 -14
- data/lib/tinkerforge/bricklet_motion_detector.rb +7 -8
- data/lib/tinkerforge/bricklet_multi_touch.rb +10 -10
- data/lib/tinkerforge/bricklet_nfc_rfid.rb +11 -11
- data/lib/tinkerforge/bricklet_oled_128x64.rb +10 -9
- data/lib/tinkerforge/bricklet_oled_64x48.rb +10 -9
- data/lib/tinkerforge/bricklet_piezo_buzzer.rb +6 -7
- data/lib/tinkerforge/bricklet_piezo_speaker.rb +7 -8
- data/lib/tinkerforge/bricklet_ptc.rb +23 -26
- data/lib/tinkerforge/bricklet_real_time_clock.rb +13 -14
- data/lib/tinkerforge/bricklet_remote_switch.rb +12 -12
- data/lib/tinkerforge/bricklet_rgb_led.rb +6 -5
- data/lib/tinkerforge/bricklet_rotary_encoder.rb +12 -15
- data/lib/tinkerforge/bricklet_rotary_poti.rb +16 -19
- data/lib/tinkerforge/bricklet_rs232.rb +12 -13
- data/lib/tinkerforge/bricklet_rs485.rb +1373 -0
- data/lib/tinkerforge/bricklet_segment_display_4x7.rb +8 -8
- data/lib/tinkerforge/bricklet_solid_state_relay.rb +8 -8
- data/lib/tinkerforge/bricklet_sound_intensity.rb +11 -12
- data/lib/tinkerforge/bricklet_temperature.rb +13 -14
- data/lib/tinkerforge/bricklet_temperature_ir.rb +18 -21
- data/lib/tinkerforge/bricklet_thermocouple.rb +14 -16
- data/lib/tinkerforge/bricklet_tilt.rb +8 -8
- data/lib/tinkerforge/bricklet_uv_light.rb +11 -12
- data/lib/tinkerforge/bricklet_voltage.rb +16 -19
- data/lib/tinkerforge/bricklet_voltage_current.rb +25 -30
- data/lib/tinkerforge/ip_connection.rb +207 -138
- data/lib/tinkerforge/version.rb +1 -1
- metadata +3 -2
@@ -52,156 +52,163 @@ module Tinkerforge
|
|
52
52
|
class NotSupportedException < TinkerforgeException
|
53
53
|
end
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
if
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
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
|
-
|
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
|
-
|
96
|
-
|
97
|
-
data += r.pack
|
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
|
-
|
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
|
-
|
112
|
+
data
|
105
113
|
end
|
106
114
|
|
107
|
-
data
|
108
|
-
|
115
|
+
def self.unpack(data, format)
|
116
|
+
unpacked = []
|
109
117
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
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
|
-
|
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
|
-
|
143
|
-
|
144
|
-
|
148
|
+
if u.length == 1
|
149
|
+
u = u[0]
|
150
|
+
end
|
145
151
|
|
146
|
-
|
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
|
-
|
159
|
-
|
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
|
-
|
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
|
-
|
167
|
-
|
172
|
+
data = r[1]
|
173
|
+
unpacked << u
|
174
|
+
end
|
168
175
|
end
|
169
|
-
end
|
170
176
|
|
171
|
-
|
172
|
-
|
177
|
+
unpacked
|
178
|
+
end
|
173
179
|
|
174
|
-
|
175
|
-
|
176
|
-
|
180
|
+
def self.get_uid_from_data(data)
|
181
|
+
data[0, 4].unpack('L<')[0]
|
182
|
+
end
|
177
183
|
|
178
|
-
|
179
|
-
|
180
|
-
|
184
|
+
def self.get_length_from_data(data)
|
185
|
+
data[4, 1].unpack('C')[0]
|
186
|
+
end
|
181
187
|
|
182
|
-
|
183
|
-
|
184
|
-
|
188
|
+
def self.get_function_id_from_data(data)
|
189
|
+
data[5, 1].unpack('C')[0]
|
190
|
+
end
|
185
191
|
|
186
|
-
|
187
|
-
|
188
|
-
|
192
|
+
def self.get_sequence_number_from_data(data)
|
193
|
+
(data[6, 1].unpack('C')[0] >> 4) & 0x0F
|
194
|
+
end
|
189
195
|
|
190
|
-
|
191
|
-
|
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
|
-
|
198
|
-
|
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
|
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
|
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
|
469
|
+
send_request FUNCTION_GET_AUTHENTICATION_NONCE, [], '', 4, 'C4'
|
464
470
|
end
|
465
471
|
|
466
472
|
def authenticate(client_nonce, digest)
|
467
|
-
send_request
|
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 \
|
data/lib/tinkerforge/version.rb
CHANGED
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.
|
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-
|
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
|