annotate service/reasoning/actions.py @ 608:62171aa2bc4e

mock output mode Ignore-this: a7b9dd184a2f3c811cd7c1d3ca4a002c
author drewp@bigasterisk.com
date Wed, 24 Jul 2019 00:34:41 -0700
parents 7f5451a76a80
children 5290df01d911
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
240
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
1 from rdflib import URIRef, Namespace, RDF, Literal
605
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
2 from twisted.internet import reactor
240
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
3 import logging
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
4 import urllib
608
62171aa2bc4e mock output mode
drewp@bigasterisk.com
parents: 607
diff changeset
5 import json
62171aa2bc4e mock output mode
drewp@bigasterisk.com
parents: 607
diff changeset
6 import time
240
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
7
605
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
8 import treq
240
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
9 log = logging.getLogger('output')
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
10
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
11 ROOM = Namespace("http://projects.bigasterisk.com/room/")
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
12 DEV = Namespace("http://projects.bigasterisk.com/device/")
602
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
13 REASONING = Namespace("http://projects.bigasterisk.com/ns/reasoning/")
240
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
14
605
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
15 class HttpPutOutput(object):
608
62171aa2bc4e mock output mode
drewp@bigasterisk.com
parents: 607
diff changeset
16 def __init__(self, url, mockOutput=False):
605
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
17 self.url = url
608
62171aa2bc4e mock output mode
drewp@bigasterisk.com
parents: 607
diff changeset
18 self.mockOutput = mockOutput
606
83ebabe81b9d actually set put payload this time. add treq dep
drewp@bigasterisk.com
parents: 605
diff changeset
19 self.payload = None
605
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
20 self.foafAgent = None
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
21 self.nextCall = None
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
22 self.numRequests = 0
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
23
606
83ebabe81b9d actually set put payload this time. add treq dep
drewp@bigasterisk.com
parents: 605
diff changeset
24 def setPayload(self, payload, foafAgent):
83ebabe81b9d actually set put payload this time. add treq dep
drewp@bigasterisk.com
parents: 605
diff changeset
25 if self.numRequests > 0 and (self.payload == payload or self.foafAgent == foafAgent):
605
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
26 return
606
83ebabe81b9d actually set put payload this time. add treq dep
drewp@bigasterisk.com
parents: 605
diff changeset
27 self.payload = payload
605
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
28 self.foafAgent = foafAgent
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
29 self.makeRequest()
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
30
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
31 def makeRequest(self):
606
83ebabe81b9d actually set put payload this time. add treq dep
drewp@bigasterisk.com
parents: 605
diff changeset
32 if self.payload is None:
607
7f5451a76a80 redo reasoning actions log levels
drewp@bigasterisk.com
parents: 606
diff changeset
33 log.debug("PUT None to %s - waiting", self.url)
605
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
34 return
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
35 h = {}
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
36 if self.foafAgent:
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
37 h['x-foaf-agent'] = self.foafAgent
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
38 if self.nextCall and self.nextCall.active():
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
39 self.nextCall.cancel()
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
40 self.nextCall = None
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
41 self.lastErr = None
607
7f5451a76a80 redo reasoning actions log levels
drewp@bigasterisk.com
parents: 606
diff changeset
42 log.debug("PUT %s payload=%s agent=%s", self.url, self.payload, self.foafAgent)
608
62171aa2bc4e mock output mode
drewp@bigasterisk.com
parents: 607
diff changeset
43 if not self.mockOutput:
62171aa2bc4e mock output mode
drewp@bigasterisk.com
parents: 607
diff changeset
44 self.currentRequest = treq.put(self.url, data=self.payload, headers=h, timeout=3)
62171aa2bc4e mock output mode
drewp@bigasterisk.com
parents: 607
diff changeset
45 self.currentRequest.addCallback(self.onResponse).addErrback(self.onError)
62171aa2bc4e mock output mode
drewp@bigasterisk.com
parents: 607
diff changeset
46 else:
62171aa2bc4e mock output mode
drewp@bigasterisk.com
parents: 607
diff changeset
47 reactor.callLater(.2, self.onResponse, None)
62171aa2bc4e mock output mode
drewp@bigasterisk.com
parents: 607
diff changeset
48
605
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
49 self.numRequests += 1
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
50
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
51 def onResponse(self, resp):
607
7f5451a76a80 redo reasoning actions log levels
drewp@bigasterisk.com
parents: 606
diff changeset
52 log.debug(" PUT %s ok", self.url)
605
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
53 self.lastErr = None
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
54 self.currentRequest = None
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
55 self.nextCall = reactor.callLater(3, self.makeRequest)
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
56
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
57 def onError(self, err):
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
58 self.lastErr = err
607
7f5451a76a80 redo reasoning actions log levels
drewp@bigasterisk.com
parents: 606
diff changeset
59 log.debug(' PUT %s failed: %s', self.url, err)
605
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
60 self.currentRequest = None
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
61 self.nextCall = reactor.callLater(5, self.makeRequest)
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
62
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
63 class HttpPutOutputs(object):
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
64 """these grow forever"""
608
62171aa2bc4e mock output mode
drewp@bigasterisk.com
parents: 607
diff changeset
65 def __init__(self, mockOutput=False):
62171aa2bc4e mock output mode
drewp@bigasterisk.com
parents: 607
diff changeset
66 self.mockOutput = mockOutput
605
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
67 self.state = {} # url: HttpPutOutput
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
68
606
83ebabe81b9d actually set put payload this time. add treq dep
drewp@bigasterisk.com
parents: 605
diff changeset
69 def put(self, url, payload, foafAgent):
605
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
70 if url not in self.state:
608
62171aa2bc4e mock output mode
drewp@bigasterisk.com
parents: 607
diff changeset
71 self.state[url] = HttpPutOutput(url, mockOutput=self.mockOutput)
606
83ebabe81b9d actually set put payload this time. add treq dep
drewp@bigasterisk.com
parents: 605
diff changeset
72 self.state[url].setPayload(payload, foafAgent)
605
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
73
240
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
74 class Actions(object):
608
62171aa2bc4e mock output mode
drewp@bigasterisk.com
parents: 607
diff changeset
75 def __init__(self, sendToLiveClients, mockOutput=False):
62171aa2bc4e mock output mode
drewp@bigasterisk.com
parents: 607
diff changeset
76 self.mockOutput = mockOutput
62171aa2bc4e mock output mode
drewp@bigasterisk.com
parents: 607
diff changeset
77 self.putOutputs = HttpPutOutputs(mockOutput=mockOutput)
240
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
78 self.sendToLiveClients = sendToLiveClients
600
a34dee00a989 comments and logging
drewp@bigasterisk.com
parents: 463
diff changeset
79
240
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
80 def putResults(self, deviceGraph, inferred):
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
81 """
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
82 some conclusions in the inferred graph lead to PUT requests
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
83 getting made
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
84
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
85 if the graph contains (?d ?p ?o) and ?d and ?p are a device
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
86 and predicate we support PUTs for, then we look up
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
87 (?d :putUrl ?url) and (?o :putValue ?val) and call
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
88 PUT ?url <- ?val
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
89
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
90 If the graph doesn't contain any matches, we use (?d
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
91 :zeroValue ?val) for the value and PUT that.
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
92 """
602
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
93 activated = set() # (subj,pred) pairs for which we're currently putting some value
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
94 activated.update(self._putDevices(deviceGraph, inferred))
240
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
95 self._oneShotPostActions(deviceGraph, inferred)
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
96 for dev, pred in [
247
b0089d1ca4f6 add bed buttons
drewp@bigasterisk.com
parents: 242
diff changeset
97 #(URIRef('http://bigasterisk.com/host/bang/monitor'), ROOM.powerState),
b0089d1ca4f6 add bed buttons
drewp@bigasterisk.com
parents: 242
diff changeset
98 (URIRef('http://bigasterisk.com/host/dash/monitor'), ROOM.powerState),
392
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
99 (URIRef('http://bigasterisk.com/host/frontdoor/monitor'), ROOM.powerState),
264
570b0e73d2bc rules updates
drewp@bigasterisk.com
parents: 259
diff changeset
100 (ROOM['storageCeilingLedLong'], ROOM.brightness),
570b0e73d2bc rules updates
drewp@bigasterisk.com
parents: 259
diff changeset
101 (ROOM['storageCeilingLedCross'], ROOM.brightness),
392
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
102 (ROOM['garageOverhead'], ROOM.brightness),
264
570b0e73d2bc rules updates
drewp@bigasterisk.com
parents: 259
diff changeset
103 (ROOM['headboardWhite'], ROOM.brightness),
570b0e73d2bc rules updates
drewp@bigasterisk.com
parents: 259
diff changeset
104 (ROOM['changingWhite'], ROOM.brightness),
570b0e73d2bc rules updates
drewp@bigasterisk.com
parents: 259
diff changeset
105 (ROOM['starTrekLight'], ROOM.brightness),
392
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
106 (ROOM['kitchenLight'], ROOM.brightness),
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
107 (ROOM['kitchenCounterLight'], ROOM.brightness),
264
570b0e73d2bc rules updates
drewp@bigasterisk.com
parents: 259
diff changeset
108 (ROOM['livingRoomLamp1'], ROOM.brightness),
570b0e73d2bc rules updates
drewp@bigasterisk.com
parents: 259
diff changeset
109 (ROOM['livingRoomLamp2'], ROOM.brightness),
603
63a3d8eeb46f loftdesk config
drewp@bigasterisk.com
parents: 602
diff changeset
110 (ROOM['loftDeskStrip'], ROOM.x),
264
570b0e73d2bc rules updates
drewp@bigasterisk.com
parents: 259
diff changeset
111 (ROOM['bedLedStrip'], ROOM.color),
240
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
112 ]:
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
113 url = deviceGraph.value(dev, ROOM.putUrl)
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
114
392
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
115 log.debug('inferredObjects of dev=%s pred=%s',
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
116 deviceGraph.qname(dev),
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
117 deviceGraph.qname(pred))
240
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
118 inferredObjects = list(inferred.objects(dev, pred))
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
119 if len(inferredObjects) == 0:
600
a34dee00a989 comments and logging
drewp@bigasterisk.com
parents: 463
diff changeset
120 # rm this- use activated instead
240
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
121 self._putZero(deviceGraph, dev, pred, url)
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
122 elif len(inferredObjects) == 1:
392
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
123 log.debug(' inferredObject: %s %s %r',
280
c192d37b2bc8 lots of logging updates (patch may be imprecise)
drewp@bigasterisk.com
parents: 264
diff changeset
124 deviceGraph.qname(dev),
c192d37b2bc8 lots of logging updates (patch may be imprecise)
drewp@bigasterisk.com
parents: 264
diff changeset
125 deviceGraph.qname(pred),
392
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
126 inferredObjects[0].toPython())
602
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
127 activated.add((dev, pred))
240
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
128 self._putInferred(deviceGraph, url, inferredObjects[0])
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
129 elif len(inferredObjects) > 1:
392
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
130 log.info(" conflict, ignoring: %s has %s of %s" %
240
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
131 (dev, pred, inferredObjects))
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
132 # write about it to the inferred graph?
602
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
133 self.putDefaults(deviceGraph, activated)
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
134
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
135 def putDefaults(self, deviceGraph, activated):
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
136 """
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
137 If inferring (:a :b :c) would cause a PUT, you can say
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
138
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
139 reasoning:defaultOutput reasoning:default [
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
140 :subject :a
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
141 :predicate :b
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
142 :defaultObject :c
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
143 ]
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
144
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
145 and we'll do that PUT if no rule has put anything else with
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
146 (:a :b *).
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
147 """
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
148
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
149 defaultStmts = set()
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
150 for defaultDesc in deviceGraph.objects(REASONING['defaultOutput'],
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
151 REASONING['default']):
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
152 s = deviceGraph.value(defaultDesc, ROOM['subject'])
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
153 p = deviceGraph.value(defaultDesc, ROOM['predicate'])
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
154 if (s, p) not in activated:
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
155 obj = deviceGraph.value(defaultDesc, ROOM['defaultObject'])
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
156
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
157 defaultStmts.add((s, p, obj))
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
158 self._putDevices(deviceGraph, defaultStmts)
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
159
240
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
160 def _oneShotPostActions(self, deviceGraph, inferred):
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
161 """
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
162 Inferred graph may contain some one-shot statements. We'll send
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
163 statement objects to anyone on web sockets, and also generate
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
164 POST requests as described in the graph.
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
165
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
166 one-shot statement ?s ?p ?o
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
167 with this in the graph:
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
168 ?osp a :OneShotPost
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
169 ?osp :subject ?s
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
170 ?osp :predicate ?p
600
a34dee00a989 comments and logging
drewp@bigasterisk.com
parents: 463
diff changeset
171 this will cause a post to ?o
240
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
172 """
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
173 # nothing in this actually makes them one-shot yet. they'll
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
174 # just fire as often as we get in here, which is not desirable
607
7f5451a76a80 redo reasoning actions log levels
drewp@bigasterisk.com
parents: 606
diff changeset
175 log.debug("_oneShotPostActions")
240
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
176 def err(e):
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
177 log.warn("post %s failed", postTarget)
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
178 for osp in deviceGraph.subjects(RDF.type, ROOM['OneShotPost']):
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
179 s = deviceGraph.value(osp, ROOM['subject'])
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
180 p = deviceGraph.value(osp, ROOM['predicate'])
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
181 if s is None or p is None:
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
182 continue
392
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
183 #log.info("checking for %s %s", s, p)
240
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
184 for postTarget in inferred.objects(s, p):
607
7f5451a76a80 redo reasoning actions log levels
drewp@bigasterisk.com
parents: 606
diff changeset
185 log.debug("post target %r", postTarget)
240
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
186 # this packet ought to have 'oneShot' in it somewhere
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
187 self.sendToLiveClients({"s":s, "p":p, "o":postTarget})
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
188
607
7f5451a76a80 redo reasoning actions log levels
drewp@bigasterisk.com
parents: 606
diff changeset
189 log.debug(" POST %s", postTarget)
608
62171aa2bc4e mock output mode
drewp@bigasterisk.com
parents: 607
diff changeset
190 if not self.mockOutput:
62171aa2bc4e mock output mode
drewp@bigasterisk.com
parents: 607
diff changeset
191 treq.post(postTarget, timeout=2).addErrback(err)
240
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
192
392
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
193 def _putDevices(self, deviceGraph, inferred):
602
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
194 activated = set()
392
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
195 agentFor = {}
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
196 for stmt in inferred:
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
197 if stmt[1] == ROOM['putAgent']:
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
198 agentFor[stmt[0]] = stmt[2]
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
199 for stmt in inferred:
607
7f5451a76a80 redo reasoning actions log levels
drewp@bigasterisk.com
parents: 606
diff changeset
200 log.debug('inferred stmt we might PUT: %s', stmt)
392
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
201 putUrl = deviceGraph.value(stmt[0], ROOM['putUrl'])
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
202 putPred = deviceGraph.value(stmt[0], ROOM['putPredicate'])
463
1ceb26846eca add separate :matchPredicate support. some build and log edits.
drewp@bigasterisk.com
parents: 392
diff changeset
203 matchPred = deviceGraph.value(stmt[0], ROOM['matchPredicate'],
1ceb26846eca add separate :matchPredicate support. some build and log edits.
drewp@bigasterisk.com
parents: 392
diff changeset
204 default=putPred)
1ceb26846eca add separate :matchPredicate support. some build and log edits.
drewp@bigasterisk.com
parents: 392
diff changeset
205 if putUrl and matchPred == stmt[1]:
607
7f5451a76a80 redo reasoning actions log levels
drewp@bigasterisk.com
parents: 606
diff changeset
206 log.debug('putDevices: stmt %r %r %r leds to putting at %r',
600
a34dee00a989 comments and logging
drewp@bigasterisk.com
parents: 463
diff changeset
207 stmt[0], stmt[1], stmt[2], putUrl)
392
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
208 self._put(putUrl + '?' + urllib.urlencode([
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
209 ('s', str(stmt[0])),
463
1ceb26846eca add separate :matchPredicate support. some build and log edits.
drewp@bigasterisk.com
parents: 392
diff changeset
210 ('p', str(putPred))]),
392
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
211 str(stmt[2].toPython()),
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
212 agent=agentFor.get(stmt[0], None))
602
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
213 activated.add((stmt[0],
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
214 # didn't test that this should be
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
215 # stmt[1] and not putPred
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
216 stmt[1]))
0b1249c3137d support for default values for http PUT outputs
drewp@bigasterisk.com
parents: 600
diff changeset
217 return activated
240
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
218
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
219 def _putInferred(self, deviceGraph, putUrl, obj):
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
220 """
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
221 HTTP PUT to putUrl, with a payload that's either obj's :putValue
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
222 or obj itself.
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
223 """
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
224 value = deviceGraph.value(obj, ROOM.putValue)
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
225 if value is not None:
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
226 self._put(putUrl, payload=str(value))
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
227 elif isinstance(obj, Literal):
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
228 self._put(putUrl, payload=str(obj))
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
229 else:
392
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
230 log.warn(" don't know what payload to put for %s. obj=%r",
240
0c306e76d8c5 ipv6 fetch support. refactor Actions to new class and file
drewp@bigasterisk.com
parents:
diff changeset
231 putUrl, obj)
600
a34dee00a989 comments and logging
drewp@bigasterisk.com
parents: 463
diff changeset
232
392
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
233 def _putZero(self, deviceGraph, dev, pred, putUrl):
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
234 # zerovalue should be a function of pred as well.
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
235 value = deviceGraph.value(dev, ROOM.zeroValue)
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
236 if value is not None:
607
7f5451a76a80 redo reasoning actions log levels
drewp@bigasterisk.com
parents: 606
diff changeset
237 log.debug(" put zero (%r) to %s", value.toPython(), putUrl)
392
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
238 self._put(putUrl, payload=str(value))
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
239 # this should be written back into the inferred graph
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
240 # for feedback
600
a34dee00a989 comments and logging
drewp@bigasterisk.com
parents: 463
diff changeset
241
392
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
242 def _put(self, url, payload, agent=None):
79d041273e26 mqtt has two devices now. various older cleanups.
drewp@bigasterisk.com
parents: 328
diff changeset
243 assert isinstance(payload, bytes)
605
ad4c4d7c1fb9 reasoning output using treq, and keep writing to PUT calls forever (but not as fast as the reasoning loop runs)
drewp@bigasterisk.com
parents: 603
diff changeset
244 self.putOutputs.put(url, payload, agent)