Error report of Matter Window Covering Edge Driver

I have a Zemismart M1 hub, which is a certified matter bridge.

A curtain motor, which is paired to the Zemismart M1 hub, is exposed to SmartThings as a Matter Window Covering device.

When I change the position of the curtain by adjusting slide bar to the 100% in the SmartThings app(=windowShadelevel.setShadeLevel(100) command),
the curtain moves to the destination position(=fully opened position) as expected.

After the motor moves to the destination position, the motor only sends currentPositionLiftPercent100ths attribute of WindowCovering matter cluster.
(as you can see in the hub log below)

It sets the windowShadelevel.shadeLevel attribute to 100% as expected, but it fails to changes the shade status to open, and still shows as if the shade is Closed.

(닫힘 means Closed)

It is because capabilities.windowShade.windowShade attribute is not changed even after it receives currentPositionLiftPercent100ths packet.

current_pos_handler() function, which is hooked to the clusters.WindowCovering.attributes.CurrentPositionLiftPercent100ths only sets capabilities.windowShadelevel.shadeLevel attributes,

and capabilities.windowShade.windowShade is updated in current_status_handler() only if clusters.WindowCovering.attributes.OperationalStatus packet is received.

As you can see in the hub log, clusters.WindowCovering.attributes.OperationalStatus packet is not always received after every motor move.

This problem needs to be fixed, to show correct windowShade status.

1 Like

@iquix Thanks for the information, I will report it to the team :saluting_face:


@iquix Thank you for the kind report.

  • Could you please tell me the exact model of curtain motor you used?
  • Is there a 100% chance of the hub not receiving the clusters.WindowCovering.attributes.OperationalStatus packet? I wonder if there are times when it works well.
1 Like

I used this model

This is the zemismart motor that I’ve been using since 2020, when I first made the tuya-window-shade DTH.

  • fingerprint : [manufacturer: “_TZE200_cowvfni3”, model: “TS0601”]
  • firmware version : Zigbee module: V1.1.2 / MCU module: V4.0.0 (as shown in tuya app)

FYI, Zemismart M1 hub only exposes selective subdevices to matter, (not all tuya subdevices) and my device is in the list below.
Sub-device Work with M1 Hub (

100% chance. Never received clusters.WindowCovering.attributes.OperationalStatus packet when I control the motor from the SmartThings app.

I haven’t tested with other models of Zemismart shade motors though. It may be different in other subdevices under M1 hub.

Actually, I have a Zemismart M1 hub compatible blind motor, but not physically installed in my home. I’ll let you know after I connect this blind motor to the M1 hub later.

But anyway, it is not guaranteed that the hub always sends operationalStatus packet, so the algorithm of the edge driver needs to be changed.

below is my personal guess…
I think device manufacturers don’t care about the operationalStatus packet.

Apple Homekit and Google Home only shows slide bar on their UI for shade devices. No information about status of the shade motor on these platforms. Manufacturers might have tested their device only on these platforms, so they never thought about OperationalStatus.


I tested with this Zemismart Blind Motor, which I bought last year (= 2023).

It didn’t send the OperationalStatus packet neither.

1 Like

I can confirm the same issue (developing Matter bridge driver on another platform) - the OpertaionalStatus attribute is not reported, although the subscription is successful.

Are you affiliated with Tuya?

@iquix, Thank you for your kind explanation. Since the Matter spec document states that the OperationalStatus attribute on the WindowCovering cluster SHALL be updated, I believe this issue is a Matter Bridge bug in the Zemismart M1 Hub as @Trakker2 mentioned.

This attribute SHALL indicate the currently ongoing operations and applies to all type of devices.

We will be working on the following tasks.

  • Purchase and test the products you use
  • Review whether workaround for Zemismart blinds device can be applied to the matter-window-covering driver
  • Contact the manufacturer

There is progress in my attempts to reach Tuya R&D - hopefully we will receive some valuable information here :

The algorithm of the stock Edge Driver needs to be changed.

I also tested with Aqara curtain motor with Aqara hub, which is a certified matter bridge.

fingerprint of the motor is
manufacturer: LUMI / model: lumi.curtain
(the same Aqara motor which is wwst certified)

In this case, the hub sends OperationalStatus packet correctly, but the app shows wrong status.
It shows last status, not the current status.

열림 : open
닫는중 : closing
일부열림 : partially open
여는중 : opening

It is because the matter bridge sends CurrentPositionLiftPercent100th packet AFTER OperationalStatus Packet.

The stock edge driver assumes that CurrentPositionLiftPercent100th packet comes before the OperationalStatus packet, but it is not guaranteed.

The algorithm of the stock edge driver needs to be changed to display the status according to CurrentPositionLiftPercent100th, regardless of the OperationalStatus packet.

1 Like

Thank you for the detailed report!

The cause of the Aqara curtain motor issue is different from the Zemismart blinds issue. Edge Driver needs to be changed, but we will also consider improving Matter specifications. The Matter specification only states that CurrentPositionLiftPercent100th and OperationalStatus SHALL be changed, but does not define the order. There is no problem from the device’s perspective, but for displaying windowShade status like SmartThings, the order is important.

  1. Edge Driver
    • Assume that the matter device sends packets in the order of CurrentPositionLiftPercent100th, OperationalStatus, or sends both at once.
  2. Aqara curtain motor with Aqara hub
    • The matter bridge device sends packets in the order of OperationalStatus, CurrentPositionLiftPercent100th.
  3. Zemismart blinds with Zemismart M1 hub
    • The matter bridge device only sends CurrentPositionLiftPercent100th packet.


With the multi admin capability of matter,

I also hooked this motor to the HomeAssistant, which is a open source IoT platform.

It displays the status correctly (both Aqara and Zemismart), regardless of the order of the packet and existence of OperationalStatus packet.

As you see in the screenshot, the status of the Aqara motor changes like this

Open → Closing → Open → Closed

It seems that HomeAssistant updates the status in both situation

logic 1. when OperationalStatus packet is received
(open → closing)
(closing → open)

logic 2. when CurrentPositionLiftPercent100th is received
(open → closed)

SmartThings does not have logic 2. Thats why the status is not correctly displayed in both Aqara and Zemismart motors.


Thank you for sharing your HomeAssistant story. :slight_smile:

I took a quick look at HomeAssistant’s code, but some further analysis is needed.

  1. If Zemismart does not send OperationalStatus packet, HomeAssistant has no way to know whether Zemismart has stopped operating. Therefore, HomeAssistant does not have a standard to determine “open” or “closed” status, but it is incomprehensible that the status changes correctly.
  2. We will modify the Edge Driver for Aqara so that the status is displayed well regardless of the packet order. However, it’s a little tricky because SmartThings has a “partially open” status. In addition, the packet order is different for each blinds manufacturer, requiring attention in the implementation of the matter controller, so improvement is needed.
1 Like

I can add Hubutat story - a lot of workarounds are implemented (and are still to be implemented) so that different manufacturers Matter WindowCovering cluster implementation is covered correctly.

There were also problems reported with SwitchBot curtain motors - seems like Switchbot Hub2 Matter bridge does not accept the UpOrOpen and DownOrClose commands, but works with the GoToLiftValue (0x04) command!

Go figure …

It’s not that tricky. I think it might work when you add the code below in the current_pos_hander() function, where between L134~L135 of the matter window coverting edge driver source code.

  current_state = device:get_latest_state(
                     "main", capabilities.windowShade.ID,

  if current_state ~= "opening" and current_state ~= "closing" then
    if position == 0 then
      window_shade_val = "closed"
    elseif position == 100 then 
      window_shade_val = "open"
    elseif position > 0 and position < 100 then
      window_shade_val = "partially open"
      window_shade_val = "unknown"

        ib.endpoint_id, capabilities.windowShade.windowShade(window_shade_val)

Thank you so much for sharing the details and patch.
I checked your patch and it’s amazing for me. because it seems to be almost the same direction I am trying to modify.

However, there’s a little different.
There are devices that change the current position in real time until the target position without changing the operational status. These devices change the operational status when the target position is reached. In addition, there may be devices that operate in various ways, so I think we need to think a little more and apply them.

Thank you very much for sharing the patch, again.
We will modify the Zemismart devices so that it can work properly in a short time.

1 Like

Thank you for chiming in and welcome to the ST community forum!

There is also a problem with Zemismart M515EGB TS0601 _TZE200_xuzcvlku chain roller shade driver - it is not visible in SmartThings via Zemismart M1 bridge.

Can you look at this issue also, please ?

I don’t think the matter bridge (Zemismart M1 hub) supports this device. Do other platforms support this?

This is the billion-dollar question - who makes what in Tuya’s ecosystem? :slight_smile:

And yes, the Tuya Matter Bridge supports many more devices than those shown on the Zemismart seller page. Not only labeled Zemismart, but made and sold by many other manufacturers and resellers.

Do you know what makes a Tuya-ecosystem Zigbee device be exposed via the Tuya Matter bridge?

I think this will be covered with the existing code of current_status_handler(), when the device sends OperationalStatus packet at the end of the move.