diff --git a/bin/effecteval b/bin/effecteval
--- a/bin/effecteval
+++ b/bin/effecteval
@@ -1,16 +1,18 @@
#!bin/python
from run_local import log
from twisted.internet import reactor
-import cyclone.web, cyclone.websocket
-import sys, optparse, logging, subprocess
+from twisted.internet.defer import inlineCallbacks
+import cyclone.web, cyclone.websocket, cyclone.httpclient
+import sys, optparse, logging, subprocess, json, re
from rdflib import URIRef, RDF
sys.path.append(".")
-from light9 import networking, showconfig
+from light9 import networking, showconfig, Submaster
from light9.rdfdb.syncedgraph import SyncedGraph
+from light9.curvecalc.curve import Curve
from light9.namespaces import L9, DCTERMS
-sys.path.append("../homeauto/lib")
+sys.path.append("/my/proj/homeauto/lib")
sys.path.append("/home/drewp/projects/homeauto/lib")
from cycloneerr import PrettyErrorHandler
@@ -42,14 +44,63 @@ class EffectData(cyclone.websocket.WebSo
log.info("got message %s" % message)
# write a patch back to the graph
-def effectDmxDict(graph, effect):
+def uriFromCode(s):
+ # i thought this was something a graph could do with its namespace manager
+ if s.startswith('sub:'):
+ return URIRef('http://light9.bigasterisk.com/show/dance2014/sub/' + s[4:])
+ if s.startswith('song1:'):
+ return URIRef('http://ex/effect/song1/' + s[6:])
+ raise NotImplementedError
+
+class EffectNode(object):
+ def __init__(self, graph, uri):
+ self.graph, self.uri = graph, uri
+ def eval(self, songTime):
+ with self.graph.currentState(tripleFilter=(self.uri, L9['code'], None)) as g:
+ code = g.value(self.uri, L9['code'])
+ # consider http://waxeye.org/ for a parser that can be used in py and js
+ m = re.match(r'^out = sub\((.*?), intensity=(.*?)\)', code)
+ if not m:
+ raise NotImplementedError
+ sub = uriFromCurie(m.group(1))
+ intensityCurve = uriFromCurie(m.group(2))
+
+ print vars()
+
+def effectDmxDict(graph, effect, songTime):
+ subs = Submaster.get_global_submasters(graph)
+
+ curve = URIRef("http://ex/effect/song1/opening")
+ c = Curve()
+ with graph.currentState(tripleFilter=(curve, None, None)) as g:
+ c.set_from_string(g.value(curve, L9['points']))
+
+ with graph.currentState(tripleFilter=(effect, None, None)) as g:
+ print 'got code', g.value(effect, L9['code'])
+ en = EffectNode(graph, effect)
+
+ en.eval(songTime)
+
+ sub = subs.get_sub_by_uri(URIRef("http://light9.bigasterisk.com/show/dance2014/sub/stageleft"))
+ level = c.eval(songTime)
+ scaledSubs = [sub * level]
+
+ out = Submaster.sub_maxes(*scaledSubs)
+ levels_dict = out.get_levels()
+ dmx = out.get_dmx_list()
+ return json.dumps(dmx)
+
class EffectEval(PrettyErrorHandler, cyclone.web.RequestHandler):
+ @inlineCallbacks
def get(self):
+ # return dmx dict for that effect
uri = URIRef(self.get_argument('uri'))
- # return dmx dict for that effect
- self.write(effectDmxDict(self.settings.graph, uri))
+ response = yield cyclone.httpclient.fetch(
+ networking.musicPlayer.path('time'))
+ songTime = json.loads(response.body)['t']
+ self.write(effectDmxDict(self.settings.graph, uri, songTime))
class SongEffectsEval(PrettyErrorHandler, cyclone.web.RequestHandler):
def get(self):
diff --git a/light9/curvecalc/curve.py b/light9/curvecalc/curve.py
--- a/light9/curvecalc/curve.py
+++ b/light9/curvecalc/curve.py
@@ -41,6 +41,15 @@ class Curve(object):
self.points.sort()
dispatcher.send("points changed",sender=self)
+ def set_from_string(self, pts):
+ self.points[:] = []
+ vals = pts.split()
+ pairs = zip(vals[0::2], vals[1::2])
+ for x, y in pairs:
+ self.points.append((float(x), ast.literal_eval(y)))
+ self.points.sort()
+ dispatcher.send("points changed",sender=self)
+
def save(self,filename):
if filename.endswith('-music') or filename.endswith('_music'):
print "not saving music track"
@@ -53,7 +62,6 @@ class Curve(object):
def eval(self, t, allow_muting=True):
if self.muted and allow_muting:
return 0
-
i = bisect_left(self.points,(t,None))-1
if i == -1:
diff --git a/show/dance2014/demo.n3 b/show/dance2014/demo.n3
--- a/show/dance2014/demo.n3
+++ b/show/dance2014/demo.n3
@@ -1,12 +1,30 @@
@prefix : .
+@prefix rdf: .
@prefix rdfs: .
+@prefix xml: .
+@prefix xsd: .
+
+@prefix ch: .
+@prefix dmx: .
+
+dmx:c68 :dmxAddress 68 .
+
+ch:house-side a :Channel;
+ :output dmx:c68;
+ rdfs:label "house-side" .
+
+ a :Submaster ;
+ rdfs:label "houseside" ;
+ :lightLevel .
+
+ a :ChannelSetting ;
+ :channel ;
+ :level 1e+00 .
# curvedb writes these. point data might be in separate files
a :Curve;
rdfs:label "opening";
- :points "0.0 0 183.695203336 0" .
-
-
+ :points "0.0 .2 183.695203336 .6" .
# :Effect replaces :Subterm
@@ -20,6 +38,6 @@
:dep ,
.
- a :Song;
+
:effect
.