Compare commits

...

7 Commits

Author SHA1 Message Date
Stefan Kögl e865fe53d2 changed ekgplotter osc thread to a process 2014-03-27 08:44:24 +01:00
Stefan Kögl e889b3a88c ported from master branch
fixed mem leak with adding external qt event processing

Conflicts:
	ekgplotter/ekgplotter/main.py
2014-03-26 14:39:57 +01:00
Stefan Kögl 41e512c9ef cpu optimized by using select 2014-03-25 22:31:42 +01:00
Stefan Kögl 9bf6f97781 prepared sensors2osc for ip family selection 2014-03-25 22:30:30 +01:00
Stefan Kögl 8dc6e67d1d made ekgplotter ready for ipv4_only 2014-03-25 22:26:19 +01:00
Stefan Kögl 9bcdc6b377 ported to python3.3 2014-03-24 06:47:02 +01:00
Stefan Kögl 7c0f56bf20 ported sensors2osc to python3.3 2014-03-23 13:01:16 +01:00
27 changed files with 3076 additions and 225 deletions

View File

@ -15,7 +15,7 @@ set -g terminal-overrides 'xterm*:smcup@:rmcup@'
new-session -s 'csession'
attach-session -t 'csession'
new-window -n 'chaosc' -t 'csession:1' '/usr/bin/chaosc'
new-window -n 'chaosc' -t 'csession:1' '/usr/bin/chaosc -4'
new-window -n 'socat-ekg-bjoern' -t 'csession:2' 'socat -d -d PTY,raw,echo=0,link=/tmp/ekg2osc-bjoern-in,b115200,user=stefan PTY,raw,echo=0,link=/tmp/ekg2osc-bjoern-out,b115200,user=stefan'
new-window -n 'socat-ekg-merle' -t 'csession:3' 'socat -d -d PTY,raw,echo=0,link=/tmp/ekg2osc-merle-in,b115200,user=stefan PTY,raw,echo=0,link=/tmp/ekg2osc-merle-out,b115200,user=stefan'
@ -29,17 +29,17 @@ new-window -n 'socat-ehealth-bjoern' -t 'csession:8' 'socat -d -d PTY,raw,echo=
new-window -n 'socat-ehealth-merle' -t 'csession:9' 'socat -d -d PTY,raw,echo=0,link=/tmp/ehealth2osc-merle-in,b115200,user=stefan PTY,raw,echo=0,link=/tmp/ehealth2osc-merle-out,b115200,user=stefan'
new-window -n 'socat-ehealth-uwe' -t 'csession:10' 'socat -d -d PTY,raw,echo=0,link=/tmp/ehealth2osc-uwe-in,b115200,user=stefan PTY,raw,echo=0,link=/tmp/ehealth2osc-uwe-out,b115200,user=stefan'
new-window -n 'ekg2osc-bjoern' -t 'csession:11' 'ekg2osc -d /tmp/ekg2osc-bjoern-out -a bjoern'
new-window -n 'ekg2osc-merle' -t 'csession:12' 'ekg2osc -d /tmp/ekg2osc-merle-out -a merle'
new-window -n 'ekg2osc-uwe' -t 'csession:13' 'ekg2osc -d /tmp/ekg2osc-uwe-out -a uwe'
new-window -n 'ekg2osc-bjoern' -t 'csession:11' 'ekg2osc -4 -d /tmp/ekg2osc-bjoern-out -a bjoern'
new-window -n 'ekg2osc-merle' -t 'csession:12' 'ekg2osc -4 -d /tmp/ekg2osc-merle-out -a merle'
new-window -n 'ekg2osc-uwe' -t 'csession:13' 'ekg2osc -4 -d /tmp/ekg2osc-uwe-out -a uwe'
new-window -n 'pulse2osc-bjoern' -t 'csession:14' 'pulse2osc -d /tmp/pulse2osc-bjoern-out -a bjoern'
new-window -n 'pulse2osc-merle' -t 'csession:15' 'pulse2osc -d /tmp/pulse2osc-merle-out -a merle'
new-window -n 'pulse2osc-uwe' -t 'csession:16' 'pulse2osc -d /tmp/pulse2osc-uwe-out -a uwe'
new-window -n 'pulse2osc-bjoern' -t 'csession:14' 'pulse2osc -4 -d /tmp/pulse2osc-bjoern-out -a bjoern'
new-window -n 'pulse2osc-merle' -t 'csession:15' 'pulse2osc -4 -d /tmp/pulse2osc-merle-out -a merle'
new-window -n 'pulse2osc-uwe' -t 'csession:16' 'pulse2osc -4 -d /tmp/pulse2osc-uwe-out -a uwe'
new-window -n 'ehealth2osc-bjoern' -t 'csession:17' 'ehealth2osc -d /tmp/ehealth2osc-bjoern-out -a bjoern'
new-window -n 'ehealth2osc-merle' -t 'csession:18' 'ehealth2osc -d /tmp/ehealth2osc-merle-out -a merle'
new-window -n 'ehealth2osc-uwe' -t 'csession:19' 'ehealth2osc -d /tmp/ehealth2osc-uwe-out -a uwe'
new-window -n 'ehealth2osc-bjoern' -t 'csession:17' 'ehealth2osc -4 -d /tmp/ehealth2osc-bjoern-out -a bjoern'
new-window -n 'ehealth2osc-merle' -t 'csession:18' 'ehealth2osc -4 -d /tmp/ehealth2osc-merle-out -a merle'
new-window -n 'ehealth2osc-uwe' -t 'csession:19' 'ehealth2osc -4 -d /tmp/ehealth2osc-uwe-out -a uwe'
new-window -n 'test-ekg-bjoern' -t 'csession:20' 'python /home/stefan/dev/psychose/sensors2osc/sensors2osc/socat_ekg_test.py /tmp/ekg2osc-bjoern-in'
new-window -n 'test-ekg-merle' -t 'csession:21' 'python /home/stefan/dev/psychose/sensors2osc/sensors2osc/socat_ekg_test.py /tmp/ekg2osc-merle-in'
@ -54,6 +54,7 @@ new-window -n 'test-ehealth-merle' -t 'csession:27' 'python /home/stefan/dev/ps
new-window -n 'test-ehealth-uwe' -t 'csession:28' 'python /home/stefan/dev/psychose/sensors2osc/sensors2osc/socat_ehealth_test.py /tmp/ehealth2osc-uwe-in'
# new-window -n 'ekgplotter' -t 'csession:29' 'sleep 5 && ekgplotter -s'
# new-window -n 'vlc' -t 'csession:30' 'sleep 10 && vlc "http://localhost:9000/camera.mjpeg"'
new-window -n 'chaosc_emitter' -t 'csession:31' 'chaosc_emitter'
select-window -t 'csession:1'

View File

@ -0,0 +1,106 @@
data = [20, 14, 9, 9, 37, 42, 33, 31, 20, 42, 255, 47, 29, 34, 8, 16, 4, 5, 10, 18, 7, 10, 19, 4, 12, 11, 29, 46, 48,
44, 25, 27, 255, 46, 48, 28, 13, 13, 13, 10, 17, 16, 20, 12, 8, 13, 0, 2, 40, 45, 37, 37, 39, 29, 255, 21, 25, 23,
18, 8, 14, 3, 16, 19, 2, 6, 20, 13, 5, 5, 37, 36, 38, 34, 21, 27, 255, 35, 31, 48, 11, 17, 1, 17, 14, 12, 20, 0, 6,
17, 1, 9, 27, 46, 21, 50, 44, 26, 255, 50, 38, 36, 35, 17, 20, 4, 18, 20, 6, 16, 20, 12, 10, 20, 8, 20, 20, 45, 40,
21, 37, 38, 255, 35, 44, 29, 17, 7, 6, 14, 6, 13, 16, 9, 8, 10, 7, 13, 49, 43, 41, 49, 40, 50, 49, 255, 29, 42, 36,
7, 5, 10, 20, 0, 19, 6, 18, 18, 13, 16, 3, 50, 40, 46, 26, 45, 49, 36, 255, 24, 39, 36, 2, 7, 3, 1, 1, 15, 12, 6,
6, 5, 0, 7, 32, 43, 30, 50, 39, 50, 47, 255, 23, 41, 24, 6, 6, 1, 11, 9, 16, 5, 6, 3, 11, 7, 17, 12, 28, 47, 31,
23, 31, 37, 32, 255, 50, 21, 22, 50, 1, 2, 1, 6, 12, 15, 9, 2, 4, 10, 14, 13, 46, 35, 39, 44, 39, 42, 29, 255, 20,
45, 38, 29, 13, 20, 7, 13, 12, 12, 3, 12, 10, 14, 15, 20, 26, 30, 44, 27, 48, 46, 21, 255, 39, 40, 38, 22, 18, 3, 20,
20, 4, 14, 11, 14, 10, 0, 12, 0, 25, 25, 28, 24, 44, 22, 31, 255, 29, 25, 39, 28, 7, 1, 6, 7, 7, 11, 15, 7, 10, 17,
0, 0, 27, 23, 41, 21, 21, 41, 45, 45, 255, 27, 36, 46, 10, 13, 14, 8, 3, 15, 14, 4, 15, 12, 11, 2, 14, 35, 42, 50, 26,
37, 30, 35, 38, 255, 34, 47, 33, 20, 3, 2, 2, 14, 11, 11, 7, 3, 15, 18, 9, 13, 27, 30, 27, 47, 34, 22, 38, 20, 255,
22, 46, 50, 3, 9, 18, 19, 11, 19, 6, 2, 4, 0, 14, 13, 5, 39, 40, 48, 43, 33, 25, 43, 20, 255, 45, 42, 47, 11, 4, 0,
1, 6, 8, 15, 16, 18, 1, 11, 0, 6, 5, 38, 47, 32, 23, 40, 37, 39, 255, 26, 30, 36, 37, 7, 5, 7, 11, 8, 13, 12, 12, 17,
12, 1, 11, 8, 14, 44, 25, 31, 41, 50, 39, 46, 255, 49, 39, 44, 23, 4, 5, 14, 15, 1, 13, 7, 9, 7, 5, 4, 7, 16, 2, 41,
30, 37, 36, 34, 23, 32, 255, 49, 32, 33, 41, 2, 13, 17, 8, 19, 18, 15, 4, 12, 18, 6, 19, 10, 8, 38, 31, 36, 34, 44,
50, 20, 255, 39, 39, 24, 30, 11, 5, 12, 16, 20, 18, 2, 8, 17, 14, 24, 7, 10, 13, 6, 27, 41, 31, 46, 29, 46, 39, 28,
255, 43, 28, 38, 49, 11, 11, 19, 1, 12, 14, 0, 18, 4, 21, 4, 16, 11, 16, 42, 44, 49, 23, 38, 31, 35, 47, 255, 30, 23,
23, 45, 1, 10, 3, 8, 16, 16, 6, 17, 10, 24, 3, 19, 11, 3, 24, 27, 42, 45, 27, 46, 26, 41, 255, 31, 44, 39, 49, 10,
4, 20, 3, 9, 15, 7, 15, 5, 19, 4, 10, 9, 13, 30, 29, 47, 21, 24, 36, 45, 20, 255, 33, 45, 25, 24, 2, 9, 19, 2, 20,
17, 19, 10, 20, 12, 10, 19, 20, 9, 20, 30, 38, 34, 22, 46, 26, 24, 26, 255, 23, 26, 29, 37, 0, 10, 9, 20, 14, 19,
2, 0, 1, 4, 12, 19, 6, 17, 17, 46, 47, 42, 34, 32, 29, 40, 47, 255, 27, 30, 25, 36, 14, 3, 11, 20, 4, 0, 1, 9, 19,
15, 13, 2, 19, 1, 7, 42, 20, 25, 46, 30, 49, 39, 28, 255, 34, 43, 24, 34, 6, 1, 18, 9, 8, 11, 11, 17, 11, 6, 26,
7, 3, 1, 14, 49, 41, 37, 27, 34, 22, 47, 20, 24, 255, 36, 34, 20, 26, 13, 7, 18, 10, 6, 9, 4, 0, 14, 14, 27, 5,
13, 0, 7, 39, 21, 42, 34, 36, 45, 24, 28, 43, 255, 20, 26, 36, 31, 8, 8, 0, 0, 14, 0, 1, 8, 15, 1, 19, 13, 15,
17, 9, 44, 38, 33, 21, 37, 48, 32, 30, 34, 255, 32, 32, 33, 40, 19, 6, 5, 2, 7, 3, 10, 19, 10, 12, 14, 16, 15,
14, 7, 29, 29, 50, 31, 26, 36, 31, 22, 32, 255, 48, 45, 42, 31, 50, 13, 9, 5, 16, 7, 12, 12, 4, 6, 1, 24, 14, 12,
6, 3, 25, 27, 50, 40, 25, 35, 37, 25, 47, 255, 30, 29, 45, 36, 34, 0, 13, 20, 13, 18, 11, 16, 16, 0, 9, 23, 8,
7, 4, 18, 41, 50, 20, 45, 48, 43, 31, 36, 30, 255, 37, 30, 22, 38, 39, 10, 16, 9, 7, 13, 18, 1, 5, 14, 20, 21,
13, 19, 15, 13, 34, 26, 21, 45, 35, 44, 39, 23, 21, 255, 27, 47, 45, 41, 39, 9, 11, 12, 10, 13, 4, 8, 15, 4,
19, 3, 1, 15, 9, 5, 2, 8, 33, 38, 35, 26, 48, 42, 25, 50, 23, 255, 24, 26, 29, 20, 32, 12, 1, 9, 10, 12, 6,
14, 6, 14, 1, 19, 14, 20, 2, 8, 4, 31, 43, 27, 24, 33, 33, 27, 23, 21, 255, 41, 37, 23, 28, 33, 2, 17, 8, 9,
16, 10, 17, 11, 4, 4, 4, 17, 19, 13, 3, 0, 20, 36, 31, 50, 48, 31, 43, 36, 34, 255, 31, 41, 29, 47, 21, 18,
15, 11, 20, 14, 14, 11, 4, 12, 2, 12]
from collections import deque
data_points = 20
item_data1 = deque([0] * data_points)
pos1 = 0
lengths = [0]
item_point1 = 0
def set_point(plotPoint, pos, value, ix, max_items):
scale = 254 / max_items * ix
return 6 * ix + value / max_items + scale
def find_max_value(item_data):
max_value = 0
max_index = 0
for ix, i in enumerate(item_data):
if i > max_value:
max_value = i
max_index = ix
return max_index, max_value
def rearrange(item_data, actual_pos, max_items):
max_value_index, max_value = find_max_value(item_data)
mean = int(max_items / 2.)
start = mean - max_value_index
if start != 0:
item_data.rotate(start)
pos = (actual_pos + start) % max_items
else:
pos = actual_pos
print "rearrange", mean, start, actual_pos, pos, item_data
return pos
def set_value(item_data, pos, max_pos, value):
print "setValue before", pos, None, max_pos, value, item_data
item_data[pos] = value
new_pos = (pos + 1) % max_pos
print "setValue after ", pos, new_pos, max_pos, value, item_data
return new_pos
def resize(item_data, max_length, new_max_length):
if new_max_length > max_length:
pad = (new_max_length - max_length)
print "pad", pad
item_data.extend([0] * pad)
return new_max_length
else:
return max_length
for value in data:
if value > 250:
data_points = resize(item_data1, data_points, lengths[-1])
lengths.append(0)
else:
lengths[-1] += 1
ix = 0
set_point(None, pos1, value, ix, 3)
pos1 = set_value(item_data1, pos1, data_points, value)
pos1 = rearrange(item_data1, pos1, data_points)
print
print "lengths", lengths

View File

@ -0,0 +1,266 @@
# -*- 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_()

View File

@ -22,19 +22,22 @@
#
# Copyright (C) 2014 Stefan Kögl
from __future__ import absolute_import
#import objgraph
#import gc
#gc.set_debug(gc.DEBUG_LEAK)
from datetime import datetime
import threading
import Queue
from queue import Empty
import numpy as np
import string,cgi,time, random, socket
from os import curdir, sep
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from SocketServer import ThreadingMixIn, ForkingMixIn
import os.path
from http.server import BaseHTTPRequestHandler, HTTPServer
from socketserver import ThreadingMixIn, ForkingMixIn
import select
import re
@ -42,7 +45,7 @@ from collections import deque
from PyQt4.QtCore import QBuffer, QByteArray, QIODevice
from PyQt4 import QtGui
from PyQt4 import QtGui, QtCore
import pyqtgraph as pg
@ -51,14 +54,13 @@ from pyqtgraph.widgets.PlotWidget import PlotWidget
from chaosc.argparser_groups import *
from chaosc.lib import resolve_host
#try:
#from chaosc.c_osc_lib import *
#except ImportError:
from chaosc.osc_lib import *
from multiprocessing import Process, Queue
QtGui.QApplication.setGraphicsSystem('opengl')
try:
from chaosc.c_osc_lib import *
except ImportError:
from chaosc.osc_lib import *
print "systemInfo", pg.systemInfo()
try:
from chaosc.c_osc_lib import decode_osc
@ -66,35 +68,24 @@ except ImportError as e:
print(e)
from chaosc.osc_lib import decode_osc
QAPP = QtGui.QApplication([])
class PlotWindow(PlotWidget):
def __init__(self, title=None, **kargs):
self.win = QtGui.QMainWindow()
PlotWidget.__init__(self, **kargs)
self.win.setCentralWidget(self)
for m in ['resize']:
setattr(self, m, getattr(self.win, m))
if title is not None:
self.win.setWindowTitle(title)
class OSCThread(threading.Thread):
def __init__(self, args):
class OSCThread(Process):
def __init__(self, args, queue):
super(OSCThread, self).__init__()
self.msg_queue = queue
self.args = args
self.running = True
self.own_address = socket.getaddrinfo(args.own_host, args.own_port, socket.AF_INET6, socket.SOCK_DGRAM, 0, socket.AI_V4MAPPED | socket.AI_ALL | socket.AI_CANONNAME)[-1][4][:2]
self.chaosc_address = chaosc_host, chaosc_port = socket.getaddrinfo(args.chaosc_host, args.chaosc_port, socket.AF_INET6, socket.SOCK_DGRAM, 0, socket.AI_V4MAPPED | socket.AI_ALL | socket.AI_CANONNAME)[-1][4][:2]
self.own_address = resolve_host(args.own_host, args.own_port, args.address_family)
self.osc_sock = socket.socket(10, 2, 17)
self.chaosc_address = chaosc_host, chaosc_port = resolve_host(args.chaosc_host, args.chaosc_port, args.address_family)
self.osc_sock = socket.socket(args.address_family, 2, 17)
self.osc_sock.bind(self.own_address)
self.osc_sock.setblocking(0)
print "%s: starting up osc receiver on '%s:%d'" % (
datetime.now().strftime("%x %X"), self.own_address[0], self.own_address[1])
print("%s: starting up osc receiver on '%s:%d'" % (
datetime.now().strftime("%x %X"), self.own_address[0], self.own_address[1]))
self.subscribe_me()
@ -110,13 +101,13 @@ class OSCThread(threading.Thread):
:param token: token to get authorized for subscription
:type token: str
"""
print "%s: subscribing to '%s:%d' with label %r" % (datetime.now().strftime("%x %X"), self.chaosc_address[0], self.chaosc_address[1], self.args.subscriber_label)
msg = OSCMessage("/subscribe")
msg.appendTypedArg(self.own_address[0], "s")
msg.appendTypedArg(self.own_address[1], "i")
msg.appendTypedArg(self.args.authenticate, "s")
print("%s: subscribing to '%s:%d' with label %r" % (datetime.now().strftime("%x %X"), self.chaosc_address[0], self.chaosc_address[1], self.args.subscriber_label))
msg = OSCMessage(b"/subscribe")
msg.appendTypedArg(bytes(self.own_address[0], "ascii"), b"s")
msg.appendTypedArg(self.own_address[1], b"i")
msg.appendTypedArg(bytes(self.args.authenticate, "ascii"), b"s")
if self.args.subscriber_label is not None:
msg.appendTypedArg(self.args.subscriber_label, "s")
msg.appendTypedArg(bytes(self.args.subscriber_label, "ascii"), b"s")
self.osc_sock.sendto(msg.encode_osc(), self.chaosc_address)
@ -124,11 +115,11 @@ class OSCThread(threading.Thread):
if self.args.keep_subscribed:
return
print "%s: unsubscribing from '%s:%d'" % (datetime.now().strftime("%x %X"), self.chaosc_address[0], self.chaosc_address[1])
msg = OSCMessage("/unsubscribe")
msg.appendTypedArg(self.own_address[0], "s")
msg.appendTypedArg(self.own_address[1], "i")
msg.appendTypedArg(self.args.authenticate, "s")
print("%s: unsubscribing from '%s:%d'" % (datetime.now().strftime("%x %X"), self.chaosc_address[0], self.chaosc_address[1]))
msg = OSCMessage(b"/unsubscribe")
msg.appendTypedArg(bytes(self.own_address[0], "ascii"), b"s")
msg.appendTypedArg(self.own_address[1], b"i")
msg.appendTypedArg(bytes(self.args.authenticate, "ascii"), b"s")
self.osc_sock.sendto(msg.encode_osc(), self.chaosc_address)
def run(self):
@ -136,21 +127,22 @@ class OSCThread(threading.Thread):
while self.running:
reads, writes, errs = select.select([self.osc_sock], [], [], 0.05)
if reads:
osc_input = reads[0].recv(4096)
osc_input = reads[0].recv(128)
osc_address, typetags, messages = decode_osc(osc_input, 0, len(osc_input))
#print "thread osc_address", osc_address
if osc_address.find("ekg") > -1 or osc_address.find("plot") != -1:
queue.put_nowait((osc_address, messages))
print("thread: osc_address", osc_address)
if osc_address.find(b"ekg") > -1 or osc_address.find(b"plot") != -1:
#print("send", osc_address)
self.msg_queue.put_nowait((osc_address, messages))
else:
queue.put_nowait(("/bjoern/ekg", [0]))
queue.put_nowait(("/merle/ekg", [0]))
queue.put_nowait(("/uwe/ekg", [0]))
print("thread: dummy values")
self.msg_queue.put_nowait((b"/bjoern/ekg", [0]))
self.msg_queue.put_nowait((b"/merle/ekg", [0]))
self.msg_queue.put_nowait((b"/uwe/ekg", [0]))
time.sleep(0.01)
self.unsubscribe_me()
print "OSCThread is going down"
print("OSCThread is going down")
queue = Queue.Queue()
class Actor(object):
shadowPen = pg.mkPen(255, 255, 255)
brush = pg.mkBrush("w")
@ -231,8 +223,8 @@ class Actor(object):
class EkgPlot(object):
def __init__(self, actor_names, num_data, colors):
self.plot = pg.PlotWidget(title="<h1>EKG</h1>")
self.plot.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.plot.hide()
self.plot.setLabel('left', "<h2>Amplitude</h2>")
self.plot.setLabel('bottom', "<h2><sup>Time</sup></h2>")
@ -256,8 +248,8 @@ class EkgPlot(object):
self.set_positions()
self.ekg_regex = re.compile("^/(.*?)/ekg$")
self.ctl_regex = re.compile("^/plot/(.*?)$")
self.ekg_regex = re.compile(b"^/(.*?)/ekg$")
self.ctl_regex = re.compile(b"^/plot/(.*?)$")
self.updated_actors = set()
@ -279,18 +271,24 @@ class EkgPlot(object):
def update(self, osc_address, value):
res = self.ekg_regex.match(osc_address)
if res:
#print("matched data")
actor_name = res.group(1)
actor_obj = self.actors[actor_name]
max_actors = len(self.active_actors)
ix = self.active_actors.index(actor_obj)
actor_data = actor_obj.data
data_pointer = actor_obj.data_pointer
actor_data[data_pointer] = value
actor_obj.set_point(value, ix, max_actors)
try:
ix = self.active_actors.index(actor_obj)
actor_obj.set_point(value, ix, max_actors)
actor_obj.plotItem.setData(y=np.array(actor_obj.scale_data(ix, max_actors)), clear=True)
except ValueError as e:
#print("data", e)
pass
actor_obj.data_pointer = (data_pointer + 1) % self.num_data
actor_obj.plotItem.setData(y=np.array(actor_obj.scale_data(ix, max_actors)), clear=True)
return
res = self.ctl_regex.match(osc_address)
@ -298,62 +296,72 @@ class EkgPlot(object):
actor_name = res.group(1)
actor_obj = self.actors[actor_name]
if value == 1 and not actor_obj.active:
print "actor on", actor_name
self.plot.addItem(actor_obj)
#print("actor on", actor_name, actor_obj, self.active_actors)
actor_obj.active = True
self.active_actors.append(actor_obj)
elif value == 0 and not actor_obj.active:
print "actor off", actor_name
self.plot.removeItem(actor_obj)
actor_obj.active = True
self.active_actors.remove(actor_obj)
if actor_obj not in self.active_actors:
self.plot.addItem(actor_obj.plotItem)
self.plot.addItem(actor_obj.plotPoint)
self.active_actors.append(actor_obj)
elif value == 0 and actor_obj.active:
#print "actor off", actor_name
actor_obj.active = False
self.plot.removeItem(actor_obj.plotItem)
self.plot.removeItem(actor_obj.plotPoint)
try:
self.active_actors.remove(actor_obj)
except ValueError as e:
pass
assert actor_obj not in self.active_actors
self.set_positions()
class MyHandler(BaseHTTPRequestHandler):
def __del__(self):
self.thread.running = False
self.thread.join()
def do_GET(self):
try:
self.path=re.sub('[^.a-zA-Z0-9]', "",str(self.path))
if self.path=="" or self.path==None or self.path[:1]==".":
self.send_error(403,'Forbidden')
self.send_error(403)
if self.path.endswith(".html"):
f = open(curdir + sep + self.path)
directory = os.path.dirname(os.path.abspath(__file__))
data = open(os.path.join(directory, self.path), "rb").read()
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(f.read())
f.close()
self.wfile.write(data)
elif self.path.endswith(".mjpeg"):
self.thread = thread = OSCThread(self.server.args)
thread.daemon = True
msg_queue = Queue()
self.thread = thread = OSCThread(self.server.args, msg_queue)
thread.start()
self.send_response(200)
actor_names = ["bjoern", "merle", "uwe"]
actor_names = [b"bjoern", b"merle", b"uwe"]
num_data = 100
colors = ["r", "g", "b"]
plotter = EkgPlot(actor_names, num_data, colors)
qtapp = QtGui.QApplication([])
self.plotter = plotter = EkgPlot(actor_names, num_data, colors)
self.wfile.write("Content-Type: multipart/x-mixed-replace; boundary=--aaboundary\r\n\r\n")
self.send_header("Content-Type", "multipart/x-mixed-replace; boundary=--aaboundary\r\n\r\n")
self.end_headers()
#lastTime = time.time()
#fps = None
event_loop = QtCore.QEventLoop()
while 1:
event_loop.processEvents()
qtapp.sendPostedEvents(None, 0)
while 1:
try:
osc_address, args = queue.get_nowait()
except Queue.Empty:
osc_address, args = msg_queue.get_nowait()
except Empty as e:
print("queue error", e, type(e))
break
print("main: got value", osc_address, args)
plotter.update(osc_address, args[0])
exporter = pg.exporters.ImageExporter.ImageExporter(plotter.plot.plotItem)
@ -361,8 +369,26 @@ class MyHandler(BaseHTTPRequestHandler):
buffer = QBuffer()
buffer.open(QIODevice.WriteOnly)
img.save(buffer, "JPG", 100)
JpegData = buffer.data()
self.wfile.write("--aaboundary\r\nContent-Type: image/jpeg\r\nContent-length: %d\r\n\r\n%s\r\n\r\n\r\n" % (len(JpegData), JpegData))
JpegData = buffer.data().data()
try:
self.send_header("--aaboundary", None)
self.send_header("Content-Type", "image/jpeg")
self.send_header("Content-length", len(JpegData))
self.end_headers()
self.wfile.write(JpegData + b"\r\n\r\n\r\n")
except (BrokenPipeError, ConnectionResetError) as e:
print("Error:", e)
if hasattr(self, "plotter"):
print("children", plotter.plot.children())
plotter.plot.deleteLater()
plotter.plot.close()
del self.plotter.plot
del self.plotter
del plotter
thread.running = False
thread.join()
return
del JpegData
del buffer
del img
@ -378,64 +404,55 @@ class MyHandler(BaseHTTPRequestHandler):
#print '%0.2f fps' % fps
elif self.path.endswith(".jpeg"):
f = open(curdir + sep + self.path)
directory = os.path.dirname(os.path.abspath(__file__))
data = open(os.path.join(directory, self.path), "rb").read()
self.send_response(200)
self.send_header('Content-type','image/jpeg')
self.end_headers()
self.wfile.write(f.read())
f.close()
self.wfile.write(data)
return
except (KeyboardInterrupt, SystemError):
print "queue size", queue.qsize()
print("queue size", msg_queue.qsize())
thread.running = False
thread.join()
except IOError:
self.send_error(404,'File Not Found: %s' % self.path)
if hasattr(self, "plotter"):
plotter.plot.deleteLater()
except IOError as e:
print("ioerror", e)
print('-'*40)
print('Exception happened during processing of request from')
import traceback
traceback.print_exc() # XXX But this goes to stderr!
print( '-'*40)
self.send_error(404, 'File Not Found: %s' % self.path)
class JustAHTTPServer(HTTPServer):
address_family = socket.AF_INET6
pass
def main():
a = create_arg_parser("ekgplotter")
own_group = add_main_group(a)
arg_parser = create_arg_parser("ekgplotter")
own_group = add_main_group(arg_parser)
own_group.add_argument('-x', "--http_host", default="::",
help='my host, defaults to "socket.gethostname()"')
own_group.add_argument('-X', "--http_port", default=9000,
type=int, help='my port, defaults to 9000')
add_chaosc_group(a)
add_subscriber_group(a, "ekgplotter")
args = finalize_arg_parser(a)
add_chaosc_group(arg_parser)
add_subscriber_group(arg_parser, "ekgplotter")
args = finalize_arg_parser(arg_parser)
http_host, http_port = resolve_host(args.http_host, args.http_port)
print http_host, http_port
http_host, http_port = resolve_host(args.http_host, args.http_port, args.address_family)
server = JustAHTTPServer((http_host, http_port), MyHandler)
server.address_family = args.address_family
server.args = args
print "%s: starting up http server on '%s:%d'" % (
datetime.now().strftime("%x %X"), http_host, http_port)
print("%s: starting up http server on '%s:%d'" % (
datetime.now().strftime("%x %X"), http_host, http_port))
print "before start:"
#objgraph.show_growth()
try:
server.serve_forever()
except KeyboardInterrupt:
print '^C received, shutting down server'
#print "queue size", queue.qsize()
#print "show growth", objgraph.show_growth()
#import random
#objgraph.show_chain(
#objgraph.find_backref_chain(
#random.choice(objgraph.by_type('function')),
#objgraph.is_proper_module),
#filename='chain.png')
#roots = objgraph.get_leaking_objects()
#print "root", len(roots)
#objgraph.show_most_common_types(objects=roots)
#objgraph.show_refs(roots[:3], refcounts=True, filename='roots.png')
server.socket.close()

View File

@ -0,0 +1,217 @@
import numpy as np
import string,cgi,time, random, socket
from os import curdir, sep
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from SocketServer import ThreadingMixIn, ForkingMixIn
import select
import re
from collections import deque
from PyQt4.QtCore import QBuffer, QByteArray, QIODevice, QThread, QObject
from PyQt4 import QtGui
from PyQt4 import QtCore
import pyqtgraph as pg
from pyqtgraph.widgets.PlotWidget import PlotWidget
try:
from chaosc.c_osc_lib import decode_osc
except ImportError as e:
print(e)
from chaosc.osc_lib import decode_osc
QAPP = None
def mkQApp():
if QtGui.QApplication.instance() is None:
global QAPP
QAPP = QtGui.QApplication([])
class PlotWindow(PlotWidget):
def __init__(self, title=None, **kargs):
mkQApp()
self.win = QtGui.QMainWindow()
PlotWidget.__init__(self, **kargs)
self.win.setCentralWidget(self)
for m in ['resize']:
setattr(self, m, getattr(self.win, m))
if title is not None:
self.win.setWindowTitle(title)
class WorkThread(QThread):
osc_received = QtCore.pyqtSignal(str, int, name='osc_received')
def __init__(self):
QThread.__init__(self)
self.osc_sock = socket.socket(2, 2, 17)
self.osc_sock.setblocking(0)
self.osc_sock.setsockopt(socket.SOL_SOCKET,
socket.SO_RCVBUF, 4096 * 8)
self.osc_sock.bind(("", 10000))
def __del__(self):
self.wait()
def run(self):
while 1:
reads, writes, errs = select.select([self.osc_sock], [], [], 0.01)
if reads:
osc_input = reads[0].recv(4096)
osc_address, typetags, args = decode_osc(osc_input, 0, len(osc_input))
print "signal", osc_address, args[0]
self.osc_received.emit(osc_address, args[0])
class MyHandler(QtCore.QObject, BaseHTTPRequestHandler):
def __init__(self, request, client_address, parent):
self.plot_data1 = deque([0] * 100)
self.plot_data2 = deque([254/3] * 100)
self.plot_data3 = deque([254/3*2] * 100)
self.is_item1 = True
self.is_item2 = True
self.is_item3 = True
QtCore.QObject.__init__(self)
BaseHTTPRequestHandler.__init__(self, request, client_address, parent)
@QtCore.pyqtSlot('QString', int, name="receive_osc")
def receive_osc(self, osc_address, value):
print "change", osc_address, value
if osc_address == "/bjoern/ekg":
self.plot_data1.appendleft(args[0] / 3)
self.plot_data1.pop()
elif osc_address == "/merle/ekg":
self.plot_data2.appendleft(args[0] / 3 + 254/3)
self.plot_data2.pop()
elif osc_address == "/uwe/ekg":
self.plot_data3.appendleft(args[0] / 3 + 254/3*2)
self.plot_data3.pop()
elif osc_address == "/plot/uwe":
if value == 1 and self.is_item3 == False:
self.plt.addItem(self.plotItem3)
elif value == 0 and self.is_item3 == True:
self.plt.removeItem(self.plotItem3)
elif osc_address == "/plot/merle":
if value == 1 and self.is_item2 == False:
self.plt.addItem(self.plotItem2)
elif value == 0 and self.is_item2 == True:
self.plt.removeItem(self.plotItem2)
elif osc_address == "/plot/bjoern":
if value == 1 and self.is_item1 == False:
self.plt.addItem(self.plotItem1)
elif value == 0 and self.is_item1 == True:
self.plt.removeItem(self.plotItem1)
def do_GET(self):
print "get"
global plotValues
try:
self.path=re.sub('[^.a-zA-Z0-9]', "",str(self.path))
if self.path=="" or self.path==None or self.path[:1]==".":
return
if self.path.endswith(".html"):
f = open(curdir + sep + self.path)
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(f.read())
f.close()
return
if self.path.endswith(".mjpeg"):
self.thread = WorkThread()
#self.thread.osc_received.connect(self.change)
#self.connect(self.thread, thread.osc_received, self.change)
self.thread.osc_received.connect(self.receive_osc)
self.thread.start()
self.send_response(200)
self.plt = plt = PlotWindow(title="EKG", name="Merle")
plt.addLegend()
#plt = pg.plot(pen=(0, 3*1.3))
plt.resize(1280, 720)
self.plotItem1 = plotItem1 = pg.PlotCurveItem(pen=pg.mkPen('r', width=4), name="bjoern")
self.plotItem2 = plotItem2 = pg.PlotCurveItem(pen=pg.mkPen('g', width=4), name="merle")
self.plotItem3 = plotItem3 = pg.PlotCurveItem(pen=pg.mkPen('b', width=4), name="uwe")
plotItem1.setPos(0, 0*6)
plotItem2.setPos(0, 1*6)
plotItem3.setPos(0, 2*6)
plt.addItem(plotItem1)
plt.addItem(plotItem2)
plt.addItem(plotItem3)
plt.setLabel('left', "EKG")
plt.setLabel('bottom', "Time")
plt.showGrid(True, True)
ba = plt.getAxis("bottom")
bl = plt.getAxis("left")
ba.setTicks([])
bl.setTicks([])
plt.setYRange(0, 254)
#print type(plt)
self.wfile.write("Content-Type: multipart/x-mixed-replace; boundary=--aaboundary")
self.wfile.write("\r\n\r\n")
last = time.time()
now = last
while 1:
plotItem1.setData(y=np.array(self.plot_data1), clear=True)
plotItem2.setData(y=np.array(self.plot_data2), clear=True)
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(plt.plotItem)
exporter.parameters()['width'] = 1280
#exporter.parameters()['height'] = 720
name = 'tmpfile'
img = exporter.export(name, True)
buffer = QBuffer()
buffer.open(QIODevice.ReadWrite)
img.save(buffer, "JPG", 100)
JpegData = buffer.data()
self.wfile.write("--aaboundary\r\n")
self.wfile.write("Content-Type: image/jpeg\r\n")
self.wfile.write("Content-length: %d\r\n\r\n" % len(JpegData))
self.wfile.write(JpegData)
self.wfile.write("\r\n\r\n\r\n")
now = time.time()
dur = now - last
#print dur
wait = 0.04 - dur
if wait > 0:
time.sleep(wait)
last = now
return
if self.path.endswith(".jpeg"):
f = open(curdir + sep + self.path)
self.send_response(200)
self.send_header('Content-type','image/jpeg')
self.end_headers()
self.wfile.write(f.read())
f.close()
return
return
except IOError:
self.send_error(404,'File Not Found: %s' % self.path)
class ThreadedHTTPServer(HTTPServer, ForkingMixIn):
"""Handle requests in a separate process."""
def main():
try:
server = ThreadedHTTPServer(('0.0.0.0', 9000), MyHandler)
print 'started httpserver...'
server.serve_forever()
except KeyboardInterrupt:
print '^C received, shutting down server'
server.socket.close()
if __name__ == '__main__':
main()

View File

@ -0,0 +1,461 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# This file is part of sensors2osc package
#
# sensors2osc is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# sensors2osc is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with sensors2osc. If not, see <http://www.gnu.org/licenses/>.
#
# found the mjpeg part here, thanks for the nice code :)
# http://hardsoftlucid.wordpress.com/2013/04/11/mjpeg-server-for-webcam-in-python-with-opencv/
# the osc integration stuff is implemented by me
#
# Copyright (C) 2014 Stefan Kögl
from __future__ import absolute_import
from datetime import datetime
import threading
import Queue
import numpy as np
import string,cgi,time, random, socket
from os import curdir, sep
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from SocketServer import ThreadingMixIn, ForkingMixIn
import select
import re
from collections import deque
from PyQt4.QtCore import QBuffer, QByteArray, QIODevice
from PyQt4 import QtGui
import pyqtgraph as pg
from pyqtgraph.widgets.PlotWidget import PlotWidget
from chaosc.argparser_groups import *
try:
from chaosc.c_osc_lib import *
except ImportError:
from chaosc.osc_lib import *
QtGui.QApplication.setGraphicsSystem('opengl')
try:
from chaosc.c_osc_lib import decode_osc
except ImportError as e:
print(e)
from chaosc.osc_lib import decode_osc
QAPP = QtGui.QApplication([])
class PlotWindow(PlotWidget):
def __init__(self, title=None, **kargs):
self.win = QtGui.QMainWindow()
PlotWidget.__init__(self, **kargs)
self.win.setCentralWidget(self)
for m in ['resize']:
setattr(self, m, getattr(self.win, m))
if title is not None:
self.win.setWindowTitle(title)
class OSCThread(threading.Thread):
def __init__(self, args):
super(OSCThread, self).__init__()
self.args = args
self.running = True
self.own_address = socket.getaddrinfo(args.own_host, args.own_port, socket.AF_INET6, socket.SOCK_DGRAM, 0, socket.AI_V4MAPPED | socket.AI_ALL | socket.AI_CANONNAME)[-1][4][:2]
self.chaosc_address = chaosc_host, chaosc_port = socket.getaddrinfo(args.chaosc_host, args.chaosc_port, socket.AF_INET6, socket.SOCK_DGRAM, 0, socket.AI_V4MAPPED | socket.AI_ALL | socket.AI_CANONNAME)[-1][4][:2]
self.osc_sock = socket.socket(2, 2, 17)
self.osc_sock.bind(self.own_address)
self.osc_sock.setblocking(0)
print "%s: starting up osc receiver on '%s:%d'" % (
datetime.now().strftime("%x %X"), self.own_address[0], self.own_address[1])
self.subscribe_me()
def subscribe_me(self):
"""Use this procedure for a quick'n dirty subscription to your chaosc instance.
:param chaosc_address: (chaosc_host, chaosc_port)
:type chaosc_address: tuple
:param receiver_address: (host, port)
:type receiver_address: tuple
:param token: token to get authorized for subscription
:type token: str
"""
print "%s: subscribing to '%s:%d' with label %r" % (datetime.now().strftime("%x %X"), self.chaosc_address[0], self.chaosc_address[1], self.args.subscriber_label)
msg = OSCMessage("/subscribe")
msg.appendTypedArg(self.own_address[0], "s")
msg.appendTypedArg(self.own_address[1], "i")
msg.appendTypedArg(self.args.authenticate, "s")
if self.args.subscriber_label is not None:
msg.appendTypedArg(self.args.subscriber_label, "s")
self.osc_sock.sendto(msg.encode_osc(), self.chaosc_address)
def unsubscribe_me(self):
if self.args.keep_subscribed:
return
print "%s: unsubscribing from '%s:%d'" % (datetime.now().strftime("%x %X"), self.chaosc_address[0], self.chaosc_address[1])
msg = OSCMessage("/unsubscribe")
msg.appendTypedArg(self.own_address[0], "s")
msg.appendTypedArg(self.own_address[1], "i")
msg.appendTypedArg(self.args.authenticate, "s")
self.osc_sock.sendto(msg.encode_osc(), self.chaosc_address)
def run(self):
while self.running:
reads, writes, errs = select.select([self.osc_sock], [], [], 0.05)
if reads:
osc_input = reads[0].recv(4096)
osc_address, typetags, messages = decode_osc(osc_input, 0, len(osc_input))
if osc_address.find("ekg") > -1 or osc_address.find("plot") != -1:
queue.put_nowait((osc_address, messages))
else:
queue.put_nowait(("/bjoern/ekg", [0]))
queue.put_nowait(("/merle/ekg", [0]))
queue.put_nowait(("/uwe/ekg", [0]))
self.unsubscribe_me()
print "OSCThread is going down"
queue = Queue.Queue()
class MyHandler(BaseHTTPRequestHandler):
def __del__(self):
self.thread.running = False
self.thread.join()
def do_GET(self):
print "get"
self.thread = thread = OSCThread(self.server.args)
thread.daemon = True
thread.start()
actors = list()
is_item1 = True
is_item2 = True
is_item3 = True
def setPositions():
for ix, item in enumerate(actors):
item.setPos(0, ix*6)
def scale_data(data, ix, max_items):
scale = 254 / max_items * ix
return [value / max_items + scale for value in data]
def set_point(plotPoint, pos, value, ix, max_items):
scale = 254 / max_items * ix
y = 6 * ix + value / max_items + scale
plotPoint.setData(x = [pos], y = [y])
def find_max_value(item_data):
max_index = -1
for ix, i in enumerate(item_data):
if i > 250:
return ix, i
return None, None
def rearrange(item_data, actual_pos, max_items):
max_value_index, max_value = find_max_value(item_data)
if max_value_index is None:
return actual_pos
mean = int(max_items / 2.)
start = mean - max_value_index
if start != 0:
item_data.rotate(start)
pos = (actual_pos + start) % max_items
else:
pos = actual_pos
#print "rearrange", mean, start, actual_pos, pos, item_data
return pos
def set_value(item_data, pos, max_pos, value):
#print "setValue before", pos, None, max_pos, value, item_data, len(item_data)
item_data[pos] = value
new_pos = (pos + 1) % max_pos
#print "setValue after ", pos, new_pos, max_pos, value, item_data, len(item_data)
return new_pos
def resize(item_data, max_length, new_max_length, pos):
#print "resize", max_length, new_max_length
if new_max_length < 15:
return max_length, pos
if new_max_length > max_length:
pad = (new_max_length - max_length)
#print "pad", pad
for i in range(pad):
if i % 2 == 0:
item_data.append(0)
else:
item_data.appendleft(0)
pos += 1
return new_max_length, pos
elif new_max_length < max_length:
pad = (max_length - new_max_length)
for i in range(pad):
if i % 2 == 0:
item_data.pop()
if pos >= new_max_length:
pos = 0
else:
item_data.popleft()
if pos > 0:
pos -= 1
return new_max_length, pos
return max_length, pos
try:
self.path=re.sub('[^.a-zA-Z0-9]', "",str(self.path))
if self.path=="" or self.path==None or self.path[:1]==".":
return
if self.path.endswith(".html"):
f = open(curdir + sep + self.path)
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(f.read())
f.close()
elif self.path.endswith(".mjpeg"):
data_points = 43
self.send_response(200)
pos1 = 0
pos2 = 0
pos3 = 0
lengths1 = [0]
data1_max_value = 0
data2_max_value = 0
data3_max_value = 0
data1_distance = data_points
data2_distance = data_points
data3_distance = data_points
plot_data1 = deque([0] * data_points)
plot_data2 = deque([0] * data_points)
plot_data3 = deque([0] * data_points)
plt = PlotWidget(title="<h1>EKG</h1>")
plt.hide()
plotItem1 = pg.PlotCurveItem(pen=pg.mkPen('r', width=1), width=1, name="bjoern")
plotItem2 = pg.PlotCurveItem(pen=pg.mkPen('g', width=1), width=1, name="merle")
plotItem3 = pg.PlotCurveItem(pen=pg.mkPen('b', width=1), width=1, name="uwe")
shadowPen = pg.mkPen("w", width=10)
plotItem1.setShadowPen(pen=shadowPen, width=3, cosmetic=True)
plotItem2.setShadowPen(pen=shadowPen, width=3, cosmetic=True)
plotItem3.setShadowPen(pen=shadowPen, width=3, cosmetic=True)
pen = pg.mkPen("w", size=1)
brush = pg.mkBrush("w")
plotPoint1 = pg.ScatterPlotItem(pen=pen, brush=brush, size=15)
plotPoint2 = pg.ScatterPlotItem(pen=pen, brush=brush, size=10)
plotPoint3 = pg.ScatterPlotItem(pen=pen, brush=brush, size=10)
actors.append(plotItem1)
actors.append(plotItem2)
actors.append(plotItem3)
plotItem1.setPos(0, 0*6)
plotItem2.setPos(0, 1*6)
plotItem3.setPos(0, 2*6)
plt.addItem(plotItem1)
plt.addItem(plotItem2)
plt.addItem(plotItem3)
plt.addItem(plotPoint1)
plt.addItem(plotPoint2)
plt.addItem(plotPoint3)
plt.setLabel('left', "<h2>Amplitude</h2>")
plt.setLabel('bottom', "<h2><sup>Time</sup></h2>")
plt.showGrid(True, True)
ba = plt.getAxis("bottom")
bl = plt.getAxis("left")
ba.setTicks([])
bl.setTicks([])
ba.setWidth(0)
ba.setHeight(0)
bl.setWidth(0)
bl.setHeight(0)
plt.setYRange(0, 255)
self.wfile.write("Content-Type: multipart/x-mixed-replace; boundary=--aaboundary")
self.wfile.write("\r\n\r\n")
plt.resize(1280, 720)
while 1:
while 1:
try:
osc_address, args = queue.get_nowait()
except Queue.Empty:
break
max_items = len(actors)
value = args[0]
if osc_address == "/bjoern/ekg":
#if value > 250:
#data_points, pos1 = resize(plot_data1, len(plot_data1), lengths1[-1], pos1)
#foo, pos2 = resize(plot_data2, len(plot_data2), lengths1[-1], pos2)
#foo, pos3 = resize(plot_data3, len(plot_data3), lengths1[-1], pos3)
#print "length1", lengths1
#lengths1.append(0)
#else:
#lengths1[-1] += 1
ix = actors.index(plotItem1)
#pos1 = rearrange(plot_data1, pos1, data_points)
set_point(plotPoint1, pos1, value, ix, max_items)
pos1 = set_value(plot_data1, pos1, data_points, value)
try:
plotItem1.setData(y=np.array(scale_data(plot_data1, ix, max_items)), clear=True)
except ValueError:
pass
elif osc_address == "/merle/ekg":
ix = actors.index(plotItem2)
#pos2 = rearrange(plot_data2, pos2, data_points)
set_point(plotPoint2, pos2, value, ix, max_items)
pos2 = set_value(plot_data2, pos2, data_points, value)
try:
plotItem2.setData(y=np.array(scale_data(plot_data2, ix, max_items)), clear=True)
except ValueError:
pass
elif osc_address == "/uwe/ekg":
ix = actors.index(plotItem3)
#pos3 = rearrange(plot_data3, pos3, data_points)
set_point(plotPoint3, pos3, value, ix, max_items)
pos3 = set_value(plot_data3, pos3, data_points, value)
try:
plotItem3.setData(y=np.array(scale_data(plot_data3, ix, max_items)), clear=True)
except ValueError:
pass
elif osc_address == "/plot/uwe":
if value == 1 and is_item3 == False:
print "uwe on"
plt.addItem(plotItem3)
is_item3 = True
actors.append(plotItem3)
setPositions()
elif value == 0 and is_item3 == True:
print "uwe off"
plt.removeItem(plotItem3)
is_item3 = False
actors.remove(plotItem3)
setPositions()
elif osc_address == "/plot/merle":
if value == 1 and is_item2 == False:
print "merle on"
plt.addItem(plotItem2)
is_item2 = True
actors.append(plotItem2)
setPositions()
elif value == 0 and is_item2 == True:
print "merle off"
plt.removeItem(plotItem2)
is_item2 = False
actors.remove(plotItem2)
setPositions()
elif osc_address == "/plot/bjoern":
if value == 1 and is_item1 == False:
print "bjoern on"
plt.addItem(plotItem1)
is_item1 = True
actors.append(plotItem1)
setPositions()
elif value == 0 and is_item1 == True:
print "bjoern off"
plt.removeItem(plotItem1)
is_item1 = False
actors.remove(plotItem1)
setPositions()
exporter = pg.exporters.ImageExporter.ImageExporter(plt.plotItem)
img = exporter.export("tmpfile", True)
buffer = QBuffer()
buffer.open(QIODevice.WriteOnly)
img.save(buffer, "JPG", 100)
JpegData = buffer.data()
del buffer
self.wfile.write("--aaboundary\r\nContent-Type: image/jpeg\r\nContent-length: %d\r\n\r\n%s\r\n\r\n\r\n" % (len(JpegData), JpegData))
elif self.path.endswith(".jpeg"):
f = open(curdir + sep + self.path)
self.send_response(200)
self.send_header('Content-type','image/jpeg')
self.end_headers()
self.wfile.write(f.read())
f.close()
return
except (KeyboardInterrupt, SystemError):
thread.running = False
thread.join()
except IOError:
self.send_error(404,'File Not Found: %s' % self.path)
class JustAHTTPServer(HTTPServer):
pass
def main():
a = create_arg_parser("ekgplotter")
own_group = add_main_group(a)
own_group.add_argument('-x', "--http_host", default="0.0.0.0",
help='my host, defaults to "socket.gethostname()"')
own_group.add_argument('-X', "--http_port", default=9000,
type=int, help='my port, defaults to 9000')
add_chaosc_group(a)
add_subscriber_group(a, "ekgplotter")
args = finalize_arg_parser(a)
try:
host, port = socket.getaddrinfo(args.http_host, args.http_port, socket.AF_INET6, socket.SOCK_DGRAM, 0, socket.AI_V4MAPPED | socket.AI_ALL | socket.AI_CANONNAME)[-1][4][:2]
server = JustAHTTPServer(("0.0.0.0", 9000), MyHandler)
server.args = args
print "%s: starting up http server on '%s:%d'" % (
datetime.now().strftime("%x %X"), host, port)
server.serve_forever()
except KeyboardInterrupt:
print '^C received, shutting down server'
server.socket.close()
if __name__ == '__main__':
main()

View File

@ -0,0 +1,408 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# This file is part of sensors2osc package
#
# sensors2osc is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# sensors2osc is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with sensors2osc. If not, see <http://www.gnu.org/licenses/>.
#
# found the mjpeg part here, thanks for the nice code :)
# http://hardsoftlucid.wordpress.com/2013/04/11/mjpeg-server-for-webcam-in-python-with-opencv/
# the osc integration stuff is implemented by me
#
# Copyright (C) 2014 Stefan Kögl
from __future__ import absolute_import
from datetime import datetime
import threading
import Queue
import numpy as np
import string,cgi,time, random, socket
from os import curdir, sep
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from SocketServer import ThreadingMixIn, ForkingMixIn
import select
import re
from collections import deque
from PyQt4.QtCore import QBuffer, QByteArray, QIODevice
from PyQt4 import QtGui
import pyqtgraph as pg
from pyqtgraph.widgets.PlotWidget import PlotWidget
from chaosc.argparser_groups import *
try:
from chaosc.c_osc_lib import *
except ImportError:
from chaosc.osc_lib import *
QtGui.QApplication.setGraphicsSystem('opengl')
try:
from chaosc.c_osc_lib import decode_osc
except ImportError as e:
print(e)
from chaosc.osc_lib import decode_osc
QAPP = QtGui.QApplication([])
class PlotWindow(PlotWidget):
def __init__(self, title=None, **kargs):
self.win = QtGui.QMainWindow()
PlotWidget.__init__(self, **kargs)
self.win.setCentralWidget(self)
for m in ['resize']:
setattr(self, m, getattr(self.win, m))
if title is not None:
self.win.setWindowTitle(title)
class OSCThread(threading.Thread):
def __init__(self, args):
super(OSCThread, self).__init__()
self.args = args
self.running = True
self.own_address = socket.getaddrinfo(args.own_host, args.own_port, socket.AF_INET6, socket.SOCK_DGRAM, 0, socket.AI_V4MAPPED | socket.AI_ALL | socket.AI_CANONNAME)[-1][4][:2]
self.chaosc_address = chaosc_host, chaosc_port = socket.getaddrinfo(args.chaosc_host, args.chaosc_port, socket.AF_INET6, socket.SOCK_DGRAM, 0, socket.AI_V4MAPPED | socket.AI_ALL | socket.AI_CANONNAME)[-1][4][:2]
self.osc_sock = socket.socket(2, 2, 17)
self.osc_sock.bind(self.own_address)
self.osc_sock.setblocking(0)
print "%s: starting up osc receiver on '%s:%d'" % (
datetime.now().strftime("%x %X"), self.own_address[0], self.own_address[1])
self.subscribe_me()
def subscribe_me(self):
"""Use this procedure for a quick'n dirty subscription to your chaosc instance.
:param chaosc_address: (chaosc_host, chaosc_port)
:type chaosc_address: tuple
:param receiver_address: (host, port)
:type receiver_address: tuple
:param token: token to get authorized for subscription
:type token: str
"""
print "%s: subscribing to '%s:%d' with label %r" % (datetime.now().strftime("%x %X"), self.chaosc_address[0], self.chaosc_address[1], self.args.subscriber_label)
msg = OSCMessage("/subscribe")
msg.appendTypedArg(self.own_address[0], "s")
msg.appendTypedArg(self.own_address[1], "i")
msg.appendTypedArg(self.args.authenticate, "s")
if self.args.subscriber_label is not None:
msg.appendTypedArg(self.args.subscriber_label, "s")
self.osc_sock.sendto(msg.encode_osc(), self.chaosc_address)
def unsubscribe_me(self):
if self.args.keep_subscribed:
return
print "%s: unsubscribing from '%s:%d'" % (datetime.now().strftime("%x %X"), self.chaosc_address[0], self.chaosc_address[1])
msg = OSCMessage("/unsubscribe")
msg.appendTypedArg(self.own_address[0], "s")
msg.appendTypedArg(self.own_address[1], "i")
msg.appendTypedArg(self.args.authenticate, "s")
self.osc_sock.sendto(msg.encode_osc(), self.chaosc_address)
def run(self):
while self.running:
reads, writes, errs = select.select([self.osc_sock], [], [], 0.05)
if reads:
osc_input = reads[0].recv(4096)
osc_address, typetags, messages = decode_osc(osc_input, 0, len(osc_input))
if osc_address.find("ekg") > -1 or osc_address.find("plot") != -1:
queue.put_nowait((osc_address, messages))
else:
queue.put_nowait(("/bjoern/ekg", [0]))
queue.put_nowait(("/merle/ekg", [0]))
queue.put_nowait(("/uwe/ekg", [0]))
self.unsubscribe_me()
print "OSCThread is going down"
queue = Queue.Queue()
class MyHandler(BaseHTTPRequestHandler):
def do_GET(self):
print "get"
self.thread = thread = OSCThread(self.server.args)
thread.daemon = True
thread.start()
actors = list()
is_item1 = True
is_item2 = True
is_item3 = True
def setPositions():
for ix, item in enumerate(actors):
item.setPos(0, ix*6)
def scale_data(data, ix, max_items):
scale = 254 / max_items * ix
return [value / max_items + scale for value in data]
def set_point(plotPoint, pos, value, ix, max_items):
scale = 254 / max_items * ix
plotPoint.setData(x = [pos], y = [6*ix + value / max_items + scale])
def setValue(dataItem, pos, maxPos, value):
dataItem[pos] = value
return (pos + 1) % maxPos
def find_max_index(dataItem):
max_value = 0
max_index = 0
for ix, i in enumerate(dataItem):
if i > max_value:
max_value = i
max_index = ix
return max_index, max_value
def rearrange(data, index, max_items):
max_value_index, max_value = findMax(data)
mean = int(max_items / 2.)
start = mean - max_value_index
data.rotate(start)
pos = (index + start) % max_items
print "rearrange", index, max_items, pos
return pos
def checkDataPoints(value, data_max_value):
if value > max_value and value > 200:
return True, value
return False, data_max_value
try:
self.path=re.sub('[^.a-zA-Z0-9]', "",str(self.path))
if self.path=="" or self.path==None or self.path[:1]==".":
return
if self.path.endswith(".html"):
f = open(curdir + sep + self.path)
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(f.read())
f.close()
elif self.path.endswith(".mjpeg"):
data_points = 21
self.send_response(200)
pos1 = 0
pos2 = 0
pos3 = 0
data1_max_value = 0
data2_max_value = 0
data3_max_value = 0
data1_distance = data_points
data2_distance = data_points
data3_distance = data_points
plot_data1 = deque([0] * data_points)
plot_data2 = deque([0] * data_points)
plot_data3 = deque([0] * data_points)
plt = PlotWidget(title="<h1>EKG</h1>", name="Merle")
plt.hide()
plotItem1 = pg.PlotCurveItem(pen=pg.mkPen('r', width=2), width=2, name="bjoern")
plotItem2 = pg.PlotCurveItem(pen=pg.mkPen('g', width=2), width=2, name="merle")
plotItem3 = pg.PlotCurveItem(pen=pg.mkPen('b', width=2), width=2, name="uwe")
shadowPen = pg.mkPen("w", width=10)
plotItem1.setShadowPen(pen=shadowPen, width=6, cosmetic=True)
plotItem2.setShadowPen(pen=shadowPen, width=6, cosmetic=True)
plotItem3.setShadowPen(pen=shadowPen, width=6, cosmetic=True)
pen = pg.mkPen("w", size=1)
brush = pg.mkBrush("w")
plotPoint1 = pg.ScatterPlotItem(pen=pen, brush=brush, size=10)
plotPoint2 = pg.ScatterPlotItem(pen=pen, brush=brush, size=10)
plotPoint3 = pg.ScatterPlotItem(pen=pen, brush=brush, size=10)
actors.append(plotItem1)
actors.append(plotItem2)
actors.append(plotItem3)
plotItem1.setPos(0, 0*6)
plotItem2.setPos(0, 1*6)
plotItem3.setPos(0, 2*6)
plt.addItem(plotItem1)
plt.addItem(plotItem2)
plt.addItem(plotItem3)
plt.addItem(plotPoint1)
plt.addItem(plotPoint2)
plt.addItem(plotPoint3)
plt.setLabel('left', "<h2>Amplitude</h2>")
plt.setLabel('bottom', "<h2>Time</h2>")
plt.showGrid(True, True)
ba = plt.getAxis("bottom")
bl = plt.getAxis("left")
ba.setTicks([])
bl.setTicks([])
plt.setYRange(0, 254)
self.wfile.write("Content-Type: multipart/x-mixed-replace; boundary=--aaboundary")
self.wfile.write("\r\n\r\n")
plt.resize(1280, 720)
while 1:
while 1:
try:
osc_address, args = queue.get_nowait()
except Queue.Empty:
break
max_items = len(actors)
value = args[0]
if osc_address == "/bjoern/ekg":
ix = actors.index(plotItem1)
res, tmp = checkDataPoints(value, data1_max_value)
if res and res > 20:
data_points = tmp
data1_maxdata1_max_value = 0
set_point(plotPoint1, pos1, value, ix, max_items)
pos1 = setValue(plot_data1, pos1, data_points, value)
pos1 = rearrange(plot_data1, pos1, data_points)
try:
plotItem1.setData(y=np.array(scale_data(plot_data1, ix, max_items)), clear=True)
except ValueError:
pass
elif osc_address == "/merle/ekg":
ix = actors.index(plotItem2)
set_point(plotPoint2, pos2, value, ix, max_items)
pos2 = setValue(plot_data2, pos2, data_points, value)
pos2 = rearrange(plot_data2, pos2, data_points)
try:
plotItem2.setData(y=np.array(scale_data(plot_data2, ix, max_items)), clear=True)
except ValueError:
pass
elif osc_address == "/uwe/ekg":
ix = actors.index(plotItem3)
set_point(plotPoint3, pos3, value, ix, max_items)
pos3 = setValue(plot_data3, pos3, data_points, value)
pos3 = rearrange(plot_data3, pos3, data_points)
try:
plotItem3.setData(y=np.array(scale_data(plot_data3, ix, max_items)), clear=True)
except ValueError:
pass
elif osc_address == "/plot/uwe":
if value == 1 and is_item3 == False:
print "uwe on"
plt.addItem(plotItem3)
is_item3 = True
actors.append(plotItem3)
setPositions()
elif value == 0 and is_item3 == True:
print "uwe off"
plt.removeItem(plotItem3)
is_item3 = False
actors.remove(plotItem3)
setPositions()
elif osc_address == "/plot/merle":
if value == 1 and is_item2 == False:
print "merle on"
plt.addItem(plotItem2)
is_item2 = True
actors.append(plotItem2)
setPositions()
elif value == 0 and is_item2 == True:
print "merle off"
plt.removeItem(plotItem2)
is_item2 = False
actors.remove(plotItem2)
setPositions()
elif osc_address == "/plot/bjoern":
if value == 1 and is_item1 == False:
print "bjoern on"
plt.addItem(plotItem1)
is_item1 = True
actors.append(plotItem1)
setPositions()
elif value == 0 and is_item1 == True:
print "bjoern off"
plt.removeItem(plotItem1)
is_item1 = False
actors.remove(plotItem1)
setPositions()
exporter = pg.exporters.ImageExporter.ImageExporter(plt.plotItem)
img = exporter.export("tmpfile", True)
buffer = QBuffer()
buffer.open(QIODevice.WriteOnly)
img.save(buffer, "JPG", 100)
JpegData = buffer.data()
del buffer
self.wfile.write("--aaboundary\r\nContent-Type: image/jpeg\r\nContent-length: %d\r\n\r\n%s\r\n\r\n\r\n" % (len(JpegData), JpegData))
elif self.path.endswith(".jpeg"):
f = open(curdir + sep + self.path)
self.send_response(200)
self.send_header('Content-type','image/jpeg')
self.end_headers()
self.wfile.write(f.read())
f.close()
return
except (KeyboardInterrupt, SystemError):
thread.running = False
thread.join()
except IOError:
self.send_error(404,'File Not Found: %s' % self.path)
class JustAHTTPServer(HTTPServer):
pass
def main():
a = create_arg_parser("ekgplotter")
own_group = add_main_group(a)
own_group.add_argument('-x', "--http_host", default="0.0.0.0",
help='my host, defaults to "socket.gethostname()"')
own_group.add_argument('-X', "--http_port", default=9000,
type=int, help='my port, defaults to 9000')
add_chaosc_group(a)
add_subscriber_group(a, "ekgplotter")
args = finalize_arg_parser(a)
try:
host, port = socket.getaddrinfo(args.http_host, args.http_port, socket.AF_INET6, socket.SOCK_DGRAM, 0, socket.AI_V4MAPPED | socket.AI_ALL | socket.AI_CANONNAME)[-1][4][:2]
server = JustAHTTPServer(("0.0.0.0", 9000), MyHandler)
server.args = args
print "%s: starting up http server on '%s:%d'" % (
datetime.now().strftime("%x %X"), host, port)
server.serve_forever()
except KeyboardInterrupt:
print '^C received, shutting down server'
server.socket.close()
if __name__ == '__main__':
main()

View File

@ -7,6 +7,7 @@ use_setuptools()
import sys
from setuptools import find_packages, setup
extras = dict()
if sys.version_info >= (3,):
extras['use_2to3'] = True

View File

@ -0,0 +1,449 @@
--- sensors2osc/common.py (original)
+++ sensors2osc/common.py (refactored)
@@ -18,7 +18,7 @@
#
# Copyright (C) 2014 Stefan Kögl
-from __future__ import absolute_import
+
import atexit
import os.path
@@ -43,12 +43,12 @@
def connect(self):
- print "connect serial"
+ print("connect serial")
self.serial_sock = serial.Serial()
self.serial_sock.port = self.args.device
self.serial_sock.baudrate = 115200
self.serial_sock.timeout = 0
- print "waiting for the device %r to come up" % self.args.device
+ print("waiting for the device %r to come up" % self.args.device)
while 1:
try:
self.serial_sock.open()
@@ -59,12 +59,12 @@
def close(self):
if self.serial_sock is not None:
- print "close serial"
+ print("close serial")
self.serial_sock.close()
def reconnect(self):
- print "reconnect serial"
+ print("reconnect serial")
self.close()
self.connect()
--- sensors2osc/ehealth2osc.py (original)
+++ sensors2osc/ehealth2osc.py (refactored)
@@ -18,7 +18,7 @@
#
# Copyright (C) 2014 Stefan Kögl
-from __future__ import absolute_import
+
from sensors2osc.common import *
import time
@@ -33,60 +33,60 @@
try:
data = platform.serial_sock.readline()[:-2]
#print repr(data)
- except socket.error, msg:
+ except socket.error as msg:
# got disconnected?
- print "serial socket error!!!", msg
+ print("serial socket error!!!", msg)
platform.reconnect()
#print "got data", repr(data)
try:
airFlow, emg, temp = data.split(";")
- except ValueError, e:
- print e
+ except ValueError as e:
+ print(e)
continue
try:
airFlow = int(airFlow)
- except ValueError, e:
- print e
+ except ValueError as e:
+ print(e)
continue
try:
osc_message = OSCMessage("/%s/airFlow" % actor)
osc_message.appendTypedArg(airFlow, "i")
platform.osc_sock.sendall(osc_message.encode_osc())
- except socket.error, msg:
- print "cannot connect to chaosc", msg
+ except socket.error as msg:
+ print("cannot connect to chaosc", msg)
continue
try:
emg = int(emg)
- except ValueError, e:
- print e
+ except ValueError as e:
+ print(e)
continue
try:
osc_message = OSCMessage("/%s/emg" % actor)
osc_message.appendTypedArg(emg, "i")
platform.osc_sock.sendall(osc_message.encode_osc())
- except socket.error, msg:
- print "cannot connect to chaosc", msg
+ except socket.error as msg:
+ print("cannot connect to chaosc", msg)
continue
try:
temp = int(temp)
- except ValueError, e:
- print e
+ except ValueError as e:
+ print(e)
continue
try:
osc_message = OSCMessage("/%s/temperatur" % actor)
osc_message.appendTypedArg(temp, "i")
platform.osc_sock.sendall(osc_message.encode_osc())
- except socket.error, msg:
- print "cannot connect to chaosc", msg
+ except socket.error as msg:
+ print("cannot connect to chaosc", msg)
continue
--- sensors2osc/ekg2osc.py (original)
+++ sensors2osc/ekg2osc.py (refactored)
@@ -18,7 +18,7 @@
#
# Copyright (C) 2014 Stefan Kögl
-from __future__ import absolute_import
+
import time
@@ -34,23 +34,23 @@
while 1:
try:
t = platform.serial_sock.read(1)
- except socket.error, msg:
+ except socket.error as msg:
# got disconnected?
- print "serial socket error!!!", msg
+ print("serial socket error!!!", msg)
platform.reconnect()
try:
t = ord(t)
- except TypeError, e:
+ except TypeError as e:
continue
try:
- print "got value", t
+ print("got value", t)
osc_message = OSCMessage("/%s/ekg" % actor)
osc_message.appendTypedArg(t, "i")
platform.osc_sock.sendall(osc_message.encode_osc())
- except socket.error, msg:
- print "cannot connect to chaosc"
+ except socket.error as msg:
+ print("cannot connect to chaosc")
continue
--- sensors2osc/main.py (original)
+++ sensors2osc/main.py (refactored)
@@ -48,7 +48,7 @@
def close(self):
"""Close all resources and unpublish service"""
- print "%s: closing..." % (self.device, )
+ print("%s: closing..." % (self.device, ))
self.serial.close()
@@ -58,7 +58,7 @@
def handle_read(self, osc_sock):
data = self.serial.readline()[:-2]
- print repr(data)
+ print(repr(data))
try:
airFlow, emg, temp = data.split(";")
except ValueError:
@@ -106,7 +106,7 @@
self.head = (self.head + 1) % self.length
def getData(self):
- print "getData", self.ring_buf, self.head
+ print("getData", self.ring_buf, self.head)
data = list()
for i in range(7, 1, -1):
value = self.ring_buf[(self.head - i) % self.length]
@@ -117,7 +117,7 @@
raise ValueError("not complete - ringbuffer resettet")
data.append(value)
if data[0] != 0x0 or data[1] != 0xff:
- print "issue", data
+ print("issue", data)
self.reset()
self.ring_buf[0] = 0
self.head = 1
@@ -146,7 +146,7 @@
osc_message.appendTypedArg(heart_rate, "i")
osc_message.appendTypedArg(o2, "i")
osc_sock.sendall(osc_message.encode_osc())
- print "heartbeat", datetime.datetime.now(), heart_signal
+ print("heartbeat", datetime.datetime.now(), heart_signal)
self.heartbeat_on = True
elif pulse == 1 and self.heartbeat_on:
#print "off heartbeat", datetime.datetime.now(), heart_signal
@@ -156,8 +156,8 @@
osc_message.appendTypedArg(heart_rate, "i")
osc_message.appendTypedArg(o2, "i")
osc_sock.sendall(osc_message.encode_osc())
- except ValueError, e:
- print e
+ except ValueError as e:
+ print(e)
def main():
@@ -187,30 +187,30 @@
used_devices = dict()
while 1:
- for device, description in naming.iteritems():
+ for device, description in naming.items():
if os.path.exists(device):
if device not in used_devices:
actor, platform = naming[device]
if description[1] == "ehealth":
- print device, actor, platform
+ print(device, actor, platform)
used_devices[device] = EHealth2OSC(actor, platform, device)
elif description[1] == "ekg":
- print device, actor, platform
+ print(device, actor, platform)
used_devices[device] = EKG2OSC(actor, platform, device)
elif description[1] == "pulse":
- print device, actor, platform
+ print(device, actor, platform)
used_devices[device] = Pulse2OSC(actor, platform, device)
else:
raise ValueError("unknown description %r for device %r" % (description, device))
else:
- print "device missing", device
+ print("device missing", device)
message = OSCMessage("/DeviceMissing")
message.appendTypedArg(description[0], "s")
message.appendTypedArg(description[1], "s")
osc_sock.sendall(message.encode_osc())
read_map = {}
- for forwarder in used_devices.values():
+ for forwarder in list(used_devices.values()):
read_map[forwarder.serial] = forwarder.handle_read
readers, writers, errors = select.select(read_map, [], [], 0.1)
--- sensors2osc/pulse2osc.py (original)
+++ sensors2osc/pulse2osc.py (refactored)
@@ -18,7 +18,7 @@
#
# Copyright (C) 2014 Stefan Kögl
-from __future__ import absolute_import
+
import time
from datetime import datetime
@@ -41,7 +41,7 @@
self.head = (self.head + 1) % self.length
def getData(self):
- print "getData", self.ring_buf, self.head
+ print("getData", self.ring_buf, self.head)
data = list()
for i in range(self.length + 1, 1, -1):
value = self.ring_buf[(self.head - i) % self.length]
@@ -52,7 +52,7 @@
raise ValueError("not complete - ringbuffer resettet")
data.append(value)
if data[0] != 0x0 or data[1] != 0xff:
- print "issue", data
+ print("issue", data)
self.reset()
self.ring_buf[0] = 0
self.head = 1
@@ -71,24 +71,24 @@
while 1:
try:
t = platform.serial_sock.read(1)
- except socket.error, msg:
+ except socket.error as msg:
# got disconnected?
- print "serial socket error!!!", msg
+ print("serial socket error!!!", msg)
platform.reconnect()
try:
t = ord(t)
- except TypeError, e:
+ except TypeError as e:
continue
- print "got value", t
+ print("got value", t)
buf.append(t)
if t == 0:
try:
heart_signal, heart_rate, o2, pulse = buf.getData()
- except ValueError, e:
- print e
+ except ValueError as e:
+ print(e)
continue
if pulse == 245 and not heartbeat_on:
@@ -99,12 +99,12 @@
osc_message.appendTypedArg(heart_rate, "i")
osc_message.appendTypedArg(o2, "i")
platform.osc_sock.sendall(osc_message.encode_osc())
- print "on heartbeat", datetime.now(), heart_signal, heart_rate, o2, pulse
- except socket.error, msg:
- print "cannot connect to chaosc"
+ print("on heartbeat", datetime.now(), heart_signal, heart_rate, o2, pulse)
+ except socket.error as msg:
+ print("cannot connect to chaosc")
continue
elif pulse == 1 and heartbeat_on:
- print "off heartbeat", datetime.now(), heart_signal, heart_rate, o2, pulse
+ print("off heartbeat", datetime.now(), heart_signal, heart_rate, o2, pulse)
heartbeat_on = False
try:
osc_message = OSCMessage("/%s/heartbeat" % actor)
@@ -112,8 +112,8 @@
osc_message.appendTypedArg(heart_rate, "i")
osc_message.appendTypedArg(o2, "i")
platform.osc_sock.sendall(osc_message.encode_osc())
- except socket.error, msg:
- print "cannot connect to chaosc"
+ except socket.error as msg:
+ print("cannot connect to chaosc")
continue
time.sleep(0.1)
--- sensors2osc/sensorTest.py (original)
+++ sensors2osc/sensorTest.py (refactored)
@@ -48,7 +48,7 @@
def close(self):
"""Close all resources and unpublish service"""
- print "%s: closing..." % (self.device, )
+ print("%s: closing..." % (self.device, ))
self.serial.close()
@@ -58,7 +58,7 @@
def handle_read(self, osc_sock):
data = self.serial.readline()[:-2]
- print repr(data)
+ print(repr(data))
try:
airFlow, emg, temp = data.split(";")
except ValueError:
@@ -94,7 +94,7 @@
class RingBuffer(object):
def __init__(self, length):
self.length = length
- self.ring_buf = [-1 for i in xrange(length)]
+ self.ring_buf = [-1 for i in range(length)]
self.head = 0
def append(self, value):
@@ -102,7 +102,7 @@
self.head = (self.head + 1) % self.length
def getData(self):
- print "getData", self.ring_buf, self.head
+ print("getData", self.ring_buf, self.head)
data = list()
for i in range(7, 1, -1):
value = self.ring_buf[(self.head - i) % self.length]
@@ -135,7 +135,7 @@
osc_message.appendTypedArg(heart_rate, "i")
osc_message.appendTypedArg(o2, "i")
osc_sock.sendall(osc_message.encode_osc())
- print "heartbeat", datetime.datetime.now(), heart_signal
+ print("heartbeat", datetime.datetime.now(), heart_signal)
self.heartbeat_on = True
elif pulse == 1 and self.heartbeat_on:
#print "off heartbeat", datetime.datetime.now(), heart_signal
@@ -145,8 +145,8 @@
osc_message.appendTypedArg(heart_rate, "i")
osc_message.appendTypedArg(o2, "i")
osc_sock.sendall(osc_message.encode_osc())
- except ValueError, e:
- print e
+ except ValueError as e:
+ print(e)
def main():
@@ -182,7 +182,7 @@
while 1:
read_map = {}
- for forwarder in used_devices.values():
+ for forwarder in list(used_devices.values()):
read_map[forwarder.serial] = forwarder.handle_read
readers, writers, errors = select.select(read_map, [], [], 0.1)
--- sensors2osc/socat_ekg_test.py (original)
+++ sensors2osc/socat_ekg_test.py (refactored)
@@ -55,13 +55,13 @@
count = 0
if data_points % (5 * steps) == 0:
- print "new steps", steps, delta
+ print("new steps", steps, delta)
steps += delta
if steps <= min_steps:
delta = 1
elif steps >= max_steps:
- print "change step sign", steps, delta
+ print("change step sign", steps, delta)
delta = -1
time.sleep(0.02)
--- sensors2osc/socat_pulse_test.py (original)
+++ sensors2osc/socat_pulse_test.py (refactored)
@@ -21,7 +21,7 @@
# socat -d -d PTY,raw,echo=0,link=/tmp/pty1,b115200,user=stefan PTY,raw,echo=0,link=/tmp/pty2,b115200,user=stefan
-from __future__ import absolute_import
+
import serial, time, random, sys, random, struct

View File

@ -18,14 +18,15 @@
#
# Copyright (C) 2014 Stefan Kögl
from __future__ import absolute_import
import atexit
import os.path
import serial
import socket
from chaosc.argparser_groups import *
from chaosc.argparser_groups import create_arg_parser, finalize_arg_parser, add_chaosc_group
try:
from chaosc.c_osc_lib import OSCMessage
@ -38,17 +39,17 @@ class Platform(object):
def __init__(self, args):
self.args = args
self.serial_sock = None
self.osc_sock = socket.socket(10, 2, 17)
self.osc_sock = socket.socket(args.address_family, 2, 17)
self.osc_sock.connect((self.args.chaosc_host, self.args.chaosc_port))
def connect(self):
print "connect serial"
print("connect serial")
self.serial_sock = serial.Serial()
self.serial_sock.port = self.args.device
self.serial_sock.baudrate = 115200
self.serial_sock.timeout = 0
print "waiting for the device %r to come up" % self.args.device
print("waiting for the device %r to come up" % self.args.device)
while 1:
try:
self.serial_sock.open()
@ -59,12 +60,12 @@ class Platform(object):
def close(self):
if self.serial_sock is not None:
print "close serial"
print("close serial")
self.serial_sock.close()
def reconnect(self):
print "reconnect serial"
print("reconnect serial")
self.close()
self.connect()
@ -76,6 +77,8 @@ def create_args(name):
type=str, help='device node under /dev')
main_group.add_argument("-a", '--actor', required=True,
type=str, help='actor name')
main_group.add_argument('-4', '--ipv4_only', action="store_true",
help='select ipv4 sockets, defaults tp ipv6"')
add_chaosc_group(arg_parser)
args = finalize_arg_parser(arg_parser)

View File

@ -0,0 +1,91 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# This file is part of sensors2osc package
#
# sensors2osc is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# sensors2osc is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with sensors2osc. If not, see <http://www.gnu.org/licenses/>.
#
# Copyright (C) 2014 Stefan Kögl
from __future__ import absolute_import
import atexit
import os.path
import serial
import socket
from chaosc.argparser_groups import *
try:
from chaosc.c_osc_lib import OSCMessage
except ImportError as e:
print(e)
from chaosc.osc_lib import OSCMessage
class Platform(object):
def __init__(self, args):
self.args = args
self.serial_sock = None
self.osc_sock = socket.socket(10, 2, 17)
self.osc_sock.connect((self.args.chaosc_host, self.args.chaosc_port))
def connect(self):
print "connect serial"
self.serial_sock = serial.Serial()
self.serial_sock.port = self.args.device
self.serial_sock.baudrate = 115200
self.serial_sock.timeout = 0
print "waiting for the device %r to come up" % self.args.device
while 1:
try:
self.serial_sock.open()
break
except serial.serialtuil.SerialException:
pass
def close(self):
if self.serial_sock is not None:
print "close serial"
self.serial_sock.close()
def reconnect(self):
print "reconnect serial"
self.close()
self.connect()
def create_args(name):
arg_parser = create_arg_parser(name)
main_group = arg_parser.add_argument_group("main")
main_group.add_argument("-d", '--device', required=True,
type=str, help='device node under /dev')
main_group.add_argument("-a", '--actor', required=True,
type=str, help='actor name')
add_chaosc_group(arg_parser)
args = finalize_arg_parser(arg_parser)
return args
def init(name):
args = create_args(name)
platform = Platform(args)
platform.connect()
atexit.register(platform.close)
return platform

View File

@ -18,75 +18,79 @@
#
# Copyright (C) 2014 Stefan Kögl
from __future__ import absolute_import
from sensors2osc.common import *
import time
import time, select
def main():
platform = init("ehealth2osc")
actor = platform.args.actor
actor = bytes(platform.args.actor, "ascii")
while 1:
try:
data = platform.serial_sock.readline()[:-2]
toread, towrite, toerrors = select.select([platform.serial_sock], [],[], 0.05)
if toread:
data = platform.serial_sock.readline()[:-2]
else:
continue
#print repr(data)
except socket.error, msg:
except socket.error as msg:
# got disconnected?
print "serial socket error!!!", msg
print("serial socket error!!!", msg)
platform.reconnect()
#print "got data", repr(data)
print("got data", repr(data))
try:
airFlow, emg, temp = data.split(";")
except ValueError, e:
print e
airFlow, emg, temp = bytearray(data).split(b";")
except ValueError as e:
print(e)
continue
try:
airFlow = int(airFlow)
except ValueError, e:
print e
except ValueError as e:
print(e)
continue
try:
osc_message = OSCMessage("/%s/airFlow" % actor)
osc_message.appendTypedArg(airFlow, "i")
osc_message = OSCMessage(b"/" + actor + b"/airFlow")
osc_message.appendTypedArg(airFlow, b"i")
platform.osc_sock.sendall(osc_message.encode_osc())
except socket.error, msg:
print "cannot connect to chaosc", msg
except socket.error as msg:
print("cannot connect to chaosc", msg)
continue
try:
emg = int(emg)
except ValueError, e:
print e
except ValueError as e:
print(e)
continue
try:
osc_message = OSCMessage("/%s/emg" % actor)
osc_message.appendTypedArg(emg, "i")
osc_message = OSCMessage(b"/" + actor + b"/emg")
osc_message.appendTypedArg(emg, b"i")
platform.osc_sock.sendall(osc_message.encode_osc())
except socket.error, msg:
print "cannot connect to chaosc", msg
except socket.error as msg:
print("cannot connect to chaosc", msg)
continue
try:
temp = int(temp)
except ValueError, e:
print e
except ValueError as e:
print(e)
continue
try:
osc_message = OSCMessage("/%s/temperatur" % actor)
osc_message.appendTypedArg(temp, "i")
osc_message = OSCMessage(b"/" + actor + b"/temperatur")
osc_message.appendTypedArg(temp, b"i")
platform.osc_sock.sendall(osc_message.encode_osc())
except socket.error, msg:
print "cannot connect to chaosc", msg
except socket.error as msg:
print("cannot connect to chaosc", msg)
continue

View File

@ -0,0 +1,94 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# This file is part of sensors2osc package
#
# sensors2osc is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# sensors2osc is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with sensors2osc. If not, see <http://www.gnu.org/licenses/>.
#
# Copyright (C) 2014 Stefan Kögl
from __future__ import absolute_import
from sensors2osc.common import *
import time
def main():
platform = init("ehealth2osc")
actor = platform.args.actor
while 1:
try:
data = platform.serial_sock.readline()[:-2]
#print repr(data)
except socket.error, msg:
# got disconnected?
print "serial socket error!!!", msg
platform.reconnect()
#print "got data", repr(data)
try:
airFlow, emg, temp = data.split(";")
except ValueError, e:
print e
continue
try:
airFlow = int(airFlow)
except ValueError, e:
print e
continue
try:
osc_message = OSCMessage("/%s/airFlow" % actor)
osc_message.appendTypedArg(airFlow, "i")
platform.osc_sock.sendall(osc_message.encode_osc())
except socket.error, msg:
print "cannot connect to chaosc", msg
continue
try:
emg = int(emg)
except ValueError, e:
print e
continue
try:
osc_message = OSCMessage("/%s/emg" % actor)
osc_message.appendTypedArg(emg, "i")
platform.osc_sock.sendall(osc_message.encode_osc())
except socket.error, msg:
print "cannot connect to chaosc", msg
continue
try:
temp = int(temp)
except ValueError, e:
print e
continue
try:
osc_message = OSCMessage("/%s/temperatur" % actor)
osc_message.appendTypedArg(temp, "i")
platform.osc_sock.sendall(osc_message.encode_osc())
except socket.error, msg:
print "cannot connect to chaosc", msg
continue
if __name__ == '__main__':
main()

View File

@ -18,9 +18,9 @@
#
# Copyright (C) 2014 Stefan Kögl
from __future__ import absolute_import
import time
import time, select
from sensors2osc.common import *
@ -29,30 +29,36 @@ from sensors2osc.common import *
def main():
platform = init("ekg2osc")
actor = platform.args.actor
actor = bytes(platform.args.actor, "ascii")
while 1:
try:
t = platform.serial_sock.read(1)
except socket.error, msg:
toread, towrite, toerrors = select.select([platform.serial_sock], [],[], 0.05)
if toread:
t = platform.serial_sock.read(1)
else:
continue
except socket.error as msg:
# got disconnected?
print "serial socket error!!!", msg
print("serial socket error!!!", msg)
platform.reconnect()
try:
t = ord(t)
except TypeError, e:
except TypeError as e:
continue
try:
print "got value", t
osc_message = OSCMessage("/%s/ekg" % actor)
osc_message.appendTypedArg(t, "i")
print("got value", t)
osc_message = OSCMessage(b"/" + actor + b"/ekg")
osc_message.appendTypedArg(t, b"i")
platform.osc_sock.sendall(osc_message.encode_osc())
except socket.error, msg:
print "cannot connect to chaosc"
except socket.error as msg:
print("cannot connect to chaosc")
continue
if __name__ == '__main__':
main()

View File

@ -0,0 +1,58 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# This file is part of sensors2osc package
#
# sensors2osc is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# sensors2osc is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with sensors2osc. If not, see <http://www.gnu.org/licenses/>.
#
# Copyright (C) 2014 Stefan Kögl
from __future__ import absolute_import
import time
from sensors2osc.common import *
def main():
platform = init("ekg2osc")
actor = platform.args.actor
while 1:
try:
t = platform.serial_sock.read(1)
except socket.error, msg:
# got disconnected?
print "serial socket error!!!", msg
platform.reconnect()
try:
t = ord(t)
except TypeError, e:
continue
try:
print "got value", t
osc_message = OSCMessage("/%s/ekg" % actor)
osc_message.appendTypedArg(t, "i")
platform.osc_sock.sendall(osc_message.encode_osc())
except socket.error, msg:
print "cannot connect to chaosc"
continue
if __name__ == '__main__':
main()

View File

@ -48,7 +48,7 @@ class Forwarder(object):
def close(self):
"""Close all resources and unpublish service"""
print "%s: closing..." % (self.device, )
print("%s: closing..." % (self.device, ))
self.serial.close()
@ -58,7 +58,7 @@ class EHealth2OSC(Forwarder):
def handle_read(self, osc_sock):
data = self.serial.readline()[:-2]
print repr(data)
print(repr(data))
try:
airFlow, emg, temp = data.split(";")
except ValueError:
@ -106,7 +106,7 @@ class RingBuffer(object):
self.head = (self.head + 1) % self.length
def getData(self):
print "getData", self.ring_buf, self.head
print("getData", self.ring_buf, self.head)
data = list()
for i in range(7, 1, -1):
value = self.ring_buf[(self.head - i) % self.length]
@ -117,7 +117,7 @@ class RingBuffer(object):
raise ValueError("not complete - ringbuffer resettet")
data.append(value)
if data[0] != 0x0 or data[1] != 0xff:
print "issue", data
print("issue", data)
self.reset()
self.ring_buf[0] = 0
self.head = 1
@ -146,7 +146,7 @@ class Pulse2OSC(Forwarder):
osc_message.appendTypedArg(heart_rate, "i")
osc_message.appendTypedArg(o2, "i")
osc_sock.sendall(osc_message.encode_osc())
print "heartbeat", datetime.datetime.now(), heart_signal
print("heartbeat", datetime.datetime.now(), heart_signal)
self.heartbeat_on = True
elif pulse == 1 and self.heartbeat_on:
#print "off heartbeat", datetime.datetime.now(), heart_signal
@ -156,8 +156,8 @@ class Pulse2OSC(Forwarder):
osc_message.appendTypedArg(heart_rate, "i")
osc_message.appendTypedArg(o2, "i")
osc_sock.sendall(osc_message.encode_osc())
except ValueError, e:
print e
except ValueError as e:
print(e)
def main():
@ -187,30 +187,30 @@ def main():
used_devices = dict()
while 1:
for device, description in naming.iteritems():
for device, description in naming.items():
if os.path.exists(device):
if device not in used_devices:
actor, platform = naming[device]
if description[1] == "ehealth":
print device, actor, platform
print(device, actor, platform)
used_devices[device] = EHealth2OSC(actor, platform, device)
elif description[1] == "ekg":
print device, actor, platform
print(device, actor, platform)
used_devices[device] = EKG2OSC(actor, platform, device)
elif description[1] == "pulse":
print device, actor, platform
print(device, actor, platform)
used_devices[device] = Pulse2OSC(actor, platform, device)
else:
raise ValueError("unknown description %r for device %r" % (description, device))
else:
print "device missing", device
print("device missing", device)
message = OSCMessage("/DeviceMissing")
message.appendTypedArg(description[0], "s")
message.appendTypedArg(description[1], "s")
osc_sock.sendall(message.encode_osc())
read_map = {}
for forwarder in used_devices.values():
for forwarder in list(used_devices.values()):
read_map[forwarder.serial] = forwarder.handle_read
readers, writers, errors = select.select(read_map, [], [], 0.1)

View File

@ -0,0 +1,218 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# This file is part of chaosc
#
# chaosc is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# chaosc is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with chaosc. If not, see <http://www.gnu.org/licenses/>.
#
# Copyright (C) 2014 Stefan Kögl
import argparse
import os.path
import select
import serial
import socket
import sys
import datetime
try:
from chaosc.c_osc_lib import OSCMessage
except ImportError as e:
print(e)
from chaosc.osc_lib import OSCMessage
class Forwarder(object):
def __init__(self, actor, platform, device):
self.actor = actor
self.platform = platform
self.device = device
self.serial = serial.Serial()
self.serial.port = device
self.serial.baudrate = 115200
self.serial.timeout = 0
self.buf_ser2osc = ""
self.serial.open()
def close(self):
"""Close all resources and unpublish service"""
print "%s: closing..." % (self.device, )
self.serial.close()
class EHealth2OSC(Forwarder):
def __init__(self, actor, platform, device):
super(EHealth2OSC, self).__init__(actor, platform, device)
def handle_read(self, osc_sock):
data = self.serial.readline()[:-2]
print repr(data)
try:
airFlow, emg, temp = data.split(";")
except ValueError:
return
try:
airFlow = int(airFlow)
emg = int(emg)
temp = int(temp);
except ValueError:
return
osc_message = OSCMessage("/%s/airFlow" % self.actor)
osc_message.appendTypedArg(airFlow, "i")
osc_sock.sendall(osc_message.encode_osc())
osc_message = OSCMessage("/%s/emg" % self.actor)
osc_message.appendTypedArg(emg, "i")
osc_sock.sendall(osc_message.encode_osc())
osc_message = OSCMessage("/%s/temperatur" % self.actor)
osc_message.appendTypedArg(temp, "i")
osc_sock.sendall(osc_message.encode_osc())
class EKG2OSC(Forwarder):
def __init__(self, actor, platform, device):
super(EKG2OSC, self).__init__(actor, platform, device)
def handle_read(self, osc_sock):
t = ord(self.serial.read(1))
osc_message = OSCMessage("/%s/ekg" % self.actor)
osc_message.appendTypedArg(t, "i")
osc_sock.sendall(osc_message.encode_osc())
class RingBuffer(object):
def __init__(self, length):
self.length = length
self.ring_buf = list()
self.reset()
def reset(self):
self.ring_buf = [-1] * self.length
self.head = 0
def append(self, value):
self.ring_buf[self.head] = value
self.head = (self.head + 1) % self.length
def getData(self):
print "getData", self.ring_buf, self.head
data = list()
for i in range(7, 1, -1):
value = self.ring_buf[(self.head - i) % self.length]
if value == -1:
self.reset()
self.ring_buf[0] = 0
self.head = 1
raise ValueError("not complete - ringbuffer resettet")
data.append(value)
if data[0] != 0x0 or data[1] != 0xff:
print "issue", data
self.reset()
self.ring_buf[0] = 0
self.head = 1
raise ValueError("not synced - ringbuffer resettet")
return data[2:]
class Pulse2OSC(Forwarder):
def __init__(self, actor, platform, device):
super(Pulse2OSC, self).__init__(actor, platform, device)
self.buf = RingBuffer(6)
self.heartbeat_on = False
def handle_read(self, osc_sock):
t = ord(self.serial.read(1))
self.buf.append(t)
if t == 0:
try:
heart_signal, heart_rate, o2, pulse = self.buf.getData()
if pulse == 245 and not self.heartbeat_on:
osc_message = OSCMessage("/%s/heartbeat" % self.actor)
osc_message.appendTypedArg(1, "i")
osc_message.appendTypedArg(heart_rate, "i")
osc_message.appendTypedArg(o2, "i")
osc_sock.sendall(osc_message.encode_osc())
print "heartbeat", datetime.datetime.now(), heart_signal
self.heartbeat_on = True
elif pulse == 1 and self.heartbeat_on:
#print "off heartbeat", datetime.datetime.now(), heart_signal
self.heartbeat_on = False
osc_message = OSCMessage("/%s/heartbeat" % self.actor)
osc_message.appendTypedArg(0, "i")
osc_message.appendTypedArg(heart_rate, "i")
osc_message.appendTypedArg(o2, "i")
osc_sock.sendall(osc_message.encode_osc())
except ValueError, e:
print e
def main():
parser = argparse.ArgumentParser(prog='psychose_actor')
parser.add_argument("-H", '--chaosc_host', required=True,
type=str, help='host of chaosc instance to control')
parser.add_argument("-p", '--chaosc_port', required=True,
type=int, help='port of chaosc instance to control')
args = parser.parse_args(sys.argv[1:])
osc_sock = socket.socket(2, 2, 17)
osc_sock.connect((args.chaosc_host, args.chaosc_port))
naming = {
"/dev/ttyUSB0" : ["bjoern", "ehealth"],
"/dev/ttyACM0" : ["bjoern", "ekg"],
"/dev/ttyACM1" : ["bjoern", "pulse"],
"/dev/ttyUSB1" : ["merle", "ehealth"],
"/dev/ttyACM2" : ["merle", "ekg"],
"/dev/ttyACM3" : ["merle", "pulse"],
"/dev/ttyUSB2" : ["uwe", "ehealth"],
"/dev/ttyACM4" : ["uwe", "ekg"],
"/dev/ttyACM5" : ["uwe", "pulse"]
}
used_devices = dict()
while 1:
for device, description in naming.iteritems():
if os.path.exists(device):
if device not in used_devices:
actor, platform = naming[device]
if description[1] == "ehealth":
print device, actor, platform
used_devices[device] = EHealth2OSC(actor, platform, device)
elif description[1] == "ekg":
print device, actor, platform
used_devices[device] = EKG2OSC(actor, platform, device)
elif description[1] == "pulse":
print device, actor, platform
used_devices[device] = Pulse2OSC(actor, platform, device)
else:
raise ValueError("unknown description %r for device %r" % (description, device))
else:
print "device missing", device
message = OSCMessage("/DeviceMissing")
message.appendTypedArg(description[0], "s")
message.appendTypedArg(description[1], "s")
osc_sock.sendall(message.encode_osc())
read_map = {}
for forwarder in used_devices.values():
read_map[forwarder.serial] = forwarder.handle_read
readers, writers, errors = select.select(read_map, [], [], 0.1)
for reader in readers:
read_map[reader](osc_sock)

View File

@ -18,7 +18,7 @@
#
# Copyright (C) 2014 Stefan Kögl
from __future__ import absolute_import
import time
from datetime import datetime
@ -41,7 +41,7 @@ class RingBuffer(object):
self.head = (self.head + 1) % self.length
def getData(self):
print "getData", self.ring_buf, self.head
print("getData", self.ring_buf, self.head)
data = list()
for i in range(self.length + 1, 1, -1):
value = self.ring_buf[(self.head - i) % self.length]
@ -52,7 +52,7 @@ class RingBuffer(object):
raise ValueError("not complete - ringbuffer resettet")
data.append(value)
if data[0] != 0x0 or data[1] != 0xff:
print "issue", data
print("issue", data)
self.reset()
self.ring_buf[0] = 0
self.head = 1
@ -63,57 +63,61 @@ class RingBuffer(object):
def main():
platform = init("pulse2osc")
actor = platform.args.actor
actor = bytes(platform.args.actor, "ascii")
buf = RingBuffer(6)
heartbeat_on = False
while 1:
try:
t = platform.serial_sock.read(1)
except socket.error, msg:
toread, towrite, toerrors = select.select([platform.serial_sock], [],[], 0.05)
if toread:
t = platform.serial_sock.read(1)
else:
continue
except socket.error as msg:
# got disconnected?
print "serial socket error!!!", msg
print("serial socket error!!!", msg)
platform.reconnect()
try:
t = ord(t)
except TypeError, e:
except TypeError as e:
continue
print "got value", t
print("got value", t)
buf.append(t)
if t == 0:
try:
heart_signal, heart_rate, o2, pulse = buf.getData()
except ValueError, e:
print e
except ValueError as e:
print(e)
continue
if pulse == 245 and not heartbeat_on:
heartbeat_on = True
try:
osc_message = OSCMessage("/%s/heartbeat" % actor)
osc_message.appendTypedArg(1, "i")
osc_message.appendTypedArg(heart_rate, "i")
osc_message.appendTypedArg(o2, "i")
osc_message = OSCMessage(b"/" + actor + b"/heartbeat")
osc_message.appendTypedArg(1, b"i")
osc_message.appendTypedArg(heart_rate, b"i")
osc_message.appendTypedArg(o2, b"i")
platform.osc_sock.sendall(osc_message.encode_osc())
print "on heartbeat", datetime.now(), heart_signal, heart_rate, o2, pulse
except socket.error, msg:
print "cannot connect to chaosc"
print("on heartbeat", datetime.now(), heart_signal, heart_rate, o2, pulse)
except socket.error as msg:
print("cannot connect to chaosc")
continue
elif pulse == 1 and heartbeat_on:
print "off heartbeat", datetime.now(), heart_signal, heart_rate, o2, pulse
print("off heartbeat", datetime.now(), heart_signal, heart_rate, o2, pulse)
heartbeat_on = False
try:
osc_message = OSCMessage("/%s/heartbeat" % actor)
osc_message.appendTypedArg(0, "i")
osc_message.appendTypedArg(heart_rate, "i")
osc_message.appendTypedArg(o2, "i")
osc_message = OSCMessage(b"/" + actor + b"/heartbeat")
osc_message.appendTypedArg(0, b"i")
osc_message.appendTypedArg(heart_rate, b"i")
osc_message.appendTypedArg(o2, b"i")
platform.osc_sock.sendall(osc_message.encode_osc())
except socket.error, msg:
print "cannot connect to chaosc"
except socket.error as msg:
print("cannot connect to chaosc")
continue
time.sleep(0.1)

View File

@ -0,0 +1,122 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# This file is part of sensors2osc package
#
# sensors2osc is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# sensors2osc is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with sensors2osc. If not, see <http://www.gnu.org/licenses/>.
#
# Copyright (C) 2014 Stefan Kögl
from __future__ import absolute_import
import time
from datetime import datetime
from sensors2osc.common import *
class RingBuffer(object):
def __init__(self, length):
self.length = length
self.ring_buf = list()
self.reset()
def reset(self):
self.ring_buf = [-1] * self.length
self.head = 0
def append(self, value):
self.ring_buf[self.head] = value
self.head = (self.head + 1) % self.length
def getData(self):
print "getData", self.ring_buf, self.head
data = list()
for i in range(self.length + 1, 1, -1):
value = self.ring_buf[(self.head - i) % self.length]
if value == -1:
self.reset()
self.ring_buf[0] = 0
self.head = 1
raise ValueError("not complete - ringbuffer resettet")
data.append(value)
if data[0] != 0x0 or data[1] != 0xff:
print "issue", data
self.reset()
self.ring_buf[0] = 0
self.head = 1
raise ValueError("not synced - ringbuffer resettet")
return data[2:]
def main():
platform = init("pulse2osc")
actor = platform.args.actor
buf = RingBuffer(6)
heartbeat_on = False
while 1:
try:
t = platform.serial_sock.read(1)
except socket.error, msg:
# got disconnected?
print "serial socket error!!!", msg
platform.reconnect()
try:
t = ord(t)
except TypeError, e:
continue
print "got value", t
buf.append(t)
if t == 0:
try:
heart_signal, heart_rate, o2, pulse = buf.getData()
except ValueError, e:
print e
continue
if pulse == 245 and not heartbeat_on:
heartbeat_on = True
try:
osc_message = OSCMessage("/%s/heartbeat" % actor)
osc_message.appendTypedArg(1, "i")
osc_message.appendTypedArg(heart_rate, "i")
osc_message.appendTypedArg(o2, "i")
platform.osc_sock.sendall(osc_message.encode_osc())
print "on heartbeat", datetime.now(), heart_signal, heart_rate, o2, pulse
except socket.error, msg:
print "cannot connect to chaosc"
continue
elif pulse == 1 and heartbeat_on:
print "off heartbeat", datetime.now(), heart_signal, heart_rate, o2, pulse
heartbeat_on = False
try:
osc_message = OSCMessage("/%s/heartbeat" % actor)
osc_message.appendTypedArg(0, "i")
osc_message.appendTypedArg(heart_rate, "i")
osc_message.appendTypedArg(o2, "i")
platform.osc_sock.sendall(osc_message.encode_osc())
except socket.error, msg:
print "cannot connect to chaosc"
continue
time.sleep(0.1)
if __name__ == '__main__':
main()

View File

@ -48,7 +48,7 @@ class Forwarder(object):
def close(self):
"""Close all resources and unpublish service"""
print "%s: closing..." % (self.device, )
print("%s: closing..." % (self.device, ))
self.serial.close()
@ -58,7 +58,7 @@ class EHealth2OSC(Forwarder):
def handle_read(self, osc_sock):
data = self.serial.readline()[:-2]
print repr(data)
print(repr(data))
try:
airFlow, emg, temp = data.split(";")
except ValueError:
@ -94,7 +94,7 @@ class EKG2OSC(Forwarder):
class RingBuffer(object):
def __init__(self, length):
self.length = length
self.ring_buf = [-1 for i in xrange(length)]
self.ring_buf = [-1 for i in range(length)]
self.head = 0
def append(self, value):
@ -102,7 +102,7 @@ class RingBuffer(object):
self.head = (self.head + 1) % self.length
def getData(self):
print "getData", self.ring_buf, self.head
print("getData", self.ring_buf, self.head)
data = list()
for i in range(7, 1, -1):
value = self.ring_buf[(self.head - i) % self.length]
@ -135,7 +135,7 @@ class Pulse2OSC(Forwarder):
osc_message.appendTypedArg(heart_rate, "i")
osc_message.appendTypedArg(o2, "i")
osc_sock.sendall(osc_message.encode_osc())
print "heartbeat", datetime.datetime.now(), heart_signal
print("heartbeat", datetime.datetime.now(), heart_signal)
self.heartbeat_on = True
elif pulse == 1 and self.heartbeat_on:
#print "off heartbeat", datetime.datetime.now(), heart_signal
@ -145,8 +145,8 @@ class Pulse2OSC(Forwarder):
osc_message.appendTypedArg(heart_rate, "i")
osc_message.appendTypedArg(o2, "i")
osc_sock.sendall(osc_message.encode_osc())
except ValueError, e:
print e
except ValueError as e:
print(e)
def main():
@ -182,7 +182,7 @@ def main():
while 1:
read_map = {}
for forwarder in used_devices.values():
for forwarder in list(used_devices.values()):
read_map[forwarder.serial] = forwarder.handle_read
readers, writers, errors = select.select(read_map, [], [], 0.1)

View File

@ -0,0 +1,190 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# This file is part of sensors2osc package
#
# sensors2osc is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# sensors2osc is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with sensors2osc. If not, see <http://www.gnu.org/licenses/>.
#
# Copyright (C) 2014 Stefan Kögl
import argparse
import os.path
import select
import serial
import socket
import sys
import datetime
try:
from chaosc.c_osc_lib import OSCMessage
except ImportError as e:
print(e)
from chaosc.osc_lib import OSCMessage
class Forwarder(object):
def __init__(self, actor, platform, device):
self.actor = actor
self.platform = platform
self.device = device
self.serial = serial.Serial()
self.serial.port = device
self.serial.baudrate = 115200
self.serial.timeout = 0
self.buf_ser2osc = ""
self.serial.open()
def close(self):
"""Close all resources and unpublish service"""
print "%s: closing..." % (self.device, )
self.serial.close()
class EHealth2OSC(Forwarder):
def __init__(self, actor, platform, device):
super(EHealth2OSC, self).__init__(actor, platform, device)
def handle_read(self, osc_sock):
data = self.serial.readline()[:-2]
print repr(data)
try:
airFlow, emg, temp = data.split(";")
except ValueError:
return
try:
airFlow = int(airFlow)
emg = int(emg)
temp = int(temp);
except ValueError:
return
osc_message = OSCMessage("/%s/airFlow" % self.actor)
osc_message.appendTypedArg(airFlow, "i")
osc_sock.sendall(osc_message.encode_osc())
osc_message = OSCMessage("/%s/emg" % self.actor)
osc_message.appendTypedArg(emg, "i")
osc_sock.sendall(osc_message.encode_osc())
osc_message = OSCMessage("/%s/temperatur" % self.actor)
osc_message.appendTypedArg(temp, "i")
osc_sock.sendall(osc_message.encode_osc())
class EKG2OSC(Forwarder):
def __init__(self, actor, platform, device):
super(EKG2OSC, self).__init__(actor, platform, device)
def handle_read(self, osc_sock):
t = ord(self.serial.read(1))
osc_message = OSCMessage("/%s/ekg" % self.actor)
osc_message.appendTypedArg(t, "i")
osc_sock.sendall(osc_message.encode_osc())
class RingBuffer(object):
def __init__(self, length):
self.length = length
self.ring_buf = [-1 for i in xrange(length)]
self.head = 0
def append(self, value):
self.ring_buf[self.head] = value
self.head = (self.head + 1) % self.length
def getData(self):
print "getData", self.ring_buf, self.head
data = list()
for i in range(7, 1, -1):
value = self.ring_buf[(self.head - i) % self.length]
if value == -1:
raise ValueError("not complete")
data.append(value)
if data[0] != 0x0 or data[1] != 0xff:
raise ValueError("not synced")
return data[2:]
class Pulse2OSC(Forwarder):
def __init__(self, actor, platform, device):
super(Pulse2OSC, self).__init__(actor, platform, device)
self.buf = RingBuffer(6)
self.heartbeat_on = False
def handle_read(self, osc_sock):
t = ord(self.serial.read(1))
self.buf.append(t)
if t == 0:
try:
heart_signal, heart_rate, o2, pulse = self.buf.getData()
if pulse == 245 and not self.heartbeat_on:
osc_message = OSCMessage("/%s/heartbeat" % self.actor)
osc_message.appendTypedArg(1, "i")
osc_message.appendTypedArg(heart_rate, "i")
osc_message.appendTypedArg(o2, "i")
osc_sock.sendall(osc_message.encode_osc())
print "heartbeat", datetime.datetime.now(), heart_signal
self.heartbeat_on = True
elif pulse == 1 and self.heartbeat_on:
#print "off heartbeat", datetime.datetime.now(), heart_signal
self.heartbeat_on = False
osc_message = OSCMessage("/%s/heartbeat" % self.actor)
osc_message.appendTypedArg(0, "i")
osc_message.appendTypedArg(heart_rate, "i")
osc_message.appendTypedArg(o2, "i")
osc_sock.sendall(osc_message.encode_osc())
except ValueError, e:
print e
def main():
parser = argparse.ArgumentParser(prog='psychose_actor')
parser.add_argument("-H", '--chaosc_host', required=True,
type=str, help='host of chaosc instance to control')
parser.add_argument("-p", '--chaosc_port', required=True,
type=int, help='port of chaosc instance to control')
parser.add_argument("-t", '--type', required=True,
type=str, help='ekg, pulse, ehealth')
parser.add_argument("-d", '--device', required=True,
type=str, help='device node under /dev')
parser.add_argument("-a", '--actor', required=True,
type=str, help='actor name')
args = parser.parse_args(sys.argv[1:])
osc_sock = socket.socket(2, 2, 17)
osc_sock.connect((args.chaosc_host, args.chaosc_port))
used_devices = dict()
actor = args.actor
if args.type == "ehealth":
used_devices[device] = EHealth2OSC(actor, "ehealth", args.device)
elif args.type == "ekg":
used_devices[device] = EKG2OSC(actor, "ekg", args.device)
elif args.type == "pulse":
used_devices[device] = Pulse2OSC(actor, "pulse", args.device)
else:
raise ValueError("unknown description %r for device %r" % (description, device))
while 1:
read_map = {}
for forwarder in used_devices.values():
read_map[forwarder.serial] = forwarder.handle_read
readers, writers, errors = select.select(read_map, [], [], 0.1)
for reader in readers:
read_map[reader](osc_sock)

View File

@ -31,5 +31,7 @@ serial_sock.open()
while 1:
serial_sock.write("%d;%d;%d\r\n" % (random.randint(0,1023), random.randint(0,1023), random.randint(0,1023)))
time.sleep(0.1)
data = b";".join((bytes(str(random.randint(0,1023)), "ascii"), bytes(str(random.randint(0,1023)), "ascii"), bytes(str(random.randint(0,1023)), "ascii"))) + b"\r\n"
print("data", data)
serial_sock.write(data)
time.sleep(0.05)

View File

@ -55,13 +55,13 @@ while 1:
count = 0
if data_points % (5 * steps) == 0:
print "new steps", steps, delta
print("new steps", steps, delta)
steps += delta
if steps <= min_steps:
delta = 1
elif steps >= max_steps:
print "change step sign", steps, delta
print("change step sign", steps, delta)
delta = -1
time.sleep(0.02)

View File

@ -0,0 +1,70 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# This file is part of sensors2osc package
#
# sensors2osc is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# sensors2osc is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with sensors2osc. If not, see <http://www.gnu.org/licenses/>.
#
# Copyright (C) 2014 Stefan Kögl
# used this line before opening that script
# socat -d -d PTY,raw,echo=0,link=/tmp/pty1,b115200,user=stefan PTY,raw,echo=0,link=/tmp/pty2,b115200,user=stefan
import serial, sys, time, random, struct
serial_sock = serial.Serial()
serial_sock.port = sys.argv[1]
serial_sock.baudrate = 115200
serial_sock.timeout = 0
serial_sock.open()
data_points = 0
min_steps = 17
max_steps = 43
steps = random.randint(17,43)
count = 0
delta = 1
result = list()
while 1:
value = random.randint(0, steps)
if count < int(steps / 100. * 20):
value = random.randint(0,20)
elif count < int(steps / 2.):
value = random.randint(20,50)
elif count == int(steps / 2.):
value = 255
elif count < int(steps / 100. * 70):
value = random.randint(20,50)
elif count <= steps:
value = random.randint(0,20)
elif count >= steps:
count = 0
if data_points % (5 * steps) == 0:
print "new steps", steps, delta
steps += delta
if steps <= min_steps:
delta = 1
elif steps >= max_steps:
print "change step sign", steps, delta
delta = -1
time.sleep(0.02)
count += 1
data_points += 1
serial_sock.write(struct.pack("B", value))

View File

@ -21,7 +21,7 @@
# socat -d -d PTY,raw,echo=0,link=/tmp/pty1,b115200,user=stefan PTY,raw,echo=0,link=/tmp/pty2,b115200,user=stefan
from __future__ import absolute_import
import serial, time, random, sys, random, struct
@ -59,4 +59,4 @@ r = DataGenenerator()
while 1:
serial_sock.write(struct.pack("B", r.read()))
#time.sleep(0.1)
time.sleep(0.02)

View File

@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
# This file is part of chaosc
#
# chaosc is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# chaosc is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with chaosc. If not, see <http://www.gnu.org/licenses/>.
#
# Copyright (C) 2014 Stefan Kögl
# used this line before opening that script
# socat -d -d PTY,raw,echo=0,link=/tmp/pty1,b115200,user=stefan PTY,raw,echo=0,link=/tmp/pty2,b115200,user=stefan
from __future__ import absolute_import
import serial, time, random, sys, random, struct
serial_sock = serial.Serial()
serial_sock.port = sys.argv[1]
serial_sock.baudrate = 115200
serial_sock.timeout = 0
serial_sock.open()
class DataGenenerator(object):
def __init__(self):
self.get_i = 0
def read(self):
value = None
if self.get_i == 0:
value = random.randint(1, 254)
elif self.get_i == 1:
value = random.sample((1, 245), 1)[0]
elif self.get_i == 2:
value = 0
elif self.get_i == 3:
value = 255
elif self.get_i == 4:
value = random.randint(1, 255)
elif self.get_i == 5:
value = random.randint(1, 255)
self.get_i = (self.get_i + 1) % 6
return value
r = DataGenenerator()
while 1:
serial_sock.write(struct.pack("B", r.read()))
#time.sleep(0.1)

View File

@ -7,6 +7,7 @@ use_setuptools()
import sys
from setuptools import find_packages, setup
extras = dict()
if sys.version_info >= (3,):
extras['use_2to3'] = True