#! /usr/bin/env python # Stage Director receiver # Copyright 2014 Stefan Schuermans # Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html import datetime import fcntl import os import select import socket import struct import sys import time scriptdir = os.path.dirname(os.path.abspath(__file__)) class Receiver: def __init__(self): """construct a Stage Director Receiver object""" # set constants self.select_timeout = 0.1 # timeout (s) for select syscall # create member variables self.sock = None # startup self.sockSetup() def __del__(self): """deconstruct object""" self.sockClose() def posyParse(self, data): """parse received PoSy packet""" if len(data) < 76 or data[0:4] != "PoSy": return False flags, name, pos_ms = struct.unpack("!I64sI", data[4:76]) name_end = name.find("\0") if name_end >= 0: name = name[:name_end] if flags & 1: pause = True else: pause = False # store info from PoSy packet print("name=%s pos=%.3fs pause=%s" % (name, pos_ms * 1e-3, pause)) def run(self): """run application""" try: while True: self.waitForInput() except KeyboardInterrupt: pass def sockRecv(self): """receive data from socket""" if self.sock is None: return # receive message data = self.sock.recv(4096) print("data from socket: %d bytes" % len(data)) # parse (ignore message on error) self.posyParse(data) def sockClose(self): """close UDP socket""" if self.sock is not None: self.sock.close() self.sock = None def sockSetup(self): """create a new UDP socket and bind it""" self.sockClose() try: self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.sock.bind(("0.0.0.0", 5740)) except: self.sockClose() def waitForInput(self): """wait for input from UDP socket""" # poll for data inputs = [] outputs = [] errors = [] wait_txt = "" if self.sock is not None: inputs.append(self.sock) wait_txt += " socket" print("waiting for input:" + wait_txt) rds, wrs, exs = select.select(inputs, outputs, errors, self.select_timeout) # obtain available data for rd in rds: if self.sock is not None and rd is self.sock: print("input from socket") self.sockRecv() # main function def main(argv): # run application app = Receiver() app.run() # done return 0 # main application entry point if __name__ == "__main__": sys.exit(main(sys.argv))