Compare commits
7 Commits
Author | SHA1 | Date |
---|---|---|
Stefan Kögl | e865fe53d2 | |
Stefan Kögl | e889b3a88c | |
Stefan Kögl | 41e512c9ef | |
Stefan Kögl | 9bf6f97781 | |
Stefan Kögl | 8dc6e67d1d | |
Stefan Kögl | 9bcdc6b377 | |
Stefan Kögl | 7c0f56bf20 |
|
@ -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'
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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_()
|
|
@ -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
|
||||
try:
|
||||
ix = self.active_actors.index(actor_obj)
|
||||
actor_obj.set_point(value, ix, max_actors)
|
||||
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)
|
||||
except ValueError as e:
|
||||
#print("data", e)
|
||||
pass
|
||||
actor_obj.data_pointer = (data_pointer + 1) % self.num_data
|
||||
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
|
||||
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 not actor_obj.active:
|
||||
print "actor off", actor_name
|
||||
self.plot.removeItem(actor_obj)
|
||||
actor_obj.active = True
|
||||
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()
|
||||
|
||||
|
||||
|
|
|
@ -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()
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -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:
|
||||
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
|
||||
|
||||
|
||||
|
|
|
@ -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()
|
|
@ -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:
|
||||
toread, towrite, toerrors = select.select([platform.serial_sock], [],[], 0.05)
|
||||
if toread:
|
||||
t = platform.serial_sock.read(1)
|
||||
except socket.error, msg:
|
||||
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()
|
||||
|
|
|
@ -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()
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
|
@ -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:
|
||||
toread, towrite, toerrors = select.select([platform.serial_sock], [],[], 0.05)
|
||||
if toread:
|
||||
t = platform.serial_sock.read(1)
|
||||
except socket.error, msg:
|
||||
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)
|
||||
|
||||
|
|
|
@ -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()
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue