# -*- coding: utf-8 -*- """ Demonstrates use of PlotWidget class. This is little more than a GraphicsView with a PlotItem placed in its center. """ from collections import deque from PyQt4 import QtNetwork from pyqtgraph.Qt import QtGui, QtCore import numpy as np import pyqtgraph as pg import numpy as np try: from chaosc.c_osc_lib import decode_osc except ImportError as e: print(e) from chaosc.osc_lib import decode_osc class OSCPlotter(QtGui.QWidget): def __init__(self, parent=None): super(OSCPlotter, self).__init__(parent) self.plot_data1 = deque([0] * 100) self.plot_data2 = deque([254 * 0.3] * 100) self.plot_data3 = deque([254 * 0.6] * 100) self.is_item1 = True self.is_item2 = True self.is_item3 = True self.osc_sock = QtNetwork.QUdpSocket(self) self.osc_sock.bind(10000) self.osc_sock.readyRead.connect(self.receive_osc) self.tcpServer = QtNetwork.QTcpServer(self) self.tcpServer.listen(QtNetwork.QHostAddress("0.0.0.0"), 9000) self.tcpServer.newConnection.connect(self.addConnection) self.connections = [] self.streams = [] self.streaming_timer = QtCore.QTimer(self) self.streaming_timer.timeout.connect(self.sendMJpeg) self.streaming_timer.start(20) def addConnection(self): clientConnection = self.tcpServer.nextPendingConnection() #clientConnection.nextBlockSize = 0 self.connections.append(clientConnection) clientConnection.readyRead.connect(self.receiveMessage) clientConnection.disconnected.connect(self.removeConnection) clientConnection.error.connect(self.socketError) def removeConnection(self): pass def socketError(self): pass def receiveMessage(self): for ix, s in enumerate(self.connections): if s.bytesAvailable() > 0: stream = QtCore.QDataStream(s) stream.setVersion(QtCore.QDataStream.Qt_4_8) #if s.nextBlockSize == 0: #if s.bytesAvailable() < 4: #return #s.nextBlockSize = stream.readUInt32() #if s.bytesAvailable() < s.nextBlockSize: #return textFromClient = stream.readRawData(s.bytesAvailable()) print "data", repr(textFromClient) socketId = s.socketDescriptor() if textFromClient.startswith("GET /index.html"): self.sendMessage("HTTP/1.1 200 Ok\r\nContent-Language: en\r\nContent-type: text/html; charset=\"utf-8\"\r\n\r\n" + open("index.html").read() + "\r\n\r\n", s.socketDescriptor()) elif textFromClient.startswith("GET /camera.jpg"): self.sendImage(socketId) elif textFromClient.startswith("GET /camera.mjpeg"): self.prepareMJpeg(socketId) #self.sendImage(s.socketDescriptor()) else: self.sendMessage("HTTP/1.1 404 Not Found\r\n\r\n", s.socketDescriptor()) def sendMessage(self, text, socketId): for s in self.connections: if s.socketDescriptor() == socketId: print "sendMessage" reply = QtCore.QByteArray() stream = QtCore.QDataStream(reply, QtCore.QIODevice.WriteOnly) #stream.setVersion(QtCore.QDataStream.Qt_4_8) stream.writeString(text) s.write(reply) s.close() def prepareMJpeg(self, socketId): for s in self.connections: if s.socketDescriptor() == socketId: self.streams.append(socketId) reply = QtCore.QByteArray() stream = QtCore.QDataStream(reply, QtCore.QIODevice.WriteOnly) stream.setVersion(QtCore.QDataStream.Qt_4_8) stream.writeRawData("HTTP/1.1 200 OK\r\nContent-Type: multipart/x-mixed-replace; boundary=--aaboundary\r\n\r\n") s.write(reply) #s.close() def sendMJpeg(self): reply = QtCore.QByteArray() stream = QtCore.QDataStream(reply, QtCore.QIODevice.WriteOnly) stream.setVersion(QtCore.QDataStream.Qt_4_8) stream.writeRawData("--aaboundary\r\nContent-Type: image/jpeg\r\nContent-length: %d\r\n\r\n%s\r\n\r\n\r\n" % (len(self.jpeg_data), self.jpeg_data)) for socketId in self.streams: for connection in self.connections: if connection.socketDescriptor() == socketId: connection.write(reply) #connection.close() def sendImage(self, socketId): for connection in self.connections: if connection.socketDescriptor() == socketId: reply = QtCore.QByteArray() stream = QtCore.QDataStream(reply, QtCore.QIODevice.WriteOnly) stream.setVersion(QtCore.QDataStream.Qt_4_8) #tmp = open("camera.jpg", "rb").read() header = QtCore.QString("HTTP/1.1 200 OK\r\nContent-Type: image/jpeg\r\nContent-length: %d\r\n\r\n" % len(self.jpeg_data)) stream.writeRawData(header) stream.writeRawData(self.jpeg_data) stream.writeRawData("\r\n\r\n\r\n") connection.write(reply) connection.close() def init(self): self.plt = pg.PlotWidget(name='EKG') ## giving the plots names allows us to link their axes together #self.legend = self.plt.addLegend() l = QtGui.QVBoxLayout() self.statusLabel = QtGui.QLabel("Listening for broadcasted messages") self.setLayout(l) l.addWidget(self.plt) l.addWidget(self.statusLabel) self.plotItem1 = pg.PlotCurveItem(pen=pg.mkPen('r', width=4), name="bjoern") self.plotItem2 = pg.PlotCurveItem(pen=pg.mkPen('g', width=4), name="merle") self.plotItem3 = pg.PlotCurveItem(pen=pg.mkPen('b', width=4), name="uwe") #self.plotItem1.setPos(0, 0*6) #self.plotItem2.setPos(0, 1*6) #self.plotItem3.setPos(0, 2*6) self.plt.addItem(self.plotItem1) self.plt.addItem(self.plotItem2) self.plt.addItem(self.plotItem3) self.plt.setLabel('left', "EKG") self.plt.setLabel('bottom', "Time") self.plt.showGrid(True, True) ba = self.plt.getAxis("bottom") bl = self.plt.getAxis("left") ba.setTicks([]) bl.setTicks([]) self.plt.setYRange(0, 254) self.plotItem1.setData(y=np.array(self.plot_data1), clear=True) self.plotItem2.setData(y=np.array(self.plot_data2), clear=True) self.plotItem3.setData(y=np.array(self.plot_data3), clear=True) #self.plotItem1.setShadowPen(pg.mkPen((200, 200, 200), width=6, cosmetic=True)) #self.plotItem2.setShadowPen(pg.mkPen((200, 200, 200), width=6, cosmetic=True)) #self.plotItem3.setShadowPen(pg.mkPen((200, 200, 200), width=6, cosmetic=True)) def receive_osc(self): #print "receive_osc" while self.osc_sock.hasPendingDatagrams(): packet, address, port = self.osc_sock.readDatagram(self.osc_sock.pendingDatagramSize()) osc_address, typetags, args = decode_osc(packet, 0, len(packet)) #print "osc", osc_address, args[0] self.statusLabel.setText(osc_address) update = False if osc_address == "/bjoern/ekg": self.plot_data1.appendleft(args[0] / 3) self.plot_data1.pop() update = True elif osc_address == "/merle/ekg": self.plot_data2.appendleft(args[0] / 3 + 254/3) self.plot_data2.pop() update = True elif osc_address == "/uwe/ekg": self.plot_data3.appendleft(args[0] /3 + 254/3*2) self.plot_data3.pop() update = True #elif osc_address == "/plot/uwe": #if args[0] == 1 and self.is_item3 == False: #self.plt.addItem(self.plotItem3) #self.is_item3 = True ##self.legend.addItem(self.plotItem3, "uwe") #elif args[0] == 0 and self.is_item3 == True: #self.plt.removeItem(self.plotItem3) #self.is_item3 = False ##self.legend.removeItem("uwe") #elif osc_address == "/plot/merle": #if args[0] == 1 and self.is_item2 == False: #self.plt.addItem(self.plotItem2) #self.is_item2 = True ##self.legend.addItem(self.plotItem2, "merle") #elif args[0] == 0 and self.is_item2 == True: #self.plt.removeItem(self.plotItem2) #self.is_item2 = True ##self.legend.removeItem("merle") #elif osc_address == "/plot/bjoern": #if args[0] == 1 and self.is_item1 == False: #self.plt.addItem(self.plotItem1) #self.is_item1 = True ##self.legend.addItem(self.plotItem1, name="bjoern") #elif args[0] == 0 and self.is_item1 == True: #self.plt.removeItem(self.plotItem1) #self.is_item1 = False ##self.legend.removeItem("bjoern") if update: self.plotItem1.setData(y=np.array(self.plot_data1), clear=True) self.plotItem2.setData(y=np.array(self.plot_data2), clear=True) self.plotItem3.setData(y=np.array(self.plot_data3), clear=True) #item = plt.plot(plot_data1, pen=(0, 3*1.3), clear=True) exporter = pg.exporters.ImageExporter.ImageExporter(self.plt.plotItem) exporter.parameters()['width'] = 1280 #exporter.parameters()['height'] = 720 name = 'tmpfile' img = exporter.export(name, True) buffer = QtCore.QBuffer() buffer.open(QtCore.QIODevice.ReadWrite) img.save(buffer, "JPG", 100) self.jpeg_data = buffer.data() #QtGui.QApplication.setGraphicsSystem('raster') app = QtGui.QApplication([]) mw = QtGui.QMainWindow() mw.setWindowTitle('pyqtgraph example: PlotWidget') mw.resize(1280, 720) cw = OSCPlotter() cw.init() mw.setCentralWidget(cw) mw.show() ## Start Qt event loop unless running in interactive mode or using pyside. if __name__ == '__main__': import sys if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'): QtGui.QApplication.instance().exec_()