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

MOES/Tuya TS0601_dimmer 1 Gang no brightness control #13174

Closed
bort900 opened this issue Jul 17, 2022 · 13 comments
Closed

MOES/Tuya TS0601_dimmer 1 Gang no brightness control #13174

bort900 opened this issue Jul 17, 2022 · 13 comments
Labels
problem Something isn't working stale Stale issues

Comments

@bort900
Copy link

bort900 commented Jul 17, 2022

What happened?

Product Link: 1 Gang US White: https://www.aliexpress.com/item/3256803386112753.html

I have a MOES branded Tuya TS0601_dimmer wall dimmer and it will respond to on/off commands but not brightness commands. The min and max do not seem responsive either. You can manually adjust the dimmer at the switch the brightness and state are reflected properly, but you cant set brightness from Zigbee2MQTT or homeassistant.

This issue sounds similar to this one here, but could be unrelated.

You'll see in the log there is lots of extra garbage this unit seems to report that has nothing to do with dimming. Perhaps the zigbee-heardsman system is getting tripped up the extra values or this manufacturer changed their protocol slightly?

The same behavior is observed with 1.26.0-dev commit: [6377746]

What did you expect to happen?

When adjusting the brightness i expect the dimmer switch to respond according to the new value set by adjusting the brightness value from Zigbee2MQTT

How to reproduce it (minimal and precise)

Attempt to set the brightness via the 'Exposes' interface to any arbitrary value and then move it again. It will be unresponsive.

Zigbee2MQTT version

1.26.0

Adapter firmware version

2022021

Adapter

SONOFF Zigbee 3.0 USB adapter

Debug log

debug 2022-07-21 20:00:25Publishing 'set' 'brightness' to '0xa4c1387c45782087'
debug 2022-07-21 20:00:25Received Zigbee message from '0xa4c1387c45782087', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,1,193],"type":"Buffer"},"datatype":2,"dp":3}],"seq":52736}' from endpoint 1 with groupID 0
info 2022-07-21 20:00:25MQTT publish: topic 'zigbee2mqtt/0xa4c1387c45782087', payload '{"brightness":113,"level":449,"linkquality":87,"state":"OFF"}'
debug 2022-07-21 20:00:25Received Zigbee message from '0xa4c1387c45782087', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,1,194],"type":"Buffer"},"datatype":2,"dp":3}],"seq":52992}' from endpoint 1 with groupID 0
info 2022-07-21 20:00:25MQTT publish: topic 'zigbee2mqtt/0xa4c1387c45782087', payload '{"brightness":113,"level":450,"linkquality":87,"state":"OFF"}'
debug 2022-07-21 20:00:25Received Zigbee message from '0xa4c1387c45782087', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,1,194],"type":"Buffer"},"datatype":2,"dp":2}],"seq":53248}' from endpoint 1 with groupID 0
warning 2022-07-21 20:00:25zigbee-herdsman-converters:tuya_dimmer: Received unexpected Tuya DataPoint #2 from 0xa4c1387c45782087 with raw data '{"dp":2,"datatype":2,"data":{"type":"Buffer","data":[0,0,1,194]}}': type='commandDataReport', datatype='value', value='450', known DP# usage: ["heatingSetpoint","coverPosition","eardaDimmerLevel","moesHold","moesSheatingSetpoint","silvercrestChangeMode","tuyaSabCO2","tuyaSahkMP25","tuyaSabCO","moes105DimmerLevel1","trsSensitivity","trsfSensitivity","tvMode","haozeeHeatingSetpoint","nousHumidity","tthHumidity","tIlluminanceLux","evanellMode","AM02PercentControl","connecteMode","tshpscSensitivity","alectoSmokeValue"]
info 2022-07-21 20:00:25MQTT publish: topic 'zigbee2mqtt/0xa4c1387c45782087', payload '{"brightness":113,"level":450,"linkquality":87,"state":"OFF"}'```
@bort900 bort900 added the problem Something isn't working label Jul 17, 2022
@bort900
Copy link
Author

bort900 commented Jul 22, 2022

I have updated the log data to the correct info. It seems to me this switch has non-standard, or just differently implemented clusters than other similar dimmers.

I did make the following discovery. I am able to get control over brightness by using the 'exposes' page and sliding both the max_brightness and the brightness sliders and then fiddling (clicking again or adjusting by a point or two) with them to make the light physically change.

In my testing, the dimmer always seems to respond with the last value you intended to set, but the dimmer does NOT ever ACTUALLY go to the set point until you move both sliders, and fiddle with it. I am still trying to define the consistent behavior to make the actual change in brightness invoke.

I used MQTT-X and tried manually publishing the brightness and max_brightness, and while the switch accepts and reports the set point, it does not actually go to it, no matter how much i fiddle with commands from MQTT-X. I can however set the state, on or off, manually and the switch does respond to that.

I think my next step is to see what exactly is being sent and received to and from the switch by the zigbee-heardsman system. I believe we are only a few adjustments away from having this working for this particular dimmer.

@github-actions
Copy link
Contributor

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days

@github-actions github-actions bot added the stale Stale issues label Aug 22, 2022
@bort900
Copy link
Author

bort900 commented Aug 22, 2022

This is still an issue with the latest edge as of 8/22/2022.

Commenting to keep issue open.

@github-actions github-actions bot removed the stale Stale issues label Aug 23, 2022
@wutr
Copy link

wutr commented Sep 15, 2022

This sounds like the problem I'm having, but using ZHA: zigpy/zha-device-handlers#1750

Happy to help with extra logs and data.

@Koenkk
Copy link
Owner

Koenkk commented Sep 16, 2022

@bort900 can you provide the data/database.db entry of this device?

@bort900
Copy link
Author

bort900 commented Sep 21, 2022

Thank you kindly. please see below.

{"id":7,"type":"Router","ieeeAddr":"0xa4c1387c45782087","nwkAddr":25371,"manufId":4417,"manufName":"_TZE200_ip2akl4w","powerSource":"Mains (single phase)","modelId":"TS0601","epList":[1,242],"endpoints":{"1":{"profId":260,"epId":1,"devId":81,"inClusterList":[4,5,61184,0],"outClusterList":[25,10],"clusters":{"genBasic":{"attributes":{"65503":"��m*i","65506":54,"65508":0,"modelId":"TS0601","manufacturerName":"_TZE200_ip2akl4w","powerSource":1,"zclVersion":3,"appVersion":70,"stackVersion":0,"hwVersion":1,"dateCode":""}},"genTime":{"attributes":{}},"genGroups":{"attributes":{"nameSupport":0}},"manuSpecificTuya_3":{"attributes":{}},"genOta":{"attributes":{"currentZigbeeStackVersion":2}}},"binds":[{"cluster":6,"type":"endpoint","deviceIeeeAddress":"0x00124b0024c0c1b2","endpointID":1},{"cluster":8,"type":"endpoint","deviceIeeeAddress":"0x00124b0024c0c1b2","endpointID":1}],"configuredReportings":[],"meta":{}},"242":{"profId":41440,"epId":242,"devId":97,"inClusterList":[],"outClusterList":[33],"clusters":{},"binds":[],"configuredReportings":[],"meta":{}}},"appVersion":70,"stackVersion":0,"hwVersion":1,"dateCode":"","zclVersion":3,"interviewCompleted":true,"meta":{"configured":1},"lastSeen":1663737283118,"defaultSendRequestWhen":"immediate"}

@Koenkk
Copy link
Owner

Koenkk commented Sep 21, 2022

Could you check if the issue is fixed with the following external converter:

const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const extend = require('zigbee-herdsman-converters/lib/extend');
const utils = require('zigbee-herdsman-converters/lib/utils');
const ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const e = exposes.presets;
const ea = exposes.access;

const tzLocal = {
    tuya_dimmer_level: {
        key: ['brightness_min', 'min_brightness', 'max_brightness', 'brightness', 'brightness_percent', 'level'],
        convertSet: async (entity, key, value, meta) => {
            // upscale to 1000
            let newValue;
            let dp = tuya.dataPoints.dimmerLevel;
            if (['_TZE200_3p5ydos3', '_TZE200_9i9dt8is', '_TZE200_dfxkcots', '_TZE200_w4cryh2i', '_TZE200_ip2akl4w'].includes(meta.device.manufacturerName)) {
                dp = tuya.dataPoints.eardaDimmerLevel;
            }
            if (key === 'brightness_min') {
                if (value >= 0 && value <= 100) {
                    newValue = utils.mapNumberRange(value, 0, 100, 0, 1000);
                    dp = tuya.dataPoints.dimmerLevel;
                } else {
                    throw new Error('Dimmer brightness_min is out of range 0..100');
                }
            } else if (key === 'min_brightness') {
                if (value >= 1 && value <= 255) {
                    newValue = utils.mapNumberRange(value, 1, 255, 0, 1000);
                    dp = tuya.dataPoints.dimmerMinLevel;
                } else {
                    throw new Error('Dimmer min_brightness is out of range 1..255');
                }
            } else if (key === 'max_brightness') {
                if (value >= 1 && value <= 255) {
                    newValue = utils.mapNumberRange(value, 1, 255, 0, 1000);
                    dp = tuya.dataPoints.dimmerMaxLevel;
                } else {
                    throw new Error('Dimmer min_brightness is out of range 1..255');
                }
            } else if (key === 'level') {
                if (value >= 0 && value <= 1000) {
                    newValue = Math.round(Number(value));
                } else {
                    throw new Error('Dimmer level is out of range 0..1000');
                }
            } else if (key === 'brightness_percent') {
                if (value >= 0 && value <= 100) {
                    newValue = utils.mapNumberRange(value, 0, 100, 0, 1000);
                } else {
                    throw new Error('Dimmer brightness_percent is out of range 0..100');
                }
            } else { // brightness
                if (value >= 0 && value <= 254) {
                    newValue = utils.mapNumberRange(value, 0, 254, 0, 1000);
                } else {
                    throw new Error('Dimmer brightness is out of range 0..254');
                }
            }
            // Always use same transid as tuya_dimmer_state (https://github.com/Koenkk/zigbee2mqtt/issues/6366)
            await tuya.sendDataPointValue(entity, dp, newValue, 'dataRequest', 1);
        },
    }
}

const fzLocal = {
    tuya_dimmer: {
        cluster: 'manuSpecificTuya',
        type: ['commandDataResponse', 'commandDataReport'],
        convert: (model, msg, publish, options, meta) => {
            const dpValue = tuya.firstDpValue(msg, meta, 'tuya_dimmer');
            const value = tuya.getDataValue(dpValue);
            if (dpValue.dp === tuya.dataPoints.state) {
                return {state: value ? 'ON': 'OFF'};
            } else if (meta.device.manufacturerName === '_TZE200_swaamsoy') {
                // https://github.com/Koenkk/zigbee-herdsman-converters/pull/3004
                if (dpValue.dp === 2) {
                    if (value < 10) {
                        tuya.logUnexpectedDataValue('tuya_dimmer', msg, dpValue, meta, 'brightness', 10, 1000);
                    }
                    return {brightness: utils.mapNumberRange(value, 10, 1000, 0, 254)};
                }
            } else if (['_TZE200_3p5ydos3', '_TZE200_9i9dt8is', '_TZE200_dfxkcots', '_TZE200_w4cryh2i', '_TZE200_ip2akl4w']
                .includes(meta.device.manufacturerName)) {
                if (dpValue.dp === tuya.dataPoints.eardaDimmerLevel) {
                    return {brightness: utils.mapNumberRange(value, 0, 1000, 0, 254)};
                } else if (dpValue.dp === tuya.dataPoints.dimmerMinLevel) {
                    return {min_brightness: utils.mapNumberRange(value, 0, 1000, 1, 255)};
                } else if (dpValue.dp === tuya.dataPoints.dimmerMaxLevel) {
                    return {max_brightness: utils.mapNumberRange(value, 0, 1000, 1, 255)};
                } else {
                    tuya.logUnexpectedDataPoint('tuya_dimmer', msg, dpValue, meta);
                }
            } else {
                if (dpValue.dp !== tuya.dataPoints.dimmerLevel) {
                    tuya.logUnexpectedDataPoint('tuya_dimmer', msg, dpValue, meta);
                }
                if (dpValue.datatype !== tuya.dataTypes.value) {
                    tuya.logUnexpectedDataType('tuya_dimmer', msg, dpValue, meta);
                } else {
                    if (value < 10) {
                        tuya.logUnexpectedDataValue('tuya_dimmer', msg, dpValue, meta, 'brightness', 10, 1000);
                    }
                    return {brightness: utils.mapNumberRange(value, 10, 1000, 0, 254), level: value};
                }
            }
        },
    }
}

const definition = {
    fingerprint: [
        {modelID: 'TS0601', manufacturerName: '_TZE200_ip2akl4w'},
    ],
    model: 'TS0601_dimmer',
    vendor: 'TuYa',
    description: 'Zigbee smart dimmer',
    fromZigbee: [fzLocal.tuya_dimmer, fz.ignore_basic_report],
    toZigbee: [tz.tuya_dimmer_state, tzLocal.tuya_dimmer_level],
    configure: async (device, coordinatorEndpoint, logger) => {
        const endpoint = device.getEndpoint(1);
        await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
    },
    exposes: [e.light_brightness().withMinBrightness().withMaxBrightness().setAccess(
        'state', ea.STATE_SET).setAccess('brightness', ea.STATE_SET).setAccess(
        'min_brightness', ea.STATE_SET).setAccess('max_brightness', ea.STATE_SET)],
    whiteLabel: [
        {vendor: 'Larkkey', model: 'ZSTY-SM-1DMZG-EU'},
        {vendor: 'Earda', model: 'EDM-1ZAA-EU'},
        {vendor: 'Earda', model: 'EDM-1ZAB-EU'},
        {vendor: 'Earda', model: 'EDM-1ZBA-EU'},
        {vendor: 'Mercator Ikuü', model: 'SSWD01'},
        {vendor: 'Moes', model: 'ZS-USD'},
    ],
};

module.exports = definition;
  • save this as file next to configuration.yaml as ext_converter.js
  • add it to configuration.yaml:
external_converters:
  - ext_converter.js
  • start z2m, check if issue is fixed

@bort900
Copy link
Author

bort900 commented Sep 21, 2022

@Koenkk I am confirming this external converter did fix the issue. Lights turn on and off and go to the set dimming level each time.

Thank you so much for your time on this!

@Koenkk
Copy link
Owner

Koenkk commented Sep 22, 2022

@bort900 great, can you also check with this converter? https://gist.github.com/Koenkk/9c36da807c3768a85aaed9a352c74e96

@bort900
Copy link
Author

bort900 commented Sep 23, 2022

@Koenkk Yes, that converter appears to work as well. Big thank you again! Happy to test more. And in fact, i have 2, 3, and 4 gang versions of this dimmer i never setup because the 1 gang was not working. I am happy to test and report on those as well.

@Koenkk
Copy link
Owner

Koenkk commented Sep 23, 2022

@bort900 please test, then we can immediately fix those. I'm interested in how z2m recognizes them.

@bort900
Copy link
Author

bort900 commented Sep 23, 2022

Will do! I will get them labbed up this weekend.

@github-actions
Copy link
Contributor

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days

@github-actions github-actions bot added the stale Stale issues label Oct 24, 2022
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Nov 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
problem Something isn't working stale Stale issues
Projects
None yet
Development

No branches or pull requests

3 participants