Closed kryanth closed 2 years ago
Actually, it looks different to that as well, might just be some TS0012 devices shipping with "enchanted device".
This is yet another enchanted device. These were newer TS0012 _TZ3000_18ejxno0 - I had to add a new device signature specifically for these, and extend the EnchantedDevice class, then remove and re-add, they are working as expected now.
Do I need to keep that signature and class, or is the enchanted device a once-off call?
Hello,
I too am having this problem with the '_TZ3000_18ejxno0' device. HASS turns on both parts when any of the software button is pressed. I have the most recent version of HA (and thus zigpy, I guess)
I'd like to know if there is something I can do on my server to make the switches work separately or if it is something I just have to wait for - zigpy update?
Thank you all for an answer
EDIT: can anyone tell me what an 'enchanted' device means?
I believe its just a wierd firmware quirk, and the enchanted class (found in that same zhaquirk library) is just a super class that initialises the device with some commands on HA startup. It does have a different signature to my other devices.
in your HA directory, find the python library for zhaquirks
I just added the following snippet to the ts001x.py, you can also just add whatever. You may need to verify the device signature, but this just worked for the couple of these "_TZ3000_18ejxno0" devices. (edited here because the formatting is whack)
class TuyaDoubleEnchantedSwitch(EnchantedDevice, TuyaSwitch):
signature = {
MODEL: "TS0012",
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Basic.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
],
OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id],
},
2: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
],
OUTPUT_CLUSTERS: [],
},
},
}
replacement = {
SKIP_CONFIGURATION: True,
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Basic.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaZBOnOffAttributeCluster,
],
OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id],
},
2: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Groups.cluster_id,
Scenes.cluster_id,
TuyaZBOnOffAttributeCluster,
],
OUTPUT_CLUSTERS: [],
},
},
}
Hello and thank you for explaining. I am running HA in a docker image and will try something tomorrow. Thank you again and have a nice day!
Hello again, I'd like to ask for a help.
I downloaded the quirk ts001x.py file for the '_TZ3000_18ejxno0' double switch, enabled ZHA quirks in HA config and restarted Home Assistant. I guess I am supposed to see something like 'Quirk: TS0012' in the 'Device info' in ZHA pane. But there is no quirk info on that device and the switch still turns on/off both parts when switched in Home Assisstant. Is there anythin else I have to do?
I guess the .py file is loaded, because the __pycache__
folder was created beside the .py file.
Thank you very much
Compare the signature for your device , and make sure it matches the signature in that snippet.
If the ts001x.pyc file in the python .cache directory exists, it will need to be removed on every restart of HA, so it rebuilds the cache file. Odds are good if you launched the docker image, it built the python cache then so updating the content has no effect until after the cache file is created.
I should be less lazy and throw a branch in to make it easier, which if it works as is for you might encourage me to do that. Not sure how many of these are accepted.
Yes, I use docker image for HA.
The signature shows:
{
"node_descriptor": "NodeDescriptor(logical_type=<LogicalType.EndDevice: 2>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress: 128>, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)",
"endpoints": {
"1": {
"profile_id": 260,
"device_type": "0x0100",
"in_clusters": [
"0x0000",
"0x0003",
"0x0004",
"0x0005",
"0x0006"
],
"out_clusters": [
"0x000a",
"0x0019"
]
},
"2": {
"profile_id": 260,
"device_type": "0x0100",
"in_clusters": [
"0x0004",
"0x0005",
"0x0006"
],
"out_clusters": []
}
},
"manufacturer": "_TZ3000_18ejxno0",
"model": "TS0012",
"class": "zigpy.device.Device"
}
Pretty sure that should match the signature from my sample, so it's not using that instance of ts001x.py , or the cache isn't being swept (possibly not even that instance of zhaquirks) so you may need to play with that.
Thank you. I'll try something (clearing cache, repairing - I guess this is not needed?)
Anyways thank you for your time! I'll get back soon.
I don't think repairing will do much in this context. You may need to look at the constant definitions for cluster_id (in zhaquirks) to check if the signature matches, it's possible they have several slightly similiar firmwares with slightly different signatures that all require the "enchanted class" to unlock.
I have just one last question - is the ts001x.py enough to copy to the HA quirks folder or do I have to put the whole tuya folder (or full zha-device-handlers folder) there (this fails on zigbee initialization - there is some python import error) When I use the ts001x.py file alone, no errors are produced.
I am so sorry, I have never used these quirks and I am pretty new to ZigBee. So I hope I do the things the right way in the first place.
Thank you :X
@eugeene Your device is 95% identical with the current "normal" TS0012 only one cluster is being added and need being added in the quirk.
Editing this device class:
https://github.com/zigpy/zha-device-handlers/blob/b8d8480c72c871e2408637231ac1a2a485e33b03/zhaquirks/tuya/ts001x.py#L68
and adding Identify.cluster_id,
on one new line in the signature and replacement (with the same indent as the other like and no extra spaces) best after the Basic.cluster_id,
so its looks nice and saving it and restarting HA and look if the system is loading the updated quirk for your device.
Yes, that worked! Now it says:
Quirk: ts001x.TuyaDoubleNoNeutralSwitch
But unfortunately, both parts are still being switched on/off :(
Great then the quirk is being loaded OK.
And the device is needing some "tuya magic spell" being casted for getting the both endpoints working OK (some other device is doing the same like LIDL power strip with new firmware).
I calling for more help !!!
Hola @javicalle can you taking one look if its one easy way getting the tuya magic being implanted on this new device ??
I dont knowing if its enough casting it then its already being pared or must being done then its paring in the init stage.
Thanks in advance !!
Thank you for your time and patience, guys. If you need any data from my device, I am ready to help. ;)
My comment has the full code snippet required to "fix" the device worked for me and I just added it to the ts001x.py file.
Need more testing then have implanting the "tuya magic" but im no code worrier so i cant doing the coding and need help from our devs for implanting the function in the quirk.
If you is changing the state of the device on the device is it reporting it OK in ZHA (manual on and off on the device) ?
@kryanth Your device have the same ID _TZ3000_18ejxno0
but is having the same firmware version (reading the sw_build_id (id: 0x4000)
on the basic cluster and you is getting it) or have your device being coonnected to one tuya ZBGW ?
My comment has the full code snippet required to "fix" the device worked for me and I just added it to the ts001x.py file.
The code from your comment extends from EnchantedDevice as well. I am missing that class in my installation. Can you tell me where do I get the class definition and where to put it? (beside the ts001x.py?)
edit: I just found the import statement for that, but it stil won't work (both sides being switched at the same time) it now shows: Quirk: ts001x.TuyaDoubleEnchantedSwitch, so that's correct. But no worky :(
If you is changing the state of the device on the device is it reporting it OK in ZHA (manual on and off on the device) ?
when I switch any part of the switch manually, HA reports correct state for both parts. Jus the 'software' swiching is wrong (always both parts)
I think the way @kryanth have doing (using the EnchantedDevice class
) shall working but its need deleting the device and resetting it and waiting one minute and then paring it agen so the "magic" is being sent to the device then its bring paired.
Try doing that @eugeene and is its not working the first time deleting the device in ZHA and resetting it and then restarting HA and try paring it then ZHA is stable after the restart.
@MattWestb I'll try that when I get home. But thank you for your patience and kindness. I'll get back to you.
Hello. Indeed, the re-pairing was needed. I removed the switches, paired again and... It seems to work! Thank you very much again for your time!
Then its verified working well :-))
Is some interesting making one PR for adding one new device lass like @kryanth was doing so its working without local quirk for all user in the future ?
Ill try that again from scratch. Currently, I added the code from the comment above (the code that inherits from EnchantedDevice, the file in this repo does not, it inherits from TuyaSwitch only) Ill try the file from this repo again tomorrow, because I am currently not at home again.
Ok, so i removed the old file, removed the pycache, installed the file from this repo, restarted HA and it seems to be working. But the file is not 'loaded' in 'quirk' part of the device info. So the switches are probably set correctly from somethig from the code above from earlier. The question is - will it work after another re-pair? Should i try that?
If the system is not loading the quirk its some problem with the signature for your device (very likely missing the cluster 0x0003).
The "tuya magic" is saved in the device so if it being casted on the device its keeping it until the device is being retested and re-powered.
Pleas making one test by deleting the device in ZHA and then resetting it on the device (pressing the reset switch or other way by the device manual) and in the end taking the power away for one minute and then trying paring it with ZHA.
If all is going as expected your device is being as it was from beginning (both switches is switching from ZHA as one).
I have only experience from the problematic TS004F that is doing very mush strange things but we have getting it working OK now.
Hello, sorry I was gone - I was Ill
So I had to edit the ts001x.py from this repo - replaced the enchanted code from above, and added these lines to the top of the file to properly make it working:
from zigpy.quirks import CustomDevice
import asyncio
class EnchantedDevice(CustomDevice):
"""Class for enchanted Tuya devices which needs to be unlocked by casting a 'spell'."""
def __init__(self, *args, **kwargs):
"""Initialize with task."""
super().__init__(*args, **kwargs)
self._init_device_task = asyncio.create_task(self.spell())
async def spell(self) -> None:
"""Initialize device so that all endpoints become available."""
attr_to_read = [4, 0, 1, 5, 7, 0xFFFE]
basic_cluster = self.endpoints[1].in_clusters[0]
await basic_cluster.read_attributes(attr_to_read)
Now everything seems to be working.
Not sure what is working and not but a few comments from my side.
The signature in the first post has diferent OUTPUT_CLUSTERS
that the quirk from https://github.com/zigpy/zha-device-handlers/issues/1744#issuecomment-1259551095. Not sure which one is the good one.
@eugeene you would not need to define the EnchantedDevice
class in the file. Just adding the import must work:
from zhaquirks.tuya.mcu import EnchantedDevice
If I have read all correctly, this quirk must work for you (or both if the signature is the same):
class TuyaDoubleNoNeutralSwitch_2(EnchantedDevice, TuyaSwitch):
"""Tuya 2 gang no neutral light switch (v2)."""
signature = {
# "node_descriptor": "NodeDescriptor(byte1=2, byte2=64, mac_capability_flags=128, manufacturer_code=4098,
# maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264,
# maximum_outgoing_transfer_size=82, descriptor_capability_field=0)
# "node_descriptor": "NodeDescriptor(byte1=2, byte2=64, mac_capability_flags=128, manufacturer_code=4098,
# maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264,
# maximum_outgoing_transfer_size=82, descriptor_capability_field=0)"
MODEL: "TS0012",
ENDPOINTS: {
# <SimpleDescriptor endpoint=1 profile=260 device_type=100
# device_version=1
# input_clusters=["0x0000", "0x0003", "0x0004", "0x0005", "0x0006"]
# output_clusters=["0x000a", "0x0019"]>
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Basic.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
],
OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id],
},
# <SimpleDescriptor endpoint=2 profile=260 device_type=100
# device_version=1
# input_clusters=[4, 5, 6]
# output_clusters=[]>
2: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
],
OUTPUT_CLUSTERS: [],
},
},
}
replacement = {
SKIP_CONFIGURATION: True,
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Basic.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaZBOnOffAttributeCluster,
],
OUTPUT_CLUSTERS: [Ota.cluster_id],
},
2: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Groups.cluster_id,
Scenes.cluster_id,
TuyaZBOnOffAttributeCluster,
],
OUTPUT_CLUSTERS: [],
},
},
}
The full file would be (not checked, not tested):
Regards.
edit: update code
Hi, @javicalle 's ts001x.py fixed the problem for me. I had to unpair / pair my switches.
Hi,
I'm on HA 2023.3 and still getting this behavior. Anything sent from HA causes both switches to be toggled.
What do I do?
@JIBYC Create a new issue on this repo (and make sure to fill out the issue template).
I have a couple of newer ts0012 "moes" switches which appear to have a newer firmware, which is fixed in koenkk's z2m
https://pullanswer.com/questions/tuya-ts0012-turns-on-both-loads-when-only-one-switch-is-pressed
The model signature is a bit different. I have some older TS0012 / _TZ3000_18ejxno0 that work without quirks, but this one appears to need some assistance as per the above URL.
{ "node_descriptor": "NodeDescriptor(logical_type=<LogicalType.EndDevice: 2>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress: 128>, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=<DescriptorCapability.NONE: 0>, allocate_address=True, is_alternate_pan_coordinator=False, is_coordinator=False, is_end_device=True, is_full_function_device=False, is_mains_powered=False, is_receiver_on_when_idle=False, is_router=False, *is_security_capable=False)", "endpoints": { "1": { "profile_id": 260, "device_type": "0x0100", "in_clusters": [ "0x0000", "0x0003", "0x0004", "0x0005", "0x0006" ], "out_clusters": [ "0x0019" ] }, "2": { "profile_id": 260, "device_type": "0x0100", "in_clusters": [ "0x0004", "0x0005", "0x0006" ], "out_clusters": [] } }, "manufacturer": "_TZ3000_18ejxno0", "model": "TS0012", }