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 ]