psychose/ekgplotter/ekgplotter/ekg_plotter_qt_only.py

267 lines
10 KiB
Python

# -*- 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_()