# HG changeset patch # User drewp@bigasterisk.com # Date 1596920199 25200 # Node ID acf58b83022fa8b5250558fc39d4deb1aeca08e6 # Parent df7035db28f1a1f7abbd2ab67c13dc6be0d67da0 rdf_to_mqtt sylvania bulbs and code cleanup and k8s updates diff -r df7035db28f1 -r acf58b83022f service/rdf_to_mqtt/.style.yapf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/rdf_to_mqtt/.style.yapf Sat Aug 08 13:56:39 2020 -0700 @@ -0,0 +1,4 @@ +# overwritten by /home/drewp/bin/setup_home_venv +[style] +based_on_style = google +column_limit = 130 diff -r df7035db28f1 -r acf58b83022f service/rdf_to_mqtt/Dockerfile --- a/service/rdf_to_mqtt/Dockerfile Sat Aug 08 13:14:49 2020 -0700 +++ b/service/rdf_to_mqtt/Dockerfile Sat Aug 08 13:56:39 2020 -0700 @@ -1,13 +1,14 @@ -FROM bang6:5000/base_x86 +FROM bang5:5000/base_x86 WORKDIR /opt COPY requirements.txt ./ RUN pip3 install --index-url https://projects.bigasterisk.com/ --extra-index-url https://pypi.org/simple -r requirements.txt RUN pip3 install -U 'https://github.com/drewp/cyclone/archive/python3.zip?v3' +RUN pip3 install -U attrs COPY *.py *.html *.js ./ EXPOSE 10011:10011 -CMD [ "python3", "./rdf_to_mqtt.py" ] +CMD [ "python3", "./rdf_to_mqtt.py", "-v" ] diff -r df7035db28f1 -r acf58b83022f service/rdf_to_mqtt/index.html --- a/service/rdf_to_mqtt/index.html Sat Aug 08 13:14:49 2020 -0700 +++ b/service/rdf_to_mqtt/index.html Sat Aug 08 13:56:39 2020 -0700 @@ -1,62 +1,102 @@ - + rdf_to_mqtt - + - - + + rdf_to_mqtt -

Send demo statements to bridge:

-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
- /stats/ - /output (post) -
+
+ /stats/ + /output (post) +
diff -r df7035db28f1 -r acf58b83022f service/rdf_to_mqtt/rdf_to_mqtt.py --- a/service/rdf_to_mqtt/rdf_to_mqtt.py Sat Aug 08 13:14:49 2020 -0700 +++ b/service/rdf_to_mqtt/rdf_to_mqtt.py Sat Aug 08 13:56:39 2020 -0700 @@ -30,9 +30,11 @@ devs = { ROOM['kitchenLight']: { 'root': 'h801_skylight', + 'hasWhite': True, }, ROOM['kitchenCounterLight']: { 'root': 'h801_counter', + 'hasWhite': True, }, ROOM['livingLampShelf']: { 'root': 'sonoff_0/switch/sonoff_basic_relay/command', @@ -60,22 +62,45 @@ }, ROOM['bedHeadboard']: { 'root': 'bed/light/headboard/command', + 'hasWhite': True, }, - #-t theater_blaster/ir_out -m 'input_game' - #-t theater_blaster/ir_out -m 'input_bd' - #-t theater_blaster/ir_out -m 'input_cbl' - #-t theater_blaster/ir_out -m 'input_pc' - #-t theater_blaster/ir_out/volume_up -m '{"times":1}' - #-t theater_blaster/ir_out/volume_down -m '{"times":1}' + # https://github.com/Koenkk/zigbee2mqtt.io/blob/new_api/docs/information/mqtt_topics_and_message_structure.md#general + ROOM['syl1']: { + 'root': 'zigbee2mqtt/syl1/set', + 'hasBrightness': True, + 'defaults': { + 'transition': 0, + } + }, + ROOM['syl2']: { + 'root': 'zigbee2mqtt/syl2/set', + 'hasBrightness': True, + 'defaults': { + 'transition': 0, + } + }, + ROOM['syl3']: { + 'root': 'zigbee2mqtt/syl3/set', + 'hasBrightness': True, + 'defaults': { + 'transition': 0, + } + }, + ROOM['syl4']: { + 'root': 'zigbee2mqtt/syl4/set', + 'hasBrightness': True, + 'defaults': { + 'transition': 0, + } + }, } class OutputPage(PrettyErrorHandler, cyclone.web.RequestHandler): + @STATS.putRequests.time() def put(self): - for stmt in rdf_over_http.rdfStatementsFromRequest( - self.request.arguments, self.request.body, - self.request.headers): + for stmt in rdf_over_http.rdfStatementsFromRequest(self.request.arguments, self.request.body, self.request.headers): self._onStatement(stmt) @STATS.statement.time() @@ -101,25 +126,34 @@ if stmt[0:2] == (dev, ROOM['volumeChange']): delta = int(stmt[2].toPython()) which = 'up' if delta > 0 else 'down' - self._publish(topic=f'theater_blaster/ir_out/volume_{which}', - message=json.dumps({'timed': abs(delta)})) + self._publish(topic=f'theater_blaster/ir_out/volume_{which}', message=json.dumps({'timed': abs(delta)})) ignored = False if stmt[0:2] == (dev, ROOM['color']): h = stmt[2].toPython() r, g, b = int(h[1:3], 16), int(h[3:5], 16), int(h[5:7], 16) - self._publish(topic=attrs['root'], - message=json.dumps({ - 'state': - 'ON' if r or g or b else 'OFF', - 'color': { - 'r': r, - 'g': g, - 'b': b - }, - 'white_value': - max(r, g, b) - })) + msg = { + 'state': 'ON' if r or g or b else 'OFF', + 'color': { + 'r': r, + 'g': g, + 'b': b + }, + } + if attrs.get('hasBrightness', False): + # todo- still not right for sylvania bulbs; they want color x-y. + # see https://www.zigbee2mqtt.io/information/mqtt_topics_and_message_structure.html#zigbee2mqttfriendly_nameset + msg['brightness'] = max(r, g, b) + if msg['brightness'] != 0: + scl = msg['brightness'] / 255 + for chan in ['r', 'g', 'b']: + msg['color'][chan] = int(msg['color'][chan] / 255.0 / scl * 255) + + if attrs.get('hasWhite', False): + msg['white_value'] = max(r, g, b) + msg.update(attrs.get('defaults', {})) + self._publish(topic=attrs['root'], message=json.dumps(msg)) ignored = False + if ignored: log.warn("ignoring %s", stmt) @@ -142,21 +176,15 @@ for line in ['line1', 'line2', 'line3', 'line4']: if stmt[1] == ROOM[line]: ignored = False - self.settings.mqtt.publish( - b'frontwindow/%s' % line.encode('ascii'), - stmt[2].toPython()) + self.settings.mqtt.publish(b'frontwindow/%s' % line.encode('ascii'), stmt[2].toPython()) return ignored @STATS.mqttPublish.time() - def _publish(self, - topic: str, - messageJson: object = None, - message: str = None): + def _publish(self, topic: str, messageJson: object = None, message: str = None): log.debug(f'mqtt.publish {topic} {message} {messageJson}') if messageJson is not None: message = json.dumps(messageJson) - self.settings.mqtt.publish(topic.encode('ascii'), - message.encode('ascii')) + self.settings.mqtt.publish(topic.encode('ascii'), message.encode('ascii')) if __name__ == '__main__': @@ -167,9 +195,7 @@ """) verboseLogging(arg['-v']) - mqtt = MqttClient(clientId='rdf_to_mqtt', - brokerHost='mosquitto-ext.default.svc.cluster.local', - brokerPort=1883) + mqtt = MqttClient(clientId='rdf_to_mqtt', brokerHost='mosquitto-ext.default.svc.cluster.local', brokerPort=1883) port = 10008 reactor.listenTCP(port, diff -r df7035db28f1 -r acf58b83022f service/rdf_to_mqtt/requirements.txt --- a/service/rdf_to_mqtt/requirements.txt Sat Aug 08 13:14:49 2020 -0700 +++ b/service/rdf_to_mqtt/requirements.txt Sat Aug 08 13:56:39 2020 -0700 @@ -4,6 +4,7 @@ twisted-mqtt==0.3.6 rx==1.6.1 git+http://github.com/drewp/scales.git@448d59fb491b7631877528e7695a93553bfaaa93#egg=scales +docopt cycloneerr patchablegraph==0.11.0