annotate light9/collector/collector.py @ 1866:3c523c71da29

pyflakes cleanups and some refactors Ignore-this: f7372e678699175feb4e628eee3d768c
author Drew Perttula <drewp@bigasterisk.com>
date Sat, 25 May 2019 12:10:51 +0000
parents 5bcb950024af
children 5cde72dfdc22
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1288
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
1 import time
1289
5a4e74f1e36a Fixed client session clearing bugs.
Drew Perttula <drewp@bigasterisk.com>
parents: 1288
diff changeset
2 import logging
1448
931d2dafca12 new feature: values can have their range remapped in the device processing
drewp@bigasterisk.com
parents: 1446
diff changeset
3 from rdflib import Literal
1506
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
4 from light9.namespaces import L9, RDF
1288
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
5 from light9.collector.output import setListElem
1302
24357038de9f resolver does per-channel max() for color attributes
Drew Perttula <drewp@bigasterisk.com>
parents: 1300
diff changeset
6 from light9.collector.device import toOutputAttrs, resolve
1288
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
7
1506
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
8 # types only
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
9 from rdflib import Graph, URIRef
1866
3c523c71da29 pyflakes cleanups and some refactors
Drew Perttula <drewp@bigasterisk.com>
parents: 1860
diff changeset
10 from typing import List, Dict, Tuple, TypeVar, Generic, Optional
1506
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
11 from light9.collector.output import Output
1866
3c523c71da29 pyflakes cleanups and some refactors
Drew Perttula <drewp@bigasterisk.com>
parents: 1860
diff changeset
12 from light9.collector.weblisteners import WebListeners
1506
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
13
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
14 ClientType = TypeVar('ClientType')
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
15 ClientSessionType = TypeVar('ClientSessionType')
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
16
1289
5a4e74f1e36a Fixed client session clearing bugs.
Drew Perttula <drewp@bigasterisk.com>
parents: 1288
diff changeset
17 log = logging.getLogger('collector')
1288
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
18
1858
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
19
1288
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
20 def outputMap(graph, outputs):
1506
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
21 # type: (Graph, List[Output]) -> Dict[Tuple[URIRef, URIRef], Tuple[Output, int]]
1288
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
22 """From rdf config graph, compute a map of
1416
ab7b40d20af0 rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents: 1412
diff changeset
23 (device, outputattr) : (output, index)
1288
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
24 that explains which output index to set for any device update.
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
25 """
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
26 ret = {}
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
27
1866
3c523c71da29 pyflakes cleanups and some refactors
Drew Perttula <drewp@bigasterisk.com>
parents: 1860
diff changeset
28 outputByUri: Dict[URIRef, Output] = {} # universeUri : output
1288
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
29 for out in outputs:
1416
ab7b40d20af0 rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents: 1412
diff changeset
30 outputByUri[out.uri] = out
1288
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
31
1416
ab7b40d20af0 rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents: 1412
diff changeset
32 for dc in graph.subjects(RDF.type, L9['DeviceClass']):
1506
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
33 log.info('mapping DeviceClass %s', dc)
1416
ab7b40d20af0 rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents: 1412
diff changeset
34 for dev in graph.subjects(RDF.type, dc):
1506
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
35 log.info(' mapping device %s', dev)
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
36 universe = graph.value(dev, L9['dmxUniverse'])
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
37 try:
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
38 output = outputByUri[universe]
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
39 except Exception:
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
40 log.warn('dev %r :dmxUniverse %r', dev, universe)
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
41 raise
1416
ab7b40d20af0 rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents: 1412
diff changeset
42 dmxBase = int(graph.value(dev, L9['dmxBase']).toPython())
ab7b40d20af0 rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents: 1412
diff changeset
43 for row in graph.objects(dc, L9['attr']):
ab7b40d20af0 rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents: 1412
diff changeset
44 outputAttr = graph.value(row, L9['outputAttr'])
ab7b40d20af0 rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents: 1412
diff changeset
45 offset = int(graph.value(row, L9['dmxOffset']).toPython())
ab7b40d20af0 rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents: 1412
diff changeset
46 index = dmxBase + offset - 1
ab7b40d20af0 rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents: 1412
diff changeset
47 ret[(dev, outputAttr)] = (output, index)
1541
c1bf296b0a74 collector uses cyclone and gets a web ui showing output attrs
Drew Perttula <drewp@bigasterisk.com>
parents: 1506
diff changeset
48 log.debug(' map %s to %s,%s', outputAttr, output, index)
1288
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
49 return ret
1858
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
50
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
51
1506
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
52 class Collector(Generic[ClientType, ClientSessionType]):
1858
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
53
1866
3c523c71da29 pyflakes cleanups and some refactors
Drew Perttula <drewp@bigasterisk.com>
parents: 1860
diff changeset
54 def __init__(self,
3c523c71da29 pyflakes cleanups and some refactors
Drew Perttula <drewp@bigasterisk.com>
parents: 1860
diff changeset
55 graph: Graph,
3c523c71da29 pyflakes cleanups and some refactors
Drew Perttula <drewp@bigasterisk.com>
parents: 1860
diff changeset
56 outputs: List[Output],
3c523c71da29 pyflakes cleanups and some refactors
Drew Perttula <drewp@bigasterisk.com>
parents: 1860
diff changeset
57 listeners: Optional[WebListeners] = None,
3c523c71da29 pyflakes cleanups and some refactors
Drew Perttula <drewp@bigasterisk.com>
parents: 1860
diff changeset
58 clientTimeoutSec: float = 10):
1307
8863b4485fd4 collector uses rdfdb
Drew Perttula <drewp@bigasterisk.com>
parents: 1302
diff changeset
59 self.graph = graph
1288
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
60 self.outputs = outputs
1541
c1bf296b0a74 collector uses cyclone and gets a web ui showing output attrs
Drew Perttula <drewp@bigasterisk.com>
parents: 1506
diff changeset
61 self.listeners = listeners
1288
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
62 self.clientTimeoutSec = clientTimeoutSec
1542
60e559cb1a5e collector now runs the device function even on devs that have no settings, in case they have some fixed output values (e.g. light mode)
Drew Perttula <drewp@bigasterisk.com>
parents: 1541
diff changeset
63 self.initTime = time.time()
60e559cb1a5e collector now runs the device function even on devs that have no settings, in case they have some fixed output values (e.g. light mode)
Drew Perttula <drewp@bigasterisk.com>
parents: 1541
diff changeset
64 self.allDevices = set()
1307
8863b4485fd4 collector uses rdfdb
Drew Perttula <drewp@bigasterisk.com>
parents: 1302
diff changeset
65
8863b4485fd4 collector uses rdfdb
Drew Perttula <drewp@bigasterisk.com>
parents: 1302
diff changeset
66 self.graph.addHandler(self.rebuildOutputMap)
1506
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
67
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
68 # client : (session, time, {(dev,devattr): latestValue})
1858
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
69 self.lastRequest = {
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
70 } # type: Dict[Tuple[ClientType, ClientSessionType], Tuple[float, Dict[Tuple[URIRef, URIRef], float]]]
1506
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
71
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
72 # (dev, devAttr): value to use instead of 0
1858
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
73 self.stickyAttrs = {} # type: Dict[Tuple[URIRef, URIRef], float]
1288
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
74
1307
8863b4485fd4 collector uses rdfdb
Drew Perttula <drewp@bigasterisk.com>
parents: 1302
diff changeset
75 def rebuildOutputMap(self):
1858
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
76 self.outputMap = outputMap(
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
77 self.graph, self.outputs) # (device, outputattr) : (output, index)
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
78 self.deviceType = {} # uri: type that's a subclass of Device
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
79 self.remapOut = {} # (device, deviceAttr) : (start, end)
1416
ab7b40d20af0 rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents: 1412
diff changeset
80 for dc in self.graph.subjects(RDF.type, L9['DeviceClass']):
ab7b40d20af0 rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents: 1412
diff changeset
81 for dev in self.graph.subjects(RDF.type, dc):
1542
60e559cb1a5e collector now runs the device function even on devs that have no settings, in case they have some fixed output values (e.g. light mode)
Drew Perttula <drewp@bigasterisk.com>
parents: 1541
diff changeset
82 self.allDevices.add(dev)
1416
ab7b40d20af0 rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents: 1412
diff changeset
83 self.deviceType[dev] = dc
1307
8863b4485fd4 collector uses rdfdb
Drew Perttula <drewp@bigasterisk.com>
parents: 1302
diff changeset
84
1448
931d2dafca12 new feature: values can have their range remapped in the device processing
drewp@bigasterisk.com
parents: 1446
diff changeset
85 for remap in self.graph.objects(dev, L9['outputAttrRange']):
931d2dafca12 new feature: values can have their range remapped in the device processing
drewp@bigasterisk.com
parents: 1446
diff changeset
86 attr = self.graph.value(remap, L9['outputAttr'])
931d2dafca12 new feature: values can have their range remapped in the device processing
drewp@bigasterisk.com
parents: 1446
diff changeset
87 start = float(self.graph.value(remap, L9['start']))
931d2dafca12 new feature: values can have their range remapped in the device processing
drewp@bigasterisk.com
parents: 1446
diff changeset
88 end = float(self.graph.value(remap, L9['end']))
931d2dafca12 new feature: values can have their range remapped in the device processing
drewp@bigasterisk.com
parents: 1446
diff changeset
89 self.remapOut[(dev, attr)] = start, end
931d2dafca12 new feature: values can have their range remapped in the device processing
drewp@bigasterisk.com
parents: 1446
diff changeset
90
1288
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
91 def _forgetStaleClients(self, now):
1506
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
92 # type: (float) -> None
1602
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
93 staleClientSessions = []
1859
f066d6e874db 2to3 with these fixers: all idioms set_literal
drewp@bigasterisk.com
parents: 1858
diff changeset
94 for c, (t, _) in self.lastRequest.items():
1288
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
95 if t < now - self.clientTimeoutSec:
1602
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
96 staleClientSessions.append(c)
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
97 for c in staleClientSessions:
1506
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
98 log.info('forgetting stale client %r', c)
1288
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
99 del self.lastRequest[c]
1300
d51014267bfd move device-specific code out of collector. resolver isn't done yet. live.html can edit colors
Drew Perttula <drewp@bigasterisk.com>
parents: 1289
diff changeset
100
1602
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
101 # todo: move to settings.py
1372
f427801da9f6 collector properly merges repeated attr settings in the same message
Drew Perttula <drewp@bigasterisk.com>
parents: 1307
diff changeset
102 def resolvedSettingsDict(self, settingsList):
1506
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
103 # type: (List[Tuple[URIRef, URIRef, float]]) -> Dict[Tuple[URIRef, URIRef], float]
1858
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
104 out = {} # type: Dict[Tuple[URIRef, URIRef], float]
1470
b1d8abc96f06 don't run rotations to zero when no one is requesting them.
drewp@bigasterisk.com
parents: 1450
diff changeset
105 for d, da, v in settingsList:
b1d8abc96f06 don't run rotations to zero when no one is requesting them.
drewp@bigasterisk.com
parents: 1450
diff changeset
106 if (d, da) in out:
b1d8abc96f06 don't run rotations to zero when no one is requesting them.
drewp@bigasterisk.com
parents: 1450
diff changeset
107 out[(d, da)] = resolve(d, da, [out[(d, da)], v])
1372
f427801da9f6 collector properly merges repeated attr settings in the same message
Drew Perttula <drewp@bigasterisk.com>
parents: 1307
diff changeset
108 else:
1470
b1d8abc96f06 don't run rotations to zero when no one is requesting them.
drewp@bigasterisk.com
parents: 1450
diff changeset
109 out[(d, da)] = v
1372
f427801da9f6 collector properly merges repeated attr settings in the same message
Drew Perttula <drewp@bigasterisk.com>
parents: 1307
diff changeset
110 return out
f427801da9f6 collector properly merges repeated attr settings in the same message
Drew Perttula <drewp@bigasterisk.com>
parents: 1307
diff changeset
111
1506
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
112 def _warnOnLateRequests(self, client, now, sendTime):
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
113 requestLag = now - sendTime
1858
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
114 if requestLag > .1 and now > self.initTime + 10 and getattr(
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
115 self, '_lastWarnTime', 0) < now - 3:
1799
0bb7b9df12e5 collector warnings and errors. the reactor.crash isn't working.
drewp@bigasterisk.com
parents: 1700
diff changeset
116 self._lastWarnTime = now
1858
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
117 log.warn(
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
118 'collector.setAttrs from %s is running %.1fms after the request was made',
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
119 client, requestLag * 1000)
1289
5a4e74f1e36a Fixed client session clearing bugs.
Drew Perttula <drewp@bigasterisk.com>
parents: 1288
diff changeset
120
1602
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
121 def _merge(self, lastRequests):
1858
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
122 deviceAttrs = {} # device: {deviceAttr: value}
1602
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
123 for _, lastSettings in lastRequests:
1859
f066d6e874db 2to3 with these fixers: all idioms set_literal
drewp@bigasterisk.com
parents: 1858
diff changeset
124 for (device, deviceAttr), value in lastSettings.items():
1448
931d2dafca12 new feature: values can have their range remapped in the device processing
drewp@bigasterisk.com
parents: 1446
diff changeset
125 if (device, deviceAttr) in self.remapOut:
931d2dafca12 new feature: values can have their range remapped in the device processing
drewp@bigasterisk.com
parents: 1446
diff changeset
126 start, end = self.remapOut[(device, deviceAttr)]
931d2dafca12 new feature: values can have their range remapped in the device processing
drewp@bigasterisk.com
parents: 1446
diff changeset
127 value = Literal(start + float(value) * (end - start))
1450
ddb7622698a8 don't mix remapped values with unremapped ones
drewp@bigasterisk.com
parents: 1448
diff changeset
128
ddb7622698a8 don't mix remapped values with unremapped ones
drewp@bigasterisk.com
parents: 1448
diff changeset
129 attrs = deviceAttrs.setdefault(device, {})
ddb7622698a8 don't mix remapped values with unremapped ones
drewp@bigasterisk.com
parents: 1448
diff changeset
130 if deviceAttr in attrs:
1858
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
131 value = resolve(device, deviceAttr,
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
132 [attrs[deviceAttr], value])
1416
ab7b40d20af0 rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents: 1412
diff changeset
133 attrs[deviceAttr] = value
1470
b1d8abc96f06 don't run rotations to zero when no one is requesting them.
drewp@bigasterisk.com
parents: 1450
diff changeset
134 # list should come from the graph. these are attrs
b1d8abc96f06 don't run rotations to zero when no one is requesting them.
drewp@bigasterisk.com
parents: 1450
diff changeset
135 # that should default to holding the last position,
b1d8abc96f06 don't run rotations to zero when no one is requesting them.
drewp@bigasterisk.com
parents: 1450
diff changeset
136 # not going to 0.
1475
a749079ec774 focus should also be sticky attr
drewp@bigasterisk.com
parents: 1470
diff changeset
137 if deviceAttr in [L9['rx'], L9['ry'], L9['zoom'], L9['focus']]:
1470
b1d8abc96f06 don't run rotations to zero when no one is requesting them.
drewp@bigasterisk.com
parents: 1450
diff changeset
138 self.stickyAttrs[(device, deviceAttr)] = value
1300
d51014267bfd move device-specific code out of collector. resolver isn't done yet. live.html can edit colors
Drew Perttula <drewp@bigasterisk.com>
parents: 1289
diff changeset
139
1470
b1d8abc96f06 don't run rotations to zero when no one is requesting them.
drewp@bigasterisk.com
parents: 1450
diff changeset
140 # e.g. don't let an unspecified rotation go to 0
1859
f066d6e874db 2to3 with these fixers: all idioms set_literal
drewp@bigasterisk.com
parents: 1858
diff changeset
141 for (d, da), v in self.stickyAttrs.items():
1470
b1d8abc96f06 don't run rotations to zero when no one is requesting them.
drewp@bigasterisk.com
parents: 1450
diff changeset
142 daDict = deviceAttrs.setdefault(d, {})
b1d8abc96f06 don't run rotations to zero when no one is requesting them.
drewp@bigasterisk.com
parents: 1450
diff changeset
143 if da not in daDict:
b1d8abc96f06 don't run rotations to zero when no one is requesting them.
drewp@bigasterisk.com
parents: 1450
diff changeset
144 daDict[da] = v
1858
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
145
1602
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
146 return deviceAttrs
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
147
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
148 def setAttrs(self, client, clientSession, settings, sendTime):
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
149 """
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
150 settings is a list of (device, attr, value). These attrs are
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
151 device attrs. We resolve conflicting values, process them into
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
152 output attrs, and call Output.update/Output.flush to send the
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
153 new outputs.
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
154
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
155 client is a string naming the type of client. (client,
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
156 clientSession) is a unique client instance.
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
157
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
158 Each client session's last settings will be forgotten after
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
159 clientTimeoutSec.
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
160 """
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
161 now = time.time()
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
162 self._warnOnLateRequests(client, now, sendTime)
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
163
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
164 self._forgetStaleClients(now)
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
165
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
166 uniqueSettings = self.resolvedSettingsDict(settings)
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
167 self.lastRequest[(client, clientSession)] = (now, uniqueSettings)
0fc61e701347 collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents: 1596
diff changeset
168
1859
f066d6e874db 2to3 with these fixers: all idioms set_literal
drewp@bigasterisk.com
parents: 1858
diff changeset
169 deviceAttrs = self._merge(iter(self.lastRequest.values()))
1858
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
170
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
171 outputAttrs = {} # device: {outputAttr: value}
1542
60e559cb1a5e collector now runs the device function even on devs that have no settings, in case they have some fixed output values (e.g. light mode)
Drew Perttula <drewp@bigasterisk.com>
parents: 1541
diff changeset
172 for d in self.allDevices:
1416
ab7b40d20af0 rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents: 1412
diff changeset
173 try:
ab7b40d20af0 rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents: 1412
diff changeset
174 devType = self.deviceType[d]
ab7b40d20af0 rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents: 1412
diff changeset
175 except KeyError:
ab7b40d20af0 rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents: 1412
diff changeset
176 log.warn("request for output to unconfigured device %s" % d)
ab7b40d20af0 rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents: 1412
diff changeset
177 continue
1809
778c67ab70c9 set zmq highWaterMark to dump stale messages, especially those sent when collector isn't running
drewp@bigasterisk.com
parents: 1799
diff changeset
178 try:
778c67ab70c9 set zmq highWaterMark to dump stale messages, especially those sent when collector isn't running
drewp@bigasterisk.com
parents: 1799
diff changeset
179 outputAttrs[d] = toOutputAttrs(devType, deviceAttrs.get(d, {}))
778c67ab70c9 set zmq highWaterMark to dump stale messages, especially those sent when collector isn't running
drewp@bigasterisk.com
parents: 1799
diff changeset
180 if self.listeners:
1858
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
181 self.listeners.outputAttrsSet(d, outputAttrs[d],
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
182 self.outputMap)
1809
778c67ab70c9 set zmq highWaterMark to dump stale messages, especially those sent when collector isn't running
drewp@bigasterisk.com
parents: 1799
diff changeset
183 except Exception as e:
778c67ab70c9 set zmq highWaterMark to dump stale messages, especially those sent when collector isn't running
drewp@bigasterisk.com
parents: 1799
diff changeset
184 log.error('failing toOutputAttrs on %s: %r', d, e)
1858
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
185
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
186 pendingOut = {} # output : values
1437
d149a2c2236c always send trailing zeros to dmx
drewp@bigasterisk.com
parents: 1436
diff changeset
187 for out in self.outputs:
d149a2c2236c always send trailing zeros to dmx
drewp@bigasterisk.com
parents: 1436
diff changeset
188 pendingOut[out] = [0] * out.numChannels
1506
37cbb245d93c fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents: 1492
diff changeset
189
1859
f066d6e874db 2to3 with these fixers: all idioms set_literal
drewp@bigasterisk.com
parents: 1858
diff changeset
190 for device, attrs in outputAttrs.items():
f066d6e874db 2to3 with these fixers: all idioms set_literal
drewp@bigasterisk.com
parents: 1858
diff changeset
191 for outputAttr, value in attrs.items():
1416
ab7b40d20af0 rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents: 1412
diff changeset
192 self.setAttr(device, outputAttr, value, pendingOut)
1288
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
193
1436
d0d5900a8031 collector run the blocking dmx output calls in another thread, so they don't add delay to our http server
drewp@bigasterisk.com
parents: 1426
diff changeset
194 dt1 = 1000 * (time.time() - now)
1288
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
195 self.flush(pendingOut)
1436
d0d5900a8031 collector run the blocking dmx output calls in another thread, so they don't add delay to our http server
drewp@bigasterisk.com
parents: 1426
diff changeset
196 dt2 = 1000 * (time.time() - now)
1676
103d67ebf5e2 collector: less log
drewp@bigasterisk.com
parents: 1602
diff changeset
197 if dt1 > 30:
1858
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
198 log.warn(
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
199 "slow setAttrs: %.1fms -> flush -> %.1fms. lr %s da %s oa %s" %
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
200 (dt1, dt2, len(
7772cc48e016 reformat all python
drewp@bigasterisk.com
parents: 1809
diff changeset
201 self.lastRequest), len(deviceAttrs), len(outputAttrs)))
1288
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
202
1416
ab7b40d20af0 rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents: 1412
diff changeset
203 def setAttr(self, device, outputAttr, value, pendingOut):
ab7b40d20af0 rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents: 1412
diff changeset
204 output, index = self.outputMap[(device, outputAttr)]
1437
d149a2c2236c always send trailing zeros to dmx
drewp@bigasterisk.com
parents: 1436
diff changeset
205 outList = pendingOut[output]
1300
d51014267bfd move device-specific code out of collector. resolver isn't done yet. live.html can edit colors
Drew Perttula <drewp@bigasterisk.com>
parents: 1289
diff changeset
206 setListElem(outList, index, value, combine=max)
1288
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
207
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
208 def flush(self, pendingOut):
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
209 """write any changed outputs"""
1859
f066d6e874db 2to3 with these fixers: all idioms set_literal
drewp@bigasterisk.com
parents: 1858
diff changeset
210 for out, vals in pendingOut.items():
1288
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
211 out.update(vals)
5e76c8fd8a03 rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
212 out.flush()