#33045·zigbee2mqtt

Aqara DS-K02D/DS-K02E: multi-click actions broken since 2.12.1

Author: smeyerspam-coderCreated Sep 5, 2026Updated Sep 17, 2026
Labelsproblem

What happened?

Multi-click actions on the Aqara H2 EU Shutter Switch, DS-K02D/DS-K02E, stopped working starting with Zigbee2MQTT 2.12.1.

The device supports the following presentValue values on the two wireless button endpoints:

0   = hold
1   = single
2   = double
255 = release

This worked correctly with Zigbee2MQTT 2.12.0.

Starting with Zigbee2MQTT 2.12.1, only single actions are published. Valid double, hold and release values are dropped.

I previously reported this as part of #32059, but that issue was primarily about ghost actions and was closed after the ghost-event problem was fixed. The remaining multi-click regression appears to be an independent issue.

Regression

Working:

Zigbee2MQTT 2.12.0
DS-K02E firmware 4122

Broken:

Zigbee2MQTT 2.12.1
Zigbee2MQTT 2.13.0
DS-K02E firmware 4122

Tested on 8 DS-K02E devices.

With 2.12.0, single, double, hold and release are handled correctly.

With 2.12.1 and 2.13.0, only single is published.

I have not claimed a runtime reproduction on 2.14.x here. However, I could not find any later DS-K02D/DS-K02E change restoring the removed multi-click action mapping.

Suspected cause

The regression appears to have been introduced by:

Koenkk/zigbee-herdsman-converters@03f52de5

Before that commit, the DS-K02D/DS-K02E definition used the generic lumiAction() converter with:

typescript
const aqaraH2EuShutterSwitchActionLookup = {
    hold: 0,
    single: 1,
    double: 2,
    release: 255,
};

and:

typescript
lumiAction({
    actionLookup: aqaraH2EuShutterSwitchActionLookup,
    endpointNames: aqaraH2EuShutterSwitchEndpointNames,
}),

Commit 03f52de5 removed this mapping and introduced lumiAqaraH2EuShutterSwitchAction() instead.

That converter only exposes:

button_3_single
button_4_single

and effectively contains this filter:

typescript
if (endpoint in buttonMap && value === 1) {
    return {action: `${buttonMap[endpoint]}_single`};
}

return null;

Therefore all valid values other than 1 are discarded:

0   hold     -> discarded
2   double   -> discarded
255 release  -> discarded

Why this should no longer be required for ghost-event prevention

The original converter change was introduced as part of the ghost-event fix from #32059.

However, the actual ghost-event problem has since been addressed separately at the reporting level.

In particular:

Koenkk/zigbee-herdsman-converters#12704
Koenkk/zigbee-herdsman-converters@96f3cd8

changed the presentValue reporting configuration on the wireless button endpoints so periodic reporting is disabled.

The PR explicitly states that physical button presses are firmware-generated unsolicited reports and are unaffected by disabling reporting.

This is also consistent with my own earlier testing.

I tested the following reporting configuration on all 8 DS-K02E devices:

minimum_report_interval = 0
maximum_report_interval = 65535
reportable_change = 1

Results:

Zigbee2MQTT 2.12.0: zero ghost actions
Zigbee2MQTT 2.13.0: zero ghost actions
8 devices
DS-K02E firmware 4122

This strongly suggests that the reporting fix and the action converter are separate concerns.

The reporting configuration solves the stale or ghost action problem.

Filtering the action converter to presentValue === 1 is therefore no longer necessary to prevent those periodic ghost events and currently breaks legitimate multi-click events.

Additional inconsistency

The DS-K02D/DS-K02E definition still exposes separate multi-click settings for the two wireless buttons.

Conceptually, these settings only make sense if the resulting multi-click values can also be converted into actions.

With an action converter accepting only presentValue === 1, enabling multi-click cannot result in a published double action.

Expected behavior

When multi-click is enabled, valid genMultistateInput.presentValue reports from endpoints 3 and 4 should be converted as before:

0   -> hold
1   -> single
2   -> double
255 -> release

For example:

button_3_single
button_3_double
button_3_hold
button_3_release

button_4_single
button_4_double
button_4_hold
button_4_release

or the equivalent endpoint names used by the current device definition.

Periodic stale reports should continue to be prevented by the reporting configuration introduced in #12704.

Suggested fix

Restore support for all valid presentValue action values while keeping the current reporting configuration.

One possible approach would be to restore the previous action mapping:

typescript
{
    hold: 0,
    single: 1,
    double: 2,
    release: 255,
}

either by reverting the action-converter portion of 03f52de5 or by extending the DS-K02D/DS-K02E-specific converter to handle all four valid values.

The reporting changes from #12704 should remain unchanged.

Related issues / changes

Koenkk/zigbee2mqtt#32059
Koenkk/zigbee-herdsman-converters@03f52de5
Koenkk/zigbee-herdsman-converters#12704
Koenkk/zigbee-herdsman-converters@96f3cd8

The key point is that #32059 fixed the ghost-event problem, while the multi-click regression introduced alongside the initial workaround remains a separate functional issue.

What did you expect to happen?

No response

How to reproduce it (minimal and precise)

No response

Zigbee2MQTT version

2.12.0

Adapter firmware version

7.4.5

Adapter

Sonoff Dongle Plus MG24

Setup

Home Assistant OS, Zigbee2MQTT Home Assistant App UTC 2026 - 6.18.39-haos - x64 CPU: Intel(R) N100 (x4) RAM: 15710 MB

Device database.db entry

No response

Debug log

No response

Notes

No response