Mercurial > code > home > repos > light9
annotate light9/collector/collector.py @ 2227:fe3543310d34
move uriTail to a better layer of code
author | drewp@bigasterisk.com |
---|---|
date | Tue, 23 May 2023 23:56:20 -0700 |
parents | e22c7d15a504 |
children | 2b8a2a25b154 |
rev | line source |
---|---|
2154 | 1 import logging |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
2 import time |
2162 | 3 from typing import Dict, List, Set, Tuple, cast |
2199 | 4 from light9.typedgraph import typedValue |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
5 |
2154 | 6 from rdfdb.syncedgraph.syncedgraph import SyncedGraph |
2193
f79fff92990b
collector.output use asyncio loop, not twisted loop. other cleanups.
drewp@bigasterisk.com
parents:
2183
diff
changeset
|
7 from rdflib import URIRef |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
8 |
2154 | 9 from light9.collector.device import resolve, toOutputAttrs |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
10 from light9.collector.output import Output as OutputInstance |
1866
3c523c71da29
pyflakes cleanups and some refactors
Drew Perttula <drewp@bigasterisk.com>
parents:
1860
diff
changeset
|
11 from light9.collector.weblisteners import WebListeners |
2193
f79fff92990b
collector.output use asyncio loop, not twisted loop. other cleanups.
drewp@bigasterisk.com
parents:
2183
diff
changeset
|
12 from light9.effect.settings import DeviceSettings |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
13 from light9.namespaces import L9, RDF |
2170
066f05ad7900
collector: even stronger types; repair test code (some are failing)
drewp@bigasterisk.com
parents:
2162
diff
changeset
|
14 from light9.newtypes import (ClientSessionType, ClientType, DeviceAttr, DeviceClass, DeviceSetting, DeviceUri, DmxIndex, DmxMessageIndex, OutputAttr, |
2227
fe3543310d34
move uriTail to a better layer of code
drewp@bigasterisk.com
parents:
2217
diff
changeset
|
15 OutputRange, OutputUri, OutputValue, UnixTime, VTUnion, uriTail) |
2072 | 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 | 19 |
2155
092967f313e1
attempt to make things more typesafe and readable (untested)
drewp@bigasterisk.com
parents:
2154
diff
changeset
|
20 def makeDmxMessageIndex(base: DmxIndex, offset: DmxIndex) -> DmxMessageIndex: |
092967f313e1
attempt to make things more typesafe and readable (untested)
drewp@bigasterisk.com
parents:
2154
diff
changeset
|
21 return DmxMessageIndex(base + offset - 1) |
092967f313e1
attempt to make things more typesafe and readable (untested)
drewp@bigasterisk.com
parents:
2154
diff
changeset
|
22 |
092967f313e1
attempt to make things more typesafe and readable (untested)
drewp@bigasterisk.com
parents:
2154
diff
changeset
|
23 |
2173
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
24 def _outputMap(graph: SyncedGraph, outputs: Set[OutputUri]) -> Dict[Tuple[DeviceUri, OutputAttr], Tuple[OutputUri, DmxMessageIndex]]: |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
25 """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
|
26 (device, outputattr) : (output, index) |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
27 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
|
28 """ |
2173
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
29 ret = cast(Dict[Tuple[DeviceUri, OutputAttr], Tuple[OutputUri, DmxMessageIndex]], {}) |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
30 |
1416
ab7b40d20af0
rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents:
1412
diff
changeset
|
31 for dc in graph.subjects(RDF.type, L9['DeviceClass']): |
2194 | 32 log.info('mapping devices of class %s', dc) |
1416
ab7b40d20af0
rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents:
1412
diff
changeset
|
33 for dev in graph.subjects(RDF.type, dc): |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
34 dev = cast(DeviceUri, dev) |
2193
f79fff92990b
collector.output use asyncio loop, not twisted loop. other cleanups.
drewp@bigasterisk.com
parents:
2183
diff
changeset
|
35 log.info(' 💡 mapping device %s', dev) |
2155
092967f313e1
attempt to make things more typesafe and readable (untested)
drewp@bigasterisk.com
parents:
2154
diff
changeset
|
36 universe = typedValue(OutputUri, graph, dev, L9['dmxUniverse']) |
2173
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
37 if universe not in outputs: |
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
38 raise ValueError(f'{dev=} is configured to be in {universe=}, but we have no Output for that universe') |
2155
092967f313e1
attempt to make things more typesafe and readable (untested)
drewp@bigasterisk.com
parents:
2154
diff
changeset
|
39 try: |
092967f313e1
attempt to make things more typesafe and readable (untested)
drewp@bigasterisk.com
parents:
2154
diff
changeset
|
40 dmxBase = typedValue(DmxIndex, graph, dev, L9['dmxBase']) |
092967f313e1
attempt to make things more typesafe and readable (untested)
drewp@bigasterisk.com
parents:
2154
diff
changeset
|
41 except ValueError: |
1966 | 42 raise ValueError('no :dmxBase for %s' % dev) |
2155
092967f313e1
attempt to make things more typesafe and readable (untested)
drewp@bigasterisk.com
parents:
2154
diff
changeset
|
43 |
2193
f79fff92990b
collector.output use asyncio loop, not twisted loop. other cleanups.
drewp@bigasterisk.com
parents:
2183
diff
changeset
|
44 for row in sorted(graph.objects(dc, L9['attr']), key=str): |
2155
092967f313e1
attempt to make things more typesafe and readable (untested)
drewp@bigasterisk.com
parents:
2154
diff
changeset
|
45 outputAttr = typedValue(OutputAttr, graph, row, L9['outputAttr']) |
092967f313e1
attempt to make things more typesafe and readable (untested)
drewp@bigasterisk.com
parents:
2154
diff
changeset
|
46 offset = typedValue(DmxIndex, graph, row, L9['dmxOffset']) |
092967f313e1
attempt to make things more typesafe and readable (untested)
drewp@bigasterisk.com
parents:
2154
diff
changeset
|
47 index = makeDmxMessageIndex(dmxBase, offset) |
2173
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
48 ret[(dev, outputAttr)] = (universe, index) |
2193
f79fff92990b
collector.output use asyncio loop, not twisted loop. other cleanups.
drewp@bigasterisk.com
parents:
2183
diff
changeset
|
49 log.info(f' {uriTail(outputAttr):15} maps to {uriTail(universe)} index {index}') |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
50 return ret |
1858 | 51 |
52 | |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
53 class Collector: |
2193
f79fff92990b
collector.output use asyncio loop, not twisted loop. other cleanups.
drewp@bigasterisk.com
parents:
2183
diff
changeset
|
54 """receives setAttrs calls; combines settings; renders them into what outputs like; calls Output.update""" |
1858 | 55 |
2072 | 56 def __init__(self, graph: SyncedGraph, outputs: List[OutputInstance], listeners: WebListeners, clientTimeoutSec: float = 10): |
1307
8863b4485fd4
collector uses rdfdb
Drew Perttula <drewp@bigasterisk.com>
parents:
1302
diff
changeset
|
57 self.graph = graph |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
58 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
|
59 self.listeners = listeners |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
60 self.clientTimeoutSec = clientTimeoutSec |
2194 | 61 |
62 self._initTime = time.time() | |
2173
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
63 self._outputByUri: Dict[OutputUri, OutputInstance] = {} |
2194 | 64 self._deviceType: Dict[DeviceUri, DeviceClass] = {} |
65 self.remapOut: Dict[Tuple[DeviceUri, OutputAttr], OutputRange] = {} | |
1307
8863b4485fd4
collector uses rdfdb
Drew Perttula <drewp@bigasterisk.com>
parents:
1302
diff
changeset
|
66 |
2194 | 67 self.graph.addHandler(self._compile) |
1506
37cbb245d93c
fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents:
1492
diff
changeset
|
68 |
2173
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
69 # rename to activeSessons ? |
2170
066f05ad7900
collector: even stronger types; repair test code (some are failing)
drewp@bigasterisk.com
parents:
2162
diff
changeset
|
70 self.lastRequest: Dict[Tuple[ClientType, ClientSessionType], Tuple[UnixTime, Dict[Tuple[DeviceUri, DeviceAttr], VTUnion]]] = {} |
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 |
2170
066f05ad7900
collector: even stronger types; repair test code (some are failing)
drewp@bigasterisk.com
parents:
2162
diff
changeset
|
73 self.stickyAttrs: Dict[Tuple[DeviceUri, DeviceAttr], VTUnion] = {} |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
74 |
2194 | 75 def _compile(self): |
76 self._outputByUri = self._compileOutputByUri() | |
77 self._outputMap = _outputMap(self.graph, set(self._outputByUri.keys())) | |
2173
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
78 |
2194 | 79 self._deviceType.clear() |
80 self.remapOut.clear() | |
1416
ab7b40d20af0
rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents:
1412
diff
changeset
|
81 for dc in self.graph.subjects(RDF.type, L9['DeviceClass']): |
2072 | 82 dc = cast(DeviceClass, dc) |
83 for dev in self.graph.subjects(RDF.type, dc): | |
84 dev = cast(DeviceUri, dev) | |
2194 | 85 self._deviceType[dev] = dc |
86 self._compileRemapForDevice(dev) | |
1307
8863b4485fd4
collector uses rdfdb
Drew Perttula <drewp@bigasterisk.com>
parents:
1302
diff
changeset
|
87 |
2194 | 88 def _compileOutputByUri(self) -> Dict[OutputUri, OutputInstance]: |
89 ret = {} | |
90 for output in self.outputs: | |
91 ret[OutputUri(output.uri)] = output | |
92 return ret | |
93 | |
94 def _compileRemapForDevice(self, dev: DeviceUri): | |
95 for remap in self.graph.objects(dev, L9['outputAttrRange']): | |
96 attr = typedValue(OutputAttr, self.graph, remap, L9['outputAttr']) | |
97 start = typedValue(float, self.graph, remap, L9['start']) | |
98 end = typedValue(float, self.graph, remap, L9['end']) | |
99 self.remapOut[(dev, attr)] = OutputRange((start, end)) | |
1448
931d2dafca12
new feature: values can have their range remapped in the device processing
drewp@bigasterisk.com
parents:
1446
diff
changeset
|
100 |
2204 | 101 def setAttrs(self, client: ClientType, clientSession: ClientSessionType, settings: DeviceSettings, sendTime: UnixTime): |
102 """ | |
103 Given DeviceSettings, we resolve conflicting values, | |
104 process them into output attrs, and call Output.update | |
105 to send the new outputs. | |
106 | |
107 client is a string naming the type of client. | |
108 (client, clientSession) is a unique client instance. | |
109 clientSession is deprecated. | |
110 | |
111 Each client session's last settings will be forgotten | |
112 after clientTimeoutSec. | |
113 """ | |
114 # todo: cleanup session code if we really don't want to be able to run multiple sessions of one client | |
115 clientSession = ClientSessionType("no_longer_used") | |
116 | |
117 now = UnixTime(time.time()) | |
118 self._warnOnLateRequests(client, now, sendTime) | |
119 | |
120 self._forgetStaleClients(now) | |
121 | |
122 self.lastRequest[(client, clientSession)] = (now, self._resolvedSettingsDict(settings)) | |
123 | |
124 deviceAttrs = self._merge(iter(self.lastRequest.values())) | |
125 | |
126 outputAttrsByDevice = self._convertToOutputAttrsPerDevice(deviceAttrs) | |
127 pendingOut = self._flattenDmxOutput(outputAttrsByDevice) | |
128 | |
2217 | 129 t2 = time.time() |
2204 | 130 |
131 self._updateOutputs(pendingOut) | |
132 | |
2217 | 133 t3 = time.time() |
134 if t2 - now > .030 or t3 - t2 > .030: | |
135 log.warning("slow setAttrs: prepare %.1fms -> updateOutputs %.1fms" % ((t2 - now) * 1000, (t3 - t2) * 1000)) | |
2204 | 136 |
137 def _warnOnLateRequests(self, client, now, sendTime): | |
138 requestLag = now - sendTime | |
139 if requestLag > .1 and now > self._initTime + 10 and getattr(self, '_lastWarnTime', 0) < now - 3: | |
140 self._lastWarnTime = now | |
141 log.warning('collector.setAttrs from %s is running %.1fms after the request was made', client, requestLag * 1000) | |
142 | |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
143 def _forgetStaleClients(self, now): |
1602
0fc61e701347
collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents:
1596
diff
changeset
|
144 staleClientSessions = [] |
2173
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
145 for clientSession, (reqTime, _) in self.lastRequest.items(): |
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
146 if reqTime < now - self.clientTimeoutSec: |
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
147 staleClientSessions.append(clientSession) |
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
148 for clientSession in staleClientSessions: |
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
149 log.info('forgetting stale client %r', clientSession) |
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
150 del self.lastRequest[clientSession] |
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
|
151 |
1602
0fc61e701347
collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents:
1596
diff
changeset
|
152 # todo: move to settings.py |
2208
091909b4b727
seems kind of important that effecteval return DeviceSettings, not more EffectSettings
drewp@bigasterisk.com
parents:
2204
diff
changeset
|
153 def _resolvedSettingsDict(self, settingsList: DeviceSettings) -> Dict[Tuple[DeviceUri, DeviceAttr], VTUnion]: |
2170
066f05ad7900
collector: even stronger types; repair test code (some are failing)
drewp@bigasterisk.com
parents:
2162
diff
changeset
|
154 out: Dict[Tuple[DeviceUri, DeviceAttr], VTUnion] = {} |
2208
091909b4b727
seems kind of important that effecteval return DeviceSettings, not more EffectSettings
drewp@bigasterisk.com
parents:
2204
diff
changeset
|
155 for devUri, devAttr, val in settingsList.asList(): |
2183
081f36506ad3
address a bunch of type errors and loose types
drewp@bigasterisk.com
parents:
2173
diff
changeset
|
156 if (devUri, devAttr) in out: |
081f36506ad3
address a bunch of type errors and loose types
drewp@bigasterisk.com
parents:
2173
diff
changeset
|
157 existingVal = out[(devUri, devAttr)] |
2194 | 158 out[(devUri, devAttr)] = resolve(self._deviceType[devUri], devAttr, [existingVal, val]) |
1372
f427801da9f6
collector properly merges repeated attr settings in the same message
Drew Perttula <drewp@bigasterisk.com>
parents:
1307
diff
changeset
|
159 else: |
2183
081f36506ad3
address a bunch of type errors and loose types
drewp@bigasterisk.com
parents:
2173
diff
changeset
|
160 out[(devUri, devAttr)] = val |
1372
f427801da9f6
collector properly merges repeated attr settings in the same message
Drew Perttula <drewp@bigasterisk.com>
parents:
1307
diff
changeset
|
161 return out |
f427801da9f6
collector properly merges repeated attr settings in the same message
Drew Perttula <drewp@bigasterisk.com>
parents:
1307
diff
changeset
|
162 |
1602
0fc61e701347
collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents:
1596
diff
changeset
|
163 def _merge(self, lastRequests): |
2170
066f05ad7900
collector: even stronger types; repair test code (some are failing)
drewp@bigasterisk.com
parents:
2162
diff
changeset
|
164 deviceAttrs: Dict[DeviceUri, Dict[DeviceAttr, VTUnion]] = {} # 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
|
165 for _, lastSettings in lastRequests: |
1859
f066d6e874db
2to3 with these fixers: all idioms set_literal
drewp@bigasterisk.com
parents:
1858
diff
changeset
|
166 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
|
167 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
|
168 start, end = self.remapOut[(device, deviceAttr)] |
2170
066f05ad7900
collector: even stronger types; repair test code (some are failing)
drewp@bigasterisk.com
parents:
2162
diff
changeset
|
169 value = start + float(value) * (end - start) |
1450
ddb7622698a8
don't mix remapped values with unremapped ones
drewp@bigasterisk.com
parents:
1448
diff
changeset
|
170 |
ddb7622698a8
don't mix remapped values with unremapped ones
drewp@bigasterisk.com
parents:
1448
diff
changeset
|
171 attrs = deviceAttrs.setdefault(device, {}) |
ddb7622698a8
don't mix remapped values with unremapped ones
drewp@bigasterisk.com
parents:
1448
diff
changeset
|
172 if deviceAttr in attrs: |
2072 | 173 value = resolve(device, deviceAttr, [attrs[deviceAttr], value]) |
1416
ab7b40d20af0
rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents:
1412
diff
changeset
|
174 attrs[deviceAttr] = value |
1470
b1d8abc96f06
don't run rotations to zero when no one is requesting them.
drewp@bigasterisk.com
parents:
1450
diff
changeset
|
175 # 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
|
176 # 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
|
177 # not going to 0. |
1475 | 178 if deviceAttr in [L9['rx'], L9['ry'], L9['zoom'], L9['focus']]: |
2072 | 179 self.stickyAttrs[(device, deviceAttr)] = cast(float, 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
|
180 |
1470
b1d8abc96f06
don't run rotations to zero when no one is requesting them.
drewp@bigasterisk.com
parents:
1450
diff
changeset
|
181 # 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
|
182 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
|
183 daDict = deviceAttrs.setdefault(d, {}) |
b1d8abc96f06
don't run rotations to zero when no one is requesting them.
drewp@bigasterisk.com
parents:
1450
diff
changeset
|
184 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
|
185 daDict[da] = v |
1858 | 186 |
1602
0fc61e701347
collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents:
1596
diff
changeset
|
187 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
|
188 |
2204 | 189 def _convertToOutputAttrsPerDevice(self, deviceAttrs): |
190 ret: Dict[DeviceUri, Dict[OutputAttr, OutputValue]] = {} | |
2194 | 191 for d, devType in self._deviceType.items(): |
1809
778c67ab70c9
set zmq highWaterMark to dump stale messages, especially those sent when collector isn't running
drewp@bigasterisk.com
parents:
1799
diff
changeset
|
192 try: |
2204 | 193 ret[d] = toOutputAttrs(devType, deviceAttrs.get(d, {})) |
194 self.listeners.outputAttrsSet(d, ret[d], 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
|
195 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
|
196 log.error('failing toOutputAttrs on %s: %r', d, e) |
2204 | 197 return ret |
2173
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
198 |
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
199 def _flattenDmxOutput(self, outputAttrs: Dict[DeviceUri, Dict[OutputAttr, OutputValue]]) -> Dict[OutputUri, bytearray]: |
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
200 pendingOut = cast(Dict[OutputUri, bytearray], {}) |
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
201 for outUri in self._outputByUri.keys(): |
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
202 pendingOut[outUri] = bytearray(512) |
1506
37cbb245d93c
fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents:
1492
diff
changeset
|
203 |
1859
f066d6e874db
2to3 with these fixers: all idioms set_literal
drewp@bigasterisk.com
parents:
1858
diff
changeset
|
204 for device, attrs in outputAttrs.items(): |
f066d6e874db
2to3 with these fixers: all idioms set_literal
drewp@bigasterisk.com
parents:
1858
diff
changeset
|
205 for outputAttr, value in attrs.items(): |
2194 | 206 outputUri, _index = self._outputMap[(device, outputAttr)] |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
207 index = DmxMessageIndex(_index) |
2173
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
208 outArray = pendingOut[outputUri] |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
209 if outArray[index] != 0: |
2202 | 210 log.warning(f'conflict: {outputUri} output array was already nonzero at 0-based index {index}') |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
211 raise ValueError(f"someone already wrote to index {index}") |
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
212 outArray[index] = value |
2173
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
213 return pendingOut |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
214 |
2173
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
215 def _updateOutputs(self, pendingOut: Dict[OutputUri, bytearray]): |
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
216 for uri, buf in pendingOut.items(): |
f239dedb025a
disable collector client sessions- we prob don't need them. refactor collector.py
drewp@bigasterisk.com
parents:
2170
diff
changeset
|
217 self._outputByUri[uri].update(bytes(buf)) |