-
Notifications
You must be signed in to change notification settings - Fork 660
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
[Device Support Request] Device support for Tuya TS110E #1415
Comments
I suggest you to remove your quirk and post the 'original' device signature. The one you have posted is with the quirk applied. |
Hmm inspecting this closer I don't think the problem is that the brightness is over 100. It seems like brightness is a scale from 0 to 255. Like when I slide the slider to 2, there is a
full logs for that:
And If I move it to 98 there is a
full logs for that
Is there anything else interesting you can find in the logs? |
Thanks for the signature. It seems that your device its a 'normal' zigbee device with the Try to get traces from operate the physical device. Usually when you interact with the device, it reports its status and we can get some information from that message. PS: dim values are from 0 to 255 😉 |
I see now what you meant. Not just control the slider of the UI, but actually the physical device. I can't quite wrap my head around yet what I can make out of that yet. The slider in the UI for the dimmer doesn't move at all when I dim the physical light. I do see log lines like
I see that the dim values from the device itself are between 0 and 1000. So that has to be mapped to the dim values 0 to 255. I think for the existing quirks that's done here: zha-device-handlers/zhaquirks/tuya/__init__.py Line 1156 in e3fa034
So I probably somehow have to incorporate that I also see that I also see that attribute Do you see anything in the logs when operating the physical device below that could give me a hint of what I'm missing?
|
Maybe interesting: When I bring back my custom quirk with these input clusters enabled:
And then setting the brightness via UI slider I get
Which has a different But I do I get my quirk to set this attribute |
Ok, first I am going to try to explain to you what we are seeing and then we will see what can be done.
Here we have an attributte report from the device. The second part is telling us that the attribute Also, the expected that values are from 0 to 255. And, what can be done? Create a new quirk for this class F000LevelControlCluster(LevelControl):
"""LevelControlCluster that reports to attrid 0xF000."""
class TuyaLevelPayload(t.Struct):
"""Tuya Level payload."""
level: t.uint16_t
transtime: t.uint16_t
manufacturer_attributes = {0xF000: ("manufacturer_current_level", t.uint16_t),}
manufacturer_server_commands = {
0x00F0: ("moveToLevelTuya", (TuyaLevelPayload,), False),
}
# 0xF000 reported values are 0-1000, convert to 0-255
def _update_attribute(self, attrid, value):
if attrid == 0xF000:
value = (value * 255) // 1000
attrid = 0x0000
super()._update_attribute(attrid, value)
async def command(
self,
command_id: Union[foundation.Command, int, t.uint8_t],
*args,
manufacturer: Optional[Union[int, t.uint16_t]] = None,
expect_reply: bool = True,
tsn: Optional[Union[int, t.uint8_t]] = None,
):
"""Override the default Cluster command."""
self.debug(
"Sending Cluster Command. Cluster Command is %x, Arguments are %s",
command_id,
args,
)
# move_to_level, move, move_to_level_with_on_off
if command_id in (0x0000, 0x0001, 0x0004):
# convert dim values to 0-1000
brightness = (args[0] * 1000) // 255
return await super().command(
0x00F0,
TuyaLevelPayload(level=brightness, transtime=0),
manufacturer,
expect_reply,
tsn
)
return super().command(command_id, *args, manufacturer, expect_reply, tsn) Be carefull with new imports. Then you can use this cluster in your quirk: class DimmerSwitchWithNeutral1Gang(TuyaDimmerSwitch):
"""Tuya Dimmer Switch Module With Neutral 1 Gang"""
signature = {
MODELS_INFO: [("_TZ3210_ngqk6jia", "TS110E")],
ENDPOINTS: {
# <SimpleDescriptor endpoint=1 profile=260 device_type=257
# input_clusters=[0, 4, 5, 6, 8, 57345]
# output_clusters=[10, 25]>
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
LevelControl.cluster_id,
TuyaZBExternalSwitchTypeCluster.cluster_id,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
242: {
# <SimpleDescriptor endpoint=242 profile=41440 device_type=97
# input_clusters=[]
# output_clusters=[33]
PROFILE_ID: 41440,
DEVICE_TYPE: 97,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.DIMMABLE_LIGHT,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
F000LevelControlCluster,
TuyaZBExternalSwitchTypeCluster.cluster_id,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
242: {
PROFILE_ID: 41440,
DEVICE_TYPE: 97,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
},
} The edit: code update |
Only for info i have one 2 gang with no neutral version |
@MattWestb do you know about any quirk that is 'translating' from one cluster attribute ( |
I have not seen one, then tuya is making all thing not 100% the same like the power on default is 2/3 function OK and have leaving it on the tuya attribute and not "converting" it to ZCL standard. Perhaps the tuya TRVs is using many attributes but i dont knowing is some is being "moved" to ZCL standard but its not the same then its to and from DP commands. Perhaps our @puddly is knowing if some Xiaomi devices is doing it (they using different attributes / commands strings for attribute reporting and setting)? |
I have putting in the new found attribute in the matrix as WIP and linked here. zigpy/zigpy#823 (comment) Then have the level working is the device very likely have more attributes that is not implanted but can being done like what Bulb type is connected (found in latest tuya dev docks and all is not tested but some is working like min and may dim). |
Wow awesome, thanks so much for your help so far. So you were exactly right, the
You were also right that the
and then a little further down
So it expects Is it now guesswork to find out what command the device needs? |
Do you think something similar to this helps? zha-device-handlers/zhaquirks/tuya/__init__.py Lines 429 to 450 in e3fa034
I already tries some variations with now success yet. |
Try uncomment this line from manufacturer_attributes = {0xF000: ("current_level", t.uint8_t),} # maybe needed for write_attributes |
Hmm no, still the same error:
But what's new is that for every tuya value greater than 256 I get this error as well:
|
changing it to
removes the second error, but still has the first error... |
Maybe this way (as a quick&dirty workaround): async def command(
self,
command_id: Union[foundation.Command, int, t.uint8_t],
*args,
manufacturer: Optional[Union[int, t.uint16_t]] = None,
expect_reply: bool = True,
tsn: Optional[Union[int, t.uint8_t]] = None,
):
"""Override the default Cluster command."""
self.debug(
"Sending Cluster Command. Cluster Command is %x, Arguments are %s",
command_id,
args,
)
# move_to_level, move, move_to_level_with_on_off
if command_id in (0x0000, 0x0001, 0x0004):
# convert dim values to 0-1000
brightness = (args[0] * 1000) // 255
self.write_attributes({0xF000: brightness}, manufacturer=manufacturer)
return [[foundation.WriteAttributesStatusRecord(foundation.Status.SUCCESS)]]
return super().command(command_id, *args, manufacturer, expect_reply, tsn) I'll keep looking... |
I think that there is a better approach: async def command(
self,
command_id: Union[foundation.Command, int, t.uint8_t],
*args,
manufacturer: Optional[Union[int, t.uint16_t]] = None,
expect_reply: bool = True,
tsn: Optional[Union[int, t.uint8_t]] = None,
):
"""Override the default Cluster command."""
self.debug(
"Sending Cluster Command. Cluster Command is %x, Arguments are %s",
command_id,
args,
)
# move_to_level, move, move_to_level_with_on_off
if command_id in (0x0000, 0x0001, 0x0004):
# convert dim values to 0-1000
brightness = (args[0] * 1000) // 255
(res,) = await self.write_attributes({0xF000: brightness}, manufacturer=manufacturer)
return [command_id, res[0].status]
return super().command(command_id, *args, manufacturer, expect_reply, tsn) 🤞🏻 |
Another test you can perform is try to read & update this attribute from cluster You can try to put a 0-255 value and hit 'Set zigbee attribute', this should change the dim value from device. Look at the logs and attach all you find relevant. |
So I tried the second better approach you sent and no error anymore, but also not changing the brightness on the device.
I will try the "Manage clusters" read and update attribute next. |
No, that is what I has expected.
The problem is that HA will 'talk' with the 0x0000 attribute, but it seems that device is listening to the 0xF000. |
It would be probably more appropriate to rename it to |
If I click 'Issue Zigbee Command' for
|
The 'sets' from 'Gets' for the Wich one of the |
That's normal because UI command can't get values for methods. |
Okay so for the |
So, it seems that device is NOT using the standard Wonderfull... maybe it's using another attribute for setting values. One last try that you can make is to change the (res,) = await self.write_attributes({0xF000: brightness}, manufacturer=b"") It's rest time for me. Tomorrow I will look if this device has been implemented in other libraries and maybe someone have found how to set the dim value 🤦🏻♂️ |
Yeah it's really weird. But the What's weird is that as I'm using the physical device the click on 'Get Zigbee Attribute' doesn't update and also that when I'm using the slider in the UI the brightness of the physical device doesn't update. I tried That would be awesome to look at other implementations. I actually did look around a bit and found these lines in zigbee2mqtt: I'm just really bad at reading this and it doesn't mean much to me. Does that mean anything to you? |
Hmm it appears in this thread they also discovered that this device is hard to implement and in September they reverted support for the |
Okay sorry for posting so much, but after even more digging, there's a post that promises more hope: A lot of other issues on zigbee2mqtt linked to this post: Koenkk/zigbee2mqtt#9878 The key seems to be this non-standard command:
|
I'm also reading the same posts. Today last offer: class F000LevelControlCluster(LevelControl):
"""LevelControlCluster that reports to attrid 0xF000."""
class TuyaLevelPayload(t.Struct):
"""Tuya Level payload."""
level: t.uint16_t
transtime: t.uint16_t
manufacturer_attributes = {0xF000: ("manufacturer_current_level", t.uint16_t),}
manufacturer_server_commands = {
0x00F0: ("moveToLevelTuya", (TuyaLevelPayload,), False),
}
# 0xF000 reported values are 0-1000, convert to 0-255
def _update_attribute(self, attrid, value):
if attrid == 0xF000:
value = (value * 255) // 1000
attrid = 0x0000
super()._update_attribute(attrid, value)
async def command(
self,
command_id: Union[foundation.Command, int, t.uint8_t],
*args,
manufacturer: Optional[Union[int, t.uint16_t]] = None,
expect_reply: bool = True,
tsn: Optional[Union[int, t.uint8_t]] = None,
):
"""Override the default Cluster command."""
self.debug(
"Sending Cluster Command. Cluster Command is %x, Arguments are %s",
command_id,
args,
)
# move_to_level, move, move_to_level_with_on_off
if command_id in (0x0000, 0x0001, 0x0004):
# convert dim values to 0-1000
brightness = (args[0] * 1000) // 255
return await super().command(
0x00F0,
TuyaLevelPayload(level=brightness, transtime=0),
manufacturer,
expect_reply,
tsn
)
return super().command(command_id, *args, manufacturer, expect_reply, tsn) Not sure if it must be I will check the results in (my) morning. 😴 |
Wow! Good news for when you wake up 😄 After a few more changes it's finally working 🎉! Thank you so much!! I had to move the Here's the final product: class TuyaLevelPayload(t.Struct):
"""Tuya Level payload."""
level: t.uint16_t
transtime: t.uint16_t
class F000LevelControlCluster(LevelControl):
"""LevelControlCluster that reports to attrid 0xF000."""
manufacturer_attributes = {0xF000: ("manufacturer_current_level", t.uint16_t),}
manufacturer_server_commands = {
0x00F0: ("moveToLevelTuya", (TuyaLevelPayload,), False),
}
# 0xF000 reported values are 0-1000, convert to 0-255
def _update_attribute(self, attrid, value):
if attrid == 0xF000:
value = (value * 255) // 1000
attrid = 0x0000
super()._update_attribute(attrid, value)
async def command(
self,
command_id: Union[foundation.Command, int, t.uint8_t],
*args,
manufacturer: Optional[Union[int, t.uint16_t]] = None,
expect_reply: bool = True,
tsn: Optional[Union[int, t.uint8_t]] = None,
):
"""Override the default Cluster command."""
self.debug(
"Sending Cluster Command. Cluster Command is %x, Arguments are %s",
command_id,
args,
)
# move_to_level, move, move_to_level_with_on_off
if command_id in (0x0000, 0x0001, 0x0004):
# convert dim values to 0-1000
brightness = (args[0] * 1000) // 255
return await super().command(
0x00F0,
TuyaLevelPayload(level=brightness, transtime=0),
manufacturer=manufacturer,
expect_reply=expect_reply,
tsn=tsn
)
return super().command(command_id, *args, manufacturer, expect_reply, tsn) I will clean up the imports, format with black and whip up a PR. Also, do you have a bitcoin lightning address? I'd like to send you a tip! This was amazing help! |
This device uses a non-default set level command. Tested in local docker environment. Thanks to @javicalle this was possible. Fix zigpy#1415
I'm glad you got it working. Nice job! I have a few changes (and tests) if you like to play a little more. min-max level attributesZ2M indicates that there are a few more attributes for this device:
The To keep or not to keep manufacturer_values?The
|
A few comments about the new attributes.
|
@MattWestb a few more Tuya attributes and a new server command for the inventory. Tuya devices are plenty of 🎁 |
We is having one device that looks the same but is being one 10V dimer (its sending 0-10V to light and for the light level in PRO light systems) that is using the 0xfc00 attribute for min and max level and its verified working OK for the user but we have not getting one PR for it (I think hi cant doing so much coding and testing for the moment (UA) ;-/ #1149. The attribute The Is the command And last but most important great work done !!! |
Not for this device. According to Z2M (not tested yet here):
Has been verified to get 0-1000 values. This is the reason we put
Yes,
And you can guess where this values came from... |
deCONZ ??? I putting in the 0xF000 attribute and the 0x00F0 command and we can fixing the other then its being tested and perhaps its can having different functions (its still tuya devices). |
Do you knowing the unit (S / 1/4 S / 1/10 S ?) an the range for the |
No, I haven't found any clues about yhis attribute units. return await super().command(
TUYA_CUSTOM_LEVEL_COMMAND,
TuyaLevelPayload(level=brightness, transtime=0),
manufacturer=manufacturer,
expect_reply=expect_reply,
tsn=tsn,
) |
So I set the values from 0 to 100 and then also to 1000 and always restarted in between, but nothing changed. I was expecting for the dimmer to just "dim slower", but it was always the same. I also noticed two more things:
Here the logs:
I updated the PR, but feel free to change things around. |
The usual behavior of the devices is as follows:
What you are seeing are the traces of those 2 events:
I would not modify the calculation of the dim value. As I've said before IMHO it's something that should be approached in a generic way and not device by device.
@jonnylangefeld Can you check if the cluster attributes |
* Add device support for TS110E This device uses a non-default set level command. Tested in local docker environment. Thanks to @javicalle this was possible. Fix #1415 * Lint * Lint * Update ts110e.py * Update ts110e.py * Update ts110e.py * Update ts110e.py
This one worked for my one gang with neutral lonsonho smart dimmers as intended but I have dimmer function on my 2 gang no neutral ones, they are both TS110E devices, is it possible to modify the quirk to make it compatible with those too?, also the dimming function from HA on the ones that work is going from around 20% to 80% from totally off to totally on, there is no difference between 0-20 and 80 to 100... |
Thid is the device signature for the two gang with no neutral ones (QS-Zigbee-D02-TRIAC-2C-L) { |
Hi guys. I rushed out and bought one of these on ebay without checking first they were compatible. I'm having the same issues with not being able to dim them. I've tried using the code above and putting it into a quirk but I get errors. It says that some of the code has been deprecated. Is there another fix for this? |
Hello. I have https://www.zigbee2mqtt.io/devices/TS110E_2gang_2.html, |
Hi, I have the same exact model _TZ3210_ngqk6jia (TS110E) and tried to apply the quirk but its not working for me, its not working and Hass doestn even display the quirk. I have the quirk stored in config - custom_zha_quirks - ts110e.py Im sorry if im being stupid, Im a little noob ;) Here is the code I've inserted, I dont even know if I copied the right one, sorry!
|
I am not sure if this is a device request, or if the device itself is just not working. Maybe someone can halp?
I ordered two of these in-wall dimmers:
If successfully installed it and paired it with home assistant (I'm using zha) and was able to use the on-off switch right away, but the dimmer slider wouldn't do anything. So naturally I thought I'd need a quirk. However, I wasn't able to get the dimmer slider working.
I pasted the device signature below and you can see that the
in_clusters
already have"0x0006"
and"0x0008"
which isOnOff
andLevelControl
. A lot of the other tuya quirks for the dimmers didn't have those, so I understand that a quirk was necessary. In this case however I was surprised that it wasn't working right out of the box, because the blakadder.com entry confirmed it working with ZHA. However, the blakadder.com entry lists it asZigbee ID: "TS110F"; "_TYZB01_qezuin6k"
, while the one I actually got itZigbee ID: "TS110E"; "_TZ3210_ngqk6jia"
. So a small difference, even though the device itself looks exactly as on the pictures on blakadder.com and aliexpress.com.I came up with the following quirk that I stored in
tuya/ts110e.py
:The quirk is seen by home assistant (I see the
Quirk: zhaquirks.tuya.ts110e.DimmerSwitchWithNeutral1Gang
on the device in the home assistant UI). As you can see I experimented with all combinations of theOnOff
andLevelControl
alternatives. So far only the originalworks for at least the switch but not the dimmer.
Other combinations i tried:
that comes with error
Which makes sense. So I tried
Which didn't throw an error and allowed me to call the switch in the UI of home assistant, but it wouldn't turn on the light and the switch in the UI jumps back like 2 seconds later.
Does anyone have any other suggestions of what I could try?
Device signature:
Additional context
Add any other context or screenshots about the feature request here.
The text was updated successfully, but these errors were encountered: