Work with XBee classes¶
When working with the XBee Python Library, start with an XBee device object that represents a physical module. A physical XBee device is the combination of hardware and firmware. Depending on that combination, the device runs a specific wireless communication protocol such as Zigbee, 802.15.4, DigiMesh, Wi-Fi, or cellular. An XBeeDevice class represents the XBee module in the API.
Most of the protocols share the same features and settings, but there are some differences between them. For that reason, the XBee Python Library also includes a set of classes that represent XBee devices running different communication protocols. The XBee Python Library supports one XBee device class per protocol, as follows:
- XBee Zigbee device (
ZigBeeDevice
) - XBee 802.15.4 device (
Raw802Device
) - XBee DigiMesh device (
DigiMeshDevice
) - XBee Point-to-multipoint device (
DigiPointDevice
) - XBee IP devices (This is a non-instantiable class)
- XBee Cellular device (
CellularDevice
) - XBee Wi-Fi device (
WiFiDevice
)
- XBee Cellular device (
All these XBee device classes allow you to configure the physical XBee device, communicate with the device, send data to other nodes on the network, receive data from remote devices, and so on. Depending on the class, you may have additional methods to execute protocol-specific features or similar methods.
To work with the API and perform actions involving the physical device, you
must instantiate a generic XBeeDevice
object or one that is
protocol-specific. This documentation refers to the XBeeDevice
object
generically when describing the different features, but they can be applicable
to any XBee device class.
Instantiate an XBee device¶
When you are working with the XBee Python Library, the first step is to
instantiate an XBee device object. The API works well using the generic
XBeeDevice
class, but you can also instantiate a protocol-specific XBee
device object if you know the protocol your physical XBee device is running.
An XBee device is represented as either local or remote in the XBee Python Library, depending upon how you communicate with the device.
Local XBee device¶
A local XBee device is the object in the library representing the device that is physically attached to your PC through a serial or USB port. The classes you can instantiate to represent a local device are listed in the following table:
Class | Description |
---|---|
XBeeDevice | Generic object, protocol-independent |
ZigBeeDevice | Zigbee protocol |
Raw802Device | 802.15.4 protocol |
DigiMeshDevice | DigiMesh protocol |
DigiPointDevice | Point-to-multipoint protocol |
CellularDevice | Cellular protocol |
WiFiDevice | Wi-Fi protocol |
To instantiate a generic or protocol-specific XBee device, you need to provide the following two parameters:
- Serial port name
- Serial port baud rate
Instantiate a local XBee device
[...]
xbee = XBeeDevice("COM1", 9600)
[...]
Remote XBee device¶
Remote XBee device objects represent remote nodes of the network. These are XBee devices that are not attached to your PC but operate in the same network as the attached (local) device.
Warning
When working with remote XBee devices, it is very important to understand that you cannot communicate directly with them. You need to provide a local XBee device operating in the same network that acts as bridge between your serial port and the remote node.
Managing remote devices is similar to managing local devices, but with limitations. You can configure them, handle their IO lines, and so on, in the same way you manage local devices. Local XBee devices have several methods for sending data to remote devices, but the remote devices cannot use these methods because they are already remote. Therefore, a remote device cannot send data to another remote device.
In the local XBee device instantiation, you can choose between instantiating a generic remote XBee device object or a protocol-specific remote XBee device. The following table lists the remote XBee device classes:
Class | Description |
---|---|
RemoteXBeeDevice | Generic object, protocol independent |
RemoteZigBeeDevice | Zigbee protocol |
RemoteRaw802Device | 802.15.4 protocol |
RemoteDigiMeshDevice | DigiMesh protocol |
RemoteDigiPointDevice | Point-to-multipoint protocol |
Note
XBee Cellular and Wi-Fi protocols do not support remote devices.
To instantiate a remote XBee device object, you need to provide the following parameters:
- Local XBee device attached to your PC that serves as the communication interface.
- 64-bit address of the remote device.
RemoteRaw802Device
objects can be also instantiated by providing the local
XBee device attached to your PC and the 16-bit address of the remote
device.
Instantiate a remote XBee device
[...]
local_xbee = XBeeDevice("COM1", 9600)
remote_xbee = RemoteXBeeDevice(local_xbee, XBee64BitAddress.from_hex_string("0013A20012345678"))
[...]
The local device must also be the same protocol for protocol-specific remote XBee devices.
Open the XBee device connection¶
Before trying to communicate with the local XBee device attached to your PC,
you need to open its communication interface, which is typically a serial/USB
port. Use the open()
method of the instantiated XBee device, and you can
then communicate and configure the device.
Remote XBee devices do not have an open method. They use a local XBee device as the connection interface. If you want to perform any operation with a remote XBee device you must open the connection of the associated local device.
[...]
# Instantiate an XBee device object.
local_xbee = XBeeDevice("COM1", 9600)
# Open the device connection.
local_xbee.open()
[...]
The open()
method may fail for the following reasons:
All the possible errors are caught as
XBeeException
:- If there is any problem with the communication, throwing a
TimeoutException
. - If the operating mode of the device is not
API
orAPI_ESCAPE
, throwing anInvalidOperatingModeException
. - There is an error writing to the XBee interface, or device is closed,
throwing a generic
XBeeException
.
- If there is any problem with the communication, throwing a
The open()
action performs some other operations apart from opening the
connection interface of the device. It reads the device information (reads
some sensitive data from it) and determines the operating mode of the device.
Use force_settings=True
as open()
method parameter, to reconfigure
the XBee serial settings (baud rate, data bits, stop bits, etc.) to those
specified in the XBee object constructor.
[...]
# Instantiate an XBee device object.
local_xbee = XBeeDevice("COM1", 9600)
# Open the connection using constructor parameters: 9600 8N1.
# This reconfigures the XBee if its serial settings do not match.
local_xbee.open(force_settings=True)
[...]
Example: Recover XBee serial communication |
---|
The XBee Python Library includes a sample application that displays how to recover the serial connection with a local XBee. It can be located in the following path: examples/configuration/RecoverSerialConnection/RecoverSerialConnection.py |
Read device information¶
The read device information process reads the following parameters from the local or remote XBee device and stores them inside. You can then access parameters at any time, calling their corresponding getters.
- 64-bit address
- 16-bit address
- Node identifier
- Firmware version
- Hardware version
- IPv4 address (only for cellular and Wi-Fi modules)
- IMEI (only for cellular modules)
The read process is performed automatically in local XBee devices when
opening them with the open()
method. If remote XBee devices cannot be
opened, you must use read_device_info()
to read their device information.
Initialize a remote XBee device
[...]
# Instantiate an XBee device object.
local_xbee = XBeeDevice("COM1", 9600)
local_xbee.open()
# Instantiate a remote XBee device object.
remote_xbee = RemoteXBeeDevice(local_xbee, XBee64BitAddress.from_hex_string("0013A20040XXXXXX"))
# Read the device information of the remote XBee device.
remote_xbee.read_device_info()
[...]
The read_device_info()
method may fail for the following reasons:
ACK of the command sent is not received in the configured timeout, throwing a
TimeoutException
.Other errors caught as
XBeeException
:- If the operating mode of the device is not
API
orAPI_ESCAPE
, throwing anInvalidOperatingModeException
. - If the response of the command is not valid, throwing an
ATCommandException
. - There is an error writing to the XBee interface, or device is closed,
throwing a generic
XBeeException
.
- If the operating mode of the device is not
Note
Although the readDeviceInfo
method is executed automatically in local XBee
devices when they are open, you can issue it at any time to refresh the
information of the device.
Get device information
[...]
# Instantiate an XBee device object.
local_xbee = XBeeDevice("COM1", 9600)
local_xbee.open()
# Get the 64-bit address of the device.
addr_64 = device.get_64bit_addr()
# Get the node identifier of the device.
node_id = device.get_node_id()
# Get the hardware version of the device.
hardware_version = device.get_hardware_version()
# Get the firmware version of the device.
firmware_version = device.get_firmware_version()
The read device information process also determines the communication protocol
of the local or remote XBee device object. This is typically something you
need to know beforehand if you are not using the generic XBeeDevice
object.
However, the API performs this operation to ensure that the class you
instantiated is the correct one. So, if you instantiated a Zigbee device and
the open()
process realizes that the physical device is actually a DigiMesh
device, you receive an XBeeDeviceException
indicating the device mismatch.
You can retrieve the protocol of the XBee device from the object executing the corresponding getter.
Get the XBee protocol
[...]
# Instantiate an XBee device object.
local_xbee = XBeeDevice("COM1", 9600)
local_xbee.open()
# Get the protocol of the device.
protocol = local_xbee.get_protocol()
Device operating mode¶
The open()
process also reads the operating mode of the physical local
device and stores it in the object. As with previous settings, you can
retrieve the operating mode from the object at any time by calling the
corresponding getter.
Get the operating mode
[...]
# Instantiate an XBee device object.
local_xbee = XBeeDevice("COM1", 9600)
local_xbee.open()
# Get the operating mode of the device.
operating_mode = local_xbee.get_operating_mode()
Remote devices do not have an open()
method, so you receive UNKNOWN
when retrieving the operating mode of a remote XBee device.
The XBee Python Library supports two operating modes for local devices:
- API
- API with escaped characters
This means that AT (transparent) mode is not supported by the API. So, if
you try to execute the open()
method in a local device working in AT mode,
you get an XBeeException
caused by an InvalidOperatingModeException
.
Close the XBee device connection¶
You must call the close()
method each time you finish your XBee
application. You can use this in the finally block or something similar.
If you don’t do this, you may have problems with the packet listener being executed in a separate thread.
This method guarantees that the listener thread will be stopped and the serial port will be closed.
Close the connection
[...]
# Instantiate an XBee device object.
local_xbee = XBeeDevice("COM1", 9600)
try:
xbee.open()
[...]
finally:
if xbee is not None and xbee.is_open():
xbee.close()
Note
Remote XBee devices cannot be opened, so they cannot be closed either. To close the connection of a remote device you need to close the connection of the local associated device.