Mercurial > code > home > repos > light9
annotate light9/collector/collector.py @ 2072:d5f1cc9615af
collector: rewrites for asyncio
author | drewp@bigasterisk.com |
---|---|
date | Sun, 22 May 2022 03:03:43 -0700 |
parents | f66dbe512025 |
children | b6a8289b1d1e |
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 |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
3 from typing import cast, List, Dict, Tuple, Optional, Set |
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
4 |
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
5 from rdflib import Graph, Literal |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
6 |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
7 from light9.collector.device import toOutputAttrs, resolve |
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
8 from light9.collector.output import Output as OutputInstance |
1866
3c523c71da29
pyflakes cleanups and some refactors
Drew Perttula <drewp@bigasterisk.com>
parents:
1860
diff
changeset
|
9 from light9.collector.weblisteners import WebListeners |
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.namespaces import L9, RDF |
2072 | 11 from rdfdb.syncedgraph.syncedgraph import SyncedGraph |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
12 from light9.newtypes import ClientType, ClientSessionType, OutputUri, DeviceUri, DeviceClass, DmxIndex, DmxMessageIndex, DeviceAttr, OutputAttr, OutputValue, UnixTime, OutputRange |
2072 | 13 |
1289
5a4e74f1e36a
Fixed client session clearing bugs.
Drew Perttula <drewp@bigasterisk.com>
parents:
1288
diff
changeset
|
14 log = logging.getLogger('collector') |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
15 |
1858 | 16 |
2072 | 17 def outputMap(graph: SyncedGraph, outputs: List[OutputInstance]) -> Dict[Tuple[DeviceUri, OutputAttr], Tuple[OutputInstance, DmxMessageIndex]]: |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
18 """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
|
19 (device, outputattr) : (output, index) |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
20 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
|
21 """ |
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
22 ret = {} |
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
23 |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
24 outputByUri: Dict[OutputUri, OutputInstance] = {} |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
25 for out in outputs: |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
26 outputByUri[OutputUri(out.uri)] = out |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
27 |
1416
ab7b40d20af0
rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents:
1412
diff
changeset
|
28 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
|
29 log.info('mapping DeviceClass %s', dc) |
1416
ab7b40d20af0
rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents:
1412
diff
changeset
|
30 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
|
31 dev = cast(DeviceUri, dev) |
1506
37cbb245d93c
fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents:
1492
diff
changeset
|
32 log.info(' mapping device %s', dev) |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
33 universe = cast(OutputUri, graph.value(dev, L9['dmxUniverse'])) |
1506
37cbb245d93c
fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents:
1492
diff
changeset
|
34 try: |
37cbb245d93c
fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents:
1492
diff
changeset
|
35 output = outputByUri[universe] |
37cbb245d93c
fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents:
1492
diff
changeset
|
36 except Exception: |
37cbb245d93c
fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents:
1492
diff
changeset
|
37 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
|
38 raise |
1966 | 39 base = graph.value(dev, L9['dmxBase']) |
40 if base is None: | |
41 raise ValueError('no :dmxBase for %s' % dev) | |
42 dmxBase = DmxIndex(cast(Literal, base).toPython()) | |
1416
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']): |
2072 | 44 outputAttr = cast(OutputAttr, graph.value(row, L9['outputAttr'])) |
45 offset = DmxIndex(cast(Literal, graph.value(row, L9['dmxOffset'])).toPython()) | |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
46 index = DmxMessageIndex(dmxBase + offset - 1) |
1416
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 | 50 |
51 | |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
52 class Collector: |
2072 | 53 """receives setAttrs calls; combines settings; renders them into what outputs like; call Output.update""" |
1858 | 54 |
2072 | 55 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
|
56 self.graph = graph |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
57 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
|
58 self.listeners = listeners |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
59 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
|
60 self.initTime = time.time() |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
61 self.allDevices: Set[DeviceUri] = set() |
1307
8863b4485fd4
collector uses rdfdb
Drew Perttula <drewp@bigasterisk.com>
parents:
1302
diff
changeset
|
62 |
8863b4485fd4
collector uses rdfdb
Drew Perttula <drewp@bigasterisk.com>
parents:
1302
diff
changeset
|
63 self.graph.addHandler(self.rebuildOutputMap) |
1506
37cbb245d93c
fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents:
1492
diff
changeset
|
64 |
37cbb245d93c
fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents:
1492
diff
changeset
|
65 # client : (session, time, {(dev,devattr): latestValue}) |
2072 | 66 self.lastRequest: Dict[Tuple[ClientType, ClientSessionType], Tuple[UnixTime, Dict[Tuple[DeviceUri, DeviceAttr], float]]] = {} |
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 # (dev, devAttr): value to use instead of 0 |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
69 self.stickyAttrs: Dict[Tuple[DeviceUri, DeviceAttr], float] = {} |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
70 |
1307
8863b4485fd4
collector uses rdfdb
Drew Perttula <drewp@bigasterisk.com>
parents:
1302
diff
changeset
|
71 def rebuildOutputMap(self): |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
72 self.outputMap = outputMap(self.graph, self.outputs) |
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
73 self.deviceType: Dict[DeviceUri, DeviceClass] = {} |
2072 | 74 self.remapOut: Dict[Tuple[DeviceUri, OutputAttr], OutputRange] = {} |
1416
ab7b40d20af0
rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents:
1412
diff
changeset
|
75 for dc in self.graph.subjects(RDF.type, L9['DeviceClass']): |
2072 | 76 dc = cast(DeviceClass, dc) |
77 for dev in self.graph.subjects(RDF.type, dc): | |
78 dev = cast(DeviceUri, dev) | |
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
|
79 self.allDevices.add(dev) |
1416
ab7b40d20af0
rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents:
1412
diff
changeset
|
80 self.deviceType[dev] = dc |
1307
8863b4485fd4
collector uses rdfdb
Drew Perttula <drewp@bigasterisk.com>
parents:
1302
diff
changeset
|
81 |
1448
931d2dafca12
new feature: values can have their range remapped in the device processing
drewp@bigasterisk.com
parents:
1446
diff
changeset
|
82 for remap in self.graph.objects(dev, L9['outputAttrRange']): |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
83 attr = OutputAttr(self.graph.value(remap, L9['outputAttr'])) |
2072 | 84 start = cast(Literal, self.graph.value(remap, L9['start'])).toPython() |
85 end = cast(Literal, self.graph.value(remap, L9['end'])).toPython() | |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
86 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
|
87 |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
88 def _forgetStaleClients(self, now): |
1506
37cbb245d93c
fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents:
1492
diff
changeset
|
89 # 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
|
90 staleClientSessions = [] |
1859
f066d6e874db
2to3 with these fixers: all idioms set_literal
drewp@bigasterisk.com
parents:
1858
diff
changeset
|
91 for c, (t, _) in self.lastRequest.items(): |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
92 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
|
93 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
|
94 for c in staleClientSessions: |
1506
37cbb245d93c
fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents:
1492
diff
changeset
|
95 log.info('forgetting stale client %r', c) |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
96 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
|
97 |
1602
0fc61e701347
collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents:
1596
diff
changeset
|
98 # todo: move to settings.py |
2072 | 99 def resolvedSettingsDict(self, settingsList: List[Tuple[DeviceUri, DeviceAttr, float]]) -> Dict[Tuple[DeviceUri, DeviceAttr], float]: |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
100 out: Dict[Tuple[DeviceUri, DeviceAttr], float] = {} |
1470
b1d8abc96f06
don't run rotations to zero when no one is requesting them.
drewp@bigasterisk.com
parents:
1450
diff
changeset
|
101 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
|
102 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
|
103 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
|
104 else: |
1470
b1d8abc96f06
don't run rotations to zero when no one is requesting them.
drewp@bigasterisk.com
parents:
1450
diff
changeset
|
105 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
|
106 return out |
f427801da9f6
collector properly merges repeated attr settings in the same message
Drew Perttula <drewp@bigasterisk.com>
parents:
1307
diff
changeset
|
107 |
1506
37cbb245d93c
fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents:
1492
diff
changeset
|
108 def _warnOnLateRequests(self, client, now, sendTime): |
37cbb245d93c
fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents:
1492
diff
changeset
|
109 requestLag = now - sendTime |
2072 | 110 if requestLag > .1 and now > self.initTime + 10 and getattr(self, '_lastWarnTime', 0) < now - 3: |
1799
0bb7b9df12e5
collector warnings and errors. the reactor.crash isn't working.
drewp@bigasterisk.com
parents:
1700
diff
changeset
|
111 self._lastWarnTime = now |
2072 | 112 log.warn('collector.setAttrs from %s is running %.1fms after the request was made', client, requestLag * 1000) |
1289
5a4e74f1e36a
Fixed client session clearing bugs.
Drew Perttula <drewp@bigasterisk.com>
parents:
1288
diff
changeset
|
113 |
1602
0fc61e701347
collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents:
1596
diff
changeset
|
114 def _merge(self, lastRequests): |
2072 | 115 deviceAttrs: Dict[DeviceUri, Dict[DeviceAttr, float]] = {} # 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
|
116 for _, lastSettings in lastRequests: |
1859
f066d6e874db
2to3 with these fixers: all idioms set_literal
drewp@bigasterisk.com
parents:
1858
diff
changeset
|
117 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
|
118 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
|
119 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
|
120 value = Literal(start + float(value) * (end - start)) |
1450
ddb7622698a8
don't mix remapped values with unremapped ones
drewp@bigasterisk.com
parents:
1448
diff
changeset
|
121 |
ddb7622698a8
don't mix remapped values with unremapped ones
drewp@bigasterisk.com
parents:
1448
diff
changeset
|
122 attrs = deviceAttrs.setdefault(device, {}) |
ddb7622698a8
don't mix remapped values with unremapped ones
drewp@bigasterisk.com
parents:
1448
diff
changeset
|
123 if deviceAttr in attrs: |
2072 | 124 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
|
125 attrs[deviceAttr] = value |
1470
b1d8abc96f06
don't run rotations to zero when no one is requesting them.
drewp@bigasterisk.com
parents:
1450
diff
changeset
|
126 # 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
|
127 # 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
|
128 # not going to 0. |
1475 | 129 if deviceAttr in [L9['rx'], L9['ry'], L9['zoom'], L9['focus']]: |
2072 | 130 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
|
131 |
1470
b1d8abc96f06
don't run rotations to zero when no one is requesting them.
drewp@bigasterisk.com
parents:
1450
diff
changeset
|
132 # 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
|
133 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
|
134 daDict = deviceAttrs.setdefault(d, {}) |
b1d8abc96f06
don't run rotations to zero when no one is requesting them.
drewp@bigasterisk.com
parents:
1450
diff
changeset
|
135 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
|
136 daDict[da] = v |
1858 | 137 |
1602
0fc61e701347
collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents:
1596
diff
changeset
|
138 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
|
139 |
2072 | 140 def setAttrs(self, client: ClientType, clientSession: ClientSessionType, settings: List[Tuple[DeviceUri, DeviceAttr, float]], sendTime: UnixTime): |
1602
0fc61e701347
collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents:
1596
diff
changeset
|
141 """ |
0fc61e701347
collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents:
1596
diff
changeset
|
142 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
|
143 device attrs. We resolve conflicting values, process them into |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
144 output attrs, and call Output.update to send the new outputs. |
1602
0fc61e701347
collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents:
1596
diff
changeset
|
145 |
0fc61e701347
collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents:
1596
diff
changeset
|
146 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
|
147 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
|
148 |
0fc61e701347
collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents:
1596
diff
changeset
|
149 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
|
150 clientTimeoutSec. |
0fc61e701347
collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents:
1596
diff
changeset
|
151 """ |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
152 now = UnixTime(time.time()) |
1602
0fc61e701347
collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents:
1596
diff
changeset
|
153 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
|
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 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
|
156 |
0fc61e701347
collector: don't confuse two clients with the same name- use the session
Drew Perttula <drewp@bigasterisk.com>
parents:
1596
diff
changeset
|
157 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
|
158 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
|
159 |
1859
f066d6e874db
2to3 with these fixers: all idioms set_literal
drewp@bigasterisk.com
parents:
1858
diff
changeset
|
160 deviceAttrs = self._merge(iter(self.lastRequest.values())) |
1858 | 161 |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
162 outputAttrs: Dict[DeviceUri, Dict[OutputAttr, OutputValue]] = {} |
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
|
163 for d in self.allDevices: |
1416
ab7b40d20af0
rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents:
1412
diff
changeset
|
164 try: |
ab7b40d20af0
rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents:
1412
diff
changeset
|
165 devType = self.deviceType[d] |
ab7b40d20af0
rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents:
1412
diff
changeset
|
166 except KeyError: |
ab7b40d20af0
rewrite theaterConfig to a better data format
Drew Perttula <drewp@bigasterisk.com>
parents:
1412
diff
changeset
|
167 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
|
168 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
|
169 try: |
778c67ab70c9
set zmq highWaterMark to dump stale messages, especially those sent when collector isn't running
drewp@bigasterisk.com
parents:
1799
diff
changeset
|
170 outputAttrs[d] = toOutputAttrs(devType, deviceAttrs.get(d, {})) |
2072 | 171 self.listeners.outputAttrsSet(d, outputAttrs[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
|
172 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
|
173 log.error('failing toOutputAttrs on %s: %r', d, e) |
1858 | 174 |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
175 pendingOut: Dict[OutputUri, Tuple[OutputInstance, bytearray]] = {} |
1437 | 176 for out in self.outputs: |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
177 pendingOut[OutputUri(out.uri)] = (out, bytearray(512)) |
1506
37cbb245d93c
fix tests. add logging, some mypy types.
Drew Perttula <drewp@bigasterisk.com>
parents:
1492
diff
changeset
|
178 |
1859
f066d6e874db
2to3 with these fixers: all idioms set_literal
drewp@bigasterisk.com
parents:
1858
diff
changeset
|
179 for device, attrs in outputAttrs.items(): |
f066d6e874db
2to3 with these fixers: all idioms set_literal
drewp@bigasterisk.com
parents:
1858
diff
changeset
|
180 for outputAttr, value in attrs.items(): |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
181 output, _index = self.outputMap[(device, outputAttr)] |
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
182 outputUri = OutputUri(output.uri) |
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
183 index = DmxMessageIndex(_index) |
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
184 _, outArray = pendingOut[outputUri] |
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
185 if outArray[index] != 0: |
2072 | 186 log.warn(f'conflict: {output} 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
|
187 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
|
188 outArray[index] = value |
1288
5e76c8fd8a03
rewrite dmx outputter to a new service
Drew Perttula <drewp@bigasterisk.com>
parents:
diff
changeset
|
189 |
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
|
190 dt1 = 1000 * (time.time() - now) |
1884
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
191 for uri, (out, buf) in pendingOut.items(): |
5cde72dfdc22
change collector output code to use very specific types. Might fix bugs too.
Drew Perttula <drewp@bigasterisk.com>
parents:
1866
diff
changeset
|
192 out.update(bytes(buf)) |
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
|
193 dt2 = 1000 * (time.time() - now) |
1676 | 194 if dt1 > 30: |
2072 | 195 log.warn("slow setAttrs: %.1fms -> flush -> %.1fms. lr %s da %s oa %s" % (dt1, dt2, len(self.lastRequest), len(deviceAttrs), len(outputAttrs))) |