Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Tuya/MEOS Thermostat - the time gets unsynchronized making built-in schedules unusable. #831

Closed
sstefanowski opened this issue Mar 30, 2021 · 17 comments

Comments

@sstefanowski
Copy link

The problem:
The Tuya/MEOS Thermostat support built-in heating schedules (and change temperature up to 6 times a day).
Unfortunately, the clock inside the device is not very precise and the time gets unsynchronized after a few days.
ZHA should take care of the device time and re-synchronize it with some default frequency (e.g. once a day).
The device should always receive a local date/time from ZHA. This also should be taken into consideration when summer/winter time changes

Similar Zigbee solutions take care of the device clock e.g. Tuya platform and Zigbee2MQT.
The solutions for the same issue in Zigbee2MQTT:
Koenkk/zigbee2mqtt#5916
Koenkk/zigbee2mqtt#5620

To Reproduce
Steps to reproduce the behaviour:

  1. Set a correct time on the Tuya/MEOS Thermostat device manually
  2. Leave it for a few days
  3. Check the time on the device after a few days
  4. The time on the device is no longer correct

Expected behaviour
When checking the time on the device it should be always correct. ZHA should take care of date/time settings and re-synchronize them periodically as the other Zigee platforms do.
The device should always receive a local date/time from ZHA. This also should be taken into consideration when summer/winter time changes

Screenshots
N/A

Additional context
N/A

@Adminiuga
Copy link
Contributor

Tuya should have just sticked to the standards. Nominally nthe device is a zigbee device, but really is using a proprietary protocol.

@sstefanowski
Copy link
Author

sstefanowski commented Mar 30, 2021

Yeah, I understand this is a nasty thing, but.... are we going to do something with it?

Edit no 1.
I just did another test with strange results...
Another strange thing is that I just did a re-pair test of the Thermostat and it got a strange time, so it looks like re-pairing with ZHA flashes some time to the device but the time is strange...

Scenario:
I removed Thermostat from the ZHA network at 6 PM and I changed the time to 9 AM manually on the device.
After re-paring, the Thermostat got strange time from ZHA, 3 PM (3 hours late to my local time - I'm in CET (GMT+2) and the thermostat set GMT-1)

. Isn't it strange?

Edit no 2.
Wooow.... It's even worse. Now, whenever I change the time manually on the device to 6PM it gets back to 3PM automatically. looks like it's syncing with ZHA time but.... incorrectly(!) - 3 hour late to local time.

Edit no 3.
Now it's getting very strange the thermostat, which was recently re-paired got somehow local time, it's 6 PM on this device (I've restarted HA nad Sonoff Zigbee bridge with Tasmota in meantime). But the other thermostats still have incorrect time. most of them are 3h late.

Any other tests I could do?

@mallorca2288
Copy link
Contributor

@sstefanowski What thermostat model do you have? I have a _TZE200_aoclfnxz thermostat and I'm having the same problem.

I'm not sure, but I believe that the command to set the time from ZHA to the device is already in the code, but it's only applied to some thermostatic valves and not to all tuya thermostats.

@mallorca2288
Copy link
Contributor

I was looking at the code and I think I've fixed it for my device. I've just added this line of code:
set_time_offset = 1970
in this line

So now the code looks like this:

class MoesBHTThermostat(TuyaThermostatCluster):
    """Thermostat cluster for some electric heating controllers."""

    set_time_offset = 1970

    def map_attribute(self, attribute, value):
        """Map standardized attribute value to dict of manufacturer values."""

I waited a few minutes until the thermostat asked for a time sync to the server:
2021-04-01 00:30:35 DEBUG (MainThread) [zhaquirks.tuya] [0xd829:1:0xef00] Got set time request (command 0x0024)

After that, I checked the thermostat and the time was correct. I'll keep an eye on it for the next few days to see if the problem was solved.

@sstefanowski
Copy link
Author

sstefanowski commented Mar 31, 2021

BTW. My Thermostat is heater valve _TZE200_ywdxldoj


OK. I can see the code and it looks like this handler should work but it is not working...

I enabled debug in configuration.yaml yesterday and... NOT a single log entry with [zhaquirks.tuya] [0xd829:1:0xef00] Got set time request (command 0x0024) was generated.
I can see just updated temperature readings generated by [zhaquirks.tuya]

but...
I can see periodic ERRORS in a log as follows:

Mar 31 23:52:23 raspberrypi hass[19459]: 2021-03-31 23:52:23 ERROR (MainThread) [zigpy.device] Failed to parse message (b'191c24004b') on cluster 61184, because Data is too short to contain 1 bytes
Mar 31 23:52:50 raspberrypi hass[19459]: 2021-03-31 23:52:50 ERROR (MainThread) [zigpy.device] Failed to parse message (b'195324004c') on cluster 61184, because Data is too short to contain 1 bytes
Mar 31 23:52:54 raspberrypi hass[19459]: 2021-03-31 23:52:54 ERROR (MainThread) [zigpy.device] Failed to parse message (b'1913240058') on cluster 61184, because Data is too short to contain 1 bytes
(...)
Mar 31 23:53:57 raspberrypi hass[19459]: 2021-03-31 23:53:57 ERROR (MainThread) [zigpy.device] Failed to parse message (b'19562403ea') on cluster 61184, because Data is too short to contain 1 bytes
(...)
Apr  1 00:52:49 raspberrypi hass[19459]: 2021-04-01 00:52:49 ERROR (MainThread) [zigpy.device] Failed to parse message (b'192124004e') on cluster 61184, because Data is too short to contain 1 bytes
Apr  1 00:53:21 raspberrypi hass[19459]: 2021-04-01 00:53:21 ERROR (MainThread) [zigpy.device] Failed to parse message (b'195b240050') on cluster 61184, because Data is too short to contain 1 bytes
Apr  1 00:53:26 raspberrypi hass[19459]: 2021-04-01 00:53:26 ERROR (MainThread) [zigpy.device] Failed to parse message (b'1926240062') on cluster 61184, because Data is too short to contain 1 bytes

and 61184=0xef00 (MeosManufCluster)
and all the messages listed contain static (b'19??24????') while 0x0024 is set_time_requestcommand in this cluster.

Can these ERRORS be related to missing time sync?
I think we are close to the solution, but I don't know how to fix it...

Isn't it something wrong with set_time_request command definition? Another custom behaviour of Tuya or just a bug?

class TuyaTimePayload(t.LVList, item_type=t.uint8_t, length_type=BigEndianInt16):

class TuyaManufCluster(CustomCluster):

the comment in the code suggests that the size of the payload of set_time_request sent from the device should be 0

    """ Time sync command (It's transparent between MCU and server)
            Time request device -> server
               payloadSize = 0

while set_time_request definition indicates some TuyaTimePayload. Isn't it a bug causing deserialization error message ...because Data is too short to contain 1 bytes?

    class Command(t.Struct):
        """Tuya manufacturer cluster command."""

        status: t.uint8_t
        tsn: t.uint8_t
        command_id: t.uint16_t
        function: t.uint8_t
        data: Data
(...)
    manufacturer_client_commands = {
        0x0001: ("get_data", (Command,), True),
        0x0002: ("set_data_response", (Command,), True),
        0x0024: ("set_time_request", (TuyaTimePayload,), True),
    }
(...)

Any hints how to fix it?

@sstefanowski
Copy link
Author

sstefanowski commented Apr 1, 2021

Update 1:
I've changed a line

0x0024: ("set_time_request", (TuyaTimePayload,), True),

to

0x0024: ("set_time_request", (t.NoData,), True),

and now...
I can see in the log
Apr 01 11:00:37 raspberrypi hass[21528]: 2021-04-01 11:00:37 DEBUG (MainThread) [zhaquirks.tuya] [0xd17c:1:0xef00] Got set time request (command 0x0024)
and one of my thermostats has valid time. I'll recheck remaining devices after some time.

Question to @Adminiuga and @xonestonex who is the main contributor to the ZHA quirk for Moes Thermostatic valve.
What do you think? Is this a proper way of fixing this?

Update 2:
Note: After applying a change all my MEOS Thermostat valves got the correct time. So there was a bug with using TuyaTime Payload for set_time_request.
but using t.NoData is not a good solution as it generates the following WARNING in a log:

Apr  2 00:04:31 raspberrypi hass[21528]: 2021-04-02 00:04:31 WARNING (MainThread) [zigpy.zcl] [0xcc53:1:0xef00] Data remains after deserializing ZCL frame
Apr  2 00:04:31 raspberrypi hass[21528]: 2021-04-02 00:04:31 DEBUG (MainThread) [zhaquirks.tuya] [0xcc53:1:0xef00] Got set time request (command 0x0024)

So I changed it to t.data16 and the WARNING is gone. Now it's just handling the set_time_request correctly. So the final version of the line
https://github.com/zigpy/zha-device-handlers/blob/dev/zhaquirks/tuya/__init__.py#L135
is as follows:
0x0024: ("set_time_request", (t.data16,), True),

I used t.data16 as I don't know the meaning of the payload (spec says it should be 0 and... I can see the payload is ignored in 0x0024 command handler. I just wanted the length of the payload to be correct.

I don't know if this is a fully correct fix. but having this is FAR more accurate than having a BUG and unsynchronized time.

I have no code branched. Can any developer implement this change and create a pull request for this, so we could have this in next release?

@almico
Copy link

almico commented Apr 12, 2021

I too have the _TZE200_ywdxldoj and would really love to see this fix applied!
Please, please, please 😄

@almico
Copy link

almico commented Apr 13, 2021

I can confirm that changing line 135 to 0x0024: ("set_time_request", (t.data16,), True), worked here too.
Thank you!

@almico
Copy link

almico commented Apr 13, 2021

I just received a new HY368 and its name is _TZE200_cwnjrr72...

@MattWestb
Copy link
Contributor

I was adding it in #820 if the user putting all info OK it shall working out of the box.

@sstefanowski
Copy link
Author

Hi @MattWestb,
I wonder.... If you have a source code already branched maybe you could update line 135 above to fix the time synchronization and create pull-request so this could to be analyzed by main ZHA contributors?

@sstefanowski
Copy link
Author

sstefanowski commented Apr 14, 2021

Hi @MattWestb,

Thanks for an update but...

I can see you committed:
0x0024: ("set_time_request", (t.NoData,), True),
while this setting generates a WARN in the log about unconsumed payload in a buffer. t.NoData means that it's not expecting any data but there are unconsumed bytes remaining (I guess 2 bytes) in the request.

Changing it to
("set_time_request", (t.data16,), True),
makes everything working without a WARN - remaining last bytes are consumed as expected but just not "interpreted".

Also, I don't meaning of these bytes but the previous entry using TuyaTimePayload for set_time_request was a real bug.

BTW. Maybe I should comment on a pull request directly what do you think?

@sstefanowski
Copy link
Author

OK, I'll comment on Pull Request
I can justify the commit

@MattWestb
Copy link
Contributor

Updated PR

@sstefanowski
Copy link
Author

@MattWestb,
Stupid question, how to install this commit? Do you mean just relacing the local file with the file from your repo?

@MattWestb
Copy link
Contributor

Download the commit as zip file or copy only the file changed and putting it in your system so we can see its working.

dmulcahey pushed a commit that referenced this issue Apr 25, 2021
* Fix for MEOS TRV Time setting

From #831 (comment)
User have reported that its working changing the time request and the TRV is getting the right time then its pulling the coordinator for it.
I dont know if its doing more bad things but for the moment its only the MOES TRV that is using the time setting (i think its made different for other models but is for the moment not used / implanted in  other then the MOES TRV).

* Update __init__.py

Updating with ("set_time_request", (t.data16,), True),
weddle pushed a commit to weddle/zha-device-handlers that referenced this issue Apr 30, 2021
* Fix for MEOS TRV Time setting

From zigpy#831 (comment)
User have reported that its working changing the time request and the TRV is getting the right time then its pulling the coordinator for it.
I dont know if its doing more bad things but for the moment its only the MOES TRV that is using the time setting (i think its made different for other models but is for the moment not used / implanted in  other then the MOES TRV).

* Update __init__.py

Updating with ("set_time_request", (t.data16,), True),
@sstefanowski
Copy link
Author

This is in release 0,57 so we can close the issue...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants