diff --git a/ledd/__init__.py b/ledd/__init__.py index 9dd686d..fb087ff 100644 --- a/ledd/__init__.py +++ b/ledd/__init__.py @@ -13,6 +13,7 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . +from json import JSONEncoder from sqlalchemy.orm import sessionmaker, scoped_session from sqlalchemy.ext.declarative import declarative_base @@ -24,3 +25,11 @@ session = scoped_session(sessionmaker()) """ :type : sqlalchemy.orm.scoping.scoped_session """ Base = declarative_base() Base.query = session.query_property() + + +def _default(self, obj): + return getattr(obj.__class__, "to_json", _default.default)(obj) + + +_default.default = JSONEncoder().default +JSONEncoder.default = _default diff --git a/ledd/controller.py b/ledd/controller.py index a0e21b8..844363e 100644 --- a/ledd/controller.py +++ b/ledd/controller.py @@ -14,15 +14,13 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from json import JSONEncoder import logging import time from sqlalchemy import Column, Integer, String -from sqlalchemy.orm import relationship - +from sqlalchemy.orm import relationship, reconstructor import smbus -from ledd.stripe import Stripe + from . import Base PCA9685_SUBADR1 = 0x2 @@ -64,6 +62,12 @@ class Controller(Base): self.bus = smbus.SMBus(self.i2c_device) self._address = int(self.address, 16) + @reconstructor + def init_on_load(self): + self._mode = None + self.bus = smbus.SMBus(self.i2c_device) + self._address = int(self.address, 16) + def __repr__(self): return "".format(len(self.stripes), self.id) @@ -115,24 +119,14 @@ class Controller(Base): self.reset() self._pwm_freq = value - -class ControllerEncoder(JSONEncoder): - def default(self, o): - if isinstance(o, Controller): - return { - 'id': o.id, - 'pwm_freq': o.pwm_freq, - 'channel': o.channels, - 'address': o.address, - 'stripes': o.stripes, - 'cstripes': len(o.stripes), - 'i2c_device': o.i2c_device, - 'mode': o.mode - } - elif isinstance(o, Stripe): - return { - 'id': o.id, - 'name': o.name, - 'rgb': o.rgb, - 'channel': o.channels - } + def to_json(self): + return { + 'id': self.id, + 'pwm_freq': self.pwm_freq, + 'channel': self.channels, + 'address': self.address, + 'stripes': self.stripes, + 'cstripes': len(self.stripes), + 'i2c_device': self.i2c_device, + 'mode': self.mode + } diff --git a/ledd/daemon.py b/ledd/daemon.py index 456eb61..2aa8187 100644 --- a/ledd/daemon.py +++ b/ledd/daemon.py @@ -16,7 +16,6 @@ import logging import configparser -import json import os import sys import asyncio @@ -27,13 +26,14 @@ 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 from ledd.effectstack import EffectStack from ledd.models import Meta from ledd.stripe import Stripe -from ledd.controller import Controller, ControllerEncoder +from ledd.controller import Controller from . import Base, session log = logging.getLogger(__name__) @@ -191,6 +191,9 @@ def set_color(**kwargs): stripe.set_color(spectra.hsv(kwargs['hsv']['h'], kwargs['hsv']['s'], kwargs['hsv']['v'])) except NoResultFound: log.warning("Stripe not found: id=%s", kwargs['sid']) + return JSONRPCError(-1003, "Stripeid not found") + + return "" @dispatcher.add_method @@ -255,7 +258,9 @@ def add_stripe(**kwargs): s = Stripe(name=kwargs['name'], rgb=bool(kwargs['rgb']), channel_r=kwargs['map']['r'], channel_g=kwargs['map']['g'], channel_b=kwargs['map']['b']) s.controller = c - log.debug("Added stripe %s to controller %s; new len %s", c.id, s.id, len(c.stripes)) + log.debug("Added stripe %s to controller %s; new len %s", s.id, c.id, len(c.stripes)) + + session.commit() return {'sid': s.id} @@ -268,8 +273,8 @@ def get_stripes(**kwargs): """ rjson = { - 'ccount': len(Controller.query), - 'controller': json.dumps(Controller.query, cls=ControllerEncoder), + 'ccount': len(Controller.query.all()), + 'controller': Controller.query.all() } return rjson @@ -293,6 +298,8 @@ def test_channel(**kwargs): else: return JSONRPCError(-1002, "Controller not found") + return "" + @dispatcher.add_method def discover(**kwargs): diff --git a/ledd/stripe.py b/ledd/stripe.py index c42263a..8d1f98d 100644 --- a/ledd/stripe.py +++ b/ledd/stripe.py @@ -17,15 +17,16 @@ from spectra import Color from sqlalchemy import Integer, ForeignKey, String, Float, Boolean from sqlalchemy import Column +from sqlalchemy.orm import reconstructor from . import Base class Stripe(Base): - __tablename__ = "stripe" """ A stripe is the smallest controllable unit. """ + __tablename__ = "stripe" id = Column(Integer, primary_key=True) controller_id = Column(Integer, ForeignKey('controller.id')) name = Column(String) @@ -39,7 +40,7 @@ class Stripe(Base): @property def channels(self): - return self.channel_r, self.channel_b, self.channel_g + return self.channel_r, self.channel_g, self.channel_b # TODO save channels to db @@ -49,11 +50,21 @@ class Stripe(Base): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + self._color = None + self.gamma_correct = (self.channel_r_gamma, self.channel_g_gamma, self.channel_b_gamma) + self.read_color() + + @reconstructor + def init_on_load(self): + self._color = None + self.gamma_correct = (self.channel_r_gamma, self.channel_g_gamma, self.channel_b_gamma) + self.read_color() def read_color(self): - rc = tuple([float(self.controller.get_channel(channel)) for channel in self.channels]) - c = Color("rgb", rc[0], rc[1], rc[2]) - self._color = c.to("hsv") + if self.controller: + rc = tuple([float(self.controller.get_channel(channel)) for channel in self.channels]) + c = Color("rgb", rc[0], rc[1], rc[2]) + self._color = c.to("hsv") def __repr__(self): return "".format(self.id) @@ -66,4 +77,12 @@ class Stripe(Base): def get_color(self): return self._color + def to_json(self): + return { + 'id': self.id, + 'name': self.name, + 'rgb': self.rgb, + 'channel': self.channels + } + color = property(get_color, set_color)