Please note that these Trac pages are no longer being updated. Wiki contents/documentation have moved to GitHub.

Version 8 (modified by albert, 7 years ago)


Using Sensors In Seattle

A Seattle / Repy program cannot access resources like GPS, wifi signal strength information, motion sensors, etc. However, many users would like to provide information about resources like this to researchers. To facilitate the exchange of information, we provide an API that sensor applications (installed separately from Seattle) can use to make the sensor available to local Repy programs.


The API that is provided by sensors may vary significantly from application to application. The philosophy is to provide an API that is as simple as possible but would allow a variety of sensor applications to operate. We intentionally under constrain the interface to make it as easy as possible to use in the base case. Further parts of this document describe how to do slightly more advanced functionality while providing this API.

Required API

All sensors must provide an XMLRPC interface bound to on any port from 63090-63099. This XMLRPC interface must support at least the following two calls: isSeattleSensor(), system.listMethods(), and system.methodSignature. (See  the SimpleXMLRPCAPI for general details on Python, but similar libraries exist on other platforms.) The isSeattleSensor() call must return True. The system.listMethods() should list the available calls. The system.methodSignature(callname) must return the calling arguments for a function.

Note: it is completely fine for a sensor to hide calls it does not want to be called by general clients. In other words, if you have a call that performs a potentially disruptive act, you need not list it. Keep in mind that this is not a security mechanism. It is just to prevent a simple and general client from calling it without understanding what it does.

It is also recommended that you provide the call system.methodHelp. This is not required and clients must not rely on their existence.

Example Use

Here is some example pseudo-code for building a sensor and client.

Sensor code:

import SimpleXMLRPCServer
import socket
import sys

for sensorport in [63095, 63096, 63097, 63098, 63099, 63090, 63091, 63092, 63093, 63094]:
    server = SimpleXMLRPCServer.SimpleXMLRPCServer(("localhost", sensorport))
  except socket.error:
    print 'port:',sensorport,'failed.   Trying backup port...' 
  print "Listening on port",sensorport,"..." 
  print 'Could not locate a port!'
def isSeattleSensor():
  """ isSeattleSensor() always returns True"""
  return True

def mySensorName():
  """ my sensor name is "Hello World Sensor"."""
  return "Hello World Sensor"

def readSensor():
  """ Read data from the hello world sensor"""
  return "Hello World!"

def readSensorForLanguage(language):
  """ Read data from the hello world sensor in a few languages.   Pass in a string."""
  if language == 'English':
    return "Hello World!"
  elif language == 'German':
    return "Hallo Welt!"
  elif language == 'Mandarin':
    return "Ni Hao!"
    raise Exception("Unsupported language")

# NOTE: the system.* calls are defined by the SimpleXMLRPCServer in Python by calling the following.   Your library's use may vary.


    print 'Use Control-C to exit'
except KeyboardInterrupt:
    print 'Exiting'

Repy sensor reading code:

include xmlrpc_client.repy

if callfunc=="initialize":
  for sensorport in [63095, 63096, 63097, 63098, 63099, 63090, 
    63091, 63092, 63093, 63094]:
      s = xmlrpc_client_Client('http://localhost:'+str(sensorport))
    except socket.error:
      print 'port:', sensorport, 'failed.   Trying backup port...' 
    print "Connected to port", sensorport
    print 'Could not locate a port!'

  # should check the error status...
    if not s.send_request("isSeattleSensor", ()):
      print 'something other than a Seattle sensor was bound to the port...'
  except Exception, e:
    print 'Got an error when checking if this is a Seattle sensor:', str(e)

  # Get the list of available methods
  methodlist = s.send_request("system.listMethods", ())

  for methodname in methodlist:
    # NOTE: Wrap the methodname string inside a tuple, otherwise
    # xmlrpc_common will treat the string's characters as separate params
    thissignature = s.send_request("system.methodSignature", (methodname,))

    # BUG: This is true for all signatures, but shouldn't be.
    if thissignature == 'signatures not supported':
      print 'Method:', methodname, 'has an unknown signature.'
      print 'Method:',methodname,'has the signature', thissignature

    if thissignature == ():
      print 'Empty call returns:', s.send_request(methodname, ())

  print s.send_request("isSeattleSensor", ())
  print s.send_request("mySensorName", ())
  print s.send_request("readSensor", ())
  print s.send_request("readSensorForLanguage", ('Mandarin',))