XBee is a radio transceiver sold by Digi Corporation which implements a network using the ZigBee standard (IEEE 802.15.4) or similar. A pair of XBee devices can provide a convenient point-to-point link for transferring serial data between a computer and a device (e.g. an Arduino).
In a point-to-point link one XBee device must be configured as a controller (by flashing it with controller firmware) and the other as an end-device (which is the firmware shipped with the device). This is often done using transparent mode, in which a stream of bytes received by one device's serial port is transmitted to its peer, and sent out the other device's serial port.
Transparent mode is only useful when you have only 2 devices. To get a star network topology with N devices, you have to burn the controller with the API mode firmware, and talk to it with API mode. That lets you send messages to different destination nodes; when data is received it tells you which node the data came from, and you can also find out things like signal strength or a list of connected nodes. End devices can continue to use transparent mode (that makes it easy for arduinos) but they can only talk to the controller doing that. That's OK by me.
I wrote perl classes to talk API mode to an XBee. But that's not enough if you consider that there will be different types of devices in the network carrying on different conversations simultaneously. So I went further and defined a protocol (using JSON) where the XBee packets are forwarded over a TCP connection. So my perl API classes are combined with a daemon which listens on a TCP socket (port 7862).
Client programs (like my aircon controller and temperature logger) connect to the daemon on port 7862. If the client wants to send to an end-device XBee it sends a formatted packet with the data and the destination address to the server daemon, which forwards it to the locally connected XBee controller for transmission. Any data packets received by the local XBee are forwarded to all connected clients. It's the responsibility of the client to ignore packets from XBees it is not interested in.
In practice this works pretty well. My temperature logging daemon receives all the data packets and it looks for the particular format the temp senders use in their every-30-seconds report of current temperature:
T=xxxxxx D=SENSOR_ID TT.TTT
If a sender has multiple sensors, it outputs multiple lines each 30 seconds. The temp logging daemon receives everything and only temp reports are logged. So if I want to add a new temp sensor, I just have to plug it into the bus somewhere and it will be logged. Or if I add a new temp sensor controller with a new XBee, it will be heard with no need to edit any config files.
The aircon controller on the other hand only needs to hear packets from a particular XBee, so I wrote a filter class which ignores everything from other devices.
The software is available for download on github: