Advice sought on application structure

I’d appreciate some advice on structuring my ConnectPort X2 python application.

Sitting behind the X2 gateway we have 7 pieces of custom electronics with XBee Series 2 radios (ZNet 2.5, v1241). 6 of these are “launchers”, the 7th is a “popper”. The origin of the naming is probably best understood by looking at this Flickr photo stream, ;-).

Every 10 seconds launchers emit a short “ping” message. The X2 is supposed to answer with a “pong” response. Failure to do so will eventually result in a launcher resetting its XBee2 radio. When a launcher is fired, it emits a sequence of short messages: “fire”, “wait”, “ready”. The popper isn’t manually activated but fires based on a countdown timer. The popper can also be put into a sleep mode. This needs to occur if no launchers fire for some number of minutes (i.e. the room is empty).

All of the infrastructure for the above is in place. We can telnet into the X2 and run simple scripts that observe the “ping” messages and fire sequences. We can send commands to the launchers and popper as required. It’s time to wrap this all up into a single application that runs on the X2 at boot time. The question then: how to structure this application?

The simple script I use at the moment opens up a socket to the endpoint (gateway) and repeatedly blocks until data is received from the mesh network. This precludes any sort of pro-active (rather than reactive) business logic happening. If I want tasks to occur - like say sending status updates by UPD back to the office - these really should occur as scheduled events. As should putting the popper into sleep mode.

On a regular computer, I’d use Twisted. What would you suggest on the X2, asyncore?

That should, of course, read “UDP”. The reason I’d go this route is that status updates back to base are far less important than the primary task of this application: responding to “pongs” and putting the popper into sleep/wake mode. In order of priority we’d have

  1. wake popper if it is asleep and a launcher fires
  2. put popper into sleep mode if no launcher fires for 5 minutes.
  3. respond to all “pong” events
  4. send system status messages by UDP back to office
  5. if external network is up, send system status messages back to office by TCP (guaranteed delivery)
  6. if external network is down, buffer status messages until TCP connection re-established.

I have not used asyncore, but I believe that it uses a well limited subset of functionality and so should work fine. It’s the right line of thinking.

However, the application seems structured simply enough that switching from synchronous to asynchronous I/O alone and using select may provide the structure that you need. 1 & 3 of your list would be receive events on the endpoint. The rest could be based off of a select timeout that is calculated each time you enter the select wait. I’m not sure what status you’re sending, but your system status messages may all be event driven, and so keeping track of the five minute interval between fire events may be all the timeout calculation that is needed.