added set_all_channel method

reintroduced caching of stripes & controllers
added session cleanup handling
renamed --daemon to --detach for better understanding
added coloredlogs to make logs better readable and more appealing
This commit is contained in:
Giovanni Harting
2015-10-15 13:26:36 +02:00
parent 4c052b8edb
commit 01ba0a4d2c
4 changed files with 82 additions and 28 deletions

21
ledd.py
View File

@@ -1,3 +1,5 @@
#!/usr/bin/python3
# LEDD Project
# Copyright (C) 2015 LEDD Team
#
@@ -17,16 +19,16 @@
"""LedD Daemon
Usage:
ledd.py [--daemon] [-d | --debug] [-v | --verbose]
ledd.py [--detach] [-d | --debug] [-v | --verbose]
ledd.py -h | --help
ledd.py --version
Options:
-h --help Show this screen.
--version Show version.
-d --debug Show debug output. (not recommended for daily use)
-d --debug Show debug output. (not recommended)
-v --verbose Be verbose.
--daemon Run in daemon mode.
--detach Detach after start.
"""
import logging
@@ -34,8 +36,12 @@ import sys
import os
from pkgutil import iter_modules
import coloredlogs
from docopt import docopt
import ledd.daemon
import ledd
if "smbus" not in (name for loader, name, ispkg in iter_modules()):
print("smbus not found, installing replacement")
@@ -62,9 +68,6 @@ if "smbus" not in (name for loader, name, ispkg in iter_modules()):
sys.modules['smbus'] = SMBusModule
sys.modules['smbus'].SMBus = SMBus
import ledd.daemon
import ledd
def pid_exists(processid):
if processid < 0:
@@ -89,10 +92,8 @@ if __name__ == "__main__":
if arguments['--debug']:
lvl = logging.DEBUG
logging.basicConfig(level=lvl,
format="[%(asctime)s] %(levelname)s [%(name)s.%(funcName)s:%(lineno)d] %(message)s",
datefmt="%H:%M:%S")
log = logging.getLogger(__name__)
coloredlogs.install(level=lvl)
try:
with open('ledd.pid', 'r') as f:
@@ -106,7 +107,7 @@ if __name__ == "__main__":
except FileNotFoundError:
pass
if arguments['--daemon']:
if arguments['--detach']:
wdir = os.path.dirname(os.path.realpath(__file__))
try:
pid = os.fork()

View File

@@ -76,6 +76,10 @@ class Controller(Base):
4095))
self.bus.write_word_data(self._address, LED0_ON_L + 4 * channel, 0)
def set_all_channel(self, val):
self.bus.write_word_data(self._address, ALLLED_OFF_L, int(val * 4095))
self.bus.write_word_data(self._address, ALLLED_ON_L, 0)
@staticmethod
def gamma_correct(gamma, val, maxval):
corrected = int(pow(float(val) / float(maxval), float(gamma)) * float(maxval) + 0.5)

View File

@@ -26,7 +26,6 @@ from jsonrpc import JSONRPCResponseManager, dispatcher
from jsonrpc.exceptions import JSONRPCError, JSONRPCInvalidParams
import spectra
from sqlalchemy.exc import OperationalError
from sqlalchemy.orm.exc import NoResultFound
from ledd import VERSION
@@ -42,6 +41,8 @@ daemonSection = 'daemon'
databaseSection = 'db'
""" :type : asyncio.BaseEventLoop """
effects = []
stripes = []
controller = []
def run():
@@ -66,6 +67,13 @@ def run():
log.debug(Controller.query.all())
logging.getLogger("asyncio").setLevel(log.getEffectiveLevel())
# Load to cache
global controller, stripes
controller = Controller.query.all()
for c in controller:
stripes.extend(c.stripes)
# sigterm handler
def sigterm_handler():
raise SystemExit
@@ -76,13 +84,13 @@ def run():
# TODO: check all plugins for existing hooks
# main loop
global loop
global loop, server
loop = asyncio.get_event_loop()
coro = loop.create_server(LedDProtocol,
config.get(daemonSection, 'host', fallback='0.0.0.0'),
config.get(daemonSection, 'port', fallback=1425))
global server
server = loop.run_until_complete(coro)
log.info("Start phase finished; starting main loop")
loop.run_forever()
except (KeyboardInterrupt, SystemExit):
log.info("Exiting")
@@ -90,7 +98,8 @@ def run():
os.remove("ledd.pid")
except FileNotFoundError:
pass
# TODO: close engine?
session.commit()
session.close()
if server is not None:
server.close()
if loop is not None:
@@ -109,7 +118,7 @@ def check_db():
db_version = Meta.get_version()
if db_version is not None:
log.info("DB connection established; db-version=%s", db_version)
log.info("DB connection established; db_version=%s", db_version)
return True
except OperationalError:
return False
@@ -186,16 +195,39 @@ def set_color(**kwargs):
if "sid" not in kwargs or "hsv" not in kwargs:
return JSONRPCInvalidParams()
try:
stripe = Stripe.query.filter(Stripe.id == kwargs['sid']).one()
stripe = get_stripe(kwargs['sid'])
if stripe:
stripe.set_color(spectra.hsv(kwargs['hsv']['h'], kwargs['hsv']['s'], kwargs['hsv']['v']))
except NoResultFound:
else:
log.warning("Stripe not found: id=%s", kwargs['sid'])
return JSONRPCError(-1003, "Stripeid not found")
return ""
@dispatcher.add_method
def set_color_all(**kwargs):
"""
Part of the Color API. Used to set brightness of all stripes a controller owns.
Required parameters: controller id: cid, value: v
"""
if "cid" not in kwargs or "v" not in kwargs:
return JSONRPCInvalidParams()
try:
c = get_controller(kwargs['cid'])
""" :type c: ledd.controller.Controller """
c.set_all_channel(kwargs['v'])
except NoResultFound:
log.warning("Controller not found: id=%s", kwargs['cid'])
return JSONRPCError(-1002, "Controller not found")
return ""
@dispatcher.add_method
def add_controller(**kwargs):
"""
@@ -217,6 +249,8 @@ def add_controller(**kwargs):
session.add(ncontroller)
session.commit()
controller.append(ncontroller)
return {'cid': ncontroller.id}
@@ -230,9 +264,9 @@ def get_color(**kwargs):
if "sid" not in kwargs:
return JSONRPCInvalidParams()
try:
stripe = Stripe.query.filter(Stripe.id == kwargs['sid']).one()
except NoResultFound:
stripe = get_stripe(kwargs['sid'])
if not stripe:
log.warning("Stripe not found: id=%s", kwargs['sid'])
return JSONRPCError(-1003, "Stripeid not found")
@@ -249,10 +283,11 @@ def add_stripe(**kwargs):
if "name" not in kwargs or "rgb" not in kwargs or "map" not in kwargs or "cid" not in kwargs:
return JSONRPCInvalidParams()
c = Controller.query.filter(Controller.id == int(kwargs['cid'])).first()
c = get_controller(kwargs['cid'])
""" :type c: ledd.controller.Controller """
if c is None:
log.warning("Controller not found: id=%s", kwargs['cid'])
return JSONRPCError(-1002, "Controller not found")
s = Stripe(name=kwargs['name'], rgb=bool(kwargs['rgb']),
@@ -260,7 +295,9 @@ def add_stripe(**kwargs):
s.controller = c
log.debug("Added stripe %s to controller %s; new len %s", s.id, c.id, len(c.stripes))
session.add(s)
session.commit()
stripes.append(s)
return {'sid': s.id}
@@ -273,8 +310,8 @@ def get_stripes(**kwargs):
"""
rjson = {
'ccount': len(Controller.query.all()),
'controller': Controller.query.all()
'ccount': len(controller),
'controller': controller
}
return rjson
@@ -290,11 +327,11 @@ def test_channel(**kwargs):
if "cid" not in kwargs or "channel" not in kwargs or "value" not in kwargs:
return JSONRPCInvalidParams()
result = Controller.query.filter(Controller.id == kwargs['cid']).first()
contr = get_controller(kwargs['cid'])
""" :type : ledd.controller.Controller """
if result is not None:
result.set_channel(kwargs['channel'], kwargs['value'], 2.8)
if contr is not None:
contr.set_channel(kwargs['channel'], kwargs['value'], 2.8)
else:
return JSONRPCError(-1002, "Controller not found")
@@ -311,6 +348,18 @@ def discover(**kwargs):
return {'version': VERSION}
def get_stripe(sid):
for s in stripes:
if s.id == sid:
return s
def get_controller(cid):
for c in controller:
if c.id == cid:
return c
class LedDProtocol(asyncio.Protocol):
transport = None

View File

@@ -25,6 +25,6 @@ setup(name='LedD',
license='GPLv3',
packages=['ledd'],
install_requires=[
'nose', 'spectra', 'docopt', 'jsonrpc', 'sqlalchemy',
'nose', 'spectra', 'docopt', 'jsonrpc', 'sqlalchemy', 'coloredlogs'
],
zip_safe=False)