Koenkk / zigbee2mqtt

Zigbee 🐝 to MQTT bridge 🌉, get rid of your proprietary Zigbee bridges 🔨
https://www.zigbee2mqtt.io
GNU General Public License v3.0
11.49k stars 1.62k forks source link

Zemismart roller blinds ZM16EL-03/33 only moves in steps of 10% #21850

Open rschuiling opened 3 months ago

rschuiling commented 3 months ago

What happened?

I have just installed a Zemismart roller blind motor ZM16EL-03/33 through Zigbee2MQTT. When I use the Home Assistant service cover.set_cover_position, the blinds will only move to a 10%-position (so 0, 10, 20, 30 etc). Any other position gets rounded, eg. 12 gets rounded to 10. But because it’s a ‘zebra’ blind, I need more granular control.

I can’t find a configuration setting in Zigbee2MQTT. Google, Github issues and the Home Assistant forum all come up empty.

Is there a way to move the cover in steps of 1% instead of 10%?

What did you expect to happen?

I expected that the cover would move in steps of 1% instead of 10%.

How to reproduce it (minimal and precise)

In Home Assistant, use service cover.set_cover_position. Set to e.g. 93%. When the cover reaches its position, see how it reports its position as 90%.

service: cover.set_cover_position data: position: 93 target: entity_id: cover.cover_zebra

Zigbee2MQTT version

1.35.3

Adapter firmware version

20211217

Adapter

Sonoff Zigbee 3.0 stick 2652P

Setup

Add-on on HA on Intel NUC

Debug log

No response

julianfs commented 3 months ago

I have a zemismart ZM25RX-08/30 and I can't reproduce the issue, I can set position to any % without rounding.

rschuiling commented 3 months ago

Thanks @julianfs, I changed the title and description to include my specific type of Zemismart roller blinds motor.

rschuiling commented 3 months ago

I can´t find a solution to his. Also tried to get something from the logs but I can´t find anything relevant myself.

This is from the standard Z2M log, it just shows I try to set it to 32 and it ends up at 30:

debug 2024-04-05 20:10:54Received MQTT message on 'zigbee2mqtt/cover_zebra/set' with data '{"position":32}'
debug 2024-04-05 20:10:54Publishing 'set' 'position' to 'cover_zebra'
info 2024-04-05 20:10:55MQTT publish: topic 'zigbee2mqtt/cover_zebra', payload '{"battery":75,"border":"up","click_control":"down","linkquality":138,"motor_fault":false,"position":32,"reverse_direction":"back","state":"STOP"}'
debug 2024-04-05 20:10:55Received Zigbee message from 'cover_zebra', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,32],"type":"Buffer"},"datatype":2,"dp":2}],"seq":1}' from endpoint 1 with groupID 0
info 2024-04-05 20:10:55MQTT publish: topic 'zigbee2mqtt/cover_zebra', payload '{"battery":75,"border":"up","click_control":"down","linkquality":145,"motor_fault":false,"position":32,"reverse_direction":"back","state":"STOP"}'
debug 2024-04-05 20:11:00Received Zigbee message from 'cover_zebra', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,30],"type":"Buffer"},"datatype":2,"dp":3}],"seq":256}' from endpoint 1 with groupID 0
info 2024-04-05 20:11:00MQTT publish: topic 'zigbee2mqtt/cover_zebra', payload '{"battery":75,"border":"up","click_control":"down","linkquality":145,"motor_fault":false,"position":30,"reverse_direction":"back","state":"STOP"}'
debug 2024-04-05 20:11:00Received Zigbee message from 'cover_zebra', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,75],"type":"Buffer"},"datatype":2,"dp":13}],"seq":256}' from endpoint 1 with groupID 0
info 2024-04-05 20:11:00MQTT publish: topic 'zigbee2mqtt/cover_zebra', payload '{"battery":75,"border":"up","click_control":"down","linkquality":142,"motor_fault":false,"position":30,"reverse_direction":"back","state":"STOP"}'

I enabled the herdsman debug logging, but that only shows an error about a Zigbee bulb that is unreachable.

rschuiling commented 2 months ago

I found the Zemismart cover motor in tuya.ts. There seem to be two mentions of the 'position' datapoint:

                [2, 'position', tuya.valueConverter.coverPosition],
                [3, 'position', tuya.valueConverter.raw],

What is the difference here? And which one would actually get used by Zigbee2mqtt?

Here is the full device info from tuya.ts:

    {
        fingerprint: tuya.fingerprint('TS0601', ['_TZE200_68nvbio9', '_TZE200_pw7mji0l', '_TZE200_cf1sl3tj', '_TZE200_nw1r9hp6', '_TZE200_9p5xmj5r',
            '_TZE200_eevqq1uv']),
        model: 'TS0601_cover_3',
        vendor: 'TuYa',
        description: 'Cover motor',
        fromZigbee: [tuya.fz.datapoints],
        toZigbee: [tuya.tz.datapoints],
        onEvent: tuya.onEventSetTime,
        options: [exposes.options.invert_cover()],
        configure: tuya.configureMagicPacket,
        exposes: [
            e.battery(), e.cover_position(),
            e.enum('reverse_direction', ea.STATE_SET, ['forward', 'back']).withDescription('Reverse the motor direction'),
            e.enum('border', ea.STATE_SET, ['up', 'down', 'up_delete', 'down_delete', 'remove_top_bottom']),
            e.enum('click_control', ea.STATE_SET, ['up', 'down']).withDescription('Single motor steps'),
            e.binary('motor_fault', ea.STATE, true, false),
        ],
        whiteLabel: [
            tuya.whitelabel('Zemismart', 'ZM16EL-03/33', 'Cover motor', ['_TZE200_68nvbio9']),
            tuya.whitelabel('Zemismart', 'ZM25EL', 'Cover motor', ['_TZE200_pw7mji0l']),
            tuya.whitelabel('Zemismart', 'ZM85EL-2Z', 'Roman Rod I type U curtains track', ['_TZE200_cf1sl3tj', '_TZE200_nw1r9hp6']),
            tuya.whitelabel('Hiladuo', 'B09M3R35GC', 'Motorized roller shade', ['_TZE200_9p5xmj5r']),
        ],
        meta: {
            // All datapoints go in here
            tuyaDatapoints: [
                [1, 'state', tuya.valueConverterBasic.lookup({'OPEN': tuya.enum(0), 'STOP': tuya.enum(1), 'CLOSE': tuya.enum(2)})],
                [2, 'position', tuya.valueConverter.coverPosition],
                [3, 'position', tuya.valueConverter.raw],
                [5, 'reverse_direction', tuya.valueConverterBasic.lookup({'forward': tuya.enum(0), 'back': tuya.enum(1)})],
                [12, 'motor_fault', tuya.valueConverter.trueFalse1],
                [13, 'battery', tuya.valueConverter.raw],
                [16, 'border', tuya.valueConverterBasic.lookup({
                    'up': tuya.enum(0), 'down': tuya.enum(1), 'up_delete': tuya.enum(2), 'down_delete': tuya.enum(3),
                    'remove_top_bottom': tuya.enum(4)})],
                [20, 'click_control', tuya.valueConverterBasic.lookup({'up': tuya.enum(0), 'down': tuya.enum(1)})],
            ],
        },
    }