-
Notifications
You must be signed in to change notification settings - Fork 809
[Device Support Request] Tuya Smart Air Detector 6 in 1 #1563
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
Comments
The device has been tunned in This could be a quirk for the device: ts0601_air_quality.py"""Tuya Air Quality sensor."""
from typing import Dict
from zigpy.profiles import zha
from zigpy.quirks import CustomDevice
from zigpy.zcl.clusters.general import Basic, GreenPowerProxy, Groups, Ota, Scenes, Time
from zigpy.zcl.clusters.measurement import PM25
from zhaquirks.const import (
DEVICE_TYPE,
ENDPOINTS,
INPUT_CLUSTERS,
MODELS_INFO,
OUTPUT_CLUSTERS,
PROFILE_ID,
)
from zhaquirks.tuya import DPToAttributeMapping, TuyaLocalCluster, TuyaNewManufCluster
from zhaquirks.tuya.air import (
TuyaAirQualityCO2,
TuyaAirQualityFormaldehyde,
TuyaAirQualityHumidity,
TuyaAirQualityTemperature,
TuyaAirQualityVOC,
TuyaCO2ManufCluster,
)
class TuyaCO2Sensor(CustomDevice):
"""Tuya Air quality device."""
signature = {
# NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress|RxOnWhenIdle|MainsPowered|FullFunctionDevice: 142>, manufacturer_code=4098, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=<DescriptorCapability.0: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)]
# device_version=1
# SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=81, device_version=1,
# input_clusters=[0, 4, 5, 61184],
# output_clusters=[25, 10])
MODELS_INFO: [
("_TZE200_8ygsuhe1", "TS0601"),
("_TZE200_yvx5lh6k", "TS0601"),
],
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaCO2ManufCluster.cluster_id,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
}
},
}
replacement = {
ENDPOINTS: {
1: {
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaCO2ManufCluster,
TuyaAirQualityCO2,
TuyaAirQualityFormaldehyde,
TuyaAirQualityHumidity,
TuyaAirQualityTemperature,
TuyaAirQualityVOC,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
}
}
}
class TuyaCO2SensorGPP(CustomDevice):
"""Tuya Air quality device with GPP."""
signature = {
# NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress|RxOnWhenIdle|MainsPowered|FullFunctionDevice: 142>, manufacturer_code=4098, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=<DescriptorCapability.0: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)]
# device_version=1
# SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=81, device_version=1,
# input_clusters=[0, 4, 5, 61184],
# output_clusters=[25, 10])
MODELS_INFO: [
("_TZE200_ryfmq5rl", "TS0601"),
("_TZE200_yvx5lh6k", "TS0601"),
("_TZE200_dwcarsat", "TS0601"),
],
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaCO2ManufCluster.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: {
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaCO2ManufCluster,
TuyaAirQualityCO2,
TuyaAirQualityFormaldehyde,
TuyaAirQualityHumidity,
TuyaAirQualityTemperature,
TuyaAirQualityVOC,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
242: {
PROFILE_ID: 41440,
DEVICE_TYPE: 97,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
}
}
class TuyaAirQualityPM25(PM25, TuyaLocalCluster):
"""Tuya PM25 concentration measurement."""
# ug/m^3 https://github.com/Koenkk/zigbee2mqtt/issues/11033#issuecomment-1124056947
class TuyaCO2ManufCluster_2(TuyaNewManufCluster):
"""Tuya with Air quality device v2 with data points."""
dp_to_attribute: Dict[int, DPToAttributeMapping] = {
2: DPToAttributeMapping(
TuyaAirQualityPM25.ep_attribute,
"measured_value",
lambda x: None if (value == 0xaaac or value == 0xaaab) else x,
),
18: DPToAttributeMapping(
TuyaAirQualityTemperature.ep_attribute, "measured_value", lambda x: x * 10
),
19: DPToAttributeMapping(
TuyaAirQualityHumidity.ep_attribute, "measured_value", lambda x: x * 10
),
20: DPToAttributeMapping(
TuyaAirQualityFormaldehyde.ep_attribute,
"measured_value",
lambda x: x * 1e-6,
),
21: DPToAttributeMapping(
TuyaAirQualityVOC.ep_attribute, "measured_value", lambda x: x * 1e-6
),
22: DPToAttributeMapping(
TuyaAirQualityCO2.ep_attribute,
"measured_value",
lambda x: x * 1e-6,
),
}
data_point_handlers = {
2: "_dp_2_attr_update",
18: "_dp_2_attr_update",
19: "_dp_2_attr_update",
20: "_dp_2_attr_update",
21: "_dp_2_attr_update",
22: "_dp_2_attr_update",
}
class TuyaCO2SensorGPP_2(CustomDevice):
"""Tuya Air quality device v2 with GPP."""
signature = {
# NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress|RxOnWhenIdle|MainsPowered|FullFunctionDevice: 142>, manufacturer_code=4098, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=<DescriptorCapability.0: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)]
# device_version=1
# SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=81, device_version=1,
# input_clusters=[0, 4, 5, 61184],
# output_clusters=[25, 10])
MODELS_INFO: [
("_TZE200_dwcarsat", "TS0601"),
],
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaCO2ManufCluster.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: {
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaCO2ManufCluster_2,
TuyaAirQualityPM25,
TuyaAirQualityCO2,
TuyaAirQualityFormaldehyde,
TuyaAirQualityHumidity,
TuyaAirQualityTemperature,
TuyaAirQualityVOC,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
242: {
PROFILE_ID: 41440,
DEVICE_TYPE: 97,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
}
} Conversion factors can be wrong. lambda x: None if (value === 0xaaac || value === 0xaaab) else x, |
Sorry looks like the PM2.5 sensor code is not right.
|
Can you try replacing this expression?: lambda x: None if (value == 0xaaac or value == 0xaaab) else x, |
Thanks but new issue
|
Ok so I tried replacing || with or and that seems to have gotten it out of the errors. But for some reason the device isn't using the custom quirk.
|
I have made a mess trying to put everything in a single file. Delete any |
Cool thanks looks like it loaded this time as denoted by Quirk: ts0601_air_quality.TuyaCO2SensorGPP_2. |
With the new quirk formaldehyde dropped from 360ppm to 4ppm, crazy co2 spikes may have been eliminated which is good. Just not sure if the formaldehyde reading is right |
You can try to change in your quirk this part: 20: DPToAttributeMapping(
TuyaAirQualityFormaldehyde.ep_attribute,
"measured_value",
lambda x: x * 1e-3,
), There's any way to validate wich values are the correct ones? The conversion factors are probably need to be revised. Tell me if there is any other value that seems strange to you. I think that I saw that PM2.5 does not generate an entity in HA, but you should be able to query it as attributes of the
Well, actually these spikes seems that aren't CO2 values but PM2.5 values (and had been filtered). The modifications would be:
In Z2M there are a table with units and range values for this device: |
Hey guys, I bought this device too, but it even does not pair ! Have you got some issue about that by your side ?
|
I'm using ZHA and paired ok for me? Did you try moving it closer to your coordinator? |
Apart from the temperature and humidity, the rest of the values I have no way of validating them. It seems that the units for VOC would not be correct (the device measures in ppm and HA shows ug/m3). Maybe needs to be adjusted here: The rest of the measures also seem to need to be adjusted. values for Formaldehyde seems to be too high, and also with the diferent units. There is no alternative sensor in HA, so maybe a units conversion can be needed: |
I own the same device with the same issues (which almost feels reassuring). Sad. Hopefully we can fine a fix and get it to the ZHA component in HA. |
Ummm, it seems that CO2 and VOC values are fine (VOC: 15µg/m3 ~ 0,012mg/m3) The measuring range of the device seems to be 0-10µg/m3 (possibly without decimals) Here I don't know what should be the correct solution. Any suggestion is welcome. |
I'd say that given these two sensors both have different units it's probably best to suggest a change in HA for the units? |
We had the same issue with VOC in HA. we can create a ppm formaldehyde entity similar to how we did for VOC |
I believe it's the same devices and issues |
#1707 is also related. |
Not sure when this happened but pm2.5 is now showing for me. Has spikes to over 40000 but generally working |
Today I have implemented the quirk for this sensor, and it shows everything apparently correct except PM2.5. In the HomeAssistant logs I get this error.
Any clue to get the PM2.5 values? I have observed that in Z2M it is possible, and there is a thread about it. |
Replace this: lambda x: None if (value == 0xaaac or value == 0xaaab) else x With: lambda x: None if (x == 0xaaac or x == 0xaaab) else x |
You've got it. Now the value appears, perfect! I think it should be divided by 10, or if the value is true (from 65 to 75 ug/m3), I have a short time to live. |
Then you can try with; lambda x: None if (x == 0xaaac or x == 0xaaab) else x/10 |
@vikitor87 Can you share the quirk file you've implemented ? |
Of course! @ylemoigne . It is the same quirk file published at the beginning but modifying code line 158 ts0601_air_quality.py
· Entities |
Excluding |
@vikitor87 thanks, it works (well at least it looks better now, i don't know the accuracy of the device) |
So after much head scratching and googling, I was able to get my 6 sensors to show up using ts0601_air_quality.py from above. However now I am fairly certain Formaldehyde, PM2.5, and VOC are all incorrect and will require some other scaling factor. From my brief research my values are out of the normal for indoor conditions. I have also noticed the Unit of Measure is incorrect for VOC and Formaldehyde, but this can be fixed with Customize. Has anyone been able to get sane readings from Tuya and compared them to the values reported by Home Assistant? |
From the various reports that I have found of this type of sensor, I think that there are at least 2 different types of sensors with mixed sensors/DPs. |
Not a lot of action here but I have the TS0601 _TZE200_dwcarsat |
RSDynamics i have same issues, humidity allways higher 100%. |
No, did not had the time yet. |
I added this entry to my configuration.yaml: (with HA core) I stored the ts0601_air_quality.py in this directory. The formaldehyde values are better now, but with 40ppm outside on the balcony still to high. I think it should not be more than 0.1ppm. Maybe the unit is µg/m³ ? 1 ppm =1240 µg/m³. Also I think that device has the VOC level in ppm, whereas HA display it in µg. Does it need conversion? |
|
By comparing the values with the tuya app, I have now found the following:
The formaldehyde unit must be changed from ppm to ppb (customize: section). |
VOC is displayed in the tuya app with the unit mg/m³, in the HA tuya integration it shows up as ppm. The numbers seem to be the same. If zhaquirks sends a value of 10, the tuya app shows it as 0,010 mg/m³ (would be 10 µg/m³) and the tuya HA integration shows it as 0,010 ppm (would be 25 µg/m³). |
There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates. Please make sure to update to the latest version and check if that solves the issue. Let us know if that works for you by adding a comment 👍 This issue has now been marked as stale and will be closed if no further activity occurs. Thank you for your contributions. |
/unstale |
The combined work of folks in this thread already results in a much better quirk than is currently available from zha-device-handlers. Would any of the contributors mind submitting a pull request so less tech-savvy people can use it as well and are not getting garbage? |
Hi, I'm trying to get this device to work and it turns out I don't have the skills yet to get this sensor to work in HA. Can somebody who figured this one out post a config / quirk here? First time working with quirks so I might be making obvious mistakes. |
Just pair it in ZHA and it will work. You don't need any skills. |
Hi Martin, How do I get this to work for ZHA? Kind regards |
This was added in #3651. |
Every few minutes, the pm2.5 sensor sends the value 0xAAAC (43692) |
Is your feature request related to a problem? Please describe.
Current device support for the Tuya Air Detector 6 in 1 is limited to only temperature and VOC sensors. Other sensors such as PM2.5 and CO2 are missing.
This is the device
https://zigbee.blakadder.com/Tuya_DCR-KQG.html
Supposedly working on Z2M
Describe the solution you'd like
Would be great if other sensor entities could be added especially the PM2.5 sensor
Device signature - this can be acquired by clicking on the "Zigbee Device Signature" button in the device settings
Diagnostic information - this can be acquired by clicking on the "Download Diagnostics" button in the device settings
Additional logs
Additional context
Add any other context or screenshots about the feature request here.
The text was updated successfully, but these errors were encountered: