Adding a /write handle on an SID to be able to write multiple attributes to a device (example MID and VOL for sound play)
This commit is contained in:
+3
-3
@@ -67,10 +67,9 @@ def process_mqtt_messages(gateway, client):
|
|||||||
_LOGGER.debug("data from mqtt: " + format(data))
|
_LOGGER.debug("data from mqtt: " + format(data))
|
||||||
|
|
||||||
sid = data.get("sid", None)
|
sid = data.get("sid", None)
|
||||||
param = data.get("param", None)
|
values = data.get("values", dict())
|
||||||
value = data.get("value", None)
|
|
||||||
|
|
||||||
resp = gateway.write_to_hub(sid, param, value)
|
resp = gateway.write_to_hub(sid, **values)
|
||||||
client._queue.task_done()
|
client._queue.task_done()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
_LOGGER.error('Error while sending from mqtt to gateway: ', str(e))
|
_LOGGER.error('Error while sending from mqtt to gateway: ', str(e))
|
||||||
@@ -87,6 +86,7 @@ if __name__ == "__main__":
|
|||||||
client.connect()
|
client.connect()
|
||||||
#only this devices can be controlled from MQTT
|
#only this devices can be controlled from MQTT
|
||||||
client.subscribe("gateway", "+", "+", "set")
|
client.subscribe("gateway", "+", "+", "set")
|
||||||
|
client.subscribe("gateway", "+", "write", None)
|
||||||
client.subscribe("plug", "+", "status", "set")
|
client.subscribe("plug", "+", "status", "set")
|
||||||
|
|
||||||
gateway = XiaomiHub(gateway_pass)
|
gateway = XiaomiHub(gateway_pass)
|
||||||
|
|||||||
+38
-13
@@ -3,6 +3,7 @@ import os
|
|||||||
import logging
|
import logging
|
||||||
from queue import Queue
|
from queue import Queue
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
import json
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -54,8 +55,10 @@ class Mqtt:
|
|||||||
t1.start()
|
t1.start()
|
||||||
self._threads.append(t1)
|
self._threads.append(t1)
|
||||||
|
|
||||||
def subscribe(self, model="+", name="+", prop="+", command="set"):
|
def subscribe(self, model="+", name="+", prop="+", command=None):
|
||||||
topic = self.prefix + "/" + model + "/" + name + "/" + prop + "/" + command
|
topic = self.prefix + "/" + model + "/" + name + "/" + prop
|
||||||
|
if command is not None:
|
||||||
|
topic += "/" + command
|
||||||
_LOGGER.info("Subscibing to " + topic + ".")
|
_LOGGER.info("Subscibing to " + topic + ".")
|
||||||
self._client.subscribe(topic)
|
self._client.subscribe(topic)
|
||||||
|
|
||||||
@@ -94,17 +97,21 @@ class Mqtt:
|
|||||||
def _mqtt_process_message(self, client, userdata, msg):
|
def _mqtt_process_message(self, client, userdata, msg):
|
||||||
_LOGGER.info("Processing message in " + str(msg.topic) + ": " + str(msg.payload) + ".")
|
_LOGGER.info("Processing message in " + str(msg.topic) + ": " + str(msg.payload) + ".")
|
||||||
parts = msg.topic.split("/")
|
parts = msg.topic.split("/")
|
||||||
if (len(parts) != 5):
|
if len(parts) < 4:
|
||||||
|
# should we return an error message ?
|
||||||
return
|
return
|
||||||
|
|
||||||
model = parts[1]
|
model = parts[1]
|
||||||
query_sid = parts[2] #sid or name part
|
query_sid = parts[2] #sid or name part
|
||||||
param = parts[3] #param part
|
param = parts[3] #param part
|
||||||
value = (msg.payload).decode('utf-8')
|
method = None
|
||||||
if self._is_int(value):
|
if len(parts) > 4:
|
||||||
value = int(value)
|
method = parts[4]
|
||||||
|
else:
|
||||||
|
method = parts[3]
|
||||||
|
|
||||||
name = "" # we will find it next
|
name = "" # we will find it next
|
||||||
sid = query_sid
|
sid = query_sid
|
||||||
|
|
||||||
isFound = False
|
isFound = False
|
||||||
for current_sid in self._sids:
|
for current_sid in self._sids:
|
||||||
if (current_sid == None):
|
if (current_sid == None):
|
||||||
@@ -124,15 +131,33 @@ class Mqtt:
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
if isFound == False:
|
if isFound == False:
|
||||||
|
# should we return an error message ?
|
||||||
return
|
return
|
||||||
|
|
||||||
# fix for rgb format
|
if method == "set":
|
||||||
if (param == "rgb" and "," in str(value)):
|
# use single value set method
|
||||||
value = self._color_rgb_to_xiaomi(value)
|
|
||||||
|
|
||||||
data = {'sid': sid, 'model': model, 'name': name, 'param':param, 'value':value}
|
value = (msg.payload).decode('utf-8')
|
||||||
# put in process queuee
|
if self._is_int(value):
|
||||||
self._queue.put(data)
|
value = int(value)
|
||||||
|
|
||||||
|
# fix for rgb format
|
||||||
|
if (param == "rgb" and "," in str(value)):
|
||||||
|
value = self._color_rgb_to_xiaomi(value)
|
||||||
|
|
||||||
|
# prepare values dict
|
||||||
|
data = {'sid': sid, 'model': model, 'name': name,
|
||||||
|
'values': {param: value}}
|
||||||
|
# put in process queuee
|
||||||
|
self._queue.put(data)
|
||||||
|
|
||||||
|
elif method == "write":
|
||||||
|
# use raw write method to the sensor, we expect a jsonified dict here.
|
||||||
|
values = json.loads((msg.payload).decode('utf-8'))
|
||||||
|
data = {'sid': sid, 'model': model, 'name': name,
|
||||||
|
'values': values}
|
||||||
|
# put in process queuee
|
||||||
|
self._queue.put(data)
|
||||||
|
|
||||||
def _mqtt_loop(self):
|
def _mqtt_loop(self):
|
||||||
_LOGGER.info("Starting mqtt loop.")
|
_LOGGER.info("Starting mqtt loop.")
|
||||||
|
|||||||
+7
-7
@@ -149,14 +149,14 @@ class XiaomiHub:
|
|||||||
_LOGGER.error("Cannot connect to Gateway")
|
_LOGGER.error("Cannot connect to Gateway")
|
||||||
socket.close()
|
socket.close()
|
||||||
|
|
||||||
def write_to_hub(self, sid, data_key, datavalue):
|
def write_to_hub(self, sid, **values):
|
||||||
key = self._get_key()
|
key = self._get_key()
|
||||||
if type(datavalue) == int:
|
cmd = {
|
||||||
datavalue_formatted = str(datavalue)
|
"cmd": "write",
|
||||||
else:
|
"sid": sid,
|
||||||
datavalue_formatted = '"' + datavalue + '"'
|
"data": dict(key=key, **values)
|
||||||
cmd = '{ "cmd":"write","sid":"' + sid + '","data":"{"' + data_key + '":' + datavalue_formatted + ',"key":"' + key + '"}}'
|
}
|
||||||
return self._send_cmd(cmd, "write_ack")
|
return self._send_cmd(json.dumps(cmd), "write_ack")
|
||||||
|
|
||||||
def get_from_hub(self, sid):
|
def get_from_hub(self, sid):
|
||||||
cmd = '{ "cmd":"read","sid":"' + sid + '"}'
|
cmd = '{ "cmd":"read","sid":"' + sid + '"}'
|
||||||
|
|||||||
Reference in New Issue
Block a user