lib/apimode/xbee_api.rb in ruby-xbee-1.1.0 vs lib/apimode/xbee_api.rb in ruby-xbee-1.2.0
- old
+ new
@@ -1,15 +1,46 @@
$: << File.dirname(__FILE__)
require 'frame/frame'
require File.dirname(File.dirname(__FILE__)) + '/ruby_xbee'
module XBee
+ ##
+ # This is the main class for API mode for XBee radios.
class BaseAPIModeInterface < RFModule
-
- VERSION = "1.1.0" # Version of this class
-
- def initialize(xbee_usbdev_str, uart_config = XBeeUARTConfig.new, operation_mode = :AT, transmission_mode = :SYNC)
+
+ VERSION = "1.2.0" # Version of this class
+
+ ##
+ # ==== Attributes
+ # * +xbee_usbdev_str+ - USB Device as a string
+ #
+ # ==== Options
+ # * +uart_config+ - XBeeUARTConfig
+ # * +operation_mode+ - Either :AT or :API for XBee operation mode
+ # * +transmission_mode+ - :SYNC for Synchronous communication or :ASYNC for Asynchonrous communication.
+ #
+ # A note on the asynchronous vs synchronous communication modes - A
+ # simplistic network of a few XBee nodes can pretty much work according to
+ # expected flows where requests and responses are always handled in
+ # synchronous ways. However, if bigger radio networks are being deployed
+ # (real scenarios) you cannot guarantee the synchronous nature of the network.
+ # You will have nodes joining/removing themselves, sleeping, sending data
+ # samples etc. Although the default behaviour is set as :SYNC, if you have a
+ # real network, then by design the network is Asynchronous, use :ASYNC instead.
+ # Otherwise you will most definitely run into "Invalid responses" issues.
+ #
+ # For handling the Asynchronous communication logic, use an external Queue
+ # and database to effectively handle the command/response and other frames
+ # that are concurrently being conversed on the PAN.
+ #
+ # ==== Example
+ # require 'ruby_xbee'
+ # @uart_config = XBee::Config::XBeeUARTConfig.new()
+ # @xbee_usbdev_str = '/dev/tty.usbserial-A101KYF6'
+ # @xbee = XBee::BaseAPIModeInterface.new(@xbee_usbdev_str, @uart_config, :API, :ASYNC)
+ #
+ def initialize(xbee_usbdev_str, uart_config = XBeeUARTConfig.new, operation_mode = :API, transmission_mode = :SYNC)
super(xbee_usbdev_str, uart_config, operation_mode, transmission_mode)
@frame_id = 1
if self.operation_mode == :AT
start_apimode_communication
end
@@ -21,26 +52,29 @@
##
# Switch to API mode - note that in Series 2 the Operation Mode is defined
# by the firmware flashed to the device. Only Series 1 can switch from
# AT (Transparent) to API Opearation and back seamlessly.
+ #
+ # API Mode 1 - API Enabled
+ # API Mode 2 - API Enabled, with escaped control characters
def start_apimode_communication
in_command_mode do
puts "Entering api mode"
# Set API Mode 2 (include escaped characters)
- self.xbee_serialport.write("ATAP2\r")
+ self.xbee_serialport.write("ATAP1\r")
self.xbee_serialport.read(3)
end
end
def get_param(at_param_name, at_param_unpack_string = nil)
frame_id = self.next_frame_id
at_command_frame = XBee::Frame::ATCommand.new(at_param_name,frame_id,nil,at_param_unpack_string)
- puts "Sending ... [#{at_command_frame._dump.unpack("C*").join(", ")}]"
- self.xbee_serialport.write(at_command_frame._dump)
+ puts "Sending ... [#{at_command_frame._dump(self.api_mode.in_symbol).unpack("C*").join(", ")}]" if $VERBOSE
+ self.xbee_serialport.write(at_command_frame._dump(self.api_mode.in_symbol))
if self.transmission_mode == :SYNC
- r = XBee::Frame.new(self.xbee_serialport)
+ r = XBee::Frame.new(self.xbee_serialport, self.api_mode.in_symbol)
if r.kind_of?(XBee::Frame::ATCommandResponse) && r.status == :OK && r.frame_id == frame_id
if block_given?
yield r
else
#### DEBUG ####
@@ -58,14 +92,14 @@
end
def set_param(at_param_name, param_value, at_param_unpack_string = nil)
frame_id = self.next_frame_id
at_command_frame = XBee::Frame::ATCommand.new(at_param_name,frame_id,param_value,at_param_unpack_string)
- # puts "Sending ... [#{at_command_frame._dump.unpack("C*").join(", ")}]"
- self.xbee_serialport.write(at_command_frame._dump)
+ # puts "Sending ... [#{at_command_frame._dump(self.api_mode.in_symbol).unpack("C*").join(", ")}]"
+ self.xbee_serialport.write(at_command_frame._dump(self.api_mode.in_symbol))
if self.transmission_mode == :SYNC
- r = XBee::Frame.new(self.xbee_serialport)
+ r = XBee::Frame.new(self.xbee_serialport, self.api_mode.in_symbol)
if r.kind_of?(XBee::Frame::ATCommandResponse) && r.status == :OK && r.frame_id == frame_id
if block_given?
yield r
else
at_param_unpack_string.nil? ? r.retrieved_value : r.retrieved_value.unpack(at_param_unpack_string).first
@@ -77,14 +111,14 @@
end
def get_remote_param(at_param_name, remote_address = 0x000000000000ffff, remote_network_address = 0xfffe, at_param_unpack_string = nil)
frame_id = self.next_frame_id
at_command_frame = XBee::Frame::RemoteCommandRequest.new(at_param_name, remote_address, remote_network_address, frame_id, nil, at_param_unpack_string)
- puts "Sending ... [#{at_command_frame._dump.unpack("C*").join(", ")}]"
- self.xbee_serialport.write(at_command_frame._dump)
+ puts "Sending ... [#{at_command_frame._dump(self.api_mode.in_symbol).unpack("C*").join(", ")}]"
+ self.xbee_serialport.write(at_command_frame._dump(self.api_mode.in_symbol))
if self.transmission_mode == :SYNC
- r = XBee::Frame.new(self.xbee_serialport)
+ r = XBee::Frame.new(self.xbee_serialport, self.api_mode.in_symbol)
if r.kind_of?(XBee::Frame::RemoteCommandResponse) && r.status == :OK && r.frame_id == frame_id
if block_given?
yield r
else
at_param_unpack_string.nil? ? r.retrieved_value : r.retrieved_value.unpack(at_param_unpack_string).first
@@ -96,14 +130,14 @@
end
def set_remote_param(at_param_name, param_value, remote_address = 0x000000000000ffff, remote_network_address = 0xfffe, at_param_unpack_string = nil)
frame_id = self.next_frame_id
at_command_frame = XBee::Frame::RemoteCommandRequest.new(at_param_name, remote_address, remote_network_address, frame_id, param_value, at_param_unpack_string)
- puts "Sending ... [#{at_command_frame._dump.unpack("C*").join(", ")}]"
- self.xbee_serialport.write(at_command_frame._dump)
+ puts "Sending ... [#{at_command_frame._dump(self.api_mode.in_symbol).unpack("C*").join(", ")}]"
+ self.xbee_serialport.write(at_command_frame._dump(self.api_mode.in_symbol))
if self.transmission_mode == :SYNC
- r = XBee::Frame.new(self.xbee_serialport)
+ r = XBee::Frame.new(self.xbee_serialport, self.api_mode.in_symbol)
if r.kind_of?(XBee::Frame::RemoteCommandResponse) && r.status == :OK && r.frame_id == frame_id
if block_given?
yield r
else
at_param_unpack_string.nil? ? r.retrieved_value : r.retrieved_value.unpack(at_param_unpack_string).first
@@ -152,19 +186,19 @@
# Signal strength (:DB) is reported in units of -dBM.
def neighbors
frame_id = self.next_frame_id
# neighbors often takes more than 1000ms to return data
node_discover_cmd = XBee::Frame::ATCommand.new("ND",frame_id,nil)
- #puts "Node discover command dump: #{node_discover_cmd._dump.unpack("C*").join(", ")}"
+ #puts "Node discover command dump: #{node_discover_cmd._dump(self.api_mode.in_symbol).unpack("C*").join(", ")}"
tmp = @xbee_serialport.read_timeout
@xbee_serialport.read_timeout = Integer(self.node_discover_timeout.in_seconds * 1050)
- @xbee_serialport.write(node_discover_cmd._dump)
+ @xbee_serialport.write(node_discover_cmd._dump(self.api_mode.in_symbol))
responses = []
#read_thread = Thread.new do
begin
loop do
- r = XBee::Frame.new(self.xbee_serialport)
+ r = XBee::Frame.new(self.xbee_serialport, self.api_mode.in_symbol)
# puts "Got a response! Frame ID: #{r.frame_id}, Command: #{r.at_command}, Status: #{r.status}, Value: #{r.retrieved_value}"
if r.kind_of?(XBee::Frame::ATCommandResponse) && r.status == :OK && r.frame_id == frame_id
if r.retrieved_value.empty?
# w00t - the module is telling us it's done with the discovery process.
break
@@ -527,11 +561,11 @@
# The module responds immediately with "OK" then performs a reset ~2 seconds later.
# The reset is a required when the module's SC or ID has been changes to take into affect.
def reset!
@xbee_serialport.write("ATFR\r")
end
-
+
##
# Performs a network reset on one or more modules within a PAN. The module responds
# immediately with an "OK" and then restarts the network. All network configuration
# and routing information is lost if not saved.
#
@@ -584,11 +618,11 @@
##
# returns results from the XBee
# echo is disabled by default
def getresponse( echo = false )
if echo == true
- r = XBee::Frame.new(self.xbee_serialport)
+ r = XBee::Frame.new(self.xbee_serialport, self.api_mode.in_symbol)
else
getresults( @xbee_serialport, echo )
end
end
@@ -601,8 +635,14 @@
@my_src_address ||= get_param("MY")
end
end # class Series1APIModeInterface
class Series2APIModeInterface < BaseAPIModeInterface
-
+ ##
+ # Initiating the application firmware OTA upgrade for Programmable XBee modules
+ def init_ota_upgrade(password = nil, remote_address = 0x000000000000ffff, remote_network_address = 0xfffe)
+ frame_id = self.next_frame_id
+ command_frame = XBee::Frame::ExplicitAddressingCommand.new(frame_id, remote_address, remote_network_address, 0xE8, 0xE8, 0x1000, 0xC105, 0x00, 0x00, password)
+ self.xbee_serialport.write(command_frame._dump(self.api_mode.in_symbol))
+ end
end # class Series2APIModeInterface
end