Merge branch 'master' of repos.ctdo.de:psychose

This commit is contained in:
Lucas Pleß 2014-05-03 11:46:27 +02:00
commit 0fd969766d
30 changed files with 4216 additions and 743 deletions

View File

@ -1,3 +0,0 @@
[chaosc]
ipv4_only = True
subscription_file = ~/dev/psychose/config_files/targets.config

View File

@ -1,31 +0,0 @@
[chaosc_ctl]
ipv4_only = True
client_host = lucas
client_port = 11111
chaosc_host = chaosc
[chaosc_dump]
ipv4_only = True
client_host = lucas
client_port = 11112
subscribe = True
chaosc_host = chaosc
[chaosc_emitter]
ipv4_only = True
client_host = lucas
client_port = 11113
chaosc_host = chaosc
[ekgplotter]
ipv4_only = True
client_host = lucas
client_port = 11114
chaosc_host = chaosc
[chaosc_recorder]
ipv4_only = True
client_host = lucas
client_port = 111115
chaosc_host = chaosc

View File

@ -1,11 +0,0 @@
[ekg2osc]
ipv4_only = True
chaosc_host = chaosc
[pulse2osc]
ipv4_only = True
chaosc_host = chaosc
[ehealth2osc]
ipv4_only = True
chaosc_host = chaosc

View File

@ -1,31 +0,0 @@
[chaosc_ctl]
ipv4_only = True
client_host = stefan
client_port = 11111
chaosc_host = chaosc
[chaosc_dump]
ipv4_only = True
client_host = stefan
client_port = 11112
subscribe = True
chaosc_host = chaosc
[chaosc_emitter]
ipv4_only = True
client_host = stefan
client_port = 11113
chaosc_host = chaosc
[ekgplotter]
ipv4_only = True
client_host = stefan
client_port = 11114
chaosc_host = chaosc
[chaosc_recorder]
ipv4_only = True
client_host = stefan
client_port = 111115
chaosc_host = chaosc

View File

@ -1,19 +0,0 @@
Port 8090
BindAddress 0.0.0.0
MaxClients 10
MaxBandwidth 1000000
CustomLog /tmp/ffserver.log
<Feed textcast.ffm>
file /tmp/textcast.ffm
FileMaxSize 10M
ACL allow 127.0.0.1
</Feed>
<Stream textcast.mjpeg>
Feed textcast.ffm
Format mjpeg
VideoFrameRate 25
VideoSize 768x576
Noaudio
</Stream>

View File

@ -0,0 +1,58 @@
[chaosc]
chaosc_host = chaosc
ipv4_only = True
subscription_file = ~/dev/psychose/config_files/test_targets.config
[pulsemerle]
chaosc_host = chaosc
ipv4_only = True
actor = merle
device = /dev/psy_spo2_a
[pulseuwe]
chaosc_host = chaosc
ipv4_only = True
actor = uwe
device = /dev/psy_spo2_b
[pulsebjoern]
chaosc_host = chaosc
ipv4_only = True
actor = bjoern
device = /dev/psy_spo2_c
[ehealthmerle]
chaosc_host = chaosc
ipv4_only = True
actor = merle
device = /dev/psy_ehealth_a
[ehealthuwe]
chaosc_host = chaosc
ipv4_only = True
actor = uwe
device = /dev/psy_ehealth_b
[ehealthbjoern]
chaosc_host = chaosc
ipv4_only = True
actor = bjoern
device = /dev/psy_ehealth_c
[ekgmerle]
chaosc_host = chaosc
ipv4_only = True
actor = merle
device = /dev/psy_ekg_a
[ekguwe]
chaosc_host = chaosc
ipv4_only = True
actor = uwe
device = /dev/psy_ekg_b
[ekgbjoern]
chaosc_host = chaosc
ipv4_only = True
actor = bjoern
device = /dev/psy_ekg_c

View File

@ -2,7 +2,7 @@
depend() {
need net
use dns localmount chaosc
use dns localmount
after bootmisc
provide dump_grabber
}
@ -10,7 +10,7 @@ depend() {
start() {
ebegin "starting dump_grabber"
start-stop-daemon --start --pidfile /var/run/dump_grabber.pid --make-pidfile --user stefan --group stefan --background --exec env DISPLAY=:0 /usr/bin/dump_grabber
start-stop-daemon --start --pidfile /var/run/dump_grabber.pid --make-pidfile --user sarah --group sarah --background --exec env DISPLAY=:0 /usr/bin/dump_grabber
eend $?
}

View File

@ -2,7 +2,7 @@
depend() {
need net
use dns localmount chaosc
use dns localmount
after bootmisc
provide ekgplotter
}
@ -10,7 +10,7 @@ depend() {
start() {
ebegin "starting ekgplotter"
start-stop-daemon --start --pidfile /var/run/ekgplotter.pid --make-pidfile --user stefan --group stefan --background --exec env DISPLAY=:0 /usr/bin/ekgplotter
start-stop-daemon --start --pidfile /var/run/ekgplotter.pid --make-pidfile --user sarah --group sarah --background --exec env DISPLAY=:0 /usr/bin/ekgplotter
eend $?
}

View File

@ -0,0 +1,22 @@
#!/sbin/runscript
depend() {
need net
use dns localmount
after bootmisc
provide psydisplay
}
start() {
ebegin "starting psydisplay"
start-stop-daemon --start --pidfile /var/run/psydisplay.pid --make-pidfile --user sarah --group sarah --background --exec /usr/bin/psydisplay
eend $?
}
stop() {
ebegin "stopping psydisplay"
start-stop-daemon --stop --quiet --pidfile /var/run/psydisplay.pid
eend $?
}

View File

@ -0,0 +1,13 @@
[ekgplotter]
ipv4_only = True
chaosc_host = chaosc
client_host = sensors
client_port = 8000
http_port = 9000
[dump_grabber]
ipv4_only = True
chaosc_host = chaosc
client_host = sensors
client_port = 8001
http_port = 9001

File diff suppressed because it is too large Load Diff

View File

@ -15,49 +15,42 @@ 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 -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'
new-window -n 'socat-ekg-uwe' -t 'csession:4' 'socat -d -d PTY,raw,echo=0,link=/tmp/ekg2osc-uwe-in,b115200,user=stefan PTY,raw,echo=0,link=/tmp/ekg2osc-uwe-out,b115200,user=stefan'
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-pulse-bjoern' -t 'csession:5' 'socat -d -d PTY,raw,echo=0,link=/tmp/pulse2osc-bjoern-in,b115200,user=stefan PTY,raw,echo=0,link=/tmp/pulse2osc-bjoern-out,b115200,user=stefan'
new-window -n 'socat-pulse-merle' -t 'csession:6' 'socat -d -d PTY,raw,echo=0,link=/tmp/pulse2osc-merle-in,b115200,user=stefan PTY,raw,echo=0,link=/tmp/pulse2osc-merle-out,b115200,user=stefan'
new-window -n 'socat-pulse-uwe' -t 'csession:7' 'socat -d -d PTY,raw,echo=0,link=/tmp/pulse2osc-uwe-in,b115200,user=stefan PTY,raw,echo=0,link=/tmp/pulse2osc-uwe-out,b115200,user=stefan'
new-window -n 'socat-pulse-bjoern' -t 'csession:5' 'socat -d -d PTY,raw,echo=0,link=/tmp/pulse2osc-bjoern-in,b115200,user=stefan PTY,raw,echo=0,link=/tmp/pulse2osc-bjoern-out,b115200,user=stefan'
new-window -n 'socat-ehealth-bjoern' -t 'csession:8' 'socat -d -d PTY,raw,echo=0,link=/tmp/ehealth2osc-bjoern-in,b115200,user=stefan PTY,raw,echo=0,link=/tmp/ehealth2osc-bjoern-out,b115200,user=stefan'
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 'socat-ehealth-bjoern' -t 'csession:8' 'socat -d -d PTY,raw,echo=0,link=/tmp/ehealth2osc-bjoern-in,b115200,user=stefan PTY,raw,echo=0,link=/tmp/ehealth2osc-bjoern-out,b115200,user=stefan'
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 'ekg2osc-merle' -t 'csession:11' 'ekgmerle -D /tmp/ekg2osc-merle-out'
new-window -n 'ekg2osc-uwe' -t 'csession:12' 'ekguwe -D /tmp/ekg2osc-uwe-out'
new-window -n 'ekg2osc-bjoern' -t 'csession:13' 'ekgbjoern -D /tmp/ekg2osc-bjoern-out'
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 'pulse2osc-merle' -t 'csession:14' 'pulse2osc -D /tmp/pulse2osc-merle-out -a merle'
new-window -n 'pulse2osc-uwe' -t 'csession:15' 'pulse2osc -D /tmp/pulse2osc-uwe-out -a uwe'
new-window -n 'pulse2osc-bjoern' -t 'csession:16' 'pulse2osc -D /tmp/pulse2osc-bjoern-out -a bjoern'
new-window -n 'ehealth2osc-bjoern' -t 'csession:17' 'sleep 1 && ehealth2osc -4 -D /tmp/ehealth2osc-bjoern-out -a bjoern'
new-window -n 'ehealth2osc-merle' -t 'csession:18' 'sleep 1 && ehealth2osc -4 -D /tmp/ehealth2osc-merle-out -a merle'
new-window -n 'ehealth2osc-uwe' -t 'csession:19' 'sleep 1 && ehealth2osc -4 -D /tmp/ehealth2osc-uwe-out -a uwe'
new-window -n 'ehealth2osc-merle' -t 'csession:17' 'sleep 1 && ehealthmerle -D /tmp/ehealth2osc-merle-out'
new-window -n 'ehealth2osc-uwe' -t 'csession:18' 'sleep 1 && ehealthuwe -D /tmp/ehealth2osc-uwe-out'
new-window -n 'ehealth2osc-bjoern' -t 'csession:19' 'sleep 1 && ehealthbjoern -D /tmp/ehealth2osc-bjoern-out'
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'
new-window -n 'test-ekg-uwe' -t 'csession:22' 'python /home/stefan/dev/psychose/sensors2osc/sensors2osc/socat_ekg_test.py /tmp/ekg2osc-uwe-in'
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-pulse-bjoern' -t 'csession:23' 'python /home/stefan/dev/psychose/sensors2osc/sensors2osc/socat_pulse_test.py /tmp/pulse2osc-bjoern-in'
new-window -n 'test-pulse-merle' -t 'csession:24' 'python /home/stefan/dev/psychose/sensors2osc/sensors2osc/socat_pulse_test.py /tmp/pulse2osc-merle-in'
new-window -n 'test-pulse-uwe' -t 'csession:25' 'python /home/stefan/dev/psychose/sensors2osc/sensors2osc/socat_pulse_test.py /tmp/pulse2osc-uwe-in'
new-window -n 'test-pulse-bjoern' -t 'csession:23' 'python /home/stefan/dev/psychose/sensors2osc/sensors2osc/socat_pulse_test.py /tmp/pulse2osc-bjoern-in'
new-window -n 'test-ehealth-bjoern' -t 'csession:26' 'python /home/stefan/dev/psychose/sensors2osc/sensors2osc/socat_ehealth_test.py /tmp/ehealth2osc-bjoern-in'
new-window -n 'test-ehealth-merle' -t 'csession:27' 'python /home/stefan/dev/psychose/sensors2osc/sensors2osc/socat_ehealth_test.py /tmp/ehealth2osc-merle-in'
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 'test-ehealth-bjoern' -t 'csession:26' 'python /home/stefan/dev/psychose/sensors2osc/sensors2osc/socat_ehealth_test.py /tmp/ehealth2osc-bjoern-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'
select-window -t 'csession:2'
set aggressive-resize on

View File

@ -19,63 +19,114 @@
#
# Copyright (C) 2014 Stefan Kögl
from __future__ import absolute_import
import os
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from chaosc.argparser_groups import *
from chaosc.lib import logger, resolve_host
from collections import deque
from datetime import datetime
from dump_grabber.dump_grabber_ui import Ui_MainWindow
from os import curdir, sep
from PyKDE4.kdecore import ki18n, KCmdLineArgs, KAboutData
from PyKDE4.kdeui import KMainWindow, KApplication
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import QBuffer, QByteArray, QIODevice
from SocketServer import ThreadingMixIn, ForkingMixIn
import logging
import numpy as np
import os
import os.path
import Queue
import random
import re
import select
import socket
import string
import sys
import threading
import time
import traceback
from datetime import datetime
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from chaosc.argparser_groups import *
from chaosc.lib import logger, resolve_host
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import QBuffer, QByteArray, QIODevice
from dump_grabber.dump_grabber_ui import Ui_MainWindow
try:
from chaosc.c_osc_lib import OSCMessage, decode_osc
except ImportError as e:
from chaosc.osc_lib import OSCMessage, decode_osc
app = QtGui.QApplication([])
class TextStorage(object):
def __init__(self, columns):
super(TextStorage, self).__init__()
self.column_count = columns
self.colors = (QtCore.Qt.red, QtCore.Qt.green, QtGui.QColor(46, 100, 254))
def init_columns(self):
raise NotImplementedError()
def add_text(self, column, text):
raise NotImplementedError()
appName = "dump_grabber"
catalog = "dump_grabber"
programName = ki18n("dump_grabber")
version = "0.1"
class ColumnTextStorage(TextStorage):
def __init__(self, columns, default_font, column_width, line_height, scene):
super(ColumnTextStorage, self).__init__(columns)
self.columns = list()
self.default_font = default_font
self.column_width = column_width
self.line_height = line_height
self.graphics_scene = scene
self.num_lines, self.offset = divmod(775, self.line_height)
aboutData = KAboutData(appName, catalog, programName, version)
def init_columns(self):
for x in range(self.column_count):
column = list()
color = self.colors[x]
for y in range(self.num_lines):
text_item = self.graphics_scene.addSimpleText("%d:%d" % (x, y), self.default_font)
text_item.setBrush(color)
text_item.setPos(x * self.column_width, y * self.line_height)
column.append(text_item)
self.columns.append(column)
KCmdLineArgs.init (sys.argv, aboutData)
def add_text(self, column, text):
text_item = self.graphics_scene.addSimpleText(text, self.default_font)
color = self.colors[column]
text_item.setBrush(color)
app = KApplication()
old_item = self.columns[column].pop(0)
self.graphics_scene.removeItem(old_item)
self.columns[column].append(text_item)
for iy, text_item in enumerate(self.columns[column]):
text_item.setPos(column * self.column_width, iy * self.line_height)
fh = logging.FileHandler(os.path.expanduser("~/.chaosc/dump_grabber.log"))
fh.setLevel(logging.DEBUG)
logger.addHandler(fh)
class MainWindow(KMainWindow, Ui_MainWindow):
def __init__(self, parent=None, columns=3):
class ExclusiveTextStorage(TextStorage):
def __init__(self, columns, default_font, column_width, line_height, scene):
super(ExclusiveTextStorage, self).__init__(columns)
self.column_count = columns
self.lines = list()
self.default_font = default_font
self.column_width = column_width
self.line_height = line_height
self.graphics_scene = scene
self.num_lines, self.offset = divmod(775, self.line_height)
def init_columns(self):
color = self.colors[0]
for y in range(self.num_lines):
text_item = self.graphics_scene.addSimpleText("", self.default_font)
text_item.setBrush(color)
text_item.setPos(0, y * self.line_height)
self.lines.append(text_item)
def add_text(self, column, text):
text_item = self.graphics_scene.addSimpleText(text, self.default_font)
text_item.setX(column * self.column_width)
color = self.colors[column]
text_item.setBrush(color)
old_item = self.lines.pop(0)
self.graphics_scene.removeItem(old_item)
self.lines.append(text_item)
for iy, text_item in enumerate(self.lines):
text_item.setY(iy * self.line_height)
class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None, columns=3, column_exclusive=False):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.graphics_view.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
@ -88,55 +139,27 @@ class MainWindow(KMainWindow, Ui_MainWindow):
self.default_font = QtGui.QFont("Monospace", 14)
self.default_font.setStyleHint(QtGui.QFont.Monospace)
self.default_font.setBold(True)
self.blue_color = QtGui.QColor(47,147,235)
self.graphics_scene.setFont(self.default_font)
self.font_metrics = QtGui.QFontMetrics(self.default_font)
self.line_height = self.font_metrics.height()
self.num_lines = 775/self.line_height
self.graphics_scene.setFont(self.default_font)
self.brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
self.brush.setStyle(QtCore.Qt.SolidPattern)
self.column_width = 775 / columns
self.column_count = columns
self.columns = list()
for i in range(columns):
column = list()
for j in range(self.num_lines):
text_item = self.graphics_scene.addSimpleText("", self.default_font)
if column == 0:
text_item.setBrush(QtCore.Qt.red)
elif column == 1:
text_item.setBrush(QtCore.Qt.green)
elif column == 2:
text_item.setBrush(self.blue_color)
text_item.setPos(j * self.line_height, i * self.column_width)
column.append(text_item)
self.columns.append(column)
self.graphics_view.show()
self.text_storage = ExclusiveTextStorage(columns, self.default_font, self.column_width, self.line_height, self.graphics_scene)
#self.text_storage = ColumnTextStorage(columns, self.default_font, self.column_width, self.line_height, self.graphics_scene)
self.text_storage.init_columns()
def add_text(self, column, text):
text_item = self.graphics_scene.addSimpleText(text, self.default_font)
if column == 0:
text_item.setBrush(QtCore.Qt.red)
elif column == 1:
text_item.setBrush(QtCore.Qt.green)
elif column == 2:
text_item.setBrush(self.blue_color)
old_item = self.columns[column].pop(0)
self.graphics_scene.removeItem(old_item)
self.columns[column].append(text_item)
for ix, text_item in enumerate(self.columns[column]):
text_item.setPos(column * self.column_width, ix * self.line_height)
self.text_storage.add_text(column, text)
def render(self):
image = QtGui.QImage(768, 576, QtGui.QImage.Format_ARGB32)
image = QtGui.QImage(768, 576, QtGui.QImage.Format_ARGB32_Premultiplied)
image.fill(QtCore.Qt.black)
painter = QtGui.QPainter(image)
#painter.setPen(QtCore.Qt.white)
painter.setRenderHints(QtGui.QPainter.RenderHint(QtGui.QPainter.Antialiasing | QtGui.QPainter.TextAntialiasing), True)
painter.setFont(self.default_font)
self.graphics_view.render(painter, target=QtCore.QRectF(0,0,768,576),source=QtCore.QRect(0,0,768,576))
painter.end()
return image
@ -159,17 +182,6 @@ class OSCThread(threading.Thread):
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
"""
logger.info("%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.client_address[0], "s")
@ -224,7 +236,6 @@ class MyHandler(BaseHTTPRequestHandler):
if self.path=="" or self.path==None or self.path[:1]==".":
self.send_error(403,'Forbidden')
if self.path.endswith(".html"):
directory = os.path.dirname(os.path.abspath(__file__))
data = open(os.path.join(directory, self.path), "rb").read()
@ -244,53 +255,52 @@ class MyHandler(BaseHTTPRequestHandler):
self.end_headers()
event_loop = QtCore.QEventLoop()
last_frame = time.time() - 1.
frame_rate = 16.0
frame_length = 1. / frame_rate
regex = re.compile("^/(uwe|merle|bjoern)/(.*?)$")
while 1:
event_loop.processEvents()
app.sendPostedEvents(None, 0)
while 1:
try:
osc_address, args = queue.get_nowait()
print osc_address
except Queue.Empty:
break
else:
if "merle" in osc_address:
window.add_text(0, "%s = %s" % (osc_address[7:], ", ".join([str(i) for i in args])))
elif "uwe" in osc_address:
window.add_text(1, "%s = %s" % (osc_address[5:], ", ".join([str(i) for i in args])))
elif "bjoern" in osc_address:
window.add_text(2, "%s = %s" % (osc_address[8:], ", ".join([str(i) for i in args])))
try:
actor, text = regex.match(osc_address).groups()
if actor == "merle":
window.add_text(0, "%s = %s" % (text, ", ".join([str(i) for i in args])))
if actor == "uwe":
window.add_text(1, "%s = %s" % (text, ", ".join([str(i) for i in args])))
if actor == "bjoern":
window.add_text(2, "%s = %s" % (text, ", ".join([str(i) for i in args])))
except AttributeError:
pass
now = time.time()
delta = now - last_frame
if delta > frame_length:
last_frame = now
img = window.render()
buffer = QBuffer()
buffer.open(QIODevice.WriteOnly)
img.save(buffer, "JPG", 50)
img.save("/tmp/test.jpg", "JPG", 50)
img.save(buffer, "JPG")
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 = None
buffer = None
img = None
time.sleep(0.06)
elif self.path.endswith(".jpeg"):
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(data)
time.sleep(0.01)
return
except (KeyboardInterrupt, SystemError):
#print "queue size", queue.qsize()
if hasattr(self, "thread") and self.thread is not None:
self.thread.running = False
self.thread.join()
self.thread = None
except IOError, e:
#print "ioerror", e, e[0]
#print dir(e)
if e[0] in (32, 104):
if hasattr(self, "thread") and self.thread is not None:
self.thread.running = False
@ -298,11 +308,6 @@ class MyHandler(BaseHTTPRequestHandler):
self.thread = None
else:
pass
#print '-'*40
#print 'Exception happened during processing of request from'
#traceback.print_exc() # XXX But this goes to stderr!
#print '-'*40
#self.send_error(404,'File Not Found: %s' % self.path)
class JustAHTTPServer(HTTPServer):

View File

@ -24,61 +24,96 @@
from __future__ import absolute_import
from datetime import datetime
import threading
import Queue
import traceback
import logging
import numpy as np
import string
import time
import random
import socket
import os.path
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, QtCore
import pyqtgraph as pg
from pyqtgraph.widgets.PlotWidget import PlotWidget
from chaosc.argparser_groups import *
from chaosc.lib import logger, resolve_host
from datetime import datetime
from operator import attrgetter
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import QBuffer, QByteArray, QIODevice
from SocketServer import ThreadingMixIn, ForkingMixIn
import logging
import numpy as np
import os.path
import pyqtgraph as pg
import Queue
import re
import select
import socket
import threading
import time
fh = logging.FileHandler(os.path.expanduser("~/.chaosc/ekgplotter.log"))
fh.setLevel(logging.DEBUG)
logger.addHandler(fh)
try:
from chaosc.c_osc_lib import OSCMessage, decode_osc
except ImportError as e:
print(e)
logging.exception(e)
from chaosc.osc_lib import OSCMessage, decode_osc
class Generator(object):
def __init__(self):
self.count = 0
self.max_count = 200
self.min_puls = 75
self.max_pulse = 160
self.pulse = 83
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)
def run(self):
data_points = 0
min_puls = 70
max_pulse = 130
pulse = random.randint(min_puls, max_pulse)
steps, sleep_time = get_steps(pulse, sleep_time)
count = 0
delta = 1
result = list()
print "pulse", pulse
print "sleep_time", sleep_time
print "steps", steps
while 1:
value = random.randint(0, steps)
if count < int(steps / 100. * 20):
value = random.randint(0,20)
elif count < int(steps / 100. * 30):
value = random.randint(20, 30)
elif count < int(steps / 100. * 40):
value = random.randint(30,100)
elif count < int(steps / 2.):
value = random.randint(100,200)
elif count == int(steps / 2.):
value = 255
elif count < int(steps / 100. * 60):
value = random.randint(100, 200)
elif count < int(steps / 100. * 70):
value = random.randint(50, 100)
elif count < int(steps / 100. * 80):
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(sleep_time)
count += 1
#data_points += 1
serial_sock.write(struct.pack("B", value))
class OSCThread(threading.Thread):
def __init__(self, args):
@ -94,24 +129,13 @@ class OSCThread(threading.Thread):
self.osc_sock.bind(self.client_address)
self.osc_sock.setblocking(0)
print "%s: starting up osc receiver on '%s:%d'" % (
logger.info("%s: starting up osc receiver on '%s:%d'",
datetime.now().strftime("%x %X"), self.client_address[0], self.client_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)
logger.info("%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.client_address[0], "s")
msg.appendTypedArg(self.client_address[1], "i")
@ -125,7 +149,7 @@ 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])
logger.info("%s: unsubscribing from '%s:%d'", datetime.now().strftime("%x %X"), self.chaosc_address[0], self.chaosc_address[1])
msg = OSCMessage("/unsubscribe")
msg.appendTypedArg(self.client_address[0], "s")
msg.appendTypedArg(self.client_address[1], "i")
@ -136,9 +160,9 @@ class OSCThread(threading.Thread):
while self.running:
try:
reads, writes, errs = select.select([self.osc_sock], [], [], 0.01)
reads, writes, errs = select.select([self.osc_sock], [], [], 0.005)
except Exception, e:
print "select error", e
logging.exception(e)
pass
else:
if reads:
@ -147,107 +171,65 @@ class OSCThread(threading.Thread):
osc_address, typetags, messages = decode_osc(osc_input, 0, len(osc_input))
queue.put_nowait((osc_address, messages))
except Exception, e:
print "recvfrom error", e
else:
queue.put_nowait(("/bjoern/ekg", [0]))
queue.put_nowait(("/merle/ekg", [0]))
queue.put_nowait(("/uwe/ekg", [0]))
logger.info(e)
self.unsubscribe_me()
print "OSCThread is going down"
self.osc_sock.close()
logger.info("OSCThread is going down")
queue = Queue.Queue()
class Actor(object):
shadowPen = pg.mkPen(255, 255, 255)
brush = pg.mkBrush("w")
def __init__(self, name, num_data, color):
self.data = [0] * num_data
self.data_pointer = 0
def __init__(self, name, num_data, color, ix, max_actors, actor_height):
self.name = name
self.active = True
self.plotItem = pg.PlotCurveItem(pen=pg.mkPen(color, width=3), name=name)
self.num_data = num_data
#self.plotItem.setShadowPen(pen=Actor.shadowPen, width=3, cosmetic=True)
self.plotPoint = pg.ScatterPlotItem(pen=Actor.shadowPen, brush=self.brush, size=5)
self.color = color
self.ix = ix
self.max_actors = max_actors
self.actor_height = actor_height
self.updated = 0
self.offset = ix * actor_height
self.data = np.array([self.offset] * num_data)
self.head = 0
self.pre_head = 0
self.plotItem = pg.PlotCurveItem(pen=pg.mkPen(color, width=3), name=name)
self.plotPoint = pg.ScatterPlotItem(pen=pg.mkPen("w", width=5), brush=pg.mkBrush(color), size=5)
def __str__(self):
return "<Actor name:%r, active=%r, position=%r>" % (self.name, self.active, self.data_pointer)
return "<Actor name:%r, active=%r, position=%r>" % (self.name, self.active, self.head)
__repr__ = __str__
def scale_data(self, ix, max_items):
scale = 255 / max_items * ix
return [value / max_items + scale for value in self.data]
def set_point(self, value, ix, max_items):
scale = 255 / max_items * ix
self.plotPoint.setData(x = [self.data_pointer], y = [value / max_items + scale])
def add_value(self, value):
dp = self.head
self.data[dp] = value / self.max_actors + self.offset
self.pre_head = dp
self.head = (dp + 1) % self.num_data
self.updated += 1
#def find_max_value(self, item_data):
#max_index = -1
#for ix, i in enumerate(item_data):
#if i > 250:
#return ix, i
#return None, None
def fill_missing(self, count):
dp = self.head
for i in range(count):
self.data[dp] = self.offset
dp = (dp + 1) % self.num_data
self.updated += 1
self.pre_head = (dp - 1) % self.num_data
self.head = dp
#def rearrange(self, 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 render(self):
self.plotItem.setData(y=self.data, clear=True)
self.plotPoint.setData(x=[self.pre_head], y = [self.data[self.pre_head]])
def set_value(self, value):
self.data[self.data_pointer] = value
self.data_pointer = (self.data_pointer + 1) % self.num_data
#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
class EkgPlot(object):
def __init__(self, actor_names, num_data, colors):
self.plot = pg.PlotWidget()
#self.plot.setConfigOptions(antialias=True)
self.plot.hide()
#self.plot.show()
#self.plot.setLabel('left', "<h2>Amplitude</h2>")
#self.plot.setLabel('bottom', "<h2><sup>Time</sup></h2>")
self.plot.showGrid(False, False)
self.plot.setYRange(0, 255)
self.plot.setXRange(0, num_data)
@ -265,8 +247,11 @@ class EkgPlot(object):
self.lengths1 = [0]
self.num_data = num_data
for actor_name, color in zip(actor_names, colors):
self.add_actor(actor_name, num_data, color)
self.max_value = 255
self.max_actors = len(actor_names)
self.actor_height = self.max_value / self.max_actors
for ix, (actor_name, color) in enumerate(zip(actor_names, colors)):
self.add_actor(actor_name, num_data, color, ix, self.max_actors, self.actor_height)
self.set_positions()
@ -275,8 +260,8 @@ class EkgPlot(object):
self.updated_actors = set()
def add_actor(self, actor_name, num_data, color):
actor_obj = Actor(actor_name, num_data, color)
def add_actor(self, actor_name, num_data, color, ix, max_actors, actor_height):
actor_obj = Actor(actor_name, num_data, color, ix, max_actors, actor_height)
self.actors[actor_name] = actor_obj
self.plot.addItem(actor_obj.plotItem)
self.plot.addItem(actor_obj.plotPoint)
@ -285,61 +270,43 @@ class EkgPlot(object):
def set_positions(self):
for ix, actor_obj in enumerate(self.active_actors):
actor_obj.plotItem.setPos(0, ix * 6)
actor_obj.plotPoint.setPos(0, ix * 6)
actor_obj.plotItem.setPos(0, ix * 2)
actor_obj.plotPoint.setPos(0, ix * 2)
def active_actor_count(self):
return len(self.active_actors)
return self.max_actors
def new_round(self):
for ix, actor in enumerate(self.active_actors):
actor.updated = 0
def update_missing_actors(self):
liste = sorted(self.active_actors, key=attrgetter("updated"))
max_values = liste[-1].updated
if max_values == 0:
# handling no signal
for actor in self.active_actors:
actor.add_value(0)
return
for ix, actor in enumerate(self.active_actors):
diff = max_values - actor.updated
if diff > 0:
for i in range(diff):
actor.add_value(0)
def update(self, osc_address, value):
#print "update", osc_address
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)
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.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
actor_obj.add_value(value)
res = self.ctl_regex.match(osc_address)
if res:
print "received cmd", osc_address
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.active_actors
self.plot.addItem(actor_obj.plotItem)
self.plot.addItem(actor_obj.plotPoint)
actor_obj.active = True
if not actor_obj in self.active_actors:
self.active_actors.append(actor_obj)
elif value == 0 and actor_obj.active:
print "actor off", actor_name, self.active_actors
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:
print "active actors error", e, self.active_actors
pass
assert actor_obj not in self.active_actors
else:
print "internal data not in sync", self.active_actors, actor_obj
self.set_positions()
def render(self):
for ix, actor in enumerate(self.active_actors):
actor.render()
class MyHandler(BaseHTTPRequestHandler):
@ -351,7 +318,6 @@ class MyHandler(BaseHTTPRequestHandler):
if self.path=="" or self.path==None or self.path[:1]==".":
self.send_error(403,'Forbidden')
if self.path.endswith(".html"):
directory = os.path.dirname(os.path.abspath(__file__))
data = open(os.path.join(directory, self.path), "rb").read()
@ -363,83 +329,61 @@ class MyHandler(BaseHTTPRequestHandler):
self.thread = thread = OSCThread(self.server.args)
thread.daemon = True
thread.start()
actor_names = ["merle", "bjoern", "uwe"]
actor_names = ["merle", "uwe", "bjoern" ]
num_data = 100
colors = ["r", "g", "b"]
qtapp = QtGui.QApplication([])
plotter = EkgPlot(actor_names, num_data, colors)
self.send_response(200)
self.send_header("Content-Type", "multipart/x-mixed-replace; boundary=--aaboundary")
self.send_header("Content-Type", "multipart/x-mixed-replace; boundary=--2342")
self.end_headers()
#lastTime = time.time()
#fps = None
event_loop = QtCore.QEventLoop()
last_frame = time.time() - 1.0
frame_rate = 13.0
frame_length = 1. / frame_rate
plotter.new_round()
while 1:
event_loop.processEvents()
qtapp.sendPostedEvents(None, 0)
while 1:
try:
osc_address, args = queue.get_nowait()
plotter.update(osc_address, args[0])
except Queue.Empty:
break
else:
plotter.update(osc_address, args[0])
now = time.time()
delta = now - last_frame
if delta > frame_length:
plotter.update_missing_actors()
plotter.render()
exporter = pg.exporters.ImageExporter.ImageExporter(plotter.plot.plotItem)
exporter.parameters()['width'] = 768
img = exporter.export("tmpfile", True)
img = exporter.export(toBytes=True)
buffer = QBuffer()
buffer.open(QIODevice.WriteOnly)
img.save(buffer, "JPG")
img.save("/tmp/test2.jpg", "JPG")
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))
self.wfile.write("--2342\r\nContent-Type: image/jpeg\r\nContent-length: %d\r\n\r\n%s\r\n\r\n\r\n" % (len(JpegData), JpegData))
last_frame = now
plotter.new_round()
#JpegData = None
#buffer = None
#img = None
#exporter = None
time.sleep(0.01)
JpegData = None
buffer = None
img = None
exporter = None
#now = time.time()
#dt = now - lastTime
#lastTime = now
#if fps is None:
#fps = 1.0/dt
#else:
#s = np.clip(dt*3., 0, 1)
#fps = fps * (1-s) + (1.0/dt) * s
#print '%0.2f fps' % fps
time.sleep(0.05)
elif self.path.endswith(".jpeg"):
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(data)
return
except (KeyboardInterrupt, SystemError):
print "queue size", queue.qsize()
if hasattr(self, "thread") and self.thread is not None:
self.thread.running = False
self.thread.join()
self.thread = None
except (KeyboardInterrupt, SystemError), e:
raise e
except IOError, e:
print "ioerror", e, e[0]
print dir(e)
if e[0] in (32, 104):
if hasattr(self, "thread") and self.thread is not None:
self.thread.running = False
self.thread.join()
self.thread = None
else:
print '-'*40
print 'Exception happened during processing of request from'
traceback.print_exc() # XXX But this goes to stderr!
print '-'*40
self.send_error(404,'File Not Found: %s' % self.path)
pass
class JustAHTTPServer(HTTPServer):
@ -463,18 +407,15 @@ def main():
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'" % (
logger.info("%s: starting up http server on '%s:%d'",
datetime.now().strftime("%x %X"), http_host, http_port)
try:
server.serve_forever()
except KeyboardInterrupt:
print '^C received, shutting down server'
logger.info('^C received, shutting down server')
server.socket.close()
sys.exit(0)
if __name__ == '__main__':
main()

View File

@ -25,6 +25,7 @@ import os.path
import serial
import socket
import time
import sys
from chaosc.argparser_groups import ArgParser
@ -39,6 +40,7 @@ except ImportError as e:
class Platform(object):
def __init__(self, args):
self.args = args
self.remote = (self.args.chaosc_host, self.args.chaosc_port)
self.serial_sock = None
self.osc_sock = socket.socket(args.address_family, 2, 17)
self.osc_sock.connect((self.args.chaosc_host, self.args.chaosc_port))
@ -78,10 +80,10 @@ def create_args(name):
arg_parser = ArgParser(name)
arg_parser.add_global_group()
main_group = arg_parser.add_argument_group("main")
arg_parser.add_argument(main_group, "-D", '--device', required=True,
type=str, help='device node under /dev')
arg_parser.add_argument(main_group, "-a", '--actor', required=True,
type=str, help='actor name')
arg_parser.add_argument(main_group, "-D", '--device',
help='device node under /dev')
arg_parser.add_argument(main_group, "-a", '--actor',
help='actor name')
arg_parser.add_argument(main_group, '-b', '--baudrate', type=int, default=115200, choices=sorted(serial.baudrate_constants.keys()),
help='selects the baudrate, default=115200, for valid values execute "import serial;print sorted(serial.baudrate_constants.keys())"')
arg_parser.add_chaosc_group()
@ -90,8 +92,8 @@ def create_args(name):
return args
def init(name):
args = create_args(name)
def init():
args = create_args(os.path.basename(sys.argv[0]))
platform = Platform(args)
platform.connect()
atexit.register(platform.close)

View File

@ -21,11 +21,11 @@
from __future__ import absolute_import
from sensors2osc.common import *
import time, select
import time, select, sys
def main():
platform = init("ehealth2osc")
platform = init()
actor = platform.args.actor
@ -42,7 +42,7 @@ def main():
print "serial socket error!!!", msg
platform.reconnect()
print "got data", repr(data)
print "data", repr(data)
try:
airFlow, emg, temp = data.split(";")
except ValueError, e:
@ -58,7 +58,7 @@ def main():
try:
osc_message = OSCMessage("/%s/airFlow" % actor)
osc_message.appendTypedArg(airFlow, "i")
platform.osc_sock.sendall(osc_message.encode_osc())
platform.osc_sock.sendto(osc_message.encode_osc(), platform.remote)
except socket.error, msg:
print "cannot connect to chaosc", msg
continue
@ -73,7 +73,7 @@ def main():
try:
osc_message = OSCMessage("/%s/emg" % actor)
osc_message.appendTypedArg(emg, "i")
platform.osc_sock.sendall(osc_message.encode_osc())
platform.osc_sock.sendto(osc_message.encode_osc(), platform.remote)
except socket.error, msg:
print "cannot connect to chaosc", msg
continue
@ -88,7 +88,7 @@ def main():
try:
osc_message = OSCMessage("/%s/temperatur" % actor)
osc_message.appendTypedArg(temp, "i")
platform.osc_sock.sendall(osc_message.encode_osc())
platform.osc_sock.sendto(osc_message.encode_osc(), platform.remote)
except socket.error, msg:
print "cannot connect to chaosc", msg
continue

View File

@ -20,27 +20,30 @@
from __future__ import absolute_import
import time, select
import time, select, sys
from sensors2osc.common import *
from chaosc.lib import logger
def main():
platform = init("ekg2osc")
platform = init()
actor = platform.args.actor
msg_count = 0
while 1:
try:
toread, towrite, toerrors = select.select([platform.serial_sock], [],[], 0.05)
toread, towrite, toerrors = select.select([platform.serial_sock], [],[], 0.01)
if toread:
t = platform.serial_sock.read(1)
else:
continue
except (socket.error, serial.serialutil.SerialException), msg:
# got disconnected?
print "serial socket error!!!", msg
logger.exception(msg)
logger.info("serial socket error!!! - try to reconnect")
platform.reconnect()
try:
@ -48,17 +51,21 @@ def main():
except TypeError, e:
continue
if msg_count >= 20:
logger.info("value = %d", t)
msg_count = 0
else:
msg_count += 1
try:
print "got value", t
osc_message = OSCMessage("/%s/ekg" % actor)
osc_message.appendTypedArg(t, "i")
platform.osc_sock.sendall(osc_message.encode_osc())
platform.osc_sock.sendto(osc_message.encode_osc(), platform.remote)
except socket.error, msg:
print "cannot connect to chaosc"
logger.info("ekg2osc error")
logger.exception(msg)
continue
if __name__ == '__main__':
main()

View File

@ -20,7 +20,7 @@
from __future__ import absolute_import
import time, select
import time, select, sys
from datetime import datetime
from sensors2osc.common import *
@ -61,7 +61,7 @@ class RingBuffer(object):
def main():
platform = init("pulse2osc")
platform = init()
actor = platform.args.actor
@ -102,7 +102,7 @@ def main():
osc_message.appendTypedArg(1, "i")
osc_message.appendTypedArg(heart_rate, "i")
osc_message.appendTypedArg(o2, "i")
platform.osc_sock.sendall(osc_message.encode_osc())
platform.osc_sock.sendto(osc_message.encode_osc(), platform.remote)
print "on heartbeat", datetime.now(), heart_signal, heart_rate, o2, pulse
except socket.error, msg:
print "cannot connect to chaosc"
@ -115,7 +115,7 @@ def main():
osc_message.appendTypedArg(0, "i")
osc_message.appendTypedArg(heart_rate, "i")
osc_message.appendTypedArg(o2, "i")
platform.osc_sock.sendall(osc_message.encode_osc())
platform.osc_sock.sendto(osc_message.encode_osc(), platform.remote)
except socket.error, msg:
print "cannot connect to chaosc"
continue

View File

@ -23,6 +23,14 @@
import serial, sys, time, random, struct
def get_steps(pulse_rate, rate):
beat_length = 60. / pulse_rate
steps_pre = int(beat_length / rate) + 1
used_sleep_time = beat_length / steps_pre
steps = int(beat_length / used_sleep_time)
return steps, used_sleep_time
serial_sock = serial.Serial()
serial_sock.port = sys.argv[1]
serial_sock.baudrate = 115200
@ -31,40 +39,57 @@ serial_sock.open()
data_points = 0
min_steps = 17
max_steps = 43
steps = random.randint(17,43)
sleep_time = 0.04
min_puls = 70
max_pulse = 130
pulse = random.randint(min_puls, max_pulse)
steps, sleep_time = get_steps(pulse, sleep_time)
count = 0
delta = 1
result = list()
print "pulse", pulse
print "sleep_time", sleep_time
print "steps", steps
while 1:
value = random.randint(0, steps)
if count < int(steps / 100. * 20):
value = random.randint(0,20)
elif count < int(steps / 100. * 30):
value = random.randint(20, 30)
elif count < int(steps / 100. * 40):
value = random.randint(30,100)
elif count < int(steps / 2.):
value = random.randint(20,50)
value = random.randint(100,200)
elif count == int(steps / 2.):
value = 255
elif count < int(steps / 100. * 60):
value = random.randint(100, 200)
elif count < int(steps / 100. * 70):
value = random.randint(50, 100)
elif count < int(steps / 100. * 80):
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 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
#if steps <= min_steps:
#delta = 1
#elif steps >= max_steps:
#print "change step sign", steps, delta
#delta = -1
time.sleep(0.02)
time.sleep(sleep_time)
count += 1
data_points += 1
#data_points += 1
serial_sock.write(struct.pack("B", value))

View File

@ -31,11 +31,18 @@ setup(
# predefined extension points, e.g. for plugins
entry_points = """
[console_scripts]
sensors2osc = sensors2osc.main:main
sensorTest = sensors2osc.sensorTest:main
ekg2osc = sensors2osc.ekg2osc:main
ekgmerle = sensors2osc.ekg2osc:main
ekguwe = sensors2osc.ekg2osc:main
ekgbjoern = sensors2osc.ekg2osc:main
pulse2osc = sensors2osc.pulse2osc:main
pulsemerle = sensors2osc.pulse2osc:main
pulseuwe = sensors2osc.pulse2osc:main
pulsebjoern = sensors2osc.pulse2osc:main
ehealth2osc = sensors2osc.ehealth2osc:main
ehealthmerle = sensors2osc.ehealth2osc:main
ehealthuwe = sensors2osc.ehealth2osc:main
ehealthbjoern = sensors2osc.ehealth2osc:main
""",
# pypi metadata
author = "Stefan Kögl",

View File

@ -1,2 +1,2 @@
pyuic4 -o texter_ui.py texter3.ui
# pykdeuic4-python2.7 -o text_sorter_ui.py texter4.ui
pyuic4 -o text_sorter_ui.py texter4.ui

View File

@ -71,6 +71,10 @@ class TextSorterDialog(QtGui.QWidget, Ui_TextSorterDialog):
def fill_list(self):
self.model = self.parent().parent().model
self.text_list.setModel(self.model)
ix = self.parent().parent().current_index
index = self.model.index(ix, 0)
self.text_list.setCurrentIndex(index)
def slot_text_up(self):
row = self.text_list.currentIndex().row()
@ -81,6 +85,7 @@ class TextSorterDialog(QtGui.QWidget, Ui_TextSorterDialog):
text_db[row-1], text_db[row] = text_db[row], text_db[row-1]
self.text_list.setCurrentIndex(self.model.index(row - 1, 0))
self.text_list.clicked.emit(self.model.index(row - 1, 0))
self.parent().parent().db_dirty = True
return True
def slot_text_down(self):
@ -93,6 +98,7 @@ class TextSorterDialog(QtGui.QWidget, Ui_TextSorterDialog):
index = self.model.index(row + 1, 0)
self.text_list.setCurrentIndex(index)
self.text_list.clicked.emit(index)
self.parent().parent().db_dirty = True
return True
def slot_show_text(self, model_index):
@ -108,6 +114,7 @@ class TextSorterDialog(QtGui.QWidget, Ui_TextSorterDialog):
index = self.model.index(0, 0)
self.text_list.setCurrentIndex(index)
self.text_list.clicked.emit(index)
self.parent().parent().db_dirty = True
class FadeAnimation(QtCore.QObject):
animation_started = QtCore.pyqtSignal()
@ -166,7 +173,6 @@ class FadeAnimation(QtCore.QObject):
print "animation_finished"
class TextAnimation(QtCore.QObject):
animation_started = QtCore.pyqtSignal()
animation_finished = QtCore.pyqtSignal()
@ -245,6 +251,7 @@ class TextAnimation(QtCore.QObject):
try:
char = self.text.next()
self.dst_cursor.insertText(char)
self.dst_text_edit.ensureCursorVisible()
except StopIteration:
self.fragment_iter += 1
self.text = None
@ -287,6 +294,9 @@ class MainWindow(KMainWindow, Ui_MainWindow):
self.db_dirty = False
self.is_animate = False
self.fade_animation = None
self.dialog = None
self.current_object = None
self.current_index = -1
self.is_auto_publish = False
@ -321,7 +331,6 @@ class MainWindow(KMainWindow, Ui_MainWindow):
self.publish_action.triggered.connect(self.slot_publish)
self.clear_live_action.triggered.connect(self.slot_clear_live)
self.clear_preview_action.triggered.connect(self.slot_clear_preview)
#self.remove_item_button.triggered.connect(self.slot_removeItem)
self.text_combo.triggered[int].connect(self.slot_load_preview_text)
app.focusChanged.connect(self.focusChanged)
@ -334,7 +343,7 @@ class MainWindow(KMainWindow, Ui_MainWindow):
self.preview_size_action.triggered[QtGui.QAction].connect(self.slot_preview_font_size)
self.live_size_action.triggered[QtGui.QAction].connect(self.slot_live_font_size)
self.fade_action.triggered.connect(self.slot_fade)
#self.fade_action.triggered.connect(self.slot_fade)
self.next_action.triggered.connect(self.slot_next_item)
self.previous_action.triggered.connect(self.slot_previous_item)
@ -365,6 +374,7 @@ class MainWindow(KMainWindow, Ui_MainWindow):
"format_font_family",
#"format_font_size",
"format_text_background_color",
"format_list_style",
"format_list_indent_more",
"format_list_indent_less",
"format_text_bold",
@ -372,7 +382,7 @@ class MainWindow(KMainWindow, Ui_MainWindow):
"format_text_strikeout",
"format_text_italic",
"format_align_right",
"format_align_justify",
#"format_align_justify",
"manage_link",
"format_text_subscript",
"format_text_superscript",
@ -381,6 +391,7 @@ class MainWindow(KMainWindow, Ui_MainWindow):
for action in self.live_editor_collection.actions():
text = str(action.objectName())
print "text", text
if text in disabled_action_names:
action.setVisible(False)
@ -495,11 +506,11 @@ class MainWindow(KMainWindow, Ui_MainWindow):
spacer = KToolBarSpacerAction(self.action_collection)
self.action_collection.addAction("1_spacer", spacer)
self.fade_action = self.action_collection.addAction("fade_action")
#icon = QtGui.QIcon.fromTheme(_fromUtf8("go-previous-view-page"))
#self.fade_action.setIcon(icon)
self.fade_action.setIconText("fade")
self.fade_action.setShortcut(KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_F)), KAction.ShortcutTypes(KAction.ActiveShortcut | KAction.DefaultShortcut))
#self.fade_action = self.action_collection.addAction("fade_action")
##icon = QtGui.QIcon.fromTheme(_fromUtf8("go-previous-view-page"))
##self.fade_action.setIcon(icon)
#self.fade_action.setIconText("fade")
#self.fade_action.setShortcut(KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_F)), KAction.ShortcutTypes(KAction.ActiveShortcut | KAction.DefaultShortcut))
self.previous_action = self.action_collection.addAction("previous_action")
icon = QtGui.QIcon.fromTheme(_fromUtf8("go-previous-view-page"))
@ -548,7 +559,7 @@ class MainWindow(KMainWindow, Ui_MainWindow):
public_rect = self.live_text.geometry()
global_rect = QtCore.QRect(self.mapToGlobal(public_rect.topLeft()), self.mapToGlobal(public_rect.bottomRight()))
self.ffserver = subprocess.Popen("ffserver -f /etc/ffserver.conf", shell=True, close_fds=True)
self.ffmpeg = subprocess.Popen("ffmpeg -f x11grab -s 768x576 -r 30 -i :0.0+%d,%d -vcodec mjpeg -pix_fmt yuvj444p -r 30 -aspect 4:3 http://localhost:8090/webcam.ffm" % (global_rect.x()+5, global_rect.y()+5), shell=True, close_fds=True)
self.ffmpeg = subprocess.Popen("ffmpeg -f x11grab -show_region 1 -s 768x576 -r 30 -i :0.0+%d,%d -vcodec mjpeg -pix_fmt yuvj444p -r 30 -aspect 4:3 http://localhost:8090/webcam.ffm" % (global_rect.x()+3, global_rect.y()+3), shell=True, close_fds=True)
self.is_streaming = True
def focusChanged(self, old, new):
@ -602,13 +613,6 @@ class MainWindow(KMainWindow, Ui_MainWindow):
pass
def slot_toggleToolbox(self, index):
if index == 0:
self.toolBar.setEnabled(True)
else:
self.toolBar.setEnabled(False)
def slot_publish(self):
if self.is_animate:
self.animation.start_animation(self.preview_text, self.live_text, 0)
@ -645,7 +649,6 @@ class MainWindow(KMainWindow, Ui_MainWindow):
self.preview_size_action.setFontSize(self.default_size)
self.preview_text.document().setDefaultFont(self.font)
def slot_set_live_defaults(self):
self.live_center_action.setChecked(True)
self.live_text.alignCenter()
@ -653,12 +656,10 @@ class MainWindow(KMainWindow, Ui_MainWindow):
self.live_size_action.setFontSize(self.default_size)
self.live_text.document().setDefaultFont(self.font)
def slot_clear_live(self):
self.live_text.clear()
self.slot_set_live_defaults()
def slot_clear_preview(self):
self.preview_text.clear()
self.slot_set_preview_defaults()
@ -668,27 +669,22 @@ class MainWindow(KMainWindow, Ui_MainWindow):
self.fade_animation.start_animation()
def fill_combo_box(self):
if self.dialog is not None:
self.dialog.deleteLater()
self.dialog = None
self.text_combo.clear()
for preview, text in self.model.text_db:
current_row = -1
for ix, list_obj in enumerate(self.model.text_db):
preview, text = list_obj
self.text_combo.addAction(preview)
if list_obj == self.current_object:
current_row = ix
self.text_combo.setCurrentItem(0)
self.slot_load_preview_text(0)
def slot_removeItem(self):
text = self.edit_item_selection.currentText()
index = self.edit_item_selection.currentIndex()
title = text.split(": ")[1]
del self.items[title]
self.edit_item_selection.removeItem(index)
new_index = self.edit_item_selection.currentIndex()
if new_index != -1:
self.slot_editLoadItem()
else:
self.item_title.clear()
self.item_position_input.setValue(0)
if current_row == -1:
current_row = self.current_index
self.slot_load_preview_text(current_row)
self.text_combo.setCurrentItem(current_row)
def slot_load_preview_text(self, index):
try:
@ -699,7 +695,6 @@ class MainWindow(KMainWindow, Ui_MainWindow):
if self.is_auto_publish:
self.slot_publish()
def slot_save_live_text(self):
text = self.live_text.toHtml()
preview = self.get_preview_text(unicode(self.live_text.toPlainText()))
@ -754,6 +749,12 @@ class MainWindow(KMainWindow, Ui_MainWindow):
def slot_open_dialog(self):
self.current_index = self.text_combo.currentItem()
self.current_object = self.model.text_db[self.current_index]
if self.dialog is not None:
self.dialog.deleteLater()
self.dialog = None
self.dialog = KDialog(self)
self.dialog_widget = TextSorterDialog(self.dialog)
self.dialog.setMainWidget(self.dialog_widget)
@ -766,8 +767,6 @@ class MainWindow(KMainWindow, Ui_MainWindow):
#self.dialog.setFixedSize(x, global_height-40)
self.dialog.okClicked.connect(self.fill_combo_box)
self.dialog.exec_()
self.dialog.deleteLater()
self.dialog = None
def slot_load(self):
path = os.path.expanduser("~/.texter")

View File

@ -19,6 +19,8 @@ class TextModel(QtCore.QAbstractTableModel):
return 2
def data(self, index, role):
if role not in (1,3,4,5,6,7,8,9,10,13):
print "role", role
if not index.isValid() or \
not 0 <= index.row() < self.rowCount():
return QVariant()
@ -28,6 +30,10 @@ class TextModel(QtCore.QAbstractTableModel):
if role == QtCore.Qt.DisplayRole:
return self.text_db[row][column]
#return "foo bar"
elif role == QtCore.Qt.ForegroundRole:
return QtGui.QBrush(QtCore.Qt.black)
elif role == QtCore.Qt.BackgroundRole:
return QtGui.QBrush(QtCore.Qt.white)
return QtCore.QVariant()
@ -43,7 +49,11 @@ class TextModel(QtCore.QAbstractTableModel):
def setData(self, index, value, role):
if role == QtCore.Qt.EditRole:
self.text_db[index.row()][index.column()] = value.toString()
text = value.toString()
if not text:
return False
else:
self.text_db[index.row()][index.column()] = text
return True

View File

@ -1,11 +1,12 @@
#!/usr/bin/env python
# coding=UTF-8
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'texter4.ui'
#
# Generated by pykdeuic4 from texter4.ui on Mon Apr 21 01:34:50 2014
# Created: Mon Apr 28 21:58:51 2014
# by: PyQt4 UI code generator 4.10.3
#
# WARNING! All changes to this file will be lost.
from PyKDE4 import kdecore
from PyKDE4 import kdeui
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
@ -39,44 +40,6 @@ class Ui_TextSorterDialog(object):
self.text_list.setSizePolicy(sizePolicy)
self.text_list.setMinimumSize(QtCore.QSize(200, 576))
self.text_list.setMaximumSize(QtCore.QSize(16777215, 576))
palette = QtGui.QPalette()
brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.WindowText, brush)
brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Text, brush)
brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Window, brush)
brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.WindowText, brush)
brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Text, brush)
brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Window, brush)
brush = QtGui.QBrush(QtGui.QColor(128, 125, 123))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.WindowText, brush)
brush = QtGui.QBrush(QtGui.QColor(128, 125, 123))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Text, brush)
brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Window, brush)
self.text_list.setPalette(palette)
self.text_list.setObjectName(_fromUtf8("text_list"))
self.text_preview = KRichTextWidget(self.splitter)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
@ -250,7 +213,7 @@ class Ui_TextSorterDialog(object):
QtCore.QMetaObject.connectSlotsByName(TextSorterDialog)
def retranslateUi(self, TextSorterDialog):
TextSorterDialog.setWindowTitle(kdecore.i18n(_fromUtf8("Form")))
self.remove_button.setText(kdecore.i18n(_fromUtf8("Remove")))
TextSorterDialog.setWindowTitle(_translate("TextSorterDialog", "Form", None))
self.remove_button.setText(_translate("TextSorterDialog", "Remove", None))
from PyKDE4.kdeui import KButtonGroup, KArrowButton, KPushButton, KRichTextWidget

View File

@ -90,13 +90,13 @@
<property name="minimumSize">
<size>
<width>775</width>
<height>578</height>
<height>582</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>775</width>
<height>578</height>
<height>582</height>
</size>
</property>
<property name="palette">
@ -233,7 +233,7 @@
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextEditable|Qt::TextEditorInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
<property name="richTextSupport">
<set>KRichTextWidget::SupportAlignment|KRichTextWidget::SupportChangeListStyle|KRichTextWidget::SupportFontFamily|KRichTextWidget::SupportFontSize|KRichTextWidget::SupportIndentLists|KRichTextWidget::SupportTextForegroundColor</set>
<set>KRichTextWidget::SupportAlignment|KRichTextWidget::SupportFontFamily|KRichTextWidget::SupportFontSize|KRichTextWidget::SupportTextForegroundColor</set>
</property>
</widget>
</item>
@ -248,13 +248,13 @@
<property name="minimumSize">
<size>
<width>300</width>
<height>577</height>
<height>582</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>769</width>
<height>577</height>
<width>775</width>
<height>582</height>
</size>
</property>
<property name="palette">

View File

@ -38,124 +38,6 @@
<height>576</height>
</size>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>128</red>
<green>125</green>
<blue>123</blue>
</color>
</brush>
</colorrole>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>128</red>
<green>125</green>
<blue>123</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
</widget>
<widget class="KRichTextWidget" name="text_preview">
<property name="sizePolicy">

View File

@ -57,8 +57,8 @@ class Ui_MainWindow(object):
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
self.live_text = KRichTextWidget(self.centralwidget)
self.live_text.setMinimumSize(QtCore.QSize(775, 578))
self.live_text.setMaximumSize(QtCore.QSize(775, 578))
self.live_text.setMinimumSize(QtCore.QSize(775, 582))
self.live_text.setMaximumSize(QtCore.QSize(775, 582))
palette = QtGui.QPalette()
brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
@ -111,8 +111,8 @@ class Ui_MainWindow(object):
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.preview_text.sizePolicy().hasHeightForWidth())
self.preview_text.setSizePolicy(sizePolicy)
self.preview_text.setMinimumSize(QtCore.QSize(300, 577))
self.preview_text.setMaximumSize(QtCore.QSize(769, 577))
self.preview_text.setMinimumSize(QtCore.QSize(300, 582))
self.preview_text.setMaximumSize(QtCore.QSize(769, 582))
palette = QtGui.QPalette()
brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
brush.setStyle(QtCore.Qt.SolidPattern)