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