changeset 2155:092967f313e1

attempt to make things more typesafe and readable (untested)
author drewp@bigasterisk.com
date Wed, 17 May 2023 19:56:17 -0700
parents b6a8289b1d1e
children c5974a6bbc28
files light9/collector/collector.py
diffstat 1 files changed, 28 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/light9/collector/collector.py	Wed May 17 19:55:15 2023 -0700
+++ b/light9/collector/collector.py	Wed May 17 19:56:17 2023 -0700
@@ -1,9 +1,9 @@
 import logging
 import time
-from typing import cast, List, Dict, Tuple, Optional, Set
+from typing import Dict, List, Set, Tuple, Type, TypeVar, cast
 
-from rdflib import Graph, Literal
 from rdfdb.syncedgraph.syncedgraph import SyncedGraph
+from rdflib import Literal, URIRef
 
 from light9.collector.device import resolve, toOutputAttrs
 from light9.collector.output import Output as OutputInstance
@@ -15,6 +15,21 @@
 log = logging.getLogger('collector')
 
 
+def makeDmxMessageIndex(base: DmxIndex, offset: DmxIndex) -> DmxMessageIndex:
+    return DmxMessageIndex(base + offset - 1)
+
+
+ObjType = TypeVar('ObjType')
+
+
+def typedValue(objType: Type[ObjType], graph, subj, pred) -> ObjType:
+    obj = graph.value(subj, pred)
+    if obj is None:
+        raise ValueError()
+    conv = obj if issubclass(objType, URIRef) else obj.toPython()
+    return cast(objType, conv)
+
+
 def outputMap(graph: SyncedGraph, outputs: List[OutputInstance]) -> Dict[Tuple[DeviceUri, OutputAttr], Tuple[OutputInstance, DmxMessageIndex]]:
     """From rdf config graph, compute a map of
        (device, outputattr) : (output, index)
@@ -31,20 +46,21 @@
         for dev in graph.subjects(RDF.type, dc):
             dev = cast(DeviceUri, dev)
             log.info('  mapping device %s', dev)
-            universe = cast(OutputUri, graph.value(dev, L9['dmxUniverse']))
+            universe = typedValue(OutputUri, graph, dev, L9['dmxUniverse'])
             try:
                 output = outputByUri[universe]
             except Exception:
                 log.warn('dev %r :dmxUniverse %r', dev, universe)
                 raise
-            base = graph.value(dev, L9['dmxBase'])
-            if base is None:
+            try:
+                dmxBase = typedValue(DmxIndex, graph, dev, L9['dmxBase'])
+            except ValueError:
                 raise ValueError('no :dmxBase for %s' % dev)
-            dmxBase = DmxIndex(cast(Literal, base).toPython())
+
             for row in graph.objects(dc, L9['attr']):
-                outputAttr = cast(OutputAttr, graph.value(row, L9['outputAttr']))
-                offset = DmxIndex(cast(Literal, graph.value(row, L9['dmxOffset'])).toPython())
-                index = DmxMessageIndex(dmxBase + offset - 1)
+                outputAttr = typedValue(OutputAttr, graph, row, L9['outputAttr'])
+                offset = typedValue(DmxIndex, graph, row, L9['dmxOffset'])
+                index = makeDmxMessageIndex(dmxBase, offset)
                 ret[(dev, outputAttr)] = (output, index)
                 log.debug('    map %s to %s,%s', outputAttr, output, index)
     return ret
@@ -81,9 +97,9 @@
                 self.deviceType[dev] = dc
 
                 for remap in self.graph.objects(dev, L9['outputAttrRange']):
-                    attr = OutputAttr(self.graph.value(remap, L9['outputAttr']))
-                    start = cast(Literal, self.graph.value(remap, L9['start'])).toPython()
-                    end = cast(Literal, self.graph.value(remap, L9['end'])).toPython()
+                    attr = typedValue(OutputAttr, self.graph, remap, L9['outputAttr'])
+                    start = typedValue(float, self.graph, remap, L9['start'])
+                    end = typedValue(float, self.graph, remap, L9['end'])
                     self.remapOut[(dev, attr)] = OutputRange((start, end))
 
     def _forgetStaleClients(self, now):