2. 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.

2.1. 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

2.2. 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.

2.3. 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!

2.4. 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.")

2.5. 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!

Table Of Contents

Previous topic

1. Intro

Next topic

3. Module Reference

This Page