Tutorial ======== Let's begin with a simple demonstration that showcases some of the strengths of FoneAstra: an application that lets users conduct remote, SMS-based polls. This tutorial assumes that Django and FoneAstra are installed, and that you are familiar with how to write Django apps, so views, urls, and templates will not be covered. In our sample app, there are two types of clients: pollers and pollees. Clients registered as pollers send text messages to the server, and these are forwarded to pollees. The pollee's responses are then forwarded back to the poller who originally sent the poll. This app is exceedingly simple for a polling application, but since this is a tutorial this is acceptable. Requirements ------------ Since this tutorial deals with SMS messaging and devices, you will need the following materials: # A server reachable over WiFi # An Android phone running SMSSync # A phone Setting up the project ---------------------- Begin by creating a Django project and app:: [~]$ django-admin.py startproject myproject [~]$ cd myproject [~/myproject]$ django-admin.py startapp poll Now we must modify urls.py to allow the SMSSync phone to communicate with the web server. Pull up urls.py in your favorite editor, and add the following line to urlpatterns:: (r'^fa/', include('fa.urls')), Once the project is set up, add the following lines to your settings file:: TRANSPORTS = { "smssync": { "ENGINE": "fa.transports.smssync", "secret": "FoneAstra" } } Then set up your database and add "fa" and "poll" to your list of installed apps, and you can move on to the next part of setup: setting up SMSSync. Setting up SMSSync ------------------ SMSSync is not the only transport usable with FoneAstra (in fact, mnore or less anything can be a transport, since transports are arbitrary Django apps), but it is the simplest to use and the only one included with FoneAstra. Open SMSSync and press Menu -> Settings. On the settings page, set the URL to point to the address of your server followed by "/fa/smssync". For example, if your server was located at 192.168.1.105:8000, you would enter "192.168.1.105:8000/fa/smssync" as the URL. Once the URL is set, set the secret to "FoneAstra" and you're ready to go! Step one: specifying your devices --------------------------------- FoneAstra is designed to facilitate communication between a server and one or more clients, so let's begin by defining the classes that handle these clients. Devices are defined in your models file, so pull up poll/models.py in your favorite text editor:: from django.db import models from fa.models import FoneAstraDevice from poll.apps import PollApp class StaffDevice(FoneAstraDevice): """ This class represents a polling staff member, and enables forwarding messages from this device to each client. """ def receive(self, message): """ Create a new poll, and forward it to every client device. """ poll = Poll(sender=message.sender, content=message.content) poll.save() for client in ClientDevice.objects.all(): client.send(str(poll)) class ClientDevice(FoneAstraDevice): """ This class represents a client who has registered to receive polls. """ # These are functions instead of methods so that they can be pulled out # into a separate file more easily if the device communication API is # particularly complex. receivers = ( (r'^(\d+): (.*)$', poll_receive), (r'^(.*)$', default_response), ) class Poll(models.Model): """ This class represents a poll. """ sender = models.CharField(max_length=25) content = models.CharField(max_length=255) def __str__(self): return "Poll number {num}: {cont}".format(num=self.pk, cont=self.content) def poll_receive(device, poll_id, answer): """ Receives a poll response. """ if len(Poll.objects.filter(pk=poll_id)) != 1: device.send("Could not find poll with given ID.") poll = Poll.objects.get(pk=poll_id) device = PollApp.get_device(poll.sender) if device is None: return False device.send("Poll response: " + answer) return True def default_response(device, message): """ Default response for malformed messages. """ device.send("Please response in the form 'ID: message' where ID is the " "poll ID.") Step two: writing the app class ------------------------------- The app class in your project makes it discoverable by FoneAstra, and also provides some useful convenience methods. If the devices are the heart and soul of a FoneAstra project, the app is what glues the heart and soul into the framework. Create a new file called poll/app.py, and open it up in your favorite text editor:: from fa.apps import FoneAstraApp class PollApp(FoneAstraApp): """ This class hooks our polling app into the FoneAstra framework. """ device_types = (StaffDevice, ClientDevice) @classmethod def receive(cls, msg): """ This method handles configuration. If the client messages with an 'S' they are a staff member; if they message with a 'C' they are a client. If the message is not a valid registration message, it might be intended for another app, so just return False. It is bad form to respond to configuration messages not intended for you. """ if msg.content == 'S': StaffDevice(phone_number=msg.sender, transport=msg.transport).save() return True if msg.content == 'C': ClientDevice(phone_number=msg.sender, transport=msg.transport).save() return True return False Now simply run the server and try it out! That's all that is necessary for a simple SMS-based FoneAstra app. For next steps you can enable the admin site, add some views, or do anything, really. Run wild!