# HG changeset patch # User Louis Opter # Date 1477259591 25200 # Node ID c38b0b9612cd9b39ca6dc069aba4fd9fd60b7488 # Parent d250169c1a69219d0c6a1bc5a8a5e93956311a0b broken wip diff -r d250169c1a69 -r c38b0b9612cd add_monolight.patch --- a/add_monolight.patch Fri Oct 21 13:31:44 2016 -0700 +++ b/add_monolight.patch Sun Oct 23 14:53:11 2016 -0700 @@ -18,7 +18,7 @@ new file mode 100644 --- /dev/null +++ b/apps/monolight/monolight/cli.py -@@ -0,0 +1,65 @@ +@@ -0,0 +1,69 @@ +# Copyright (c) 2016, Louis Opter +# +# This file is part of lightsd. @@ -50,8 +50,6 @@ + +ENCODING = locale.getpreferredencoding() + -+FADERS_MAX_VALUE = 100 -+ +logging.basicConfig(level=logging.INFO) + + @@ -62,21 +60,27 @@ +def main(serialoscd_host: str, serialoscd_port: int, lightsd_url: str): + loop = asyncio.get_event_loop() + ++ monome_future = asyncio.Future() ++ grid = ui.MonomeGrid() ++ + tasks = asyncio.gather( + loop.create_task(lightsc.create_async_lightsd_connection(lightsd_url)), -+ loop.create_task(monome.create_serialosc_connection( -+ functools.partial(osc.MonomeApplication, ui.submit_keypress) -+ )) ++ loop.create_task(monome.create_serialosc_connection(functools.partial( ++ osc.MonomeApplication, monome_future, grid.submit_input ++ ))), ++ asyncio.ensure_future(monome_future) + ) + loop.run_until_complete(tasks) -+ lightsd, serialosc = tasks.result() ++ lightsd, serialosc, monome_app = tasks.result() ++ ++ grid.set_monome(monome_app) + + if hasattr(loop, "add_signal_handler"): + for signum in (signal.SIGINT, signal.SIGTERM, signal.SIGQUIT): + loop.add_signal_handler(signum, ui.stop) + + # TODO: make which monome instance to use something configurable -+ ui_task = loop.create_task(ui.start(loop, lightsd, serialosc)) ++ ui_task = loop.create_task(ui.start(loop, lightsd, grid)) + + loop.run_until_complete(ui_task) + @@ -84,10 +88,128 @@ + loop.run_until_complete(lightsd.close()) + + loop.close() -diff --git a/apps/monolight/monolight/components/__init__.py b/apps/monolight/monolight/components/__init__.py +diff --git a/apps/monolight/monolight/osc.py b/apps/monolight/monolight/osc.py new file mode 100644 --- /dev/null -+++ b/apps/monolight/monolight/components/__init__.py ++++ b/apps/monolight/monolight/osc.py +@@ -0,0 +1,66 @@ ++# Copyright (c) 2016, Louis Opter ++# ++# This file is part of lightsd. ++# ++# lightsd 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. ++# ++# lightsd 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 lightsd. If not, see . ++ ++import asyncio ++import monome ++ ++from enum import IntEnum ++from typing import Callable ++ ++ ++class MonomeKeyState(IntEnum): ++ ++ DOWN = 1 ++ UP = 0 ++ ++ ++class MonomeLedLevel(IntEnum): ++ ++ OFF = 0 ++ VERY_LOW_1 = 1 ++ VERY_LOW_2 = 2 ++ VERY_LOW_3 = 3 ++ LOW = LOW_1 = 4 ++ LOW_2 = 5 ++ LOW_3 = 6 ++ LOW_4 = 7 ++ MEDIUM = MEDIUM_1 = 8 ++ MEDIUM_2 = 9 ++ MEDIUM_3 = 10 ++ MEDIUM_4 = 11 ++ HIGH = HIGH_1 = 12 ++ HIGH_2 = 13 ++ HIGH_3 = 14 ++ HIGH_4 = ON = 15 ++ ++ ++class MonomeApplication(monome.Monome): ++ ++ def __init__( ++ self, ++ future: asyncio.Future, ++ keypress_callback: Callable[[int, int, int], None] ++ ) -> None: ++ monome.Monome.__init__(self, "/monolight") ++ future.set_result(self) ++ self._keypress_callback = keypress_callback ++ ++ def ready(self) -> None: ++ self.led_all(MonomeLedLevel.OFF) ++ ++ def grid_key(self, x: int, y: int, s: int): ++ self._keypress_callback(x, y, s) +diff --git a/apps/monolight/monolight/types.py b/apps/monolight/monolight/types.py +new file mode 100644 +--- /dev/null ++++ b/apps/monolight/monolight/types.py +@@ -0,0 +1,18 @@ ++# Copyright (c) 2016, Louis Opter ++# ++# This file is part of lightsd. ++# ++# lightsd 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. ++# ++# lightsd 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 lightsd. If not, see . ++ ++TimeMonotonic = float +diff --git a/apps/monolight/monolight/ui/__init__.py b/apps/monolight/monolight/ui/__init__.py +new file mode 100644 +--- /dev/null ++++ b/apps/monolight/monolight/ui/__init__.py +@@ -0,0 +1,19 @@ ++# Copyright (c) 2016, Louis Opter ++# ++# This file is part of lightsd. ++# ++# lightsd 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. ++# ++# lightsd 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 lightsd. If not, see . ++ ++from .grid import MonomeGrid # noqa ++from .ui import start, stop, submit_keypress # noqa +diff --git a/apps/monolight/monolight/ui/components/__init__.py b/apps/monolight/monolight/ui/components/__init__.py +new file mode 100644 +--- /dev/null ++++ b/apps/monolight/monolight/ui/components/__init__.py @@ -0,0 +1,20 @@ +# Copyright (c) 2016, Louis Opter +# @@ -109,11 +231,11 @@ +from .base import MonomeGrid # noqa +from .layers import Layer # noqa +from .button import button # noqa -diff --git a/apps/monolight/monolight/components/base.py b/apps/monolight/monolight/components/base.py +diff --git a/apps/monolight/monolight/ui/components/base.py b/apps/monolight/monolight/ui/components/base.py new file mode 100644 --- /dev/null -+++ b/apps/monolight/monolight/components/base.py -@@ -0,0 +1,139 @@ ++++ b/apps/monolight/monolight/ui/components/base.py +@@ -0,0 +1,110 @@ +# Copyright (c) 2016, Louis Opter +# +# This file is part of lightsd. @@ -131,37 +253,8 @@ +# You should have received a copy of the GNU General Public License +# along with lightsd. If not, see . + -+from typing import ( -+ NamedTuple, -+) -+ -+from ..osc import ( -+ MONOME_LED_OFF, -+ MonomeLedLevel, -+) -+ -+_Dimensions = NamedTuple("Dimensions", [("height", int), ("width", int)]) -+_Position = NamedTuple("Position", [("x", int), ("y", int)]) -+ -+ -+class Dimensions(_Dimensions): -+ -+ def __repr__(self) -> str: -+ return "height={}, width={}".format(*self) -+ -+ -+class Position(_Position): -+ -+ def __repr__(self) -> str: -+ return "{}, {}".format(*self) -+ -+ -+class MonomeGrid: -+ -+ def __init__(self, size: Dimensions) -> None: -+ from .layers import Layer # noqa; break import loop -+ self.size = size -+ self.layers = [] # z-order, type: List[Layer] ++from ...osc import MonomeLedLevel ++from ..types import Dimensions, Position + + +class LedSprite: @@ -169,7 +262,7 @@ + def __init__( + self, + size: Dimensions, -+ level: MonomeLedLevel = MONOME_LED_OFF ++ level: MonomeLedLevel = MonomeLedLevel.OFF + ) -> None: + self.size = size + self._levels = [level] * size.width * size.height @@ -253,11 +346,11 @@ + # maybe that bool return type could become an enum or a composite: + def submit_input(self, offset: Position) -> bool: + return False -diff --git a/apps/monolight/monolight/components/button.py b/apps/monolight/monolight/components/button.py +diff --git a/apps/monolight/monolight/ui/components/button.py b/apps/monolight/monolight/ui/components/button.py new file mode 100644 --- /dev/null -+++ b/apps/monolight/monolight/components/button.py -@@ -0,0 +1,57 @@ ++++ b/apps/monolight/monolight/ui/components/button.py +@@ -0,0 +1,49 @@ +# Copyright (c) 2016, Louis Opter +# +# This file is part of lightsd. @@ -275,17 +368,9 @@ +# You should have received a copy of the GNU General Public License +# along with lightsd. If not, see . + -+from .base import ( -+ Dimensions, -+ Position, -+ LedSprite, -+ UIComponentBase, -+) -+ -+from ..osc import ( -+ MONOME_LED_OFF, -+ MONOME_LED_ON, -+) ++from .base import LedSprite, UIComponentBase ++from ...osc import MONOME_LED_OFF, MONOME_LED_ON ++from ..types import Dimensions, Position + + +class Button(UIComponentBase): @@ -315,61 +400,11 @@ + self.toggle() + return True + return False -diff --git a/apps/monolight/monolight/components/layers.py b/apps/monolight/monolight/components/layers.py +diff --git a/apps/monolight/monolight/ui/components/layer.py b/apps/monolight/monolight/ui/components/layer.py new file mode 100644 --- /dev/null -+++ b/apps/monolight/monolight/components/layers.py -@@ -0,0 +1,45 @@ -+# Copyright (c) 2016, Louis Opter -+# -+# This file is part of lightsd. -+# -+# lightsd 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. -+# -+# lightsd 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 lightsd. If not, see . -+ -+import monome -+ -+from .base import ( -+ Dimensions, -+ UIComponentBase, -+) -+from ..osc import MONOME_LED_OFF -+from ..types import TimeMonotonic -+ -+ -+class Layer(UIComponentBase): -+ -+ def __init_(self, size: Dimensions): -+ self.size = size -+ self.led_buffer = monome.LedBuffer( -+ width=size.width, height=size.height -+ ) -+ -+ def _blit(self, component: UIComponentBase): -+ for off_x, off_y, level in component.to_sprite(): -+ self.led_buffer.led_set( -+ component.offset.x + off_x, component.offset.y + off_y, level -+ ) -+ -+ def render(self, frame_ts: TimeMonotonic) -> None: -+ self.led_buffer.led_level_all(MONOME_LED_OFF) -+ for component in self.children: -+ self._blit(component) -diff --git a/apps/monolight/monolight/osc.py b/apps/monolight/monolight/osc.py -new file mode 100644 ---- /dev/null -+++ b/apps/monolight/monolight/osc.py -@@ -0,0 +1,82 @@ ++++ b/apps/monolight/monolight/ui/components/layer.py +@@ -0,0 +1,41 @@ +# Copyright (c) 2016, Louis Opter +# +# This file is part of lightsd. @@ -389,74 +424,33 @@ + +import monome + -+MONOME_KEYPRESS_DOWN = 1 -+MONOME_KEYPRESS_UP = 0 -+MONOME_KEYPRESS_STATES = frozenset({ -+ MONOME_KEYPRESS_DOWN, -+ MONOME_KEYPRESS_UP, -+}) -+ -+MONOME_LED_OFF = 0 -+MONOME_LED_VERY_LOW_1 = 1 -+MONOME_LED_VERY_LOW_2 = 2 -+MONOME_LED_VERY_LOW_3 = 3 -+MONOME_LED_LOW = MONOME_LED_LOW_1 = 4 -+MONOME_LED_LOW_2 = 5 -+MONOME_LED_LOW_3 = 6 -+MONOME_LED_LOW_4 = 7 -+MONOME_LED_MEDIUM = MONOME_LED_MEDIUM_1 = 8 -+MONOME_LED_MEDIUM_2 = 9 -+MONOME_LED_MEDIUM_3 = 10 -+MONOME_LED_MEDIUM_4 = 11 -+MONOME_LED_HIGH = MONOME_LED_HIGH_1 = 12 -+MONOME_LED_HIGH_2 = 13 -+MONOME_LED_HIGH_3 = 14 -+MONOME_LED_HIGH_4 = MONOME_LED_ON = 15 -+MONOME_VARIBRIGHT_LEVELS = ( -+ MONOME_LED_OFF, -+ MONOME_LED_VERY_LOW_1, -+ MONOME_LED_VERY_LOW_2, -+ MONOME_LED_VERY_LOW_3, -+ MONOME_LED_LOW, -+ MONOME_LED_LOW_2, -+ MONOME_LED_LOW_3, -+ MONOME_LED_LOW_4, -+ MONOME_LED_MEDIUM, -+ MONOME_LED_MEDIUM_2, -+ MONOME_LED_MEDIUM_3, -+ MONOME_LED_MEDIUM_4, -+ MONOME_LED_HIGH, -+ MONOME_LED_HIGH_2, -+ MONOME_LED_HIGH_3, -+ MONOME_LED_HIGH_4, -+) -+ -+MonomeLedLevel = int ++from .base import UIComponentBase ++from ...osc import MONOME_LED_OFF ++from ..types import Dimensions ++from ...types import TimeMonotonic + + -+class MonomeApplication(monome.Monome): ++class Layer(UIComponentBase): + -+ def __init__(self, keypress_callback): -+ self._keypress_callback = keypress_callback -+ monome.Monome.__init__(self, "/monolight") -+ -+ def ready(self): -+ self.led_all(0) ++ def __init_(self, size: Dimensions): ++ self.size = size ++ self.led_buffer = monome.LedBuffer(width=size.width, height=size.height) + -+ def grid_key(self, x, y, s): -+ self._keypress_callback(x, y, s) -+ ++ def _blit(self, component: UIComponentBase): ++ for off_x, off_y, level in component.to_sprite(): ++ self.led_buffer.led_set( ++ component.offset.x + off_x, component.offset.y + off_y, level ++ ) + -+def monome_apply(serialosc, method, *args, **kwargs): -+ for device in serialosc.app_instances.values(): -+ for app in device: -+ if isinstance(app, MonomeApplication): -+ method(app, *args, **kwargs) -diff --git a/apps/monolight/monolight/types.py b/apps/monolight/monolight/types.py ++ def render(self, frame_ts: TimeMonotonic) -> None: ++ self.led_buffer.led_level_all(MONOME_LED_OFF) ++ for component in self.children: ++ self._blit(component) +diff --git a/apps/monolight/monolight/ui/grid.py b/apps/monolight/monolight/ui/grid.py new file mode 100644 --- /dev/null -+++ b/apps/monolight/monolight/types.py -@@ -0,0 +1,18 @@ ++++ b/apps/monolight/monolight/ui/grid.py +@@ -0,0 +1,37 @@ +# Copyright (c) 2016, Louis Opter +# +# This file is part of lightsd. @@ -474,11 +468,92 @@ +# You should have received a copy of the GNU General Public License +# along with lightsd. If not, see . + -+TimeMonotonic = float -diff --git a/apps/monolight/monolight/ui.py b/apps/monolight/monolight/ui.py ++from .. import osc ++from .components.layer import Layer ++from .types import Dimensions, Keypress, Position ++ ++ ++class MonomeGrid: ++ ++ def __init__(self) -> None: ++ self.size = None # type: Dimensions ++ self.layers = None # z-order, type: List[Layer] ++ self.monome = None # type: osc.MonomeApplication ++ ++ def set_monome(self, grid: osc.MonomeApplication) -> None: ++ self.size = Dimensions(height=grid.height, width=grid.width) ++ self.layers = [Layer(self.size)] ++ self.grid = grid ++ ++ def submit_input(self, x: int, y: int, s: int) -> None: ++ if self.layers: ++ self.layers[-1].submit_input(Keypress(Position(x, y), s)) +diff --git a/apps/monolight/monolight/ui/types.py b/apps/monolight/monolight/ui/types.py new file mode 100644 --- /dev/null -+++ b/apps/monolight/monolight/ui.py ++++ b/apps/monolight/monolight/ui/types.py +@@ -0,0 +1,57 @@ ++# Copyright (c) 2016, Louis Opter ++# ++# This file is part of lightsd. ++# ++# lightsd 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. ++# ++# lightsd 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 lightsd. If not, see . ++ ++from typing import NamedTuple ++ ++from .. import osc ++ ++_Dimensions = NamedTuple("Dimensions", [("height", int), ("width", int)]) ++_Position = NamedTuple("Position", [("x", int), ("y", int)]) ++ ++ ++class Dimensions(_Dimensions): ++ ++ def __repr__(self) -> str: ++ return "height={}, width={}".format(*self) ++ ++ ++class Position(_Position): ++ ++ def __repr__(self) -> str: ++ return "{}, {}".format(*self) ++ ++_Keypress = NamedTuple("KeyPress", [ ++ ("position", Position), ("state", osc.MonomeKeyState) ++]) ++ ++ ++class Keypress(_Keypress): ++ ++ @property ++ def x(self): ++ return self.position.x ++ ++ @property ++ def y(self): ++ return self.position.y ++ ++ @property ++ def s(self): ++ return self.state.value ++ ++ def __repr__(self) -> str: ++ return "{!r}, {}".format(self.position, self.state.name) +diff --git a/apps/monolight/monolight/ui/ui.py b/apps/monolight/monolight/ui/ui.py +new file mode 100644 +--- /dev/null ++++ b/apps/monolight/monolight/ui/ui.py @@ -0,0 +1,124 @@ +# Copyright (c) 2016, Louis Opter +# @@ -512,7 +587,7 @@ + PowerOn, + PowerToggle, +) -+from .osc import ( ++from ..osc import ( + MONOME_KEYPRESS_DOWN, + monome_apply, +) diff -r d250169c1a69 -r c38b0b9612cd add_slides.patch --- a/add_slides.patch Fri Oct 21 13:31:44 2016 -0700 +++ b/add_slides.patch Sun Oct 23 14:53:11 2016 -0700 @@ -1,5 +1,5 @@ # HG changeset patch -# Parent 3539266939bc4808efd5c32db5e1627b2948210f +# Parent 1bc74610c471047ba4ac28e55c77c44db07b1142 Start to setup some slides for 33C3 Hopefully my talk proposal will be selected! @@ -1692,7 +1692,7 @@ new file mode 100644 --- /dev/null +++ b/slides/33c3/33c3.tex -@@ -0,0 +1,86 @@ +@@ -0,0 +1,89 @@ +\documentclass[xcolor={usenames,svgnames}]{beamer} + +\usepackage[american]{babel} @@ -1717,16 +1717,19 @@ +% carrément des targets différentes pour être sûr de pas te tromper). + +\pdfnote{% Notes: -+- Monolithic approach to solve the problem,\ ++- Monolithic approach to solve the problem;\ +- Est-ce que l'argument de l'isolation fonctionne ou IoTivity le résoud aussi?\ +- Je ressens pas le besoin d'investir dans plus de domotique donc que lightsd\ -+soit restreint ne me dérange pas, puis la stabilitité m'arrange.\ ++ soit restreint ne me dérange pas, puis la stabilitité m'arrange;\ +- Ce qui peut faire la différence avec IoTivity c'est la documentation, en -+bonus un plan pour vraiment extend.\ ++ bonus un plan pour vraiment extend;\ ++- Tu peux aussi dire: « voilà, moi j'ai fais ça, je sais pas trop comment\ ++ fonctionne IoTivity et les autres projets, mais si vous avez été déçu, venez\ ++ jeter un coup d'œil. »\ +- Interfaces are bad because they encourage inheritance, I believe composition\ -+is a better design pattern. (Though you can't really say the \"mixin\" approach\ -+is composition, it really is inheritance, like interfaces, in the sense that it\ -+delegates all attributes of the composite object).\ ++ is a better design pattern. (Though you can't really say the \"mixin\"\ ++ approach is composition, it really is inheritance, like interfaces, in the \ ++ sense that it delegates all attributes of the composite object).\ +} + +\begin{frame}{Being a daemon}