comparison service/piNode/devices.py @ 182:9fff29ebca71

start pinode Ignore-this: bfafd9994f7f9a61919d49274417ebbb
author drewp@bigasterisk.com
date Sun, 31 May 2015 00:56:55 -0700
parents
children 634d6e477953
comparison
equal deleted inserted replaced
181:71577a849628 182:9fff29ebca71
1 from __future__ import division
2 import pigpio
3 import time
4 from rdflib import Namespace, RDF, URIRef, Literal
5
6 ROOM = Namespace('http://projects.bigasterisk.com/room/')
7
8 class DeviceType(object):
9 deviceType = None
10 @classmethod
11 def findInstances(cls, graph, board, pi):
12 """
13 return any number of instances of this class for all the separately
14 controlled devices on the board. Two LEDS makes two instances,
15 but two sensors on the same onewire bus makes only one device
16 (which yields more statements).
17 """
18 for row in graph.query("""SELECT ?dev ?pinNumber WHERE {
19 ?board :hasPin ?pin .
20 ?pin :pinNumber ?pinNumber;
21 :connectedTo ?dev .
22 ?dev a ?thisType .
23 } ORDER BY ?dev""",
24 initBindings=dict(board=board,
25 thisType=cls.deviceType),
26 initNs={'': ROOM}):
27 yield cls(graph, row.dev, pi, int(row.pinNumber))
28
29 def __init__(self, graph, uri, pi, pinNumber):
30 self.graph, self.uri, self.pi = graph, uri, pi
31 self.pinNumber = pinNumber
32
33 def description(self):
34 return {
35 'uri': self.uri,
36 'className': self.__class__.__name__,
37 'pinNumber': self.pinNumber,
38 'outputPatterns': self.outputPatterns(),
39 'watchPrefixes': self.watchPrefixes(),
40 'outputWidgets': self.outputWidgets(),
41 }
42
43 def watchPrefixes(self):
44 """
45 subj,pred pairs of the statements that might be returned from
46 readFromPoll, so the dashboard knows what it should
47 watch. This should be eliminated, as the dashboard should just
48 always watch the whole tree of statements starting self.uri
49 """
50 return []
51
52 def poll(self):
53 return [] # statements
54
55 def outputPatterns(self):
56 """
57 Triple patterns, using None as a wildcard, that should be routed
58 to sendOutput
59 """
60 return []
61
62 def outputWidgets(self):
63 """
64 structs to make output widgets on the dashboard. ~1 of these per
65 handler you have in sendOutput
66 """
67 return []
68
69 def sendOutput(self, statements):
70 """
71 If we got statements that match this class's outputPatterns, this
72 will be called with the statements that matched.
73
74 Todo: it would be fine to read back confirmations or
75 whatever. Just need a way to collect them into graph statements.
76 """
77 raise NotImplementedError
78
79 _knownTypes = set()
80 def register(deviceType):
81 _knownTypes.add(deviceType)
82 return deviceType
83
84 @register
85 class MotionSensorInput(DeviceType):
86 deviceType = ROOM['MotionSensor']
87
88 def setup(self):
89 self.pi.set_mode(17, pigpio.INPUT)
90 self.pi.set_pull_up_down(17, pigpio.PUD_DOWN)
91
92 def poll(self):
93 motion = self.pi.read(17)
94
95 return [
96 (self.uri, ROOM['sees'],
97 ROOM['motion'] if motion else ROOM['noMotion']),
98 self.recentMotionStatement(motion),
99 ]
100
101 def recentMotionStatement(self, motion):
102 if not hasattr(self, 'lastMotionTime'):
103 self.lastMotionTime = 0
104 now = time.time()
105 if motion:
106 self.lastMotionTime = now
107 recentMotion = now - self.lastMotionTime < 60 * 10
108 return (self.uri, ROOM['seesRecently'],
109 ROOM['motion'] if recentMotion else ROOM['noMotion'])
110
111 def watchPrefixes(self):
112 return [
113 (self.uri, ROOM['sees']),
114 (self.uri, ROOM['seesRecently']),
115 ]
116
117 def makeDevices(graph, board, pi):
118 out = []
119 for dt in sorted(_knownTypes, key=lambda cls: cls.__name__):
120 out.extend(dt.findInstances(graph, board, pi))
121 return out
122