Closed agrabren closed 2 years ago
I've not tested against Mosquito 2.
This is interesting behaviour, it's possible the device is expecting a response.
We know that Meross devices are hard coded to contact one of several NTP servers, are your devices able to do so?
Update: I tested with a basic Mosquitto 2.0.14 setup and my MSS310 connected fine.
Hello,
What is the model of your switch ?
For my Meross MSS310, I have to configure Appliance.System.Clock and Appliance.System.Time for them to work.
This is the code I use :
import paho.mqtt.client as mqtt
import json
import time as t
import hashlib
from datetime import *
from dateutil import tz
from dateutil.relativedelta import *
import dateutil
import threading
uuid_tab = ["211028369287905189876876","2110280560197851807867687","2110283878849551867867","21102869179984518075486876757","2110284045264867687654","687654564567","211028286904815168754687"]
key_tab = ["yrteytr","rezttytr","zregdvh","iyourrrte","jhgjkjkh","tryed","nbvbnr"]
run_thread = True
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
for i in range(0, len(uuid_tab)):
client.subscribe("/appliance/" + uuid_tab[i] + "/publish")
client.subscribe("/app/0-" + uuid_tab[i] + "/subscribe")
message=generateMqttMessage(uuid_tab[i], key_tab[i], "PUSH", "Appliance.System.Clock")
client.publish("/appliance/" + uuid_tab[i] + "/subscribe", payload=message)
message2=generateMqttMessage(uuid_tab[i], key_tab[i], "SET", "Appliance.System.Time")
client.publish("/appliance/" + uuid_tab[i] + "/subscribe", payload=message2)
#message=generateMqttMessage(uuid_tab[0], key_tab[0], "GET", "Appliance.Control.Electricity")
#client.publish("/appliance/" + uuid_tab[0] + "/subscribe", payload=message)
run_thread = True
# x.start()
def on_disconnect(client, userdata, rc):
run_thread = False
# x.join()
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
#print(msg.topic+" "+str(msg.payload))
for i in range(0, len(uuid_tab)):
if(msg.topic == "/app/0-"+uuid_tab[i]+"/subscribe"):
#print("Topic OK")
reponse=json.loads(msg.payload)
if("namespace" in reponse["header"]):
#print("Namespace trouve")
if(reponse["header"]["namespace"]=="Appliance.Control.Electricity" and reponse["header"]["method"]=="GETACK"):
#print("Envoi a Emoncms")
client.publish("emon/prise"+str(i+1)+"/power1", payload=str(int((reponse["payload"]["electricity"]["power"])/1000)))
break
elif(msg.topic == "/appliance/"+uuid_tab[i]+"/publish"):
reponse=json.loads(msg.payload)
if("namespace" in reponse["header"]):
if(reponse["header"]["namespace"]=="Appliance.System.Clock" and reponse["header"]["method"]=="PUSH"):
timeupdate=generateMqttMessage(uuid_tab[i], key_tab[i], "PUSH", "Appliance.System.Clock")
client.publish("/appliance/" + uuid_tab[i] + "/subscribe", payload=timeupdate)
break
def on_publish(client, userdata, mid):
print("MID : "+str(mid))
def generateMqttMessage(uuid, key, messageType, namespace, parameters=None):
data={}
data["header"]={}
data["header"]["from"]="/app/0-"+uuid+"/subscribe"
data["header"]["messageId"]="47e87acd7ced4519517df8916942f1a1"
data["header"]["method"]=messageType
data["header"]["namespace"]=namespace
data["header"]["payloadVersion"]=1
data["header"]["sign"]="0"
data["header"]["timestamp"]=int(datetime.now(timezone.utc).timestamp())
stringToHash = data["header"]["messageId"] + key + str(data["header"]["timestamp"])
hash=hashlib.md5(stringToHash.encode())
data["header"]["sign"]=hash.hexdigest()
data["payload"]={}
if(namespace == "Appliance.System.Clock"):
data["payload"]["clock"]={}
data["payload"]["clock"]["timestamp"]=data["header"]["timestamp"]
elif(namespace == "Appliance.System.Time"):
data["payload"]["time"]={}
data["payload"]["time"]["timestamp"]=data["header"]["timestamp"]
data["payload"]["time"]["timezone"] = "Europe/Paris"
data["payload"]["time"]["timeRule"] = []
tm = tz.gettz(data["payload"]["time"]["timezone"])
maintenant=datetime.now(tm)
#maintenant = maintenant + relativedelta(months=10)
#print(maintenant)
# Previous end or debut of DST
if(datetime.dst(maintenant) != timedelta()):
dst1 = maintenant + relativedelta(month=3, day=31, weekday=SU(-1), second=0, minute=0, hour=3, microsecond=0)
dst2 = maintenant + relativedelta(month=10, day=31, weekday=SU(-1), second=59, minute=59, hour=2, microsecond=0)
dst3 = maintenant + relativedelta(years=1, month=3, day=31, weekday=SU(-1), second=0, minute=0, hour=3, microsecond=0)
dst1on = 1
dst2on = 0
dst3on = 1
else:
dst2 = maintenant + relativedelta(month=3, day=31, weekday=SU(-1), second=0, minute=0, hour=3)
if(maintenant < dst2):
dst1 = maintenant + relativedelta(years=-1, month=10, day=31, weekday=SU(-1), second=59, minute=59, hour=2)
dst3 = maintenant + relativedelta(month=10, day=31, weekday=SU(-1), second=59, minute=59, hour=2)
else:
dst1 = maintenant + relativedelta(month=10, day=31, weekday=SU(-1), second=59, minute=59, hour=2, microsecond=0)
dst2 = maintenant + relativedelta(years=1, month=3, day=31, weekday=SU(-1), second=0, minute=0, hour=3, microsecond=0)
dst3 = maintenant + relativedelta(years=1, month=10, day=31, weekday=SU(-1), second=59, minute=59, hour=2, microsecond=0)
dst1on = 0
dst2on = 1
dst3on = 0
data["payload"]["time"]["timeRule"].append([int(dst1.timestamp()) + dst2on, 3600 + (dst1on*3600), dst1on])
data["payload"]["time"]["timeRule"].append([int(dst2.timestamp()) + dst1on, 3600 + (dst2on*3600), dst2on])
data["payload"]["time"]["timeRule"].append([int(dst3.timestamp()) + dst2on, 3600 + (dst3on*3600), dst3on])
print(dst1)
print(dst2)
print(dst3)
elif(namespace == "Appliance.Control.Electricity"):
data["payload"]["channel"] = 0
else:
return None
#print(json.dumps(data, indent=4))
return(json.dumps(data))
def sendElectricityRequest(name):
while(run_thread):
for i in range(0, len(uuid_tab)):
requete=generateMqttMessage(uuid_tab[i], key_tab[i], "GET", "Appliance.Control.Electricity")
client.publish("/appliance/" + uuid_tab[i] + "/subscribe", payload=requete)
t.sleep(10)
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
#client.on_publish = on_publish
client.on_disconnect = on_disconnect
client.tls_set()
client.reconnect_delay_set(min_delay=1, max_delay=120)
client.username_pw_set("gfdhghg", "4578746197987")
client.connect("mqtts.domain.fr", 8883, 60)
#x = threading.Thread(target=sendElectricityRequest, args=(1,))
client.loop_start()
sendElectricityRequest("test")
client.loop_stop()
#t.sleep(30)
#message=generateMqttMessage(uuid_tab[0], key_tab[0], "GET", "Appliance.Control.Electricity")
#client.publish("/appliance/" + uuid_tab[0] + "/publish", payload=message)
#while(True):
# Blocking call that processes network traffic, dispatches callbacks and
# handles reconnecting.
# Other loop*() functions are available that give a threaded interface and a
# mnual interface.
#client.loop_forever()
I don't use Home Assistant, that's why I have my own script to handle the MQTT messages. The script listen to the MQTT messages sent by the MSS310 and send the power consumption to an other topic.
I'm really sorry I can't get test all this stuff tonight, my work day got the best of me and I haven't had much luck getting an easier-to-debug MQTT server setup. So I lost a little ground on this. I can provide these details about the device I'm using: Type: mss510x Version: 3.0.0 Chip: mt7682 Firmware ver: 3.2.2 Hopefully tomorrow I'll have better luck with a clean MQTT installation and configuration with new certs and such. Then I will update with my latest, and hopefully some additional debug information.
@agrabren Make sure you try the setup on a network with no restriction on out going traffic. Then as @lechercheur123 explains, try configuring Appliance.System.Clock and Appliance.System.Time.
Another option is to use Home Assistant and the Meross LAN integration. Be aware that you must use version <= 5.1 of the MQTT integration as in later versions compatibility with Meross devices broke and they refuse to fix it stating that they will not support usernames that don't conform with the "Unix password file" convention (Meross devices use MAC addresses as usernames and the colon breaks the password file).
Thanks to both of your insights and comments, I've made progress! Thank you so much (although I may update the Custom Pairer app as it could really use some TLC and documentation for us newbies). The problem I was encountering was that I didn't have the correct key. Since I did a full factory reset of the switch and fumbled around with the custom pairing app, I hadn't noticed that the MQTT key was both required and something that could be programmed in via the app. Once I got MQTT Hub going with the correct key, I started getting to register the switch, which led to everything appearing to work. So I'm going to close this with comment, and I'll suggest some edits and make a pull request on some fixes for the custom pairer (I'm an Android dev by day, home automation newbie by night)
I'm not sure what I'm doing wrong, but watching the Mosquitto log, I keep seeing the device connect, subscribe, publish a few times, and disconnect. I have over 60 different Meross switches that I will eventually all pair to my home assistant, but only after I can reliably control one.
Mosquitto version:
Log: