tinkerforge 2.1.24 → 2.1.25

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 (142) hide show
  1. checksums.yaml +4 -4
  2. data/lib/tinkerforge/brick_dc.rb +155 -74
  3. data/lib/tinkerforge/brick_hat.rb +70 -30
  4. data/lib/tinkerforge/brick_hat_zero.rb +56 -22
  5. data/lib/tinkerforge/brick_imu.rb +184 -77
  6. data/lib/tinkerforge/brick_imu_v2.rb +208 -105
  7. data/lib/tinkerforge/brick_master.rb +484 -182
  8. data/lib/tinkerforge/brick_red.rb +197 -74
  9. data/lib/tinkerforge/brick_servo.rb +185 -101
  10. data/lib/tinkerforge/brick_silent_stepper.rb +246 -166
  11. data/lib/tinkerforge/brick_stepper.rb +210 -98
  12. data/lib/tinkerforge/bricklet_accelerometer.rb +58 -23
  13. data/lib/tinkerforge/bricklet_accelerometer_v2.rb +105 -54
  14. data/lib/tinkerforge/bricklet_air_quality.rb +117 -59
  15. data/lib/tinkerforge/bricklet_ambient_light.rb +51 -21
  16. data/lib/tinkerforge/bricklet_ambient_light_v2.rb +40 -22
  17. data/lib/tinkerforge/bricklet_ambient_light_v3.rb +61 -25
  18. data/lib/tinkerforge/bricklet_analog_in.rb +63 -25
  19. data/lib/tinkerforge/bricklet_analog_in_v2.rb +57 -23
  20. data/lib/tinkerforge/bricklet_analog_in_v3.rb +67 -25
  21. data/lib/tinkerforge/bricklet_analog_out.rb +23 -9
  22. data/lib/tinkerforge/bricklet_analog_out_v2.rb +20 -8
  23. data/lib/tinkerforge/bricklet_analog_out_v3.rb +54 -20
  24. data/lib/tinkerforge/bricklet_barometer.rb +66 -26
  25. data/lib/tinkerforge/bricklet_barometer_v2.rb +99 -37
  26. data/lib/tinkerforge/bricklet_can.rb +83 -18
  27. data/lib/tinkerforge/bricklet_can_v2.rb +172 -38
  28. data/lib/tinkerforge/bricklet_co2.rb +34 -14
  29. data/lib/tinkerforge/bricklet_co2_v2.rb +97 -37
  30. data/lib/tinkerforge/bricklet_color.rb +69 -27
  31. data/lib/tinkerforge/bricklet_color_v2.rb +87 -33
  32. data/lib/tinkerforge/bricklet_compass.rb +78 -30
  33. data/lib/tinkerforge/bricklet_current12.rb +58 -24
  34. data/lib/tinkerforge/bricklet_current25.rb +58 -24
  35. data/lib/tinkerforge/bricklet_distance_ir.rb +57 -23
  36. data/lib/tinkerforge/bricklet_distance_ir_v2.rb +83 -31
  37. data/lib/tinkerforge/bricklet_distance_us.rb +40 -16
  38. data/lib/tinkerforge/bricklet_distance_us_v2.rb +67 -25
  39. data/lib/tinkerforge/bricklet_dmx.rb +88 -34
  40. data/lib/tinkerforge/bricklet_dual_button.rb +24 -10
  41. data/lib/tinkerforge/bricklet_dual_button_v2.rb +64 -24
  42. data/lib/tinkerforge/bricklet_dual_relay.rb +27 -11
  43. data/lib/tinkerforge/bricklet_dust_detector.rb +40 -16
  44. data/lib/tinkerforge/bricklet_e_paper_296x128.rb +88 -32
  45. data/lib/tinkerforge/bricklet_energy_monitor.rb +73 -27
  46. data/lib/tinkerforge/bricklet_gps.rb +64 -26
  47. data/lib/tinkerforge/bricklet_gps_v2.rb +117 -47
  48. data/lib/tinkerforge/bricklet_hall_effect.rb +43 -23
  49. data/lib/tinkerforge/bricklet_hall_effect_v2.rb +71 -27
  50. data/lib/tinkerforge/bricklet_humidity.rb +51 -21
  51. data/lib/tinkerforge/bricklet_humidity_v2.rb +83 -31
  52. data/lib/tinkerforge/bricklet_industrial_analog_out.rb +38 -14
  53. data/lib/tinkerforge/bricklet_industrial_analog_out_v2.rb +81 -29
  54. data/lib/tinkerforge/bricklet_industrial_counter.rb +101 -39
  55. data/lib/tinkerforge/bricklet_industrial_digital_in_4.rb +45 -17
  56. data/lib/tinkerforge/bricklet_industrial_digital_in_4_v2.rb +77 -29
  57. data/lib/tinkerforge/bricklet_industrial_digital_out_4.rb +36 -14
  58. data/lib/tinkerforge/bricklet_industrial_digital_out_4_v2.rb +73 -27
  59. data/lib/tinkerforge/bricklet_industrial_dual_0_20ma.rb +40 -16
  60. data/lib/tinkerforge/bricklet_industrial_dual_0_20ma_v2.rb +79 -29
  61. data/lib/tinkerforge/bricklet_industrial_dual_analog_in.rb +49 -19
  62. data/lib/tinkerforge/bricklet_industrial_dual_analog_in_v2.rb +82 -30
  63. data/lib/tinkerforge/bricklet_industrial_dual_relay.rb +61 -23
  64. data/lib/tinkerforge/bricklet_industrial_quad_relay.rb +36 -14
  65. data/lib/tinkerforge/bricklet_industrial_quad_relay_v2.rb +67 -25
  66. data/lib/tinkerforge/bricklet_io16.rb +55 -21
  67. data/lib/tinkerforge/bricklet_io16_v2.rb +90 -34
  68. data/lib/tinkerforge/bricklet_io4.rb +55 -23
  69. data/lib/tinkerforge/bricklet_io4_v2.rb +96 -36
  70. data/lib/tinkerforge/bricklet_isolator.rb +72 -28
  71. data/lib/tinkerforge/bricklet_joystick.rb +59 -25
  72. data/lib/tinkerforge/bricklet_joystick_v2.rb +68 -26
  73. data/lib/tinkerforge/bricklet_laser_range_finder.rb +82 -32
  74. data/lib/tinkerforge/bricklet_laser_range_finder_v2.rb +96 -36
  75. data/lib/tinkerforge/bricklet_lcd_128x64.rb +192 -70
  76. data/lib/tinkerforge/bricklet_lcd_16x2.rb +45 -18
  77. data/lib/tinkerforge/bricklet_lcd_20x4.rb +58 -23
  78. data/lib/tinkerforge/bricklet_led_strip.rb +60 -22
  79. data/lib/tinkerforge/bricklet_led_strip_v2.rb +91 -46
  80. data/lib/tinkerforge/bricklet_line.rb +34 -14
  81. data/lib/tinkerforge/bricklet_linear_poti.rb +51 -21
  82. data/lib/tinkerforge/bricklet_linear_poti_v2.rb +55 -21
  83. data/lib/tinkerforge/bricklet_load_cell.rb +61 -23
  84. data/lib/tinkerforge/bricklet_load_cell_v2.rb +80 -30
  85. data/lib/tinkerforge/bricklet_moisture.rb +40 -16
  86. data/lib/tinkerforge/bricklet_motion_detector.rb +22 -10
  87. data/lib/tinkerforge/bricklet_motion_detector_v2.rb +62 -24
  88. data/lib/tinkerforge/bricklet_motorized_linear_poti.rb +71 -27
  89. data/lib/tinkerforge/bricklet_multi_touch.rb +31 -13
  90. data/lib/tinkerforge/bricklet_multi_touch_v2.rb +76 -28
  91. data/lib/tinkerforge/bricklet_nfc.rb +123 -58
  92. data/lib/tinkerforge/bricklet_nfc_rfid.rb +33 -13
  93. data/lib/tinkerforge/bricklet_oled_128x64.rb +29 -11
  94. data/lib/tinkerforge/bricklet_oled_128x64_v2.rb +66 -24
  95. data/lib/tinkerforge/bricklet_oled_64x48.rb +29 -11
  96. data/lib/tinkerforge/bricklet_one_wire.rb +66 -24
  97. data/lib/tinkerforge/bricklet_outdoor_weather.rb +71 -27
  98. data/lib/tinkerforge/bricklet_particulate_matter.rb +75 -30
  99. data/lib/tinkerforge/bricklet_piezo_buzzer.rb +19 -9
  100. data/lib/tinkerforge/bricklet_piezo_speaker.rb +22 -10
  101. data/lib/tinkerforge/bricklet_piezo_speaker_v2.rb +80 -42
  102. data/lib/tinkerforge/bricklet_ptc.rb +74 -42
  103. data/lib/tinkerforge/bricklet_ptc_v2.rb +95 -48
  104. data/lib/tinkerforge/bricklet_real_time_clock.rb +45 -33
  105. data/lib/tinkerforge/bricklet_real_time_clock_v2.rb +78 -44
  106. data/lib/tinkerforge/bricklet_remote_switch.rb +39 -29
  107. data/lib/tinkerforge/bricklet_remote_switch_v2.rb +87 -49
  108. data/lib/tinkerforge/bricklet_rgb_led.rb +18 -8
  109. data/lib/tinkerforge/bricklet_rgb_led_button.rb +62 -30
  110. data/lib/tinkerforge/bricklet_rgb_led_matrix.rb +79 -33
  111. data/lib/tinkerforge/bricklet_rgb_led_v2.rb +52 -20
  112. data/lib/tinkerforge/bricklet_rotary_encoder.rb +39 -19
  113. data/lib/tinkerforge/bricklet_rotary_encoder_v2.rb +60 -24
  114. data/lib/tinkerforge/bricklet_rotary_poti.rb +53 -28
  115. data/lib/tinkerforge/bricklet_rotary_poti_v2.rb +57 -23
  116. data/lib/tinkerforge/bricklet_rs232.rb +90 -28
  117. data/lib/tinkerforge/bricklet_rs232_v2.rb +118 -44
  118. data/lib/tinkerforge/bricklet_rs485.rb +223 -95
  119. data/lib/tinkerforge/bricklet_segment_display_4x7.rb +25 -14
  120. data/lib/tinkerforge/bricklet_segment_display_4x7_v2.rb +75 -35
  121. data/lib/tinkerforge/bricklet_solid_state_relay.rb +25 -13
  122. data/lib/tinkerforge/bricklet_solid_state_relay_v2.rb +59 -25
  123. data/lib/tinkerforge/bricklet_sound_intensity.rb +35 -18
  124. data/lib/tinkerforge/bricklet_sound_pressure_level.rb +72 -31
  125. data/lib/tinkerforge/bricklet_temperature.rb +40 -16
  126. data/lib/tinkerforge/bricklet_temperature_ir.rb +57 -23
  127. data/lib/tinkerforge/bricklet_temperature_ir_v2.rb +71 -27
  128. data/lib/tinkerforge/bricklet_temperature_v2.rb +61 -25
  129. data/lib/tinkerforge/bricklet_thermal_imaging.rb +105 -44
  130. data/lib/tinkerforge/bricklet_thermocouple.rb +45 -24
  131. data/lib/tinkerforge/bricklet_thermocouple_v2.rb +65 -27
  132. data/lib/tinkerforge/bricklet_tilt.rb +24 -10
  133. data/lib/tinkerforge/bricklet_uv_light.rb +36 -18
  134. data/lib/tinkerforge/bricklet_uv_light_v2.rb +85 -37
  135. data/lib/tinkerforge/bricklet_voltage.rb +52 -28
  136. data/lib/tinkerforge/bricklet_voltage_current.rb +91 -73
  137. data/lib/tinkerforge/bricklet_voltage_current_v2.rb +90 -68
  138. data/lib/tinkerforge/bricklet_xmc1400_breakout.rb +80 -30
  139. data/lib/tinkerforge/device_display_names.rb +163 -0
  140. data/lib/tinkerforge/ip_connection.rb +151 -32
  141. data/lib/tinkerforge/version.rb +1 -1
  142. metadata +3 -2
@@ -1,14 +1,16 @@
1
1
  # -*- ruby encoding: utf-8 -*-
2
2
  #############################################################
3
- # This file was automatically generated on 2019-11-25. #
3
+ # This file was automatically generated on 2020-04-07. #
4
4
  # #
5
- # Ruby Bindings Version 2.1.24 #
5
+ # Ruby Bindings Version 2.1.25 #
6
6
  # #
7
7
  # If you have a bugfix for this file and want to commit it, #
8
8
  # please fix the bug in the generator. You can find a link #
9
9
  # to the generators git repository on tinkerforge.com #
10
10
  #############################################################
11
11
 
12
+ require_relative './ip_connection'
13
+
12
14
  module Tinkerforge
13
15
  # Breakout for Infineon XMC1400 microcontroller
14
16
  class BrickletXMC1400Breakout < Device
@@ -87,7 +89,7 @@ module Tinkerforge
87
89
  # Creates an object with the unique device ID <tt>uid</tt> and adds it to
88
90
  # the IP Connection <tt>ipcon</tt>.
89
91
  def initialize(uid, ipcon)
90
- super uid, ipcon
92
+ super uid, ipcon, DEVICE_IDENTIFIER, DEVICE_DISPLAY_NAME
91
93
 
92
94
  @api_version = [2, 0, 0]
93
95
 
@@ -115,21 +117,26 @@ module Tinkerforge
115
117
  @response_expected[FUNCTION_READ_UID] = RESPONSE_EXPECTED_ALWAYS_TRUE
116
118
  @response_expected[FUNCTION_GET_IDENTITY] = RESPONSE_EXPECTED_ALWAYS_TRUE
117
119
 
118
- @callback_formats[CALLBACK_ADC_VALUES] = 'S8'
119
- @callback_formats[CALLBACK_COUNT] = 'L'
120
+ @callback_formats[CALLBACK_ADC_VALUES] = [24, 'S8']
121
+ @callback_formats[CALLBACK_COUNT] = [12, 'L']
120
122
 
123
+ @ipcon.add_device self
121
124
  end
122
125
 
123
126
  # Example for a setter function. The values are the values that can be given to
124
127
  # the XMC_GPIO_Init function. See communication.c in the firmware.
125
128
  def set_gpio_config(port, pin, mode, input_hysteresis, output_level)
126
- send_request FUNCTION_SET_GPIO_CONFIG, [port, pin, mode, input_hysteresis, output_level], 'C C C C ?', 0, ''
129
+ check_validity
130
+
131
+ send_request FUNCTION_SET_GPIO_CONFIG, [port, pin, mode, input_hysteresis, output_level], 'C C C C ?', 8, ''
127
132
  end
128
133
 
129
134
  # Example for a getter function. Returns the result of a
130
135
  # XMC_GPIO_GetInput call for the given port/pin.
131
136
  def get_gpio_input(port, pin)
132
- send_request FUNCTION_GET_GPIO_INPUT, [port, pin], 'C C', 1, '?'
137
+ check_validity
138
+
139
+ send_request FUNCTION_GET_GPIO_INPUT, [port, pin], 'C C', 9, '?'
133
140
  end
134
141
 
135
142
  # Enables a ADC channel for the ADC driver example (adc.c/adc.h).
@@ -145,17 +152,23 @@ module Tinkerforge
145
152
  # * Channel 6: P2_1
146
153
  # * Channel 7: P2_2
147
154
  def set_adc_channel_config(channel, enable)
148
- send_request FUNCTION_SET_ADC_CHANNEL_CONFIG, [channel, enable], 'C ?', 0, ''
155
+ check_validity
156
+
157
+ send_request FUNCTION_SET_ADC_CHANNEL_CONFIG, [channel, enable], 'C ?', 8, ''
149
158
  end
150
159
 
151
160
  # Returns the config for the given channel as set by BrickletXMC1400Breakout#set_adc_channel_config.
152
161
  def get_adc_channel_config(channel)
153
- send_request FUNCTION_GET_ADC_CHANNEL_CONFIG, [channel], 'C', 1, '?'
162
+ check_validity
163
+
164
+ send_request FUNCTION_GET_ADC_CHANNEL_CONFIG, [channel], 'C', 9, '?'
154
165
  end
155
166
 
156
167
  # Returns the 12-bit value of the given ADC channel of the ADC driver example.
157
168
  def get_adc_channel_value(channel)
158
- send_request FUNCTION_GET_ADC_CHANNEL_VALUE, [channel], 'C', 2, 'S'
169
+ check_validity
170
+
171
+ send_request FUNCTION_GET_ADC_CHANNEL_VALUE, [channel], 'C', 10, 'S'
159
172
  end
160
173
 
161
174
  # Returns the values for all 8 ADC channels of the adc driver example.
@@ -164,7 +177,9 @@ module Tinkerforge
164
177
  #
165
178
  # See BrickletXMC1400Breakout#set_adc_values_callback_configuration and CALLBACK_ADC_VALUES callback.
166
179
  def get_adc_values
167
- send_request FUNCTION_GET_ADC_VALUES, [], '', 16, 'S8'
180
+ check_validity
181
+
182
+ send_request FUNCTION_GET_ADC_VALUES, [], '', 24, 'S8'
168
183
  end
169
184
 
170
185
  # The period is the period with which the CALLBACK_ADC_VALUES
@@ -177,13 +192,17 @@ module Tinkerforge
177
192
  # If it is set to false, the callback is continuously triggered with the period,
178
193
  # independent of the value.
179
194
  def set_adc_values_callback_configuration(period, value_has_to_change)
180
- send_request FUNCTION_SET_ADC_VALUES_CALLBACK_CONFIGURATION, [period, value_has_to_change], 'L ?', 0, ''
195
+ check_validity
196
+
197
+ send_request FUNCTION_SET_ADC_VALUES_CALLBACK_CONFIGURATION, [period, value_has_to_change], 'L ?', 8, ''
181
198
  end
182
199
 
183
200
  # Returns the callback configuration as set by
184
201
  # BrickletXMC1400Breakout#set_adc_values_callback_configuration.
185
202
  def get_adc_values_callback_configuration
186
- send_request FUNCTION_GET_ADC_VALUES_CALLBACK_CONFIGURATION, [], '', 5, 'L ?'
203
+ check_validity
204
+
205
+ send_request FUNCTION_GET_ADC_VALUES_CALLBACK_CONFIGURATION, [], '', 13, 'L ?'
187
206
  end
188
207
 
189
208
  # Returns the value of the example count (see example.c).
@@ -197,7 +216,9 @@ module Tinkerforge
197
216
  # CALLBACK_COUNT callback. You can set the callback configuration
198
217
  # with BrickletXMC1400Breakout#set_count_callback_configuration.
199
218
  def get_count
200
- send_request FUNCTION_GET_COUNT, [], '', 4, 'L'
219
+ check_validity
220
+
221
+ send_request FUNCTION_GET_COUNT, [], '', 12, 'L'
201
222
  end
202
223
 
203
224
  # The period is the period with which the CALLBACK_COUNT callback is triggered
@@ -226,12 +247,16 @@ module Tinkerforge
226
247
  #
227
248
  # If the option is set to 'x' (threshold turned off) the callback is triggered with the fixed period.
228
249
  def set_count_callback_configuration(period, value_has_to_change, option, min, max)
229
- send_request FUNCTION_SET_COUNT_CALLBACK_CONFIGURATION, [period, value_has_to_change, option, min, max], 'L ? k L L', 0, ''
250
+ check_validity
251
+
252
+ send_request FUNCTION_SET_COUNT_CALLBACK_CONFIGURATION, [period, value_has_to_change, option, min, max], 'L ? k L L', 8, ''
230
253
  end
231
254
 
232
255
  # Returns the callback configuration as set by BrickletXMC1400Breakout#set_count_callback_configuration.
233
256
  def get_count_callback_configuration
234
- send_request FUNCTION_GET_COUNT_CALLBACK_CONFIGURATION, [], '', 14, 'L ? k L L'
257
+ check_validity
258
+
259
+ send_request FUNCTION_GET_COUNT_CALLBACK_CONFIGURATION, [], '', 22, 'L ? k L L'
235
260
  end
236
261
 
237
262
  # Returns the error count for the communication between Brick and Bricklet.
@@ -246,7 +271,9 @@ module Tinkerforge
246
271
  # The errors counts are for errors that occur on the Bricklet side. All
247
272
  # Bricks have a similar function that returns the errors on the Brick side.
248
273
  def get_spitfp_error_count
249
- send_request FUNCTION_GET_SPITFP_ERROR_COUNT, [], '', 16, 'L L L L'
274
+ check_validity
275
+
276
+ send_request FUNCTION_GET_SPITFP_ERROR_COUNT, [], '', 24, 'L L L L'
250
277
  end
251
278
 
252
279
  # Sets the bootloader mode and returns the status after the requested
@@ -259,12 +286,16 @@ module Tinkerforge
259
286
  # This function is used by Brick Viewer during flashing. It should not be
260
287
  # necessary to call it in a normal user program.
261
288
  def set_bootloader_mode(mode)
262
- send_request FUNCTION_SET_BOOTLOADER_MODE, [mode], 'C', 1, 'C'
289
+ check_validity
290
+
291
+ send_request FUNCTION_SET_BOOTLOADER_MODE, [mode], 'C', 9, 'C'
263
292
  end
264
293
 
265
294
  # Returns the current bootloader mode, see BrickletXMC1400Breakout#set_bootloader_mode.
266
295
  def get_bootloader_mode
267
- send_request FUNCTION_GET_BOOTLOADER_MODE, [], '', 1, 'C'
296
+ check_validity
297
+
298
+ send_request FUNCTION_GET_BOOTLOADER_MODE, [], '', 9, 'C'
268
299
  end
269
300
 
270
301
  # Sets the firmware pointer for BrickletXMC1400Breakout#write_firmware. The pointer has
@@ -274,7 +305,9 @@ module Tinkerforge
274
305
  # This function is used by Brick Viewer during flashing. It should not be
275
306
  # necessary to call it in a normal user program.
276
307
  def set_write_firmware_pointer(pointer)
277
- send_request FUNCTION_SET_WRITE_FIRMWARE_POINTER, [pointer], 'L', 0, ''
308
+ check_validity
309
+
310
+ send_request FUNCTION_SET_WRITE_FIRMWARE_POINTER, [pointer], 'L', 8, ''
278
311
  end
279
312
 
280
313
  # Writes 64 Bytes of firmware at the position as written by
@@ -286,7 +319,9 @@ module Tinkerforge
286
319
  # This function is used by Brick Viewer during flashing. It should not be
287
320
  # necessary to call it in a normal user program.
288
321
  def write_firmware(data)
289
- send_request FUNCTION_WRITE_FIRMWARE, [data], 'C64', 1, 'C'
322
+ check_validity
323
+
324
+ send_request FUNCTION_WRITE_FIRMWARE, [data], 'C64', 9, 'C'
290
325
  end
291
326
 
292
327
  # Sets the status LED configuration. By default the LED shows
@@ -297,22 +332,28 @@ module Tinkerforge
297
332
  #
298
333
  # If the Bricklet is in bootloader mode, the LED is will show heartbeat by default.
299
334
  def set_status_led_config(config)
300
- send_request FUNCTION_SET_STATUS_LED_CONFIG, [config], 'C', 0, ''
335
+ check_validity
336
+
337
+ send_request FUNCTION_SET_STATUS_LED_CONFIG, [config], 'C', 8, ''
301
338
  end
302
339
 
303
340
  # Returns the configuration as set by BrickletXMC1400Breakout#set_status_led_config
304
341
  def get_status_led_config
305
- send_request FUNCTION_GET_STATUS_LED_CONFIG, [], '', 1, 'C'
342
+ check_validity
343
+
344
+ send_request FUNCTION_GET_STATUS_LED_CONFIG, [], '', 9, 'C'
306
345
  end
307
346
 
308
- # Returns the temperature in °C as measured inside the microcontroller. The
347
+ # Returns the temperature as measured inside the microcontroller. The
309
348
  # value returned is not the ambient temperature!
310
349
  #
311
350
  # The temperature is only proportional to the real temperature and it has bad
312
351
  # accuracy. Practically it is only useful as an indicator for
313
352
  # temperature changes.
314
353
  def get_chip_temperature
315
- send_request FUNCTION_GET_CHIP_TEMPERATURE, [], '', 2, 's'
354
+ check_validity
355
+
356
+ send_request FUNCTION_GET_CHIP_TEMPERATURE, [], '', 10, 's'
316
357
  end
317
358
 
318
359
  # Calling this function will reset the Bricklet. All configurations
@@ -322,7 +363,9 @@ module Tinkerforge
322
363
  # calling functions on the existing ones will result in
323
364
  # undefined behavior!
324
365
  def reset
325
- send_request FUNCTION_RESET, [], '', 0, ''
366
+ check_validity
367
+
368
+ send_request FUNCTION_RESET, [], '', 8, ''
326
369
  end
327
370
 
328
371
  # Writes a new UID into flash. If you want to set a new UID
@@ -331,25 +374,32 @@ module Tinkerforge
331
374
  #
332
375
  # We recommend that you use Brick Viewer to change the UID.
333
376
  def write_uid(uid)
334
- send_request FUNCTION_WRITE_UID, [uid], 'L', 0, ''
377
+ check_validity
378
+
379
+ send_request FUNCTION_WRITE_UID, [uid], 'L', 8, ''
335
380
  end
336
381
 
337
382
  # Returns the current UID as an integer. Encode as
338
383
  # Base58 to get the usual string version.
339
384
  def read_uid
340
- send_request FUNCTION_READ_UID, [], '', 4, 'L'
385
+ check_validity
386
+
387
+ send_request FUNCTION_READ_UID, [], '', 12, 'L'
341
388
  end
342
389
 
343
390
  # Returns the UID, the UID where the Bricklet is connected to,
344
391
  # the position, the hardware and firmware version as well as the
345
392
  # device identifier.
346
393
  #
347
- # The position can be 'a', 'b', 'c' or 'd'.
394
+ # The position can be 'a', 'b', 'c', 'd', 'e', 'f', 'g' or 'h' (Bricklet Port).
395
+ # The Raspberry Pi HAT (Zero) Brick is always at position 'i' and the Bricklet
396
+ # connected to an :ref:`Isolator Bricklet <isolator_bricklet>` is always as
397
+ # position 'z'.
348
398
  #
349
399
  # The device identifier numbers can be found :ref:`here <device_identifier>`.
350
400
  # |device_identifier_constant|
351
401
  def get_identity
352
- send_request FUNCTION_GET_IDENTITY, [], '', 25, 'Z8 Z8 k C3 C3 S'
402
+ send_request FUNCTION_GET_IDENTITY, [], '', 33, 'Z8 Z8 k C3 C3 S'
353
403
  end
354
404
 
355
405
  # Registers a callback with ID <tt>id</tt> to the block <tt>block</tt>.
@@ -0,0 +1,163 @@
1
+ # -*- ruby encoding: utf-8 -*-
2
+ #############################################################
3
+ # This file was automatically generated on 2020-04-07. #
4
+ # #
5
+ # Ruby Bindings Version 2.1.25 #
6
+ # #
7
+ # If you have a bugfix for this file and want to commit it, #
8
+ # please fix the bug in the generator. You can find a link #
9
+ # to the generators git repository on tinkerforge.com #
10
+ #############################################################
11
+
12
+ module Tinkerforge
13
+ DEVICE_DISPLAY_NAMES = {
14
+ 11 => 'DC Brick',
15
+ 13 => 'Master Brick',
16
+ 14 => 'Servo Brick',
17
+ 15 => 'Stepper Brick',
18
+ 16 => 'IMU Brick',
19
+ 17 => 'RED Brick',
20
+ 18 => 'IMU Brick 2.0',
21
+ 19 => 'Silent Stepper Brick',
22
+ 21 => 'Ambient Light Bricklet',
23
+ 23 => 'Current12 Bricklet',
24
+ 24 => 'Current25 Bricklet',
25
+ 25 => 'Distance IR Bricklet',
26
+ 26 => 'Dual Relay Bricklet',
27
+ 27 => 'Humidity Bricklet',
28
+ 28 => 'IO-16 Bricklet',
29
+ 29 => 'IO-4 Bricklet',
30
+ 111 => 'HAT Brick',
31
+ 112 => 'HAT Zero Brick',
32
+ 210 => 'Joystick Bricklet',
33
+ 211 => 'LCD 16x2 Bricklet',
34
+ 212 => 'LCD 20x4 Bricklet',
35
+ 213 => 'Linear Poti Bricklet',
36
+ 214 => 'Piezo Buzzer Bricklet',
37
+ 215 => 'Rotary Poti Bricklet',
38
+ 216 => 'Temperature Bricklet',
39
+ 217 => 'Temperature IR Bricklet',
40
+ 218 => 'Voltage Bricklet',
41
+ 219 => 'Analog In Bricklet',
42
+ 220 => 'Analog Out Bricklet',
43
+ 221 => 'Barometer Bricklet',
44
+ 222 => 'GPS Bricklet',
45
+ 223 => 'Industrial Digital In 4 Bricklet',
46
+ 224 => 'Industrial Digital Out 4 Bricklet',
47
+ 225 => 'Industrial Quad Relay Bricklet',
48
+ 226 => 'PTC Bricklet',
49
+ 227 => 'Voltage/Current Bricklet',
50
+ 228 => 'Industrial Dual 0-20mA Bricklet',
51
+ 229 => 'Distance US Bricklet',
52
+ 230 => 'Dual Button Bricklet',
53
+ 231 => 'LED Strip Bricklet',
54
+ 232 => 'Moisture Bricklet',
55
+ 233 => 'Motion Detector Bricklet',
56
+ 234 => 'Multi Touch Bricklet',
57
+ 235 => 'Remote Switch Bricklet',
58
+ 236 => 'Rotary Encoder Bricklet',
59
+ 237 => 'Segment Display 4x7 Bricklet',
60
+ 238 => 'Sound Intensity Bricklet',
61
+ 239 => 'Tilt Bricklet',
62
+ 240 => 'Hall Effect Bricklet',
63
+ 241 => 'Line Bricklet',
64
+ 242 => 'Piezo Speaker Bricklet',
65
+ 243 => 'Color Bricklet',
66
+ 244 => 'Solid State Relay Bricklet',
67
+ 246 => 'NFC/RFID Bricklet',
68
+ 249 => 'Industrial Dual Analog In Bricklet',
69
+ 250 => 'Accelerometer Bricklet',
70
+ 251 => 'Analog In Bricklet 2.0',
71
+ 253 => 'Load Cell Bricklet',
72
+ 254 => 'RS232 Bricklet',
73
+ 255 => 'Laser Range Finder Bricklet',
74
+ 256 => 'Analog Out Bricklet 2.0',
75
+ 258 => 'Industrial Analog Out Bricklet',
76
+ 259 => 'Ambient Light Bricklet 2.0',
77
+ 260 => 'Dust Detector Bricklet',
78
+ 262 => 'CO2 Bricklet',
79
+ 263 => 'OLED 128x64 Bricklet',
80
+ 264 => 'OLED 64x48 Bricklet',
81
+ 265 => 'UV Light Bricklet',
82
+ 266 => 'Thermocouple Bricklet',
83
+ 267 => 'Motorized Linear Poti Bricklet',
84
+ 268 => 'Real-Time Clock Bricklet',
85
+ 270 => 'CAN Bricklet',
86
+ 271 => 'RGB LED Bricklet',
87
+ 272 => 'RGB LED Matrix Bricklet',
88
+ 276 => 'GPS Bricklet 2.0',
89
+ 277 => 'RS485 Bricklet',
90
+ 278 => 'Thermal Imaging Bricklet',
91
+ 279 => 'XMC1400 Breakout Bricklet',
92
+ 282 => 'RGB LED Button Bricklet',
93
+ 283 => 'Humidity Bricklet 2.0',
94
+ 284 => 'Industrial Dual Relay Bricklet',
95
+ 285 => 'DMX Bricklet',
96
+ 286 => 'NFC Bricklet',
97
+ 288 => 'Outdoor Weather Bricklet',
98
+ 289 => 'Remote Switch Bricklet 2.0',
99
+ 290 => 'Sound Pressure Level Bricklet',
100
+ 291 => 'Temperature IR Bricklet 2.0',
101
+ 292 => 'Motion Detector Bricklet 2.0',
102
+ 293 => 'Industrial Counter Bricklet',
103
+ 294 => 'Rotary Encoder Bricklet 2.0',
104
+ 295 => 'Analog In Bricklet 3.0',
105
+ 296 => 'Solid State Relay Bricklet 2.0',
106
+ 297 => 'Air Quality Bricklet',
107
+ 298 => 'LCD 128x64 Bricklet',
108
+ 299 => 'Distance US Bricklet 2.0',
109
+ 2100 => 'Industrial Digital In 4 Bricklet 2.0',
110
+ 2101 => 'PTC Bricklet 2.0',
111
+ 2102 => 'Industrial Quad Relay Bricklet 2.0',
112
+ 2103 => 'LED Strip Bricklet 2.0',
113
+ 2104 => 'Load Cell Bricklet 2.0',
114
+ 2105 => 'Voltage/Current Bricklet 2.0',
115
+ 2106 => 'Real-Time Clock Bricklet 2.0',
116
+ 2107 => 'CAN Bricklet 2.0',
117
+ 2108 => 'RS232 Bricklet 2.0',
118
+ 2109 => 'Thermocouple Bricklet 2.0',
119
+ 2110 => 'Particulate Matter Bricklet',
120
+ 2111 => 'IO-4 Bricklet 2.0',
121
+ 2112 => 'OLED 128x64 Bricklet 2.0',
122
+ 2113 => 'Temperature Bricklet 2.0',
123
+ 2114 => 'IO-16 Bricklet 2.0',
124
+ 2115 => 'Analog Out Bricklet 3.0',
125
+ 2116 => 'Industrial Analog Out Bricklet 2.0',
126
+ 2117 => 'Barometer Bricklet 2.0',
127
+ 2118 => 'UV Light Bricklet 2.0',
128
+ 2119 => 'Dual Button Bricklet 2.0',
129
+ 2120 => 'Industrial Dual 0-20mA Bricklet 2.0',
130
+ 2121 => 'Industrial Dual Analog In Bricklet 2.0',
131
+ 2122 => 'Isolator Bricklet',
132
+ 2123 => 'One Wire Bricklet',
133
+ 2124 => 'Industrial Digital Out 4 Bricklet 2.0',
134
+ 2125 => 'Distance IR Bricklet 2.0',
135
+ 2127 => 'RGB LED Bricklet 2.0',
136
+ 2128 => 'Color Bricklet 2.0',
137
+ 2129 => 'Multi Touch Bricklet 2.0',
138
+ 2130 => 'Accelerometer Bricklet 2.0',
139
+ 2131 => 'Ambient Light Bricklet 3.0',
140
+ 2132 => 'Hall Effect Bricklet 2.0',
141
+ 2137 => 'Segment Display 4x7 Bricklet 2.0',
142
+ 2138 => 'Joystick Bricklet 2.0',
143
+ 2139 => 'Linear Poti Bricklet 2.0',
144
+ 2140 => 'Rotary Poti Bricklet 2.0',
145
+ 2144 => 'Laser Range Finder Bricklet 2.0',
146
+ 2145 => 'Piezo Speaker Bricklet 2.0',
147
+ 2146 => 'E-Paper 296x128 Bricklet',
148
+ 2147 => 'CO2 Bricklet 2.0',
149
+ 2152 => 'Energy Monitor Bricklet',
150
+ 2153 => 'Compass Bricklet'
151
+ }
152
+
153
+ # internal
154
+ def get_device_display_name(device_identifier)
155
+ device_display_name = DEVICE_DISPLAY_NAMES[device_identifier]
156
+
157
+ if device_display_name == nil
158
+ device_display_name = "Unknown Device [#{device_identifier}]"
159
+ end
160
+
161
+ device_display_name
162
+ end
163
+ end
@@ -1,5 +1,5 @@
1
1
  # -*- ruby encoding: utf-8 -*-
2
- # Copyright (C) 2012-2014, 2019 Matthias Bolte <matthias@tinkerforge.com>
2
+ # Copyright (C) 2012-2014, 2019-2020 Matthias Bolte <matthias@tinkerforge.com>
3
3
  #
4
4
  # Redistribution and use in source and binary forms of this file,
5
5
  # with or without modification, are permitted. See the Creative
@@ -10,8 +10,10 @@ require 'thread'
10
10
  require 'timeout'
11
11
  require 'securerandom'
12
12
  require 'openssl'
13
+ require_relative './device_display_names'
13
14
 
14
15
  module Tinkerforge
16
+ # internal
15
17
  class Base58
16
18
  ALPHABET = '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'
17
19
 
@@ -64,6 +66,16 @@ module Tinkerforge
64
66
  class StreamOutOfSyncException < TinkerforgeException
65
67
  end
66
68
 
69
+ class WrongDeviceTypeException < TinkerforgeException
70
+ end
71
+
72
+ class DeviceReplacedException < TinkerforgeException
73
+ end
74
+
75
+ class WrongResponseLengthException < TinkerforgeException
76
+ end
77
+
78
+ # internal
67
79
  class Packer
68
80
  def self.pack(unpacked, format)
69
81
  data = ''
@@ -207,12 +219,18 @@ module Tinkerforge
207
219
  end
208
220
  end
209
221
 
222
+ # internal
210
223
  class Device
224
+ DEVICE_IDENTIFIER_CHECK_PENDING = 0
225
+ DEVICE_IDENTIFIER_CHECK_MATCH = 1
226
+ DEVICE_IDENTIFIER_CHECK_MISMATCH = 2
227
+
211
228
  RESPONSE_EXPECTED_INVALID_FUNCTION_ID = 0
212
229
  RESPONSE_EXPECTED_ALWAYS_TRUE = 1 # getter
213
230
  RESPONSE_EXPECTED_TRUE = 2 # setter
214
231
  RESPONSE_EXPECTED_FALSE = 3 # setter, default
215
232
 
233
+ attr_accessor :replaced
216
234
  attr_accessor :uid
217
235
  attr_accessor :expected_response_function_id
218
236
  attr_accessor :expected_response_sequence_number
@@ -220,10 +238,11 @@ module Tinkerforge
220
238
  attr_accessor :high_level_callbacks
221
239
  attr_accessor :registered_callbacks
222
240
 
223
- # Creates the device object with the unique device ID <tt>uid</tt> and adds
224
- # it to the IPConnection <tt>ipcon</tt>.
225
- def initialize(uid, ipcon)
241
+ # internal
242
+ def initialize(uid, ipcon, device_identifier, device_display_name)
243
+ @replaced = false
226
244
  @uid = Base58.decode uid
245
+ @uid_string = uid
227
246
 
228
247
  if @uid > (1 << 64) - 1
229
248
  raise ArgumentError, "UID '#{uid}' is too big"
@@ -249,6 +268,12 @@ module Tinkerforge
249
268
 
250
269
  @ipcon = ipcon
251
270
 
271
+ @device_identifier = device_identifier
272
+ @device_display_name = device_display_name
273
+ @device_identifier_lock = Mutex.new
274
+ @device_identifier_check = DEVICE_IDENTIFIER_CHECK_PENDING # protected by device_identifier_lock
275
+ @wrong_device_display_name = '?' # protected by device_identifier_lock
276
+
252
277
  @request_mutex = Mutex.new
253
278
 
254
279
  @response_expected = Array.new(256, RESPONSE_EXPECTED_INVALID_FUNCTION_ID)
@@ -265,8 +290,6 @@ module Tinkerforge
265
290
  @callback_formats = {}
266
291
  @high_level_callbacks = {}
267
292
  @registered_callbacks = {}
268
-
269
- @ipcon.devices[@uid] = self # FIXME: use a weakref here
270
293
  end
271
294
 
272
295
  # Returns the API version (major, minor, revision) of the bindings for
@@ -288,7 +311,7 @@ module Tinkerforge
288
311
  # Enabling the response expected flag for a setter function allows to
289
312
  # detect timeouts and other error conditions calls of this setter as
290
313
  # well. The device will then send a response for this purpose. If this
291
- # flag is disabled for a setter function then no response is send and
314
+ # flag is disabled for a setter function then no response is sent and
292
315
  # errors are silently ignored, because they cannot be detected.
293
316
  def get_response_expected(function_id)
294
317
  if function_id < 0 or function_id > 255
@@ -317,7 +340,7 @@ module Tinkerforge
317
340
  # Enabling the response expected flag for a setter function allows to
318
341
  # detect timeouts and other error conditions calls of this setter as
319
342
  # well. The device will then send a response for this purpose. If this
320
- # flag is disabled for a setter function then no response is send and
343
+ # flag is disabled for a setter function then no response is sent and
321
344
  # errors are silently ignored, because they cannot be detected.
322
345
  def set_response_expected(function_id, response_expected)
323
346
  if function_id < 0 or function_id > 255
@@ -360,7 +383,7 @@ module Tinkerforge
360
383
 
361
384
  # internal
362
385
  def send_request(function_id, request_data, request_format,
363
- response_length, response_format)
386
+ expected_response_length, response_format)
364
387
  response = nil
365
388
 
366
389
  if request_data.length > 0
@@ -402,7 +425,13 @@ module Tinkerforge
402
425
  error_code = Packer.get_error_code_from_data packet
403
426
 
404
427
  if error_code == 0
405
- # no error
428
+ if expected_response_length == 0
429
+ expected_response_length = 8 # setter with response-expected enabled
430
+ end
431
+
432
+ if packet.length != expected_response_length
433
+ raise WrongResponseLengthException, "Expected response of #{expected_response_length} byte for function ID #{function_id}, got #{packet.length} byte instead"
434
+ end
406
435
  elsif error_code == 1
407
436
  raise InvalidParameterException, "Got invalid parameter for function ID #{function_id}"
408
437
  elsif error_code == 2
@@ -411,7 +440,7 @@ module Tinkerforge
411
440
  raise UnknownErrorCodeException, "Function ID #{function_id} returned an unknown error"
412
441
  end
413
442
 
414
- if response_length > 0
443
+ if response_format.length > 0
415
444
  response = Packer.unpack packet[8..-1], response_format
416
445
 
417
446
  if response.length == 1
@@ -449,6 +478,34 @@ module Tinkerforge
449
478
 
450
479
  response
451
480
  end
481
+
482
+ # internal
483
+ def check_validity()
484
+ if @replaced
485
+ raise DeviceReplacedException, 'Device has been replaced'
486
+ end
487
+
488
+ if @device_identifier_check == DEVICE_IDENTIFIER_CHECK_MATCH
489
+ return
490
+ end
491
+
492
+ @device_identifier_lock.synchronize {
493
+ if @device_identifier_check == DEVICE_IDENTIFIER_CHECK_PENDING
494
+ device_identifier = send_request(255, [], '', 33, 'Z8 Z8 k C3 C3 S')[5] # <device>.get_identity
495
+
496
+ if device_identifier == @device_identifier
497
+ @device_identifier_check = DEVICE_IDENTIFIER_CHECK_MATCH
498
+ else
499
+ @device_identifier_check = DEVICE_IDENTIFIER_CHECK_MISMATCH
500
+ @wrong_device_display_name = get_device_display_name device_identifier
501
+ end
502
+ end
503
+
504
+ if @device_identifier_check == DEVICE_IDENTIFIER_CHECK_MISMATCH
505
+ raise WrongDeviceTypeException, "UID #{@uid_string} belongs to a #{@wrong_device_display_name} instead of the expected #{@device_display_name}"
506
+ end
507
+ }
508
+ end
452
509
  end
453
510
 
454
511
  # internal
@@ -474,16 +531,18 @@ module Tinkerforge
474
531
  # Creates an object with the unique device ID <tt>uid</tt> and adds it to
475
532
  # the IP Connection <tt>ipcon</tt>.
476
533
  def initialize(uid, ipcon)
477
- super uid, ipcon
534
+ super uid, ipcon, 0, 'Brick Daemon'
478
535
 
479
536
  @api_version = [2, 0, 0]
480
537
 
481
538
  @response_expected[FUNCTION_GET_AUTHENTICATION_NONCE] = RESPONSE_EXPECTED_ALWAYS_TRUE
482
539
  @response_expected[FUNCTION_AUTHENTICATE] = RESPONSE_EXPECTED_TRUE
540
+
541
+ @ipcon.add_device self
483
542
  end
484
543
 
485
544
  def get_authentication_nonce
486
- send_request FUNCTION_GET_AUTHENTICATION_NONCE, [], '', 4, 'C4'
545
+ send_request FUNCTION_GET_AUTHENTICATION_NONCE, [], '', 12, 'C4'
487
546
  end
488
547
 
489
548
  def authenticate(client_nonce, digest)
@@ -492,7 +551,6 @@ module Tinkerforge
492
551
  end
493
552
 
494
553
  class IPConnection
495
- attr_accessor :devices
496
554
  attr_accessor :timeout
497
555
 
498
556
  CALLBACK_ENUMERATE = 253
@@ -538,6 +596,7 @@ module Tinkerforge
538
596
  @authentication_mutex = Mutex.new # protects authentication handshake
539
597
 
540
598
  @devices = {}
599
+ @replace_mutex = Mutex.new # used to synchronize replacements in the devices dict
541
600
 
542
601
  @registered_callbacks = {}
543
602
 
@@ -731,6 +790,19 @@ module Tinkerforge
731
790
  @registered_callbacks[id] = callback
732
791
  end
733
792
 
793
+ # internal
794
+ def add_device(device)
795
+ @replace_mutex.synchronize {
796
+ replaced_device = @devices.fetch device.uid, nil
797
+
798
+ if replaced_device != nil
799
+ replaced_device.replaced = true
800
+ end
801
+
802
+ @devices[device.uid] = device # FIXME: use a weakref here
803
+ }
804
+ end
805
+
734
806
  # internal
735
807
  def get_next_sequence_number
736
808
  @sequence_number_mutex.synchronize {
@@ -951,8 +1023,10 @@ module Tinkerforge
951
1023
  # internal
952
1024
  def dispatch_meta(function_id, parameter, socket_id)
953
1025
  if function_id == CALLBACK_CONNECTED
954
- if @registered_callbacks.has_key? CALLBACK_CONNECTED
955
- @registered_callbacks[CALLBACK_CONNECTED].call parameter
1026
+ cb = @registered_callbacks[CALLBACK_CONNECTED]
1027
+
1028
+ if cb != nil
1029
+ cb.call parameter
956
1030
  end
957
1031
  elsif function_id == CALLBACK_DISCONNECTED
958
1032
  if parameter != DISCONNECT_REASON_REQUEST
@@ -980,8 +1054,10 @@ module Tinkerforge
980
1054
  # socket. the first receive will then fail directly
981
1055
  sleep 0.1
982
1056
 
983
- if @registered_callbacks.has_key? CALLBACK_DISCONNECTED
984
- @registered_callbacks[CALLBACK_DISCONNECTED].call parameter
1057
+ cb = @registered_callbacks[CALLBACK_DISCONNECTED]
1058
+
1059
+ if cb != nil
1060
+ cb.call parameter
985
1061
  end
986
1062
 
987
1063
  if parameter != DISCONNECT_REASON_REQUEST and @auto_reconnect and @auto_reconnect_allowed
@@ -1018,16 +1094,41 @@ module Tinkerforge
1018
1094
  uid = Packer.get_uid_from_data packet
1019
1095
  function_id = Packer.get_function_id_from_data packet
1020
1096
 
1021
- if function_id == CALLBACK_ENUMERATE and \
1022
- @registered_callbacks.has_key? CALLBACK_ENUMERATE
1097
+ if function_id == CALLBACK_ENUMERATE
1098
+ cb = @registered_callbacks[CALLBACK_ENUMERATE]
1099
+
1100
+ if cb == nil
1101
+ return
1102
+ end
1103
+
1104
+ if packet.length != 34
1105
+ return # silently ignoring callback with wrong length
1106
+ end
1107
+
1023
1108
  payload = Packer.unpack packet[8..-1], 'Z8 Z8 k C3 C3 S C'
1024
- @registered_callbacks[CALLBACK_ENUMERATE].call(*payload)
1025
- elsif @devices.has_key? uid
1026
- device = @devices[uid]
1109
+
1110
+ cb.call(*payload)
1111
+ return
1112
+ end
1113
+
1114
+ device = @devices[uid]
1115
+
1116
+ if device != nil
1117
+ begin
1118
+ device.check_validity
1119
+ rescue TinkerforgeException
1120
+ return # silently ignoring callback for invalid device
1121
+ end
1027
1122
 
1028
1123
  if device.high_level_callbacks.has_key?(-function_id)
1029
1124
  hlcb = device.high_level_callbacks[-function_id] # [roles, options, data]
1030
- payload = Packer.unpack packet[8..-1], device.callback_formats[function_id]
1125
+ format = device.callback_formats[function_id] # FIXME: currently assuming that low-level callback has more than one element
1126
+
1127
+ if packet.length != format[0]
1128
+ return # silently ignoring callback with wrong length
1129
+ end
1130
+
1131
+ payload = Packer.unpack packet[8..-1], format[1]
1031
1132
  has_data = false
1032
1133
  data = nil
1033
1134
 
@@ -1071,7 +1172,9 @@ module Tinkerforge
1071
1172
  end
1072
1173
  end
1073
1174
 
1074
- if has_data and device.registered_callbacks.has_key?(-function_id)
1175
+ cb = device.registered_callbacks[-function_id]
1176
+
1177
+ if has_data and cb != nil
1075
1178
  result = []
1076
1179
 
1077
1180
  hlcb[0].zip(payload).each do |role, value|
@@ -1082,14 +1185,27 @@ module Tinkerforge
1082
1185
  end
1083
1186
  end
1084
1187
 
1085
- device.registered_callbacks[-function_id].call(*result)
1188
+ cb.call(*result)
1086
1189
  end
1087
1190
  end
1088
1191
  end
1089
1192
 
1090
- if device.registered_callbacks.has_key? function_id
1091
- payload = Packer.unpack packet[8..-1], device.callback_formats[function_id]
1092
- device.registered_callbacks[function_id].call(*payload)
1193
+ cb = device.registered_callbacks[function_id]
1194
+
1195
+ if cb != nil
1196
+ format = device.callback_formats[function_id]
1197
+
1198
+ if format == nil
1199
+ return # silently ignore registered but unknown callback
1200
+ end
1201
+
1202
+ if packet.length != format[0]
1203
+ return # silently ignoring callback with wrong length
1204
+ end
1205
+
1206
+ payload = Packer.unpack packet[8..-1], format[1]
1207
+
1208
+ cb.call(*payload)
1093
1209
  end
1094
1210
  end
1095
1211
  end
@@ -1172,7 +1288,6 @@ module Tinkerforge
1172
1288
  def handle_response(packet)
1173
1289
  @disconnect_probe_flag = false
1174
1290
 
1175
- uid = Packer.get_uid_from_data packet
1176
1291
  function_id = Packer.get_function_id_from_data packet
1177
1292
  sequence_number = Packer.get_sequence_number_from_data packet
1178
1293
 
@@ -1180,9 +1295,13 @@ module Tinkerforge
1180
1295
  if @registered_callbacks.has_key? CALLBACK_ENUMERATE
1181
1296
  @callback.queue.push [QUEUE_KIND_PACKET, packet]
1182
1297
  end
1183
- elsif @devices.has_key? uid
1184
- device = @devices[uid]
1298
+ return
1299
+ end
1300
+
1301
+ uid = Packer.get_uid_from_data packet
1302
+ device = @devices[uid]
1185
1303
 
1304
+ if device != nil
1186
1305
  if sequence_number == 0
1187
1306
  if device.registered_callbacks.has_key? function_id or \
1188
1307
  device.high_level_callbacks.has_key?(-function_id)