bytespider / Meross

Investigating the Meross/Refoss MSS310 Smart Plug and getting these devices to communicate with our private MQTT brokers
113 stars 19 forks source link

No time synchronisation with 5.1.1 firmware #61

Closed al-r1517 closed 1 year ago

al-r1517 commented 1 year ago

Hello,

I am using several devices (mss110, mss210, mss310, mss710) with a local mqtt. The ntp port is open.

The device with 5.1.1 firmware (mss110 and some mss310) do not synchronise the time with ntp. At the boot, the timestamp starts at 0 up to ~2200000

For the devices with firmware <5, there is not problem : the timestamp is well synchronized.

Is there a some configuration on mosquitto or somewhere to do ?

lechercheur123 commented 1 year ago

Hello,

I have some MSS310 with firmware 6.1.10 and I had the same issue.

The solution I use is setting Appliance.System.Clock and Appliance.System.Time manually through MQTT.

Here is a the code I use to generate the JSON payload of the corresponding MQTT messages:

def generateMqttMessage(uuid, key, messageType, namespace, parameters=None):        
        data={}
        data["header"]={}
        data["header"]["from"]="/app/0-"+uuid+"/subscribe"
        data["header"]["messageId"]="4541214e421e874f1248fabcd587fe48"
        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"])
                now=datetime.now(tm)
                #now= now+ relativedelta(months=10)
                #print(now)
                # Previous end or debut of DST
                if(datetime.dst(now) != timedelta()):
                        dst1 = now + relativedelta(month=3, day=31, weekday=SU(-1), second=0, minute=0, hour=3, microsecond=0)
                        dst2 = now + relativedelta(month=10, day=31, weekday=SU(-1), second=59, minute=59, hour=2, microsecond=0)
                        dst3 = now + 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 = now + relativedelta(month=3, day=31,  weekday=SU(-1), second=0, minute=0, hour=3)
                        if(now < dst2):
                                dst1 = now + relativedelta(years=-1, month=10, day=31, weekday=SU(-1), second=59, minute=59, hour=2)
                                dst3 = now + relativedelta(month=10, day=31, weekday=SU(-1), second=59, minute=59, hour=2)
                        else:
                                dst1 = now + relativedelta(month=10, day=31, weekday=SU(-1), second=59, minute=59, hour=2, microsecond=0)
                                dst2 = now + relativedelta(years=1, month=3, day=31, weekday=SU(-1), second=0, minute=0, hour=3, microsecond=0)
                                dst3 = now + 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)

Appliance.System.Time also set the DST period. As I am french and I live in Metropolitan France, I use Europe/Paris for my timezone and my DST period begins at 3 o'clock on the last Sunday of March, and finishes at 3 o'clock the las Sunday of October. You may need to change my code accordingly ;)

I hope this can help.

al-r1517 commented 1 year ago

Thank you for your quick response. It is working.