diff --git a/LedD/__init__.py b/LedD/__init__.py
index e69de29..22cc96d 100644
--- a/LedD/__init__.py
+++ b/LedD/__init__.py
@@ -0,0 +1,15 @@
+# LEDD Project
+# Copyright (C) 2015 LEDD Team
+#
+# This program 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.
+#
+# This program 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 this program. If not, see .
\ No newline at end of file
diff --git a/LedD/controller.py b/LedD/controller.py
index 2f25a28..82aeeda 100644
--- a/LedD/controller.py
+++ b/LedD/controller.py
@@ -1,3 +1,19 @@
+# LEDD Project
+# Copyright (C) 2015 LEDD Team
+#
+# This program 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.
+#
+# This program 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 this program. If not, see .
+
from json import JSONEncoder
import smbus
diff --git a/LedD/daemon.py b/LedD/daemon.py
index 65bb3f8..c7e4621 100644
--- a/LedD/daemon.py
+++ b/LedD/daemon.py
@@ -24,13 +24,16 @@ import sys
import traceback
import time
-from . import controller
+from LedD import controller
+from LedD.decorators import add_action
class Daemon:
daemonSection = 'daemon'
databaseSection = 'db'
instance = None
+ """:type : Daemon """
+ action_dict = {}
def __init__(self):
Daemon.instance = self
@@ -94,67 +97,142 @@ class Daemon:
c.close()
self.check_db()
+ @add_action(action_dict)
+ def set_color(self, req_json):
+ """
+ Part of the Color API. Used to set color of a stripe.
+ Required JSON parameters: stripe ID: sid; HSV values: h,s,v
+ :param req_json: dict of request json
+ """
+ # TODO: add adapter setting stripe with color here
+ print("recieved action: {}".format(req_json['action']))
+
+ @add_action(action_dict)
+ def add_controller(self, req_json):
+ """
+ Part of the Color API. Used to add a controller.
+ Required JSON parameters: channels; i2c_dev: number of i2c device (e.g. /dev/i2c-1 would be i2c_dev = 1);
+ address: hexdecimal address of controller on i2c bus, e.g. 0x40
+ :param req_json: dict of request json
+ """
+ print("recieved action: {}".format(req_json['action']))
+ try:
+ ncontroller = controller.Controller(Daemon.instance.sqldb, req_json['channels'],
+ req_json['i2c_dev'], req_json['address'])
+ except OSError as e:
+ print("Error opening i2c device!")
+ rjson = {
+ 'success': False,
+ 'message': "Error while opening i2c device",
+ 'message_detail': os.strerror(e.errno),
+ 'ref': req_json['ref']
+ }
+ return json.dumps(rjson)
+
+ self.controllers.append(ncontroller)
+
+ rjson = {
+ 'success': True,
+ 'cid': ncontroller.id,
+ 'ref': req_json['ref']
+ }
+
+ return json.dumps(rjson)
+
+ @add_action(action_dict)
+ def get_color(self, req_json):
+ """
+ Part of the Color API. Used to get the currect color of an stripe.
+ Required JSON parameters: stripeid: sid
+ :param req_json: dict of request json
+ """
+ print("recieved action: {}".format(req_json['action']))
+ # TODO: Add get color logic
+
+ @add_action(action_dict)
+ def add_stripes(self, req_json):
+ """
+ Part of the Color API. Used to add stripes.
+ Required JSON parameters:
+ :param req_json: dict of request json
+ """
+ print("recieved action: {}".format(req_json['action']))
+ if "stripes" in req_json:
+ for stripe in req_json['stripes']:
+ # TODO: add stripe here
+ print(len(req_json['stripes']))
+
+ @add_action(action_dict)
+ def get_controllers(self, req_json):
+ """
+ Part of the Color API. Used to get all registered controllers known to the daemon.
+ Required JSON parameters: none
+ :param req_json: dict of request json
+ """
+ print("recieved action: {}".format(req_json['action']))
+
+ rjson = {
+ 'success': True,
+ 'ccount': len(Daemon.instance.controllers),
+ 'controller': Daemon.instance.controllers,
+ 'ref': req_json['ref']
+ }
+
+ return json.dumps(rjson, cls=controller.ControllerEncoder)
+
+ @add_action(action_dict)
+ def connection_check(self, req_json):
+ """
+ Part of the Color API. Used to query all channels on a specified controller.
+ Required JSON parameters: controller id: cid
+ :param req_json: dict of request json
+ """
+ print("recieved action: {}".format(req_json['action']))
+
+ result = next(filter(lambda x: x.id == req_json['cid'], self.controllers), None)
+ """ :type : Controller """
+
+ if result is not None:
+ for i in range(result.channels):
+ print("set channel {}={}".format(i, "1"))
+ result.set_channel(i, 1)
+ time.sleep(2)
+ result.set_channel(i, 0)
+
+ rjson = {
+ 'success': True,
+ 'ref': req_json['ref']
+ }
+
+ return json.dumps(rjson)
+
class ConnectionHandler(asyncore.dispatcher_with_send):
def handle_read(self):
data = self.recv(5120)
self.debug = True
+
+ def no_action_found(self, req_json):
+ rjson = {
+ 'success': False,
+ 'message': "No action found",
+ 'ref': req_json['ref']
+ }
+ return json.dumps(rjson)
+
if data:
- print(data)
try:
json_decoded = json.loads(data.decode())
print(json.dumps(json_decoded, sort_keys=True, indent=4, separators=(',', ': ')))
- if "action" in json_decoded:
- if json_decoded['action'] == "set_color":
+ if "action" in json_decoded and "ref" in json_decoded:
+ return_data = Daemon.instance.action_dict.get(json_decoded['action'], no_action_found)(
+ self=Daemon.instance,
+ req_json=json_decoded)
- # TODO: add adapter setting stripe with color here
- print("recieved action: {}".format(json_decoded['action']))
- elif json_decoded['action'] == "add_controller":
- print("recieved action: {}".format(json_decoded['action']))
- ncontroller = None
- try:
- ncontroller = controller.Controller(Daemon.instance.sqldb, json_decoded['channels'],
- json_decoded['i2c_dev'], json_decoded['address'])
- except OSError:
- print("Error opening i2c device!")
-
- self.send("{}\n".format(ncontroller.id).encode())
- Daemon.instance.controllers.append(ncontroller)
- elif json_decoded['action'] == "get_color":
- # TODO: add stripe color get logic
- print("recieved action: {}".format(json_decoded['action']))
- elif json_decoded['action'] == "add_stripes":
- if "stripes" in json_decoded:
- for stripe in json_decoded['stripes']:
- # TODO: add stripe here
- print(len(json_decoded['stripes']))
- elif json_decoded['action'] == "get_controllers":
- rjson = {
- 'status': 'success',
- 'ccount': len(Daemon.instance.controllers),
- 'controller': Daemon.instance.controllers
- }
- self.send("{}\n".format(json.dumps(rjson, cls=controller.ControllerEncoder)).encode())
- elif json_decoded['action'] == "connection_check":
- result = next(filter(lambda x: x.id == json_decoded['id'], Daemon.instance.controllers),
- None)
- """ :type : Controller """
-
- if result is not None:
- print("we can do it!")
- for i in range(result.channels):
- print("set channel {}={}".format(i, "1"))
- result.set_channel(i, 1)
- time.sleep(2)
- result.set_channel(i, 0)
-
- rjson = {
- 'status': 'success'
- }
-
- self.send("{}\n".format(json.dumps(rjson, cls=controller.ControllerEncoder)).encode())
+ if return_data is not None:
+ self.send("{}\n".format(return_data).encode())
else:
- print("no action found, ignoring")
+ print("no action or ref value found, ignoring")
except TypeError as e:
print("No valid JSON found: {}".format(e))
traceback.print_exc(file=sys.stdout)
@@ -175,4 +253,4 @@ class Daemon:
if pair is not None:
sock, addr = pair
print('Incoming connection from %s' % repr(addr))
- handler = Daemon.ConnectionHandler(sock)
+ handler = Daemon.ConnectionHandler(sock)
\ No newline at end of file
diff --git a/LedD/decorators.py b/LedD/decorators.py
new file mode 100644
index 0000000..bbc2cbb
--- /dev/null
+++ b/LedD/decorators.py
@@ -0,0 +1,33 @@
+# LEDD Project
+# Copyright (C) 2015 LEDD Team
+#
+# This program 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.
+#
+# This program 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 this program. If not, see .
+
+
+def add_action(actiondict):
+ """
+ Decorator used to add functions to action dict
+ :param actiondict: dict to add to
+ :type actiondict: dict
+ """
+
+ def wrap(f):
+ actiondict[f.__name__] = f
+
+ def wrapped_f(*args):
+ f(*args)
+
+ return wrapped_f
+
+ return wrap
\ No newline at end of file
diff --git a/LedD/effects/__init__.py b/LedD/effects/__init__.py
index e69de29..22cc96d 100644
--- a/LedD/effects/__init__.py
+++ b/LedD/effects/__init__.py
@@ -0,0 +1,15 @@
+# LEDD Project
+# Copyright (C) 2015 LEDD Team
+#
+# This program 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.
+#
+# This program 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 this program. If not, see .
\ No newline at end of file
diff --git a/LedD/effects/baseeffect.py b/LedD/effects/baseeffect.py
index e69de29..22cc96d 100644
--- a/LedD/effects/baseeffect.py
+++ b/LedD/effects/baseeffect.py
@@ -0,0 +1,15 @@
+# LEDD Project
+# Copyright (C) 2015 LEDD Team
+#
+# This program 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.
+#
+# This program 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 this program. If not, see .
\ No newline at end of file
diff --git a/README.md b/README.md
index 13bd842..afe00f1 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,23 @@ LedD is a daemon for interfacing LED stripes written in python3. It provides an
- an open effects github repository with simple download-and-run system
- automatic enumeration of the connected controller devices, restart/reset and status querys
-### License
+### Plugins
+
+Plugin functionality is planned as we provide APIs for effects and plugins to use. Here are some we are going to provide if they are finished.
+
+- plugins
+ - lux sensor (TSL2591) for providing information if lights need to be turned on
+ - start/stop hook so you can switch your LED power supply
+ - planned hook points for plugins include
+ - start/stop
+ - set color (for e.g. gamma correction)
+- effects
+ - pulse
+ - fade
+ - drop
+ - blink
+ - strobe (as far as possible)
+
+#### License
This project is licensed under the conditions of the GNU GPL 3.0.
diff --git a/start.py b/start.py
index 77d5c72..bd0af26 100644
--- a/start.py
+++ b/start.py
@@ -1,3 +1,19 @@
+# LEDD Project
+# Copyright (C) 2015 LEDD Team
+#
+# This program 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.
+#
+# This program 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 this program. If not, see .
+
from pkgutil import iter_modules
if "smbus" not in (name for loader, name, ispkg in iter_modules()):