annotate light9/collector/collector.py @ 2154:b6a8289b1d1e

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