ruby-xbee 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,608 @@
1
+ $: << File.dirname(__FILE__)
2
+ require 'frame/frame'
3
+ require File.dirname(File.dirname(__FILE__)) + '/ruby_xbee'
4
+
5
+ module XBee
6
+ class BaseAPIModeInterface < RFModule
7
+
8
+ VERSION = "1.1.0" # Version of this class
9
+
10
+ def initialize(xbee_usbdev_str, uart_config = XBeeUARTConfig.new, operation_mode = :AT, transmission_mode = :SYNC)
11
+ super(xbee_usbdev_str, uart_config, operation_mode, transmission_mode)
12
+ @frame_id = 1
13
+ if self.operation_mode == :AT
14
+ start_apimode_communication
15
+ end
16
+ end
17
+
18
+ def next_frame_id
19
+ @frame_id += 1
20
+ end
21
+
22
+ ##
23
+ # Switch to API mode - note that in Series 2 the Operation Mode is defined
24
+ # by the firmware flashed to the device. Only Series 1 can switch from
25
+ # AT (Transparent) to API Opearation and back seamlessly.
26
+ def start_apimode_communication
27
+ in_command_mode do
28
+ puts "Entering api mode"
29
+ # Set API Mode 2 (include escaped characters)
30
+ self.xbee_serialport.write("ATAP2\r")
31
+ self.xbee_serialport.read(3)
32
+ end
33
+ end
34
+
35
+ def get_param(at_param_name, at_param_unpack_string = nil)
36
+ frame_id = self.next_frame_id
37
+ at_command_frame = XBee::Frame::ATCommand.new(at_param_name,frame_id,nil,at_param_unpack_string)
38
+ puts "Sending ... [#{at_command_frame._dump.unpack("C*").join(", ")}]"
39
+ self.xbee_serialport.write(at_command_frame._dump)
40
+ if self.transmission_mode == :SYNC
41
+ r = XBee::Frame.new(self.xbee_serialport)
42
+ if r.kind_of?(XBee::Frame::ATCommandResponse) && r.status == :OK && r.frame_id == frame_id
43
+ if block_given?
44
+ yield r
45
+ else
46
+ #### DEBUG ####
47
+ if $DEBUG then
48
+ print "At parameter unpack string to be used: #{at_param_unpack_string} | "
49
+ puts "Debug Return value for value: #{r.retrieved_value.unpack(at_param_unpack_string)}"
50
+ end
51
+ #### DEBUG ####
52
+ at_param_unpack_string.nil? ? r.retrieved_value : r.retrieved_value.unpack(at_param_unpack_string).first
53
+ end
54
+ else
55
+ raise "Response did not indicate successful retrieval of that parameter: #{r.inspect}"
56
+ end
57
+ end
58
+ end
59
+
60
+ def set_param(at_param_name, param_value, at_param_unpack_string = nil)
61
+ frame_id = self.next_frame_id
62
+ at_command_frame = XBee::Frame::ATCommand.new(at_param_name,frame_id,param_value,at_param_unpack_string)
63
+ # puts "Sending ... [#{at_command_frame._dump.unpack("C*").join(", ")}]"
64
+ self.xbee_serialport.write(at_command_frame._dump)
65
+ if self.transmission_mode == :SYNC
66
+ r = XBee::Frame.new(self.xbee_serialport)
67
+ if r.kind_of?(XBee::Frame::ATCommandResponse) && r.status == :OK && r.frame_id == frame_id
68
+ if block_given?
69
+ yield r
70
+ else
71
+ at_param_unpack_string.nil? ? r.retrieved_value : r.retrieved_value.unpack(at_param_unpack_string).first
72
+ end
73
+ else
74
+ raise "Response did not indicate successful retrieval of that parameter: #{r.inspect}"
75
+ end
76
+ end
77
+ end
78
+
79
+ def get_remote_param(at_param_name, remote_address = 0x000000000000ffff, remote_network_address = 0xfffe, at_param_unpack_string = nil)
80
+ frame_id = self.next_frame_id
81
+ at_command_frame = XBee::Frame::RemoteCommandRequest.new(at_param_name, remote_address, remote_network_address, frame_id, nil, at_param_unpack_string)
82
+ puts "Sending ... [#{at_command_frame._dump.unpack("C*").join(", ")}]"
83
+ self.xbee_serialport.write(at_command_frame._dump)
84
+ if self.transmission_mode == :SYNC
85
+ r = XBee::Frame.new(self.xbee_serialport)
86
+ if r.kind_of?(XBee::Frame::RemoteCommandResponse) && r.status == :OK && r.frame_id == frame_id
87
+ if block_given?
88
+ yield r
89
+ else
90
+ at_param_unpack_string.nil? ? r.retrieved_value : r.retrieved_value.unpack(at_param_unpack_string).first
91
+ end
92
+ else
93
+ raise "Response did not indicate successful retrieval of that parameter: #{r.inspect}"
94
+ end
95
+ end
96
+ end
97
+
98
+ def set_remote_param(at_param_name, param_value, remote_address = 0x000000000000ffff, remote_network_address = 0xfffe, at_param_unpack_string = nil)
99
+ frame_id = self.next_frame_id
100
+ at_command_frame = XBee::Frame::RemoteCommandRequest.new(at_param_name, remote_address, remote_network_address, frame_id, param_value, at_param_unpack_string)
101
+ puts "Sending ... [#{at_command_frame._dump.unpack("C*").join(", ")}]"
102
+ self.xbee_serialport.write(at_command_frame._dump)
103
+ if self.transmission_mode == :SYNC
104
+ r = XBee::Frame.new(self.xbee_serialport)
105
+ if r.kind_of?(XBee::Frame::RemoteCommandResponse) && r.status == :OK && r.frame_id == frame_id
106
+ if block_given?
107
+ yield r
108
+ else
109
+ at_param_unpack_string.nil? ? r.retrieved_value : r.retrieved_value.unpack(at_param_unpack_string).first
110
+ end
111
+ else
112
+ raise "Response did not indicate successful retrieval of that parameter: #{r.inspect}"
113
+ end
114
+ end
115
+ end
116
+
117
+ ##
118
+ # Association Indication. Read information regarding last node join request:
119
+ # * 0x00 - Successful completion - Coordinator started or Router/End Device found and joined with a parent.
120
+ # * 0x21 - Scan found no PANs
121
+ # * 0x22 - Scan found no valid PANs based on current SC and ID settings
122
+ # * 0x23 - Valid Coordinator or Routers found, but they are not allowing joining (NJ expired) 0x27 - Node Joining attempt failed
123
+ # * 0x2A - Coordinator Start attempt failed‘
124
+ # * 0xFF - Scanning for a Parent
125
+ def association_indication
126
+ @association_indication ||= get_param("AI","n")
127
+ if @association_indication == nil then @association_indication = 0 end
128
+ end
129
+
130
+ ##
131
+ # Retrieve XBee firmware version
132
+ def fw_rev
133
+ @fw_rev ||= get_param("VR","n")
134
+ end
135
+
136
+ ##
137
+ # Retrieve XBee hardware version
138
+ def hw_rev
139
+ @hw_rev ||= get_param("HV","n")
140
+ end
141
+
142
+ ##
143
+ # Neighbor node discovery. Returns an array of hashes each element of the array contains a hash
144
+ # each hash contains keys: :MY, :SH, :SL, :DB, :NI
145
+ # representing addresses source address, Serial High, Serial Low, Received signal strength,
146
+ # node identifier respectively. Aan example of the results returned (hash as seen by pp):
147
+ #
148
+ # [{:NI=>" ", :MY=>"0", :SH=>"13A200", :SL=>"4008A642", :DB=>-24},
149
+ # {:NI=>" ", :MY=>"0", :SH=>"13A200", :SL=>"4008A697", :DB=>-33},
150
+ # {:NI=>" ", :MY=>"0", :SH=>"13A200", :SL=>"40085AD5", :DB=>-52}]
151
+ #
152
+ # Signal strength (:DB) is reported in units of -dBM.
153
+ def neighbors
154
+ frame_id = self.next_frame_id
155
+ # neighbors often takes more than 1000ms to return data
156
+ node_discover_cmd = XBee::Frame::ATCommand.new("ND",frame_id,nil)
157
+ #puts "Node discover command dump: #{node_discover_cmd._dump.unpack("C*").join(", ")}"
158
+ tmp = @xbee_serialport.read_timeout
159
+ @xbee_serialport.read_timeout = Integer(self.node_discover_timeout.in_seconds * 1050)
160
+ @xbee_serialport.write(node_discover_cmd._dump)
161
+ responses = []
162
+ #read_thread = Thread.new do
163
+ begin
164
+ loop do
165
+ r = XBee::Frame.new(self.xbee_serialport)
166
+ # puts "Got a response! Frame ID: #{r.frame_id}, Command: #{r.at_command}, Status: #{r.status}, Value: #{r.retrieved_value}"
167
+ if r.kind_of?(XBee::Frame::ATCommandResponse) && r.status == :OK && r.frame_id == frame_id
168
+ if r.retrieved_value.empty?
169
+ # w00t - the module is telling us it's done with the discovery process.
170
+ break
171
+ else
172
+ responses << r
173
+ end
174
+ else
175
+ raise "Unexpected response to ATND command: #{r.inspect}"
176
+ end
177
+ end
178
+ rescue Exception => e
179
+ puts "Okay, must have finally timed out on the serial read: #{e}."
180
+ end
181
+ @xbee_serialport.read_timeout = tmp
182
+ responses.map do |r|
183
+ unpacked_fields = r.retrieved_value.unpack("nNNZxnCCnn")
184
+ return_fields = [:SH, :SL, :NI, :PARENT_NETWORK_ADDRESS, :DEVICE_TYPE, :STATUS, :PROFILE_ID, :MANUFACTURER_ID]
185
+ unpacked_fields.shift #Throw out the junk at the start of the discover packet
186
+ return_fields.inject(Hash.new) do |return_hash, field_name|
187
+ return_hash[field_name] = unpacked_fields.shift
188
+ return_hash
189
+ end
190
+ end
191
+ end
192
+
193
+ ##
194
+ # Returns the low portion of the XBee device's current destination address
195
+ def destination_low
196
+ @destination_low ||= get_param("DL")
197
+ end
198
+
199
+ ##
200
+ # Sets the low portion of the XBee device's destination address
201
+ # Parameter range: 0 - 0xFFFFFFFF
202
+ def destination_low!(low_addr)
203
+ @xbee_serialport.write("ATDL#{low_addr}\r")
204
+ getresponse if self.transmission_mode == :SYNC
205
+ end
206
+
207
+ ##
208
+ # Returns the high portion of the XBee device's current destination address
209
+ def destination_high
210
+ @destination_high ||= get_param("DH")
211
+ end
212
+
213
+ ##
214
+ # Sets the high portion of the XBee device's current destination address
215
+ # Parameter range: 0 - 0xFFFFFFFF
216
+ def destination_high!(high_addr)
217
+ self.xbee_serialport.write("ATDH#{high_addr}\r")
218
+ getresponse if self.transmission_mode == :SYNC
219
+ end
220
+
221
+ ##
222
+ # Returns the low portion of the XBee device's serial number. this value is factory set.
223
+ def serial_num_low
224
+ @serial_low ||= get_param("SL","N")
225
+ end
226
+
227
+ ##
228
+ # Returns the high portion of the XBee device's serial number. this value is factory set.
229
+ def serial_num_high
230
+ @serial_high ||= get_param("SH","N")
231
+ end
232
+
233
+ ##
234
+ # Returns the complete serialnumber of XBee device by quering the high and low parts.
235
+ def serial_num
236
+ self.serial_num_high() << 32 | self.serial_num_low
237
+ end
238
+
239
+ ##
240
+ # returns the channel number of the XBee device. this value, along with the PAN ID,
241
+ # and MY address determines the addressability of the device and what it can listen to
242
+ def channel
243
+ # channel often takes more than 1000ms to return data
244
+ tmp = @xbee_serialport.read_timeout
245
+ @xbee_serialport.read_timeout = read_timeout(:long)
246
+ @xbee_serialport.write("ATCH\r")
247
+ if self.tranmission_mode == :SYNC
248
+ response = getresponse
249
+ @xbee_serialport.read_timeout = tmp
250
+ response.strip.chomp
251
+ end
252
+ end
253
+
254
+ ##
255
+ # sets the channel number of the device. The valid channel numbers are those of the 802.15.4 standard.
256
+ def channel!(new_channel)
257
+ # channel takes more than 1000ms to return data
258
+ tmp = @xbee_serialport.read_timeout
259
+ @xbee_serialport.read_timeout = read_timeout(:long)
260
+ @xbee_serialport.write("ATCH#{new_channel}\r")
261
+ if self.transmission_mode == :SYNC
262
+ response = getresponse
263
+ @xbee_serialport.read_timeout = tmp
264
+ response.strip.chomp
265
+ end
266
+ end
267
+
268
+ ##
269
+ # returns the node ID of the device. Node ID is typically a human-meaningful name
270
+ # to give to the XBee device, much like a hostname.
271
+ def node_id
272
+ @node_id ||= get_param("NI")
273
+ end
274
+
275
+ ##
276
+ # sets the node ID to a user-definable text string to make it easier to
277
+ # identify the device with "human" names. This node id is reported to
278
+ # neighboring XBees so consider it "public".
279
+ def node_id!(new_id)
280
+ tmp = @xbee_serialport.read_timeout
281
+ @xbee_serialport.read_timeout = read_timeout(:long)
282
+ @xbee_serialport.write("ATNI#{new_id}\r")
283
+ if self.transmission_mode == :SYNC
284
+ response = getresponse
285
+ @xbee_serialport.read_timeout = tmp
286
+ if ( response.nil? )
287
+ return ""
288
+ else
289
+ response.strip.chomp
290
+ end
291
+ end
292
+ end
293
+
294
+ ##
295
+ # returns the PAN ID of the device. PAN ID is one of the 3 main identifiers used to
296
+ # communicate with the device from other XBees. All XBees which are meant to communicate
297
+ # must have the same PAN ID and channel number. The 3rd identifier is the address of the
298
+ # device itself represented by its serial number (High and Low) and/or it's 16-bit MY
299
+ # source address.
300
+ def pan_id
301
+ @pan_id ||= get_param("ID").unpack("n")
302
+ end
303
+
304
+ ##
305
+ # sets the PAN ID of the device. Modules must have the same PAN ID in order to communicate
306
+ # with each other. The PAN ID value can range from 0 - 0xffff. The default from the factory
307
+ # is set to 0x3332.
308
+ def pan_id!(new_id)
309
+ @xbee_serialport.write("ATID#{new_id}\r")
310
+ getresponse if self.transmission_mode == :SYNC
311
+ end
312
+
313
+ ##
314
+ # returns the signal strength in dBm units of the last received packet. Expect a negative integer
315
+ # or 0 to be returned. If the XBee device has not received any neighboring packet data, the signal strength
316
+ # value will be 0
317
+ def received_signal_strength
318
+ -(get_param("DB").hex)
319
+ end
320
+
321
+ ##
322
+ # retrieves the baud rate of the device. Generally, this will be the same as the
323
+ # rate you're currently using to talk to the device unless you've changed the device's
324
+ # baud rate and are still in the AT command mode and/or have not exited command mode explicitly for
325
+ # the new baud rate to take effect.
326
+ def baud
327
+ @xbee_serialport.write("ATBD\r")
328
+ baudcode = getresponse
329
+ @baudcodes.index( baudcode.to_i )
330
+ end
331
+
332
+ ##
333
+ # sets the given baud rate into the XBee device. The baud change will not take
334
+ # effect until the AT command mode times out or the exit command mode command is given.
335
+ # acceptable baud rates are: 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200
336
+ def baud!( baud_rate )
337
+ @xbee_serialport.write("ATBD#{@baudcodes[baud_rate]}\r")
338
+ getresponse if self.transmission_mode == :SYNC
339
+ end
340
+
341
+ ##
342
+ # returns the parity of the device as represented by a symbol:
343
+ # :None - for 8-bit none
344
+ # :Even - for 8-bit even
345
+ # :Odd - for 8-bit odd
346
+ # :Mark - for 8-bit mark
347
+ # :Space - for 8-bit space
348
+ def parity
349
+ @xbee_serialport.write("ATNB\r")
350
+ if self.transmission_mode == :SYNC
351
+ response = getresponse().strip.chomp
352
+ @paritycodes.index( response.to_i )
353
+ end
354
+ end
355
+
356
+ ##
357
+ # sets the parity of the device to one represented by a symbol contained in the parity_type parameter
358
+ # :None - for 8-bit none
359
+ # :Even - for 8-bit even
360
+ # :Odd - for 8-bit odd
361
+ # :Mark - for 8-bit mark
362
+ # :Space - for 8-bit space
363
+ def parity!( parity_type )
364
+ # validate symbol before writing parity param
365
+ if !@paritycodes.include?(parity_type)
366
+ return false
367
+ end
368
+ @xbee_serialport.write("ATNB#{@paritycodes[parity_type]}\r")
369
+ getresponse if self.transmission_mode == :SYNC
370
+ end
371
+
372
+ ##
373
+ # reads an i/o port configuration on the XBee for analog to digital or digital input or output (GPIO)
374
+ # this method returns an I/O type symbol of:
375
+ #
376
+ # :Disabled
377
+ # :ADC
378
+ # :DI
379
+ # :DO_Low
380
+ # :DO_High
381
+ # :Associated_Indicator
382
+ # :RTS
383
+ # :CTS
384
+ # :RS485_Low
385
+ # :RS485_High
386
+ #
387
+ # Not all DIO ports are capable of every configuration listed above. This method will properly translate
388
+ # the XBee's response value to the symbol above when the same value has different meanings from port to port.
389
+ #
390
+ # The port parameter may be any symbol :D0 through :D8 representing the 8 I/O ports on an XBee
391
+ def dio( port )
392
+ at = "AT#{port.to_s}\r"
393
+ @xbee_serialport.write( at )
394
+ if self.transmission_mode == :SYNC
395
+ response = getresponse.to_i
396
+
397
+ if response == 1 # the value of 1 is overloaded based on port number
398
+ case port
399
+ when :D5
400
+ return :Associated_Indicator
401
+ when :D6
402
+ return :RTS
403
+ when :D7
404
+ return :CTS
405
+ end
406
+ else
407
+ @iotypes.index(response)
408
+ end
409
+ end
410
+ end
411
+
412
+ ##
413
+ # configures an i/o port on the XBee for analog to digital or digital input or output (GPIO)
414
+ #
415
+ # port parameter valid values are the symbols :D0 through :D8
416
+ #
417
+ # iotype parameter valid values are symbols:
418
+ # :Disabled
419
+ # :ADC
420
+ # :DI
421
+ # :DO_Low
422
+ # :DO_High
423
+ # :Associated_Indicator
424
+ # :RTS
425
+ # :CTS
426
+ # :RS485_Low
427
+ # :RS485_High
428
+ #
429
+ # note: not all iotypes are compatible with every port type, see the XBee manual for exceptions and semantics
430
+ #
431
+ # note: it is critical you have upgraded firmware in your XBee or DIO ports 0-4 cannot be read
432
+ # (ie: ATD0 will return ERROR - this is an XBee firmware bug that's fixed in revs later than 1083)
433
+ #
434
+ # note: tested with rev 10CD, fails with rev 1083
435
+ def dio!( port, iotype )
436
+ at = "AT#{port.to_s}#{@iotypes[iotype]}\r"
437
+ @xbee_serialport.write( at )
438
+ getresponse if self.transmission_mode == :SYNC
439
+ end
440
+
441
+ ##
442
+ # reads the bitfield values for change detect monitoring. returns a bitmask indicating
443
+ # which DIO lines, 0-7 are enabled or disabled for change detect monitoring
444
+ def dio_change_detect
445
+ @xbee_serialport.write("ATIC\r")
446
+ getresponse if self.transmission_mode == :SYNC
447
+ end
448
+
449
+ ##
450
+ # sets the bitfield values for change detect monitoring. The hexbitmap parameter is a bitmap
451
+ # which enables or disables the change detect monitoring for any of the DIO ports 0-7
452
+ def dio_change_detect!( hexbitmap )
453
+ @xbee_serialport.write("ATIC#{hexbitmask}\r")
454
+ getresponse if self.transmission_mode == :SYNC
455
+ end
456
+
457
+ ##
458
+ # Sets the digital output levels of any DIO lines which were configured for output using the dio! method.
459
+ # The parameter, hexbitmap, is a hex value which represents the 8-bit bitmap of the i/o lines on the
460
+ # XBee.
461
+ def io_output!( hexbitmap )
462
+ @xbee_serialport.write("ATIO#{hexbitmap}\r")
463
+ getresponse if self.transmission_mode == :SYNC
464
+ end
465
+
466
+ ##
467
+ # Forces a sampling of all DIO pins configured for input via dio!
468
+ # Returns a hash with the following key/value pairs:
469
+ # :NUM => number of samples
470
+ # :CM => channel mask
471
+ # :DIO => dio data if DIO lines are enabled
472
+ # :ADCn => adc sample data (one for each ADC channel enabled)
473
+ def io_input
474
+
475
+ tmp = @xbee_serialport.read_timeout
476
+ @xbee_serialport.read_timeout = read_timeout(:long)
477
+
478
+ @xbee_serialport.write("ATIS\r")
479
+ if self.transmission_mode == :SYNC
480
+ response = getresponse
481
+ linenum = 1
482
+ adc_sample = 1
483
+ samples = Hash.new
484
+
485
+ if response.match("ERROR")
486
+ samples[:ERROR] = "ERROR"
487
+ return samples
488
+ end
489
+
490
+ # otherwise parse input data
491
+ response.each_line do | line |
492
+ case linenum
493
+ when 1
494
+ samples[:NUM] = line.to_i
495
+ when 2
496
+ samples[:CM] = line.strip.chomp
497
+ when 3
498
+ samples[:DIO] = line.strip.chomp
499
+ else
500
+ sample = line.strip.chomp
501
+ if ( !sample.nil? && sample.size > 0 )
502
+ samples["ADC#{adc_sample}".to_sym] = line.strip.chomp
503
+ adc_sample += 1
504
+ end
505
+ end
506
+
507
+ linenum += 1
508
+ end
509
+
510
+ @xbee_serialport.read_timeout = tmp
511
+ samples
512
+ end
513
+ end
514
+
515
+ ##
516
+ # writes the current XBee configuration to the XBee device's flash. There
517
+ # is no undo for this operation
518
+ def save!
519
+ @xbee_serialport.write("ATWR\r")
520
+ getresponse if self.transmission_mode == :SYNC
521
+ end
522
+
523
+ ##
524
+ # Resets the XBee module through software and simulates a power off/on. Any configuration
525
+ # changes that have not been saved with the save! method will be lost during reset.
526
+ #
527
+ # The module responds immediately with "OK" then performs a reset ~2 seconds later.
528
+ # The reset is a required when the module's SC or ID has been changes to take into affect.
529
+ def reset!
530
+ @xbee_serialport.write("ATFR\r")
531
+ end
532
+
533
+ ##
534
+ # Performs a network reset on one or more modules within a PAN. The module responds
535
+ # immediately with an "OK" and then restarts the network. All network configuration
536
+ # and routing information is lost if not saved.
537
+ #
538
+ # Parameter range: 0-1
539
+ # * 0: Resets network layer parameters on the node issuing the command.
540
+ # * 1: Sends broadcast transmission to reset network layer parameters on all nodes in the PAN.
541
+ def network_reset!(reset_range)
542
+ if reset_range == 0
543
+ @xbee_serialport.write("ATNR0\r")
544
+ elsif reset_range == 1 then
545
+ @xbee_serialport.write("ATNR1\r")
546
+ else
547
+ #### DEBUG ####
548
+ if $DEBUG then
549
+ puts "Invalid parameter provided: #{reset_range}"
550
+ end
551
+ #### DEBUG ####
552
+ end
553
+ end
554
+
555
+ ##
556
+ # Restores all the module parameters to factory defaults
557
+ # Restore (RE) command does not reset the ID parameter.
558
+ def restore!
559
+ @xbee_serialport.write("ATRE\r")
560
+ end
561
+
562
+ ##
563
+ # just a straight pass through of data to the XBee. This can be used to send
564
+ # data when not in AT command mode, or if you want to control the XBee with raw
565
+ # commands, you can send them this way.
566
+ def send!(message)
567
+ @xbee_serialport.write( message )
568
+ end
569
+
570
+ ##
571
+ # exits the AT command mode - all changed parameters will take effect such as baud rate changes
572
+ # after the exit is complete. exit_command_mode does not permanently save the parameter changes
573
+ # when it exits AT command mode. In order to permanently change parameters, use the save! method
574
+ def exit_command_mode
575
+ @xbee_serialport.write("ATCN\r")
576
+ end
577
+
578
+ ##
579
+ # returns the version of this class
580
+ def version
581
+ VERSION
582
+ end
583
+
584
+ ##
585
+ # returns results from the XBee
586
+ # echo is disabled by default
587
+ def getresponse( echo = false )
588
+ if echo == true
589
+ r = XBee::Frame.new(self.xbee_serialport)
590
+ else
591
+ getresults( @xbee_serialport, echo )
592
+ end
593
+ end
594
+
595
+ end
596
+
597
+ class Series1APIModeInterface < BaseAPIModeInterface
598
+ ##
599
+ # returns the source address of the XBee device - the MY address value
600
+ def my_src_address
601
+ @my_src_address ||= get_param("MY")
602
+ end
603
+ end # class Series1APIModeInterface
604
+
605
+ class Series2APIModeInterface < BaseAPIModeInterface
606
+
607
+ end # class Series2APIModeInterface
608
+ end