Mercurial > code > home > repos > light9
changeset 2190:51c670ce5d50
fade (on web) now makes it all the way to collector!
author | drewp@bigasterisk.com |
---|---|
date | Sat, 20 May 2023 16:26:23 -0700 |
parents | 504978369ab0 |
children | ffae830fda12 |
files | light9/effect/effecteval.py light9/effect/sequencer/eval_faders.py light9/effect/sequencer/eval_faders_test.py light9/effect/sequencer/note.py light9/effect/sequencer/service.py light9/effect/simple_outputs.py |
diffstat | 6 files changed, 58 insertions(+), 31 deletions(-) [+] |
line wrap: on
line diff
--- a/light9/effect/effecteval.py Sat May 20 16:24:47 2023 -0700 +++ b/light9/effect/effecteval.py Sat May 20 16:26:23 2023 -0700 @@ -87,7 +87,6 @@ the effect code. """ # both callers need to apply note overrides - print(f'outputFromEffect({effectSettings=}, {songTime=}, {noteTime=})') strength = float(effectSettings.s[EffectAttr(L9['strength'])]) if strength <= 0: return EffectSettings(self.graph, []), {'zero': True} @@ -107,7 +106,6 @@ out.update(func(effectSettings, strength, songTime, noteTime)) outList = [(d, a, v) for (d, a), v in out.items()] - print(f'{outList=}') return EffectSettings(self.graph, outList), report
--- a/light9/effect/sequencer/eval_faders.py Sat May 20 16:24:47 2023 -0700 +++ b/light9/effect/sequencer/eval_faders.py Sat May 20 16:26:23 2023 -0700 @@ -12,7 +12,7 @@ from light9.effect.simple_outputs import SimpleOutputs from light9.metrics import metrics from light9.namespaces import L9, RDF -from light9.newtypes import NoteUri, UnixTime +from light9.newtypes import EffectAttr, NoteUri, UnixTime log = logging.getLogger('seq.fader') @@ -32,6 +32,7 @@ self.notes: List[Note] = [] self.simpleOutputs = SimpleOutputs(self.graph) + log.info('fader adds handler') self.graph.addHandler(self.compileGraph) self.lastLoopSucceeded = False @@ -39,9 +40,9 @@ # have caller do this #asyncio.create_task(self.startUpdating()) - async def startUpdating(self): - await self.graph.addAsyncHandler(self.update) - log.info('startupdating task done') + # async def startUpdating(self): + # await self.graph.addAsyncHandler(self.update) + # log.info('startupdating task done') def onCodeChange(self): log.debug('seq.onCodeChange') @@ -66,25 +67,29 @@ return Note(self.graph, cast(NoteUri, fader), timed=False) - def _computeOutput(self) -> DeviceSettings: + def computeOutput(self) -> DeviceSettings: notesSettings = [] now = UnixTime(time.time()) for note in self.notes: effectSettings, report = note.outputCurrent() + if effectSettings.s[EffectAttr(L9['strength'])]==0: + continue + ee = effecteval.EffectEval(self.graph, note.effectClass, self.simpleOutputs) deviceSettings, report = ee.outputFromEffect( effectSettings, songTime=now, # probably wrong noteTime=now, # wrong ) - notesSettings.append(deviceSettings) + if deviceSettings: + notesSettings.append(deviceSettings) return DeviceSettings.merge(self.graph, notesSettings) - @metrics('update_call_fader').time() - async def update(self): - log.info(f'update {len(self.notes)=}') - devSettings = self._computeOutput() - with metrics('update_s3_send_fader').time(): # our measurement - sendSecs = await self.sendToCollector(devSettings) + # @metrics('update_call_fader').time() + # async def update(self): + # log.info(f'update {len(self.notes)=}') + # devSettings = self.computeOutput() + # with metrics('update_s3_send_fader').time(): # our measurement + # sendSecs = await self.sendToCollector(devSettings)
--- a/light9/effect/sequencer/eval_faders_test.py Sat May 20 16:24:47 2023 -0700 +++ b/light9/effect/sequencer/eval_faders_test.py Sat May 20 16:26:23 2023 -0700 @@ -57,5 +57,5 @@ sender = mock.MagicMock() f = FaderEval(g, sender) - devSettings = f._computeOutput() + devSettings = f.computeOutput() assert devSettings == DeviceSettings(g, [(L9['light1'], L9['brightness'], 0.3)]) \ No newline at end of file
--- a/light9/effect/sequencer/note.py Sat May 20 16:24:47 2023 -0700 +++ b/light9/effect/sequencer/note.py Sat May 20 16:26:23 2023 -0700 @@ -54,7 +54,7 @@ # simpleOutputs: SimpleOutputs timed: bool = True - def __post_init__(self): + def __post_init__(self): # graph ok ec = self.graph.value(self.uri, L9['effectClass']) if ec is None: raise ValueError(f'note {self.uri} has no :effectClass') @@ -70,8 +70,9 @@ self.points.sort() else: self.points = [] + self.value = typedValue(float, self.graph, self.uri, L9['value']) - def getBaseEffectSettings(self) -> BareEffectSettings: + def getBaseEffectSettings(self) -> BareEffectSettings: # graph ok """i think these are settings that are fixed over time, e.g. that you set in the note's body in the timeline editor """ @@ -117,21 +118,21 @@ y = p1[1] + (p2[1] - p1[1]) * frac return y - def outputCurrent(self): - st = typedValue(float, self.graph, self.uri, L9['value']) - return self._outputSettings(t=None, strength=st) + def outputCurrent(self): # no graph + + return self._outputSettings(t=None, strength=self.value) def _outputSettings( self, t: float | None, strength: Optional[float] = None # - ) -> Tuple[BareEffectSettings, Dict]: - + ) -> Tuple[BareEffectSettings, Dict]: # no graph + if t is None: if self.timed: raise TypeError() t = time.time() # so live effects will move - report:Dict[str,Any] = { + report: Dict[str, Any] = { 'note': str(self.uri), 'effectClass': str(self.effectClass), }
--- a/light9/effect/sequencer/service.py Sat May 20 16:24:47 2023 -0700 +++ b/light9/effect/sequencer/service.py Sat May 20 16:26:23 2023 -0700 @@ -45,6 +45,22 @@ async def send_page_updates(request): return EventSourceResponse(changes()) +################################################################### + + +async def _send_one(faders:FaderEval): + ds = faders.computeOutput() + await sendToCollector('effectSequencer', session='0', settings=ds) + +async def _forever(faders): + while True: + await _send_one(faders) + await asyncio.sleep(0.1) + +def send_updates_forever(faders): + asyncio.create_task(_forever(faders)) + +#################################################################### def main(): session = 'effectSequencer' @@ -56,8 +72,11 @@ async def send(settings: DeviceSettings): await sendToCollector('effectSequencer', session, settings) - seq = Sequencer(graph, send) # per-song timed notes + # seq = Sequencer(graph, send) # per-song timed notes faders = FaderEval(graph, send) # bin/fade's untimed notes + # asyncio.create_task(faders.startUpdating()) + + send_updates_forever(faders) app = Starlette( debug=True,
--- a/light9/effect/simple_outputs.py Sat May 20 16:24:47 2023 -0700 +++ b/light9/effect/simple_outputs.py Sat May 20 16:26:23 2023 -0700 @@ -1,8 +1,13 @@ +import logging import traceback -from light9.namespaces import L9, RDF +from typing import Any, Dict, List, Tuple + +from rdflib import URIRef + from light9.effect.scale import scale -from typing import Dict, List, Tuple, Any -from rdflib import URIRef +from light9.namespaces import L9, RDF + +log = logging.getLogger('simple') class SimpleOutputs: @@ -20,10 +25,9 @@ self.graph.addHandler(self.updateEffectsFromGraph) def updateEffectsFromGraph(self): + self.effectOutputs={} for effect in self.graph.subjects(RDF.type, L9['Effect']): - raise TypeError('change graph from Effect to EffectClass') - - for effect in self.graph.subjects(RDF.type, L9['EffectClass']): + log.debug(f' {effect=}') settings = [] for setting in self.graph.objects(effect, L9['setting']): settingValues = dict(self.graph.predicate_objects(setting)) @@ -43,7 +47,7 @@ continue settings.append((d, a, v if v is not None else sv, bool(sv))) - + log.debug(f' effect {effect} has {settings=}') if settings: self.effectOutputs[effect] = settings # also have to read eff :effectAttr [ :tint x; :tintStrength y ]