FoneAstra is a Django library, written in Python, to facilitate communication between client devices and a server. In keeping with Django and Python’s batteries included philosophy, FoneAstra seeks to automate as much as possible, and make what can’t be automated easy to implement.
The original FoneAstra project (and the project which originally held the FoneAstra name) is Vax, which uses mobile phones connected to temperature probes as remote devices embedded in vaccine refrigerators which send regular temperature readings to the server, which graphs the data and sends out alarms to staff members if a device sends an alert.
After Vax came Milk Bank, which showed that FoneAstra should be not just one project, but a general library for communication between client devices and a server. FoneAstra’s elements of design came from a synthesis of RapidSMS (which FoneAstra is a fork of) and the Encouragement System, a capstone project I worked on during spring of 2012.
First, a bit of definition. FoneAstra treats all text messages from the server’s point of view, so sending a text message from the server to a client is referred to as sending, and sending a text message from a client to the server is called receiving.
Sending text messages is easy. Simply call fa.transports.base.TransportBase.send(), and FoneAstra will take care of the rest. If you’re trying to send a message to a device, use fa.models.FoneAstraDevice.send() and the device will automatically handle the rest. Note that TransportBase.send is called with an OutgoingMessage, while FoneAstraDevice.send is called with a string.
Receiving text messages is slightly more complex, and is the heart and soul of FoneAstra. The life of an incoming text message begins with fa.transports.base.TransportBase.receive(). There are two other vitally important methods that bear the name receive: fa.models.FoneAstraDevice.receive(), which is called if the incoming message’s phone number matches a registered device, and fa.apps.FoneAstraApp.receive(), which is called if no FoneAstraDevice in the database has a matching phone number. In general, the former is used for regular day-to-day messages and the latter is used to register new devices.
When an incoming message is received, FoneAstra first checks every FoneAstra app (defined as every subclass of fa.apps.FoneAstraApp in every installed app), asking it if it has a registered FoneAstra device with the same phone number as the incoming message. If so, that device’s fa.models.FoneAstraDevice.receive() is called. The default implementation of this method operates in a similar manner to Django’s existing URL handling, but feel free to override that behavior.
If no device was found, then each FoneAstra app has its fa.apps.FoneAstraApp.receive() method called in turn until one of them returns True. If none of them return True, then fa.transports.base.TransportBase.receive() returns False.