Mercurial > code > home > repos > homeauto
annotate service/rdf_to_mqtt/rdf_to_mqtt.py @ 1563:71eec31da919
more theater output controls
Ignore-this: 34e105c3760b9df22d63eb0035aca19d
darcs-hash:095f5932e595b89d909c85018999fa926503abcd
author | drewp <drewp@bigasterisk.com> |
---|---|
date | Fri, 14 Feb 2020 10:21:24 -0800 |
parents | d786df082a73 |
children | ffbebd7902ee |
rev | line source |
---|---|
1539 | 1 """ |
2 We get output statements that are like light9's deviceAttrs (:dev1 :color "#ff0000"), | |
3 convert those to outputAttrs (:dev1 :red 255; :green 0; :blue 0) and post them to mqtt. | |
4 | |
5 This is like light9/bin/collector. | |
6 """ | |
7 import json | |
8 from mqtt_client import MqttClient | |
9 from docopt import docopt | |
10 from rdflib import Namespace, Literal | |
11 from twisted.internet import reactor | |
12 import cyclone.web | |
13 | |
14 from patchablegraph import PatchableGraph, CycloneGraphHandler, CycloneGraphEventsHandler | |
15 from standardservice.logsetup import log, verboseLogging | |
16 import rdf_over_http | |
1563
71eec31da919
more theater output controls
drewp <drewp@bigasterisk.com>
parents:
1541
diff
changeset
|
17 from cycloneerr import PrettyErrorHandler |
1539 | 18 |
19 ROOM = Namespace('http://projects.bigasterisk.com/room/') | |
20 | |
21 devs = { | |
22 ROOM['kitchenLight']: { | |
23 'root': 'h801_skylight', | |
24 }, | |
25 ROOM['kitchenCounterLight']: { | |
26 'root': 'h801_counter', | |
27 }, | |
28 ROOM['livingLampShelf']: { | |
29 'root': 'sonoff_0/switch/sonoff_basic_relay/command', | |
30 'values': 'binary', | |
31 }, | |
1540 | 32 ROOM['livingLamp1']: { |
33 'root': 'sonoff_1/switch/sonoff_basic_relay/command', | |
34 'values': 'binary', | |
35 }, | |
36 ROOM['livingLamp2']: { | |
37 'root': 'sonoff_2/switch/sonoff_basic_relay/command', | |
38 'values': 'binary', | |
39 }, | |
40 ROOM['livingLamp3']: { | |
41 'root': 'sonoff_3/switch/sonoff_basic_relay/command', | |
42 'values': 'binary', | |
43 }, | |
44 ROOM['livingLamp4']: { | |
45 'root': 'sonoff_4/switch/sonoff_basic_relay/command', | |
46 'values': 'binary', | |
47 }, | |
48 ROOM['livingLamp5']: { | |
49 'root': 'sonoff_5/switch/sonoff_basic_relay/command', | |
50 'values': 'binary', | |
51 }, | |
1563
71eec31da919
more theater output controls
drewp <drewp@bigasterisk.com>
parents:
1541
diff
changeset
|
52 ROOM['theater']: { |
71eec31da919
more theater output controls
drewp <drewp@bigasterisk.com>
parents:
1541
diff
changeset
|
53 'root': 'theater_blaster/ir_out', |
71eec31da919
more theater output controls
drewp <drewp@bigasterisk.com>
parents:
1541
diff
changeset
|
54 'values': 'theaterOutputs', |
71eec31da919
more theater output controls
drewp <drewp@bigasterisk.com>
parents:
1541
diff
changeset
|
55 }, |
1540 | 56 #-t theater_blaster/ir_out -m 'input_game' |
57 #-t theater_blaster/ir_out -m 'input_bd' | |
58 #-t theater_blaster/ir_out -m 'input_cbl' | |
59 #-t theater_blaster/ir_out -m 'input_pc' | |
60 #-t theater_blaster/ir_out/volume_up -m '{"times":1}' | |
61 #-t theater_blaster/ir_out/volume_down -m '{"times":1}' | |
1539 | 62 } |
63 | |
64 | |
1563
71eec31da919
more theater output controls
drewp <drewp@bigasterisk.com>
parents:
1541
diff
changeset
|
65 class OutputPage(PrettyErrorHandler, cyclone.web.RequestHandler): |
1539 | 66 def put(self): |
67 for stmt in rdf_over_http.rdfStatementsFromRequest( | |
68 self.request.arguments, | |
69 self.request.body, | |
70 self.request.headers): | |
71 self._onStatement(stmt) | |
72 | |
73 def _onStatement(self, stmt): | |
74 log.info(f'incoming statement: {stmt}') | |
75 ignored = True | |
76 for dev, attrs in devs.items(): | |
77 if stmt[0] == ROOM['frontWindow']: | |
78 ignored = ignored and self._publishFrontScreenText(stmt) | |
79 if stmt[0:2] == (dev, ROOM['brightness']): | |
80 log.info(f'brightness request: {stmt}') | |
81 brightness = stmt[2].toPython() | |
82 | |
83 if attrs.get('values', '') == 'binary': | |
84 self._publishOnOff(attrs, brightness) | |
85 else: | |
86 self._publishRgbw(attrs, brightness) | |
87 ignored = False | |
1563
71eec31da919
more theater output controls
drewp <drewp@bigasterisk.com>
parents:
1541
diff
changeset
|
88 if stmt[0:2] == (dev, ROOM['inputSelector']): |
71eec31da919
more theater output controls
drewp <drewp@bigasterisk.com>
parents:
1541
diff
changeset
|
89 self._publish(topic=attrs['root'], |
71eec31da919
more theater output controls
drewp <drewp@bigasterisk.com>
parents:
1541
diff
changeset
|
90 message='input_'+str(stmt[2].toPython())) |
71eec31da919
more theater output controls
drewp <drewp@bigasterisk.com>
parents:
1541
diff
changeset
|
91 ignored = False |
71eec31da919
more theater output controls
drewp <drewp@bigasterisk.com>
parents:
1541
diff
changeset
|
92 if stmt[0:2] == (dev, ROOM['volumeChange']): |
71eec31da919
more theater output controls
drewp <drewp@bigasterisk.com>
parents:
1541
diff
changeset
|
93 delta = int(stmt[2].toPython()) |
71eec31da919
more theater output controls
drewp <drewp@bigasterisk.com>
parents:
1541
diff
changeset
|
94 which = 'up' if delta > 0 else 'down' |
71eec31da919
more theater output controls
drewp <drewp@bigasterisk.com>
parents:
1541
diff
changeset
|
95 self._publish(topic=f'theater_blaster/ir_out/volume_{which}', |
71eec31da919
more theater output controls
drewp <drewp@bigasterisk.com>
parents:
1541
diff
changeset
|
96 message=json.dumps({'timed': abs(delta)})) |
71eec31da919
more theater output controls
drewp <drewp@bigasterisk.com>
parents:
1541
diff
changeset
|
97 ignored = False |
1539 | 98 if ignored: |
99 log.warn("ignoring %s", stmt) | |
100 | |
101 def _publishOnOff(self, attrs, brightness): | |
102 msg = 'OFF' | |
103 if brightness > 0: | |
104 msg = 'ON' | |
105 self._publish(topic=attrs['root'], message=msg) | |
106 | |
107 def _publishRgbw(self, attrs, brightness): | |
108 for chan, scale in [('w1', 1), | |
109 ('r', 1), | |
110 ('g', .8), | |
111 ('b', .8)]: | |
112 self._publish( | |
113 topic=f"{attrs['root']}/light/kit_{chan}/command", | |
114 messageJson={ | |
115 'state': 'ON', | |
116 'brightness': int(brightness * 255) | |
117 }) | |
118 | |
119 def _publishFrontScreenText(self, stmt): | |
120 ignored = True | |
121 for line in ['line1', 'line2', 'line3', 'line4']: | |
122 if stmt[1] == ROOM[line]: | |
123 ignored = False | |
124 self.settings.mqtt.publish( | |
125 b'frontwindow/%s' % line.encode('ascii'), | |
126 stmt[2].toPython()) | |
127 return ignored | |
128 | |
129 def _publish(self, topic: str, messageJson: object=None, | |
130 message: str=None): | |
131 if messageJson is not None: | |
132 message = json.dumps(messageJson) | |
133 self.settings.mqtt.publish( | |
134 topic.encode('ascii'), | |
135 message.encode('ascii')) | |
136 | |
137 | |
138 if __name__ == '__main__': | |
139 arg = docopt(""" | |
140 Usage: rdf_to_mqtt.py [options] | |
141 | |
142 -v Verbose | |
143 """) | |
144 verboseLogging(arg['-v']) | |
145 | |
146 mqtt = MqttClient(clientId='rdf_to_mqtt', brokerPort=1883) | |
147 | |
148 port = 10008 | |
149 reactor.listenTCP(port, cyclone.web.Application([ | |
150 (r"/()", cyclone.web.StaticFileHandler, | |
151 {"path": ".", "default_filename": "index.html"}), | |
152 (r'/output', OutputPage), | |
153 ], mqtt=mqtt, debug=arg['-v']), interface='::') | |
154 log.warn('serving on %s', port) | |
155 | |
156 reactor.run() |