|
|
|
@ -27,19 +27,21 @@ from conf import Conf
|
|
|
|
|
|
|
|
|
|
mqueueMutex = threading.Lock()
|
|
|
|
|
squeueMutex = threading.Lock()
|
|
|
|
|
exqueue = Queue.Queue()
|
|
|
|
|
|
|
|
|
|
class QrDisplay(gtk.Window):
|
|
|
|
|
def __init__(self, mqueue, squeue, displog, timeout=250):
|
|
|
|
|
super(QrDisplay, self).__init__()
|
|
|
|
|
|
|
|
|
|
self.fullscreen()
|
|
|
|
|
self.qrimgPadding = 20
|
|
|
|
|
(wx, wy) = self.getHackySize()
|
|
|
|
|
self.timeout = timeout
|
|
|
|
|
self.mqueue = mqueue
|
|
|
|
|
self.squeue = squeue
|
|
|
|
|
self.displog = displog
|
|
|
|
|
|
|
|
|
|
self.fullscreen()
|
|
|
|
|
self.qrimgPadding = 20
|
|
|
|
|
(wx, wy) = self.getHackySize()
|
|
|
|
|
|
|
|
|
|
# build up gui
|
|
|
|
|
self.vbox = gtk.VBox(False, 0)
|
|
|
|
|
self.qrimg = gtk.Image()
|
|
|
|
@ -54,7 +56,7 @@ class QrDisplay(gtk.Window):
|
|
|
|
|
self.add(self.vbox)
|
|
|
|
|
|
|
|
|
|
# connect signals
|
|
|
|
|
self.connect("destroy", gtk.main_quit)
|
|
|
|
|
self.connect("destroy", self.quitGui)
|
|
|
|
|
self.set_size_request(wx, wy)
|
|
|
|
|
self.maximize()
|
|
|
|
|
self.set_position(gtk.WIN_POS_CENTER)
|
|
|
|
@ -62,6 +64,9 @@ class QrDisplay(gtk.Window):
|
|
|
|
|
self.qrSet("")
|
|
|
|
|
gobject.timeout_add(self.timeout, self.checkQueue)
|
|
|
|
|
|
|
|
|
|
def quitGui(self, *args, **kwargs):
|
|
|
|
|
exqueue.put(KeyboardInterrupt())
|
|
|
|
|
|
|
|
|
|
def checkQueue(self):
|
|
|
|
|
#print "Check queue...",
|
|
|
|
|
mqueueMutex.acquire()
|
|
|
|
@ -87,7 +92,7 @@ class QrDisplay(gtk.Window):
|
|
|
|
|
def getHackySize(self):
|
|
|
|
|
""" Obtain current size of screen via xrandr. """
|
|
|
|
|
#p = subprocess.Popen(["bash", "-c", 'xrandr|egrep "\*+"|egrep -o "[0-9]+x[0-9]+"'], stdout=subprocess.PIPE)
|
|
|
|
|
p = subprocess.Popen('xrandr|egrep "\*+"|egrep -o "[0-9]+x[0-9]+"', stdout=subprocess.PIPE)
|
|
|
|
|
p = subprocess.Popen('xrandr|egrep "\*+"|egrep -o "[0-9]+x[0-9]+"', stdout=subprocess.PIPE, shell=True)
|
|
|
|
|
p.wait()
|
|
|
|
|
(myout, myin) = p.communicate()
|
|
|
|
|
return map(lambda x: int(x)-self.qrimgPadding, myout.strip().split("x"))
|
|
|
|
@ -124,14 +129,17 @@ class DisplayThread(threading.Thread):
|
|
|
|
|
threading.Thread.__init__(self)
|
|
|
|
|
self.dev = dev
|
|
|
|
|
self.quit = False
|
|
|
|
|
self.qrdisplay = QrDisplay(mqueue, squeue, )
|
|
|
|
|
self.qrdisplay = QrDisplay(mqueue, squeue, displog)
|
|
|
|
|
self.mqueue = mqueue
|
|
|
|
|
self.squeue = squeue
|
|
|
|
|
self.displog = displog
|
|
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
|
self.displog.info("Display GTK Gui is up and running.")
|
|
|
|
|
gtk.main()
|
|
|
|
|
try:
|
|
|
|
|
gtk.main()
|
|
|
|
|
except Exception, e:
|
|
|
|
|
exqueue.push(e)
|
|
|
|
|
|
|
|
|
|
class CamThread(threading.Thread):
|
|
|
|
|
""" Captures images from a webcam and decodes them.
|
|
|
|
@ -151,55 +159,57 @@ class CamThread(threading.Thread):
|
|
|
|
|
self.success = 0
|
|
|
|
|
self.lastPacket = ""
|
|
|
|
|
|
|
|
|
|
self.reader = highgui.cvCreateCameraCapture(camnum)
|
|
|
|
|
self.reader = highgui.cvCreateCameraCapture(Conf.get("camnum", 0))
|
|
|
|
|
self.scanner = zbar.ImageScanner()
|
|
|
|
|
self.scanner.parse_config('enable')
|
|
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
|
while not self.quit:
|
|
|
|
|
frame = highgui.cvQueryFrame(self.reader)
|
|
|
|
|
self.frame += 1
|
|
|
|
|
|
|
|
|
|
frame = opencv.cvGetMat(frame)
|
|
|
|
|
img = adaptors.Ipl2PIL(frame)
|
|
|
|
|
width, height = img.size
|
|
|
|
|
zimg = zbar.Image(width, height, 'Y800', img.convert("L").tostring())
|
|
|
|
|
self.scanner.scan(zimg)
|
|
|
|
|
data = None
|
|
|
|
|
for symbol in zimg:
|
|
|
|
|
data = symbol.data
|
|
|
|
|
self.camlog.debug("Data is: %s" % data)
|
|
|
|
|
self.success += 1
|
|
|
|
|
# handle data
|
|
|
|
|
if not self.lastPacket == data:
|
|
|
|
|
self.lastPacket = data
|
|
|
|
|
try:
|
|
|
|
|
msg = base64.b64decode(data)
|
|
|
|
|
(rawtime, packet) = (msg[0:8], msg[8:])
|
|
|
|
|
ptime = struct.unpack("<d", rawtime)
|
|
|
|
|
self.camlog.debug("Network packet! Heade (time) is %s" % (ptime,))
|
|
|
|
|
self.dev.write(packet)
|
|
|
|
|
except base64.binascii.Error:
|
|
|
|
|
print " ==> base64 error"
|
|
|
|
|
self.camlog.error("Base64 error - could not decode packet")
|
|
|
|
|
except struct.error:
|
|
|
|
|
self.camlog.error("Header error - could not extract header information")
|
|
|
|
|
else:
|
|
|
|
|
# packet is already known, discard
|
|
|
|
|
pass
|
|
|
|
|
try:
|
|
|
|
|
while not self.quit:
|
|
|
|
|
frame = highgui.cvQueryFrame(self.reader)
|
|
|
|
|
self.frame += 1
|
|
|
|
|
|
|
|
|
|
frame = opencv.cvGetMat(frame)
|
|
|
|
|
img = adaptors.Ipl2PIL(frame)
|
|
|
|
|
width, height = img.size
|
|
|
|
|
zimg = zbar.Image(width, height, 'Y800', img.convert("L").tostring())
|
|
|
|
|
self.scanner.scan(zimg)
|
|
|
|
|
data = None
|
|
|
|
|
for symbol in zimg:
|
|
|
|
|
data = symbol.data
|
|
|
|
|
self.camlog.debug("Data is: %s" % data)
|
|
|
|
|
self.success += 1
|
|
|
|
|
# handle data
|
|
|
|
|
if not self.lastPacket == data:
|
|
|
|
|
self.lastPacket = data
|
|
|
|
|
try:
|
|
|
|
|
msg = base64.b64decode(data)
|
|
|
|
|
(rawtime, packet) = (msg[0:8], msg[8:])
|
|
|
|
|
ptime = struct.unpack("<d", rawtime)
|
|
|
|
|
self.camlog.debug("Network packet! Heade (time) is %s" % (ptime,))
|
|
|
|
|
self.dev.write(packet)
|
|
|
|
|
except (base64.binascii.Error, TypeError):
|
|
|
|
|
self.camlog.error("Base64 error - could not decode packet")
|
|
|
|
|
except struct.error:
|
|
|
|
|
self.camlog.error("Header error - could not extract header information")
|
|
|
|
|
else:
|
|
|
|
|
# packet is already known, discard
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
# status report to gui
|
|
|
|
|
|
|
|
|
|
if self.frame % self.reportAfter == 0:
|
|
|
|
|
self.frame = self.success = 0
|
|
|
|
|
# too much status codes? flush 'em
|
|
|
|
|
squeueMutex.acquire()
|
|
|
|
|
if self.squeue.qsize() > self.reportAfter/2:
|
|
|
|
|
while not self.squeue.empty():
|
|
|
|
|
self.squeue.get()
|
|
|
|
|
# add new status code
|
|
|
|
|
self.squeue.put((self.frame, self.success))
|
|
|
|
|
squeueMutex.release()
|
|
|
|
|
# status report to gui
|
|
|
|
|
if self.frame % self.reportAfter == 0:
|
|
|
|
|
self.frame = self.success = 0
|
|
|
|
|
|
|
|
|
|
squeueMutex.acquire()
|
|
|
|
|
if self.squeue.qsize() > self.reportAfter/2:
|
|
|
|
|
while not self.squeue.empty():
|
|
|
|
|
self.squeue.get()
|
|
|
|
|
# add new status code
|
|
|
|
|
self.squeue.put((self.frame, self.success))
|
|
|
|
|
squeueMutex.release()
|
|
|
|
|
except Exception, e:
|
|
|
|
|
exqueue.put(e)
|
|
|
|
|
raise e
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class QrNet(Ether2Any):
|
|
|
|
@ -208,10 +218,15 @@ class QrNet(Ether2Any):
|
|
|
|
|
# device
|
|
|
|
|
Ether2Any.__init__(self, tap=True)
|
|
|
|
|
self.qrlog = self.setupLogging("QrNet")
|
|
|
|
|
self.dev.ifconfig(address=ip, netmask=netmask, mtu=mtu)
|
|
|
|
|
self.packetDrop = packetDrop
|
|
|
|
|
self.mqueue = Queue.Queue()
|
|
|
|
|
self.squeue = Queue.Queue()
|
|
|
|
|
self.setTimeout(1)
|
|
|
|
|
|
|
|
|
|
network = Conf.get("network", {'mtu': 400})
|
|
|
|
|
self.packetDrop = Conf.get("packetDrop", 20)
|
|
|
|
|
|
|
|
|
|
self.dev.ifconfig(**network)
|
|
|
|
|
self.dev.up()
|
|
|
|
|
|
|
|
|
|
# thread starting...
|
|
|
|
|
gtk.gdk.threads_init()
|
|
|
|
@ -221,10 +236,10 @@ class QrNet(Ether2Any):
|
|
|
|
|
self.display = DisplayThread(self.dev, self.mqueue, self.squeue, self.setupLogging("DisplayThread"))
|
|
|
|
|
self.display.start()
|
|
|
|
|
|
|
|
|
|
def sendToNet(self):
|
|
|
|
|
def sendToNet(self, msg):
|
|
|
|
|
# prepare data for queue && display
|
|
|
|
|
self.qrlog.debug("Data from the device")
|
|
|
|
|
msg = self.dev.read()
|
|
|
|
|
|
|
|
|
|
# add acttime to generate "unique" images
|
|
|
|
|
acttime = struct.pack("<d", time.time())
|
|
|
|
|
bmsg = base64.b64encode(acttime + msg)
|
|
|
|
@ -238,10 +253,26 @@ class QrNet(Ether2Any):
|
|
|
|
|
self.qrlog.debug("Dropping packet!")
|
|
|
|
|
mqueueMutex.release()
|
|
|
|
|
|
|
|
|
|
def callAfterSelect(self):
|
|
|
|
|
# check queue for excetions
|
|
|
|
|
if exqueue.qsize() > 0:
|
|
|
|
|
ex = exqueue.get()
|
|
|
|
|
raise ex
|
|
|
|
|
|
|
|
|
|
def quit(self):
|
|
|
|
|
self.display.quit = True
|
|
|
|
|
self.cam.quit = True
|
|
|
|
|
gtk.main_quit()
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
qrnet = QrNet()
|
|
|
|
|
qrnet.run()
|
|
|
|
|
try:
|
|
|
|
|
qrnet = QrNet()
|
|
|
|
|
qrnet.run()
|
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
|
try:
|
|
|
|
|
qrnet.quit()
|
|
|
|
|
except NameError:
|
|
|
|
|
pass
|
|
|
|
|
sys.exit(0)
|
|
|
|
|
except Exception, e:
|
|
|
|
|
raise e
|
|
|
|
|