diff --git a/main.py b/main.py index 934b2ad..eb2009f 100644 --- a/main.py +++ b/main.py @@ -1,14 +1,4 @@ -# What's my current problem? -# unit -> xbee -> python xbee -> OSC -> Processing - - -# Processing -> OSC -> python osc -> python xbee -> unit -> deserialize at unit -# NEED: -# -serialize message in Python and pack into xbee : can I do this with liblo.send?...no, think I need message.serialise() - -# -------------------------------------------- -# -------------------------------------------- -# x- IMPORT NECESSARY STUFF +# This is a lightweight gateway from xBee to UDP OSC and vice versa import logging import sys @@ -42,27 +32,11 @@ - - # -------------------------------------------- # -------------------------------------------- -# x- INITIALIZE INTERNAL STUFF - -# Main data structure for communications tracking -global allReports, numberStoredEntries -allReports = [] -numberStoredEntries = 5000 - - - - - - +# -------------- OSC IN and OUT -------------- # -------------------------------------------- # -------------------------------------------- -# x- INITIALIZE OSC SERVER and CLIENT -# x- WRITE ALL MIDI FUNCTIONS - def OSCtoXbeeBroadcast(xbee, OSCmsg): # Convert from OSC message to byte stream of packed_data @@ -75,106 +49,22 @@ def OSCtoXbeeMessage(xbee, address, OSCmsg): # OSC Server for receiving messages -class MyServer(ServerThread): +class OSCServer(ServerThread): def __init__(self): ServerThread.__init__(self, 9049) - # @make_method('/foo', 'ifs') - # def foo_callback(self, path, args): - # i, f, s = args - # print "received message '%s' with arguments: %d, %f, %s" % (path, i, f, s) - @make_method(None, None) def fallback(self, path, args): print "--------------------" print "OSC CALLBACK FUNCTION" - print datetime.now(), "received unknown message '%s', '%s'" % (path, args) - # print path - # print args - - # Select out paths where we want to control the units - if path == '/eq': - print "Path '/eq' found!" - # Repack the message...seems like a stupid step - msg = liblo.Message(path) - for data in args: - msg.add(data) - - # Send to a unit of my choice - OSCtoXbeeBroadcast(xbee, msg) - - if path == '/midi/cc': - print "Path '/midi/cc' found!" - # Repack the message...seems like a stupid step - msg = liblo.Message(path) - for data in args: - msg.add(data) - - # Send to a unit of my choice - OSCtoXbeeBroadcast(xbee, msg) - - # Messages to change - if path == 'report/acc_r': - print "Path 'report/acc_r' found!" - msg = liblo.Message(path) - - OSCtoXbeeBroadcast(xbee, msg) - - if path == 'report/acc_p': - print "Path 'report/acc_p' found!" - msg = liblo.Message(path) - - OSCtoXbeeBroadcast(xbee, msg) - - if path == 'report/gyr_r': - print "Path 'report/gyr_r' found!" - msg = liblo.Message(path) - - OSCtoXbeeBroadcast(xbee, msg) - - if path == 'report/gyr_p': - print "Path 'report/gyr_p' found!" - msg = liblo.Message(path) - - OSCtoXbeeBroadcast(xbee, msg) - - if path == 'report/mix': - print "Path 'report/mix' found!" - msg = liblo.Message(path) - - OSCtoXbeeBroadcast(xbee, msg) - - - if path in ["anim/power", "anim/sparkle", "anim/eq"]: - print "Path ", path, " found!" - msg = liblo.Message(path) - - # OSCtoXbeeBroadcast(xbee, msg) - OSCtoXbeeMessage(xbee, '\x00\x0A', msg) - OSCtoXbeeMessage(xbee, '\x00\x0B', msg) - OSCtoXbeeBroadcast(xbee, msg) - - - - # Pass forward messages from Processing to OSC control of specific units - # Need to update this to select the wildcards - if path == 'unit/*/anim/hue': - print "Path 'unit/*/anim/hue' found!" - msg = liblo.Message(path) - msg.add(args) - - # Need to properly format the address here - OSCtoXbeeMessage(xbee, address, msg) - - - print "--------------------" - print "" - + print datetime.now(), "received message '%s', '%s'" % (path, args) + # Is this what I want? I should have something about the message address pick which xBee this goes to + OSCtoXbeeBroadcast(xbee, msg) try: - server = MyServer() + server = OSCServer() except ServerError, err: print str(err) sys.exit() @@ -182,47 +72,39 @@ def fallback(self, path, args): server.start() -# send all messages to port 9050 on the local machine +# Send all messages to port 9050 on the local machine try: targetOSC = liblo.Address(9050) except liblo.AddressError, err: print str(err) sys.exit() + # Sends OSC messages to Processing port -def forwardOSCMessage(reports): +def xBeeToOSCMessage(reports): # print "Report[0]: ", reports[0] - msg = reports[0]["msg"] + msg = reports["OSCmsg"] # print "Forwarding OSC Message: ", reports[0]["msg"] liblo.send(targetOSC, msg) -# WRITE FUNCTIONS FOR SENDING AND PACKING STUFF -# WHAT DO THE MESSAGES I SEND FORTH LOOK LIKE? - - # -------------------------------------------- # -------------------------------------------- -# x- INITIALIZE XBEE -# SET XBEE CALLBACK TO INTERNAL STUFF - -def printReports(reports): - for report in reports: - print "-Start Report-" - for message in report['msg']: - print "message ", message - print "-End Report-" +# ------------ XBEE IN and OUT --------------- +# -------------------------------------------- +# -------------------------------------------- +# Take in xBee response, return report {timestamp, address, OSCMessage} def getOSCFromXbeeMessage(response): - reports = [] packed_data = response['rf_data'] # print "xBee payload = ", packed_data # print "Size of xBee payload ", len(packed_data) + # Take the bit data from xBee and extract the OSC Message (address, types, data) deserializedMessage = decodeOSC(packed_data) addr = deserializedMessage.pop(0) typeString = deserializedMessage.pop(0) @@ -238,6 +120,8 @@ def getOSCFromXbeeMessage(response): # for byte in addr: # addr = + + # Extract the message source unitID = response['source_addr'] # need to convert to string? # print "unitID: ", repr(unitID) # REALLY need to replace this with something even remotely slick... ;) @@ -252,60 +136,55 @@ def getOSCFromXbeeMessage(response): else: print "Address of unit not detected" - addr = 'unit/' + unitID + addr - msg = liblo.Message(addr) + + # Add the OSC data to the OSCMessage object + OSCmsg = liblo.Message(addr) for entry in data: - msg.add(entry) + OSCmsg.add(entry) + + # Record the message timestamp timeStamp = datetime.now() - reportToStore = {} - reportToStore["msg"] = msg - reportToStore["time"] = datetime.now() - reportToStore["unitID"] = unitID - reports.insert( 0, reportToStore ) + # Place the time, message, and source address into a report + report = {} + report["OSCmsg"] = OSCmsg + report["time"] = datetime.now() + report["unitID"] = unitID - return reports + return report -def message_received(response): - global allReports, numberStoredEntries +# Called upon incoming xBee message +def xBee_received(response): # if response['id'] is not 'rx': # print "RESPONSE: ", response['id'] - # print "--------------------" - # print "XBEE Message RECEIVED" + print "--------------------" + print "XBEE Message RECEIVED" - # print "Response: ", response + print "Response: ", response # If statement is to exclude poorly formatted xbee messages # Usually there is only one sent, when units start (all empty \x00) # Should eliminate this from xBee end... if ',' in response['rf_data']: - reports = getOSCFromXbeeMessage(response) + report = getOSCFromXbeeMessage(response) # print "In message_received: ", reports # Pass OSC message through to Processing - forwardOSCMessage(reports) + xBeeToOSCMessage(report) - # Process the report and trigger actions - - # Store it when done - # check to see if queue is too big - for report in reports: - while len(allReports) >= numberStoredEntries: - allReports.pop() # remove last entry - allReports.insert( 0, report ) else: print "Received bad xBee message" - # print "--------------------" - # print "" + print "--------------------" + print "" @@ -331,7 +210,7 @@ def message_received(response): raise OSError # Initialize xbee object if Serial connetion successful -xbee = XBee(ser, escaped = True, callback=message_received) +xbee = XBee(ser, escaped = True, callback=xBee_received) print "XBEE Object CREATED" @@ -398,18 +277,8 @@ def xbeeSendMessage(xbee, address, packed_data): try: while True: - # NEED TO BUILD INTO PROPER MODEL LOGIC STRUCTURE - # Put broadcast data into structure and send out to units - # - # sleep(1) - # Send test OSC messages to units # xbeeSendBroadcast(xbee, OSC_Tx_Test) - # print "filterTimes", filter_midiMusic_timesSent - - # print "magnitudeCutoff", magnitudeCutoff - # print "----------" - # print pass except KeyboardInterrupt: