zigpy / zha-device-handlers

ZHA device handlers bridge the functionality gap created when manufacturers deviate from the ZCL specification, handling deviations and exceptions by parsing custom messages to and from Zigbee devices.
Apache License 2.0
683 stars 634 forks source link

[BUG] Issue with Develco Air Quality Sensor AQSZB-110 #1273

Closed Tappser closed 1 year ago

Tappser commented 2 years ago

Hello,

i got me a Develco Air Quality Sensor AQSZB-110. My Neighbor has one, too and it works perfect with HA. Mine wont :(

The Signature seems to be the same. Whats different is: The Firmware of his is 0x00030604 On mine its: 0x00040001

{ "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.NONE: 0>, manufacturer_code=4117, maximum_buffer_size=80, maximum_incoming_transfer_size=80, server_mask=10752, maximum_outgoing_transfer_size=80, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=False, *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": 49353, "device_type": "0x0001", "in_clusters": [ "0x0003", "0x0005", "0x0006" ], "out_clusters": [] }, "38": { "profile_id": 260, "device_type": "0x0302", "in_clusters": [ "0x0000", "0x0001", "0x0003", "0x0020", "0x0402", "0x0405", "0x042e", "0xfc03" ], "out_clusters": [ "0x0003", "0x000a", "0x0019" ] } }, "manufacturer": "frient A/S", "model": "AQSZB-110", "class": "zigpy.device.Device" }

Wolverine80 commented 2 years ago

Neighbor here. Mine has firmware 0x00030604 Signature:

{
  "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.NONE: 0>, manufacturer_code=4117, maximum_buffer_size=80, maximum_incoming_transfer_size=80, server_mask=0, maximum_outgoing_transfer_size=80, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=False, *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": 49353,
      "device_type": "0x0001",
      "in_clusters": [
        "0x0003",
        "0x0005",
        "0x0006"
      ],
      "out_clusters": []
    },
    "38": {
      "profile_id": 260,
      "device_type": "0x0302",
      "in_clusters": [
        "0x0000",
        "0x0001",
        "0x0003",
        "0x0020",
        "0x0402",
        "0x0405",
        "0x042e",
        "0xfc03"
      ],
      "out_clusters": [
        "0x0003",
        "0x000a",
        "0x0019"
      ]
    }
  },
  "manufacturer": "frient A/S",
  "model": "AQSZB-110",
  "class": "zhaquirks.develco.air_quality.AQSZB110"
}

I have unusual long times when humidity gets updated after I reset the device. At the moment it updated 24 hours ago the last time. Even after plugging the battery.

Tappser commented 2 years ago

grafik Reconfigure crashes, showing only "on_off" as fail.

criscaru commented 2 years ago

Same issue here. Firmware: 0x00040001

0x042e should be air quality (and air quality ppm) but shows as unknown.

Both temp and hum work fine, battery is not reported.

{ "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.NONE: 0>, manufacturer_code=4117, maximum_buffer_size=80, maximum_incoming_transfer_size=80, server_mask=10752, maximum_outgoing_transfer_size=80, descriptor_capability_field=<DescriptorCapability.NONE: 0>, allocate_address=False, 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": 49353, "device_type": "0x0001", "in_clusters": [ "0x0003", "0x0005", "0x0006" ], "out_clusters": [] }, "38": { "profile_id": 260, "device_type": "0x0302", "in_clusters": [ "0x0000", "0x0001", "0x0003", "0x0020", "0x0402", "0x0405", "0x042e", "0xfc03" ], "out_clusters": [ "0x0003", "0x000a", "0x0019" ] } }, "manufacturer": "frient A/S", "model": "AQSZB-110", "class": "zigpy.device.Device" }

criscaru commented 2 years ago

Seems that the problem is related to class "class": "zigpy.device.Device" instead of "class": "zhaquirks.develco.air_quality.AQSZB110"

Is there a way to fix this?

MattWestb commented 2 years ago

class "class": "zigpy.device.Device" = ZHA have not found one matching quirk (look in the log file). Very likely the device have other cluster setting on the endpoints or name and need one new device class in the quirk.

criscaru commented 2 years ago

I agree but I'm unable to do so... The difference I can see in the signature seems to be server_mask

The one working has server_mask=0 the other server_mask=10752

criscaru commented 2 years ago

2022-02-16 12:21:04 DEBUG (MainThread) [zigpy.quirks.registry] Checking quirks for frient A/S AQSZB-110 (00:15:bc:00:36:00:10:95) 2022-02-16 12:21:04 DEBUG (MainThread) [zigpy.quirks.registry] Considering <class 'zhaquirks.develco.air_quality.AQSZB110'> 2022-02-16 12:21:04 DEBUG (MainThread) [zigpy.quirks.registry] Fail because input cluster mismatch on at least one endpoint

MattWestb commented 2 years ago

server_mask is not checked then its not putting in the signature (only as one info for later use). I have looking on every cluster on the end points and i cant see any wrong (with glasses but it no 110% grantee).

If looking on the heat_alarm.py: https://github.com/zigpy/zha-device-handlers/blob/6a4788476cc1cba6f8f4671e03ef0b9780196ee0/zhaquirks/develco/heat_alarm.py#L43 is the manufacture defined in the INIT and is imported and i think it the right way but i dont knowing if the other way is braking the linking.

You can trying making the same with the air quirk and see is its working. The import is made in: https://github.com/zigpy/zha-device-handlers/blob/6a4788476cc1cba6f8f4671e03ef0b9780196ee0/zhaquirks/develco/heat_alarm.py#L26 and shall being added in: https://github.com/zigpy/zha-device-handlers/blob/6a4788476cc1cba6f8f4671e03ef0b9780196ee0/zhaquirks/develco/air_quality.py#L28

MattWestb commented 2 years ago

Also ZHA is some time not loading the quirk OK after adding new devices or playing around and rejoining / resting device so need one restart of HA for the quirk being OK loaded but i think you have doing that many times and its not loading.

MattWestb commented 2 years ago

Sorry i have cleaning my glasses and the updated firmware is having one unknown cluster 0x042e on endpoint 38.

So need adding it in the signature in one new device class and it shall working.

If you like configuring local quirk and adding this in the end of the normal quirk for the device with 2 empty line between the classes:

class AQSZB110A(CustomDevice):
    """Custom device Develco air quality sensor New FW."""

    manufacturer_id_override = MANUFACTURER

    def __init__(self, *args, **kwargs):
        """Init."""
        self.voc_bus = Bus()
        super().__init__(*args, **kwargs)

    signature = {
        # <SimpleDescriptor endpoint=1 profile=49353 device_type=1 device_version=1
        # input_clusters=[3, 5, 6] output_clusters=[]>
        # <SimpleDescriptor endpoint=38 profile=260 device_type=770 device_version=0
        # input_clusters=[0, 1, 3, 32, 1026, 1029, 64515] output_clusters=[3, 10, 25]>
        MODELS_INFO: [
            (DEVELCO, "AQSZB-110"),
            ("frient A/S", "AQSZB-110"),
        ],
        ENDPOINTS: {
            1: {
                PROFILE_ID: 0xC0C9,
                DEVICE_TYPE: 1,
                INPUT_CLUSTERS: [
                    Identify.cluster_id,
                    Scenes.cluster_id,
                    OnOff.cluster_id,
                ],
                OUTPUT_CLUSTERS: [],
            },
            38: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    PowerConfiguration.cluster_id,
                    Identify.cluster_id,
                    PollControl.cluster_id,
                    TemperatureMeasurement.cluster_id,
                    RelativeHumidity.cluster_id,
                    0x042e,
                    0xFC03,
                ],
                OUTPUT_CLUSTERS: [Identify.cluster_id, Time.cluster_id, Ota.cluster_id],
            },
        },
    }

    replacement = {
        ENDPOINTS: {
            1: {
                PROFILE_ID: 0xC0C9,
                DEVICE_TYPE: 1,
                INPUT_CLUSTERS: [
                    Identify.cluster_id,
                    Scenes.cluster_id,
                    OnOff.cluster_id,
                ],
                OUTPUT_CLUSTERS: [],
            },
            38: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    DevelcoPowerConfiguration,
                    Identify.cluster_id,
                    PollControl.cluster_id,
                    DevelcoTemperatureMeasurement,
                    DevelcoRelativeHumidity,
                    DevelcoVOCMeasurement,
                    EmulatedVOCMeasurement,
                ],
                OUTPUT_CLUSTERS: [Identify.cluster_id, Time.cluster_id, Ota.cluster_id],
            },
        },
    }
X52p commented 2 years ago

If you like configuring local quirk and adding this in the end of the normal quirk for the device with 2 empty line between the classes:

Hi, this worked for me! Would be nice if it was added to the quirk by default.

The device also should give an Enum on how good the air quality is (like bad, moderate, good, etc.) (at least in zigbee2Mqtt it does that) How would I add this? If you can point me at some documentation on how I can find out what data is sent from the device, then I also could have a look into this.

MattWestb commented 2 years ago

The best is if you can doing on PR for adding it in the dev branch then you caan testing that the code is working OK. If you cant doing it i can helping but i need help for testing that the final version is working in real or its cant being merged.

I was looking on the Z2M code and its being made here: https://github.com/Koenkk/zigbee-herdsman-converters/blob/dc19775944d7d5e8050f492aa599d920e50e99df/converters/fromZigbee.js#L1774-L1801

Its possible making the same with ZHA quirks and also in HA but i think the maintainers dont like have it in the quirks then its not one Zigbee standard function. You can making the same in HA with automatons / trample sensors and getting the written quality your sensor is reporting to the system.

IKEA Starkvind is "needing" the same but its not being added in ZHA more then the standard Zigbee functions then not user or devs with enough knowledge have getting there hands one for testing.

github-actions[bot] commented 1 year ago

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.

cvicari commented 1 year ago

Writing here just because I have the same problem, and that would be nice to have a solution for everyone to have this working with ZHA just out of the box

Tappser commented 1 year ago

Writing here just because I have the same problem, and that would be nice to have a solution for everyone to have this working with ZHA just out of the box

I've already given it up. Even with the file posted here i didnt get igt up and running -.-

ruN86 commented 3 months ago

If you like configuring local quirk and adding this in the end of the normal quirk for the device with 2 empty line between the classes:

Hi, this worked for me! Would be nice if it was added to the quirk by default.

The device also should give an Enum on how good the air quality is (like bad, moderate, good, etc.) (at least in zigbee2Mqtt it does that) How would I add this? If you can point me at some documentation on how I can find out what data is sent from the device, then I also could have a look into this.

can you post your complete quirk file pls?

ViperRNMC commented 1 month ago

Hi all, same problem here, see no VOC with firmware 0x00040001. Anyone solved this? Try to add the extra class from @MattWestb, but no success.

Sorry i have cleaning my glasses and the updated firmware is having one unknown cluster 0x042e on endpoint 38.

So need adding it in the signature in one new device class and it shall working.

If you like configuring local quirk and adding this in the end of the normal quirk for the device with 2 empty line between the classes:

class AQSZB110A(CustomDevice):
    """Custom device Develco air quality sensor New FW."""

    manufacturer_id_override = MANUFACTURER

    def __init__(self, *args, **kwargs):
        """Init."""
        self.voc_bus = Bus()
        super().__init__(*args, **kwargs)

    signature = {
        # <SimpleDescriptor endpoint=1 profile=49353 device_type=1 device_version=1
        # input_clusters=[3, 5, 6] output_clusters=[]>
        # <SimpleDescriptor endpoint=38 profile=260 device_type=770 device_version=0
        # input_clusters=[0, 1, 3, 32, 1026, 1029, 64515] output_clusters=[3, 10, 25]>
        MODELS_INFO: [
            (DEVELCO, "AQSZB-110"),
            ("frient A/S", "AQSZB-110"),
        ],
        ENDPOINTS: {
            1: {
                PROFILE_ID: 0xC0C9,
                DEVICE_TYPE: 1,
                INPUT_CLUSTERS: [
                    Identify.cluster_id,
                    Scenes.cluster_id,
                    OnOff.cluster_id,
                ],
                OUTPUT_CLUSTERS: [],
            },
            38: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    PowerConfiguration.cluster_id,
                    Identify.cluster_id,
                    PollControl.cluster_id,
                    TemperatureMeasurement.cluster_id,
                    RelativeHumidity.cluster_id,
                    0x042e,
                    0xFC03,
                ],
                OUTPUT_CLUSTERS: [Identify.cluster_id, Time.cluster_id, Ota.cluster_id],
            },
        },
    }

    replacement = {
        ENDPOINTS: {
            1: {
                PROFILE_ID: 0xC0C9,
                DEVICE_TYPE: 1,
                INPUT_CLUSTERS: [
                    Identify.cluster_id,
                    Scenes.cluster_id,
                    OnOff.cluster_id,
                ],
                OUTPUT_CLUSTERS: [],
            },
            38: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    DevelcoPowerConfiguration,
                    Identify.cluster_id,
                    PollControl.cluster_id,
                    DevelcoTemperatureMeasurement,
                    DevelcoRelativeHumidity,
                    DevelcoVOCMeasurement,
                    EmulatedVOCMeasurement,
                ],
                OUTPUT_CLUSTERS: [Identify.cluster_id, Time.cluster_id, Ota.cluster_id],
            },
        },
    }