Repository: zigpy/zha-device-handlers

Issue:
Visonic MCT-340 SMA battery unknown
### Problem description

The MCT-340 E model is already in, but for the SMA the battery status is unknown. 

The open/close and temperature reports fine and instantly but battery is always “Unknown”

In HA logs:
```
[homeassistant.components.zha.core.cluster_handlers] [0xCC25:1:0x0001]: Failed to configure reporting for '['battery_percentage_remaining']' on 'power' cluster: [ConfigureReportingResponseRecord(status=<Status.UNSUPPORTED_ATTRIBUTE: 134>, direction=<ReportingDirection.SendReports: 0>, attrid=33)]
```

### Solution description

A custom tweak for SMA is probably needed, something must differ in the command IDs. I know these can report battery because on HA forms someone had the exact issue but fixed it (Didn't list their fix though)

https://community.home-assistant.io/t/mct-340-sma-battery-shows-unknown/431726

### Screenshots/Video

_No response_

### Device signature

<details><summary>Device signature</summary>

```json
{
  "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=4113, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=0, maximum_outgoing_transfer_size=82, 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": "0x0104",
      "device_type": "0x0402",
      "input_clusters": [
        "0x0000",
        "0x0001",
        "0x0003",
        "0x0020",
        "0x0402",
        "0x0500",
        "0x0b05"
      ],
      "output_clusters": [
        "0x0019"
      ]
    }
  },
  "manufacturer": "Visonic",
  "model": "MCT-340 SMA",
  "class": "zigpy.device.Device"
}
```

</details>


### Diagnostic information

<details><summary>Diagnostic information</summary>

```json
{
  "home_assistant": {
    "installation_type": "Home Assistant Supervised",
    "version": "2023.12.3",
    "dev": false,
    "hassio": true,
    "virtualenv": false,
    "python_version": "3.11.6",
    "docker": true,
    "arch": "aarch64",
    "timezone": "America/Chicago",
    "os_name": "Linux",
    "os_version": "6.1.0-16-arm64",
    "supervisor": "2023.12.0",
    "host_os": "Debian GNU/Linux 12 (bookworm)",
    "docker_version": "24.0.7",
    "chassis": "",
    "run_as_root": true
  },
  "custom_components": {},
  "integration_manifest": {
    "domain": "zha",
    "name": "Zigbee Home Automation",
    "after_dependencies": [
      "onboarding",
      "usb"
    ],
    "codeowners": [
      "@dmulcahey",
      "@adminiuga",
      "@puddly",
      "@TheJulianJES"
    ],
    "config_flow": true,
    "dependencies": [
      "file_upload"
    ],
    "documentation": "https://www.home-assistant.io/integrations/zha",
    "iot_class": "local_polling",
    "loggers": [
      "aiosqlite",
      "bellows",
      "crccheck",
      "pure_pcapy3",
      "zhaquirks",
      "zigpy",
      "zigpy_deconz",
      "zigpy_xbee",
      "zigpy_zigate",
      "zigpy_znp",
      "universal_silabs_flasher"
    ],
    "requirements": [
      "bellows==0.37.3",
      "pyserial==3.5",
      "pyserial-asyncio==0.6",
      "zha-quirks==0.0.107",
      "zigpy-deconz==0.22.2",
      "zigpy==0.60.1",
      "zigpy-xbee==0.20.1",
      "zigpy-zigate==0.12.0",
      "zigpy-znp==0.12.0",
      "universal-silabs-flasher==0.0.15",
      "pyserial-asyncio-fast==0.11"
    ],
    "usb": [
      {
        "vid": "10C4",
        "pid": "EA60",
        "description": "*2652*",
        "known_devices": [
          "slae.sh cc2652rb stick"
        ]
      },
      {
        "vid": "1A86",
        "pid": "55D4",
        "description": "*sonoff*plus*",
        "known_devices": [
          "sonoff zigbee dongle plus v2"
        ]
      },
      {
        "vid": "10C4",
        "pid": "EA60",
        "description": "*sonoff*plus*",
        "known_devices": [
          "sonoff zigbee dongle plus"
        ]
      },
      {
        "vid": "10C4",
        "pid": "EA60",
        "description": "*tubeszb*",
        "known_devices": [
          "TubesZB Coordinator"
        ]
      },
      {
        "vid": "1A86",
        "pid": "7523",
        "description": "*tubeszb*",
        "known_devices": [
          "TubesZB Coordinator"
        ]
      },
      {
        "vid": "1A86",
        "pid": "7523",
        "description": "*zigstar*",
        "known_devices": [
          "ZigStar Coordinators"
        ]
      },
      {
        "vid": "1CF1",
        "pid": "0030",
        "description": "*conbee*",
        "known_devices": [
          "Conbee II"
        ]
      },
      {
        "vid": "0403",
        "pid": "6015",
        "description": "*conbee*",
        "known_devices": [
          "Conbee III"
        ]
      },
      {
        "vid": "10C4",
        "pid": "8A2A",
        "description": "*zigbee*",
        "known_devices": [
          "Nortek HUSBZB-1"
        ]
      },
      {
        "vid": "0403",
        "pid": "6015",
        "description": "*zigate*",
        "known_devices": [
          "ZiGate+"
        ]
      },
      {
        "vid": "10C4",
        "pid": "EA60",
        "description": "*zigate*",
        "known_devices": [
          "ZiGate"
        ]
      },
      {
        "vid": "10C4",
        "pid": "8B34",
        "description": "*bv 2010/10*",
        "known_devices": [
          "Bitron Video AV2010/10"
        ]
      }
    ],
    "zeroconf": [
      {
        "type": "_esphomelib._tcp.local.",
        "name": "tube*"
      },
      {
        "type": "_zigate-zigbee-gateway._tcp.local.",
        "name": "*zigate*"
      },
      {
        "type": "_zigstar_gw._tcp.local.",
        "name": "*zigstar*"
      },
      {
        "type": "_uzg-01._tcp.local.",
        "name": "uzg-01*"
      },
      {
        "type": "_slzb-06._tcp.local.",
        "name": "slzb-06*"
      }
    ],
    "is_built_in": true
  },
  "data": {
    "ieee": "**REDACTED**",
    "nwk": 64897,
    "manufacturer": "Visonic",
    "model": "MCT-340 SMA",
    "name": "Visonic MCT-340 SMA",
    "quirk_applied": false,
    "quirk_class": "zigpy.device.Device",
    "quirk_id": null,
    "manufacturer_code": 4113,
    "power_source": "Battery or Unknown",
    "lqi": 164,
    "rssi": -59,
    "last_seen": "2023-12-23T21:02:46",
    "available": true,
    "device_type": "EndDevice",
    "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.AllocateAddress: 128>, manufacturer_code=4113, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=0, maximum_outgoing_transfer_size=82, 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": "0x0104",
          "device_type": "0x0402",
          "input_clusters": [
            "0x0000",
            "0x0001",
            "0x0003",
            "0x0020",
            "0x0402",
            "0x0500",
            "0x0b05"
          ],
          "output_clusters": [
            "0x0019"
          ]
        }
      },
      "manufacturer": "Visonic",
      "model": "MCT-340 SMA"
    },
    "active_coordinator": false,
    "entities": [
      {
        "entity_id": "sensor.front_door_battery",
        "name": "Visonic MCT-340 SMA"
      },
      {
        "entity_id": "button.front_door_identify",
        "name": "Visonic MCT-340 SMA"
      },
      {
        "entity_id": "binary_sensor.front_door_opening",
        "name": "Visonic MCT-340 SMA"
      },
      {
        "entity_id": "sensor.front_door_temperature",
        "name": "Visonic MCT-340 SMA"
      }
    ],
    "neighbors": [],
    "routes": [],
    "endpoint_names": [
      {
        "name": "IAS_ZONE"
      }
    ],
    "user_given_name": "Front Door",
    "device_reg_id": "646abcb38799a03b00616f5d8e1fbc3f",
    "area_id": null,
    "cluster_details": {
      "1": {
        "device_type": {
          "name": "IAS_ZONE",
          "id": 1026
        },
        "profile_id": 260,
        "in_clusters": {
          "0x0000": {
            "endpoint_attribute": "basic",
            "attributes": {
              "0x0004": {
                "attribute_name": "manufacturer",
                "value": "Visonic"
              },
              "0x0005": {
                "attribute_name": "model",
                "value": "MCT-340 SMA"
              }
            },
            "unsupported_attributes": {}
          },
          "0x0001": {
            "endpoint_attribute": "power",
            "attributes": {
              "0x0033": {
                "attribute_name": "battery_quantity",
                "value": 1
              },
              "0x0031": {
                "attribute_name": "battery_size",
                "value": 2
              },
              "0x0020": {
                "attribute_name": "battery_voltage",
                "value": 28
              }
            },
            "unsupported_attributes": {
              "0x0021": {
                "attribute_name": "battery_percentage_remaining"
              }
            }
          },
          "0x0003": {
            "endpoint_attribute": "identify",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0x0402": {
            "endpoint_attribute": "temperature",
            "attributes": {
              "0x0000": {
                "attribute_name": "measured_value",
                "value": 2200
              }
            },
            "unsupported_attributes": {}
          },
          "0x0500": {
            "endpoint_attribute": "ias_zone",
            "attributes": {
              "0x0010": {
                "attribute_name": "cie_addr",
                "value": [
                  110,
                  210,
                  211,
                  254,
                  255,
                  141,
                  121,
                  224
                ]
              },
              "0x0000": {
                "attribute_name": "zone_state",
                "value": 1
              },
              "0x0002": {
                "attribute_name": "zone_status",
                "value": 32
              },
              "0x0001": {
                "attribute_name": "zone_type",
                "value": 21
              }
            },
            "unsupported_attributes": {}
          },
          "0x0020": {
            "endpoint_attribute": "poll_control",
            "attributes": {
              "0x0000": {
                "attribute_name": "checkin_interval",
                "value": 13200
              }
            },
            "unsupported_attributes": {}
          },
          "0x0b05": {
            "endpoint_attribute": "diagnostic",
            "attributes": {},
            "unsupported_attributes": {}
          }
        },
        "out_clusters": {
          "0x0019": {
            "endpoint_attribute": "ota",
            "attributes": {},
            "unsupported_attributes": {}
          }
        }
      }
    }
  }
}
```

</details>


### Logs

_No response_

### Custom quirk

_No response_

### Additional information

_No response_


Discussion:
Looks like the issue was it simply not applying the quirk, signature didn't match because MODELS_INFO model name was different. Simply changing E to SMA in the model name fixed it and battery reports now. It is the same implementation as the E model.

I am very new to HomeAssistant and ZHA but I'll make a pull request and just rename mct340e to mct340x since I think that's the convention I saw instead of a new file.

Resolving patch:
diff --git a/zhaquirks/visonic/mct340e.py b/zhaquirks/visonic/mct340.py
old mode 100755
new mode 100644
similarity index 92%
rename from zhaquirks/visonic/mct340e.py
rename to zhaquirks/visonic/mct340.py
--- a/zhaquirks/visonic/mct340e.py
+++ b/zhaquirks/visonic/mct340.py
@@ -1,4 +1,4 @@
-"""Visonic MCT340E device."""
+"""Visonic MCT340 device."""
 
 from zigpy.profiles import zha
 from zigpy.quirks import CustomDevice
@@ -28,15 +28,15 @@ class CustomPowerConfigurationCluster(PowerConfigurationCluster):
     MAX_VOLTS = 3.0
 
 
-class MCT340E(CustomDevice):
-    """Visonic MCT340E device."""
+class MCT340(CustomDevice):
+    """Visonic MCT340 device."""
 
     signature = {
         #  <SimpleDescriptor endpoint=1 profile=260 device_type=1026
         # device_version=0
         # input_clusters=[0, 1, 3, 1026, 1280, 32, 2821]
         # output_clusters=[25]>
-        MODELS_INFO: [("Visonic", "MCT-340 E")],
+        MODELS_INFO: [("Visonic", "MCT-340 E"), ("Visonic", "MCT-340 SMA")],
         ENDPOINTS: {
             1: {
                 PROFILE_ID: zha.PROFILE_ID,


Test patch: