Less code

This commit is contained in:
Andreas Völker 2018-12-30 21:23:05 +01:00
parent 352df31f8f
commit e270cc32d0

109
main.py
View File

@ -14,7 +14,6 @@ import logging
import math import math
logging.basicConfig(filename='pixelserver.log', level=config.LogLevel) logging.basicConfig(filename='pixelserver.log', level=config.LogLevel)
running = True running = True
######################################################################## ########################################################################
@ -28,6 +27,7 @@ class DataSource:
return self.data return self.data
def addListener(self, listener): def addListener(self, listener):
self.listeners.append(listener) self.listeners.append(listener)
return self
def pushData(self, data): def pushData(self, data):
self.data = data self.data = data
for listener in self.listeners: for listener in self.listeners:
@ -81,11 +81,9 @@ if config.UseGui:
class Gui(threading.Thread): class Gui(threading.Thread):
def __init__(self, datasource): def __init__(self, datasource):
super().__init__() super().__init__()
self.datasource = datasource
self.cv = threading.Condition() self.cv = threading.Condition()
self.datasource.addListener(self.cv) self.datasource = datasource.addListener(self.cv)
def run(self): def run(self):
global running
logging.info("Starting GUI") logging.info("Starting GUI")
sf = config.GuiScaleFactor sf = config.GuiScaleFactor
screen = pygame.display.set_mode((sf*config.ScreenX, sf*config.ScreenY)) screen = pygame.display.set_mode((sf*config.ScreenX, sf*config.ScreenY))
@ -101,10 +99,8 @@ if config.UseGui:
for x in range(config.ScreenX): for x in range(config.ScreenX):
for y in range(config.ScreenY): for y in range(config.ScreenY):
i = x+y*config.ScreenX i = x+y*config.ScreenX
r = (data[i*3+0]) color = (data[i*3+0], data[i*3+1], data[i*3+2])
g = (data[i*3+1]) pygame.draw.rect(screen, color, pygame.Rect(sf*x, sf*y, sf, sf))
b = (data[i*3+2])
pygame.draw.rect(screen, (r, g, b), pygame.Rect(sf*x, sf*y, sf, sf))
except: except:
raise raise
pygame.display.flip() pygame.display.flip()
@ -121,8 +117,7 @@ class SerialWriter(threading.Thread):
def __init__(self, datasource): def __init__(self, datasource):
super().__init__() super().__init__()
self.cv = threading.Condition() self.cv = threading.Condition()
self.datasource = datasource self.datasource = datasource.addListener(self.cv)
self.datasource.addListener(self.cv)
self.updateGamma = False self.updateGamma = False
def run(self): def run(self):
should_connect = True should_connect = True
@ -137,20 +132,13 @@ class SerialWriter(threading.Thread):
with self.cv: with self.cv:
self.cv.wait(timeout = 1/30) self.cv.wait(timeout = 1/30)
data = self.datasource.getData() data = self.datasource.getData()
with self.cv:
if self.updateGamma: if self.updateGamma:
buf = bytearray(b"\x00")*3*256 buf = bytearray(b"\x00")*3*256
self.updateGamma = False
r = self.r
g = self.g
b = self.b
for i in range(256): for i in range(256):
gr = int(math.pow(i/255, r)*255) apply = lambda x, g: max(0, min(255, int(math.pow(x/255, g)*255)))
gg = int(math.pow(i/255, g)*255) buf[i] = apply(i, self.r)
gb = int(math.pow(i/255, b)*255) buf[i+256] = apply(i, self.g)
buf[i] = max(0, min(255, gr)) buf[i+512] = apply(i, self.b)
buf[i+256] = max(0, min(255, gg))
buf[i+512] = max(0, min(255, gb))
ser.write(b"\x02") ser.write(b"\x02")
ser.write(buf) ser.write(buf)
self.updateGamma = False self.updateGamma = False
@ -171,9 +159,7 @@ class SerialWriter(threading.Thread):
super().join() super().join()
def setGamma(self, r, g, b): def setGamma(self, r, g, b):
with self.cv: with self.cv:
self.r = r self.r, self.g, self.b = r, g, b
self.g = g
self.b = b
self.updateGamma = True self.updateGamma = True
self.cv.notify_all() self.cv.notify_all()
@ -195,7 +181,7 @@ class App(threading.Thread):
self.logreader = LogReader(self) self.logreader = LogReader(self)
self.logreader.start() self.logreader.start()
self.datasource = DataSource(b"\x00"*config.ScreenX*config.ScreenY*3) self.datasource = DataSource(b"\x00"*config.ScreenX*config.ScreenY*3)
self.running = running self.running = True
self.listener = listener self.listener = listener
self.is_persistent = is_persistent self.is_persistent = is_persistent
def run(self): def run(self):
@ -225,8 +211,6 @@ class App(threading.Thread):
self.logreader.stop() self.logreader.stop()
def getLog(self): def getLog(self):
return self.logreader.getLog() return self.logreader.getLog()
def isPersistent(self):
return self.is_persistent
def terminateApp(self): def terminateApp(self):
logging.error("Terminate app!") logging.error("Terminate app!")
self.stop() self.stop()
@ -251,10 +235,7 @@ class AppRunner(threading.Thread):
#start persistent apps #start persistent apps
for app, i in zip(config.Apps, range(len(config.Apps))): for app, i in zip(config.Apps, range(len(config.Apps))):
if app["persistent"]: if app["persistent"]:
newapp = App(app["cmd"], "", self.cv, is_persistent=True) self.startApp(i)
newapp.datasource.addListener(self.cv)
newapp.start()
self.persistent_apps[i] = newapp
if config.UseGui: if config.UseGui:
self.gui = Gui(self.datasource) self.gui = Gui(self.datasource)
self.gui.start() self.gui.start()
@ -264,22 +245,22 @@ class AppRunner(threading.Thread):
self.param = param self.param = param
self.cv.notify_all() self.cv.notify_all()
logging.info("Requesting app: "+str(app)) logging.info("Requesting app: "+str(app))
def startApp(self, i, param=""):
app = config.Apps[i]
newapp = App(app["cmd"], param, self.cv, is_persistent=app["persistent"])
newapp.datasource.addListener(self.cv)
newapp.start()
if app["persistent"]:
self.persistent_apps[self.currentApp] = newapp
return newapp
def updateApp(self): def updateApp(self):
if self.app != None and not self.app.isPersistent(): if self.app != None and not self.app.is_persistent:
self.app.stop() self.app.stop()
self.currentApp = self.requestedApp self.currentApp = self.requestedApp
if self.currentApp in self.persistent_apps.keys(): if self.currentApp in self.persistent_apps.keys():
self.app = self.persistent_apps[self.currentApp] self.app = self.persistent_apps[self.currentApp]
else: else:
persistent = config.Apps[self.requestedApp]["persistent"] self.app = self.startApp(self.requestedApp, self.param)
logging.info("Starting app "+config.Apps[self.requestedApp]["name"])
cmd = config.Apps[self.requestedApp]["cmd"]
logging.debug(str(cmd))
self.app = App(cmd, self.param, self.cv, is_persistent=persistent)
self.app.datasource.addListener(self.cv)
self.app.start()
if persistent:
self.persistent_apps[self.currentApp] = self.app
def run(self): def run(self):
logging.info("Starting Apprunner") logging.info("Starting Apprunner")
while running: while running:
@ -289,10 +270,9 @@ class AppRunner(threading.Thread):
if self.requestedApp != None: if self.requestedApp != None:
self.updateApp() self.updateApp()
self.requestedApp = None self.requestedApp = None
self.cv.wait()
if self.app != None:
data = self.app.datasource.getData() data = self.app.datasource.getData()
self.datasource.pushData(data) self.datasource.pushData(data)
self.cv.wait()
self.serial.join() self.serial.join()
if config.UseGui: if config.UseGui:
self.gui.join() self.gui.join()
@ -322,50 +302,34 @@ def add_cors_headers():
bottle.response.headers['Access-Control-Allow-Headers'] = \ bottle.response.headers['Access-Control-Allow-Headers'] = \
'Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token' 'Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token'
def getAppIdx(name): def startApp(name, param=""):
for i in range(len(config.Apps)): for i in range(len(config.Apps)):
if config.Apps[i]["name"] == name: if config.Apps[i]["name"] == name:
return i runner.requestApp(i, param)
return -1 return "ok"
return "not_found"
@route("/apps/list") @route("/apps/list")
def apps_list(): def apps_list():
s = [] s = []
for app in config.Apps: for app in config.Apps:
s.append({ s.append({"name": app["name"],
"name": app["name"], "guiname": app["guiname"],
"guiname": app["guiname"], "persistent": app["persistent"]})
"persistent": app["persistent"],
})
return json.dumps(s) return json.dumps(s)
@route("/apps/start/<name>") @route("/apps/start/<name>")
def apps_start_param(name): def apps_start_param(name):
i = getAppIdx(name) return startApp(name)
if i >= 0:
runner.requestApp(i)
return "ok"
else:
return "not_found"
@post("/apps/start/<name>") @post("/apps/start/<name>")
def apps_start_post(name): def apps_start_post(name):
param = request.forms.get('param') param = request.forms.get('param')
i = getAppIdx(name) return startApp(name, param)
if i >= 0:
runner.requestApp(i, param)
return "ok"
else:
return "not_found"
@route("/apps/start/<name>/<param>") @route("/apps/start/<name>/<param>")
def apps_start(name, param): def apps_start(name, param):
i = getAppIdx(name) return startApp(name, param)
if i >= 0:
runner.requestApp(i, param)
return "ok"
else:
return "not_found"
@route("/apps/log") @route("/apps/log")
def apps_log(): def apps_log():
@ -373,8 +337,7 @@ def apps_log():
@route("/apps/running") @route("/apps/running")
def apps_running(): def apps_running():
i = runner.currentApp return config.Apps[runner.currentApp]["name"]
return config.Apps[i]["name"]
@route("/") @route("/")
def index(): def index():
@ -397,10 +360,8 @@ for app in config.Apps:
app["persistent"] = False app["persistent"] = False
if "guiname" not in app.keys(): if "guiname" not in app.keys():
app["guiname"] = app["name"] app["guiname"] = app["name"]
#remove non existing apps
for app in config.Apps:
cmd = app["cmd"] cmd = app["cmd"]
#remove non existing apps
if type(cmd) == str and not os.path.isfile(cmd): if type(cmd) == str and not os.path.isfile(cmd):
config.Apps.remove(app) config.Apps.remove(app)
logging.warning("Removed app "+app["name"]) logging.warning("Removed app "+app["name"])