Advertisement
Guest User

Zemismart_ZTB25.py

a guest
Sep 12th, 2022
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.07 KB | Software | 0 0
  1. import asyncio
  2. import logging
  3.  
  4. from zigpy.profiles import zha
  5. from zigpy.device import Device
  6. import zigpy.types as t
  7. from zigpy.quirks import CustomCluster
  8.  
  9. from zigpy.zcl.clusters.general import (
  10.     Basic,
  11.     GreenPowerProxy,
  12.     Groups,
  13.     Identify,
  14.     OnOff,
  15.     Ota,
  16.     Scenes,
  17.     Time,
  18. )
  19.  
  20. from zhaquirks.const import (
  21.     DEVICE_TYPE,
  22.     ENDPOINTS,
  23.     INPUT_CLUSTERS,
  24. #    MODEL,
  25.     OUTPUT_CLUSTERS,
  26.     PROFILE_ID,
  27.     MODELS_INFO,
  28. )
  29. from zhaquirks.tuya import (
  30.     TuyaZBE000Cluster,
  31.     TuyaZBExternalSwitchTypeCluster,
  32.     TuyaZBOnOffAttributeCluster,
  33.     TuyaOnOff
  34. )
  35. from zhaquirks.tuya.ts000x import Switch_3G_GPP
  36.  
  37. _LOGGER = logging.getLogger(__name__)
  38.  
  39. async def cast_tuya_magic_spell_task(
  40.     dev: Device, tries: int = 100, rejoin: bool = False
  41. ) -> None:
  42.     """Initialize device so that all endpoints become available."""
  43.     import inspect
  44.  
  45.     basic_cluster = dev.endpoints[1].in_clusters[0]
  46.  
  47.     # The magic spell is needed only once.
  48.     # TODO: Improve by doing this only once (successfully).
  49.  
  50.     # Magic spell - part 1
  51.     # Note: attribute order is important
  52.     attr_to_read = [
  53.         "manufacturer",
  54.         "zcl_version",
  55.         "app_version",
  56.         "model",
  57.         "power_source",
  58.         0xFFFE,
  59.     ]
  60.     if "tries" in inspect.getfullargspec(basic_cluster.read_attributes)[0]:
  61.         _LOGGER.debug(f"Cast Tuya Magic Spell on {dev.ieee!r} with {tries} tries")
  62.         res = await basic_cluster.read_attributes(attr_to_read, tries=tries)
  63.     else:
  64.         _LOGGER.debug(f"Cast Tuya Magic Spell on {dev.ieee!r}")
  65.         res = await basic_cluster.read_attributes(attr_to_read)
  66.  
  67.     _LOGGER.debug(f"Tuya Magic Spell result {res!r} for {dev.ieee!r}")
  68.  
  69.     # Magic spell - part 2 (skipped - does not seem to be needed)
  70.     # attr_to_write={0xffde:13}
  71.     # basic_cluster.write_attributes(attr_to_write)
  72.  
  73.     if rejoin:
  74.         # Leave with rejoin - may need to be adjuste to work everywhere
  75.         # or require a minimum zigpy version
  76.         # This should have the device leave and rejoin immediately triggering
  77.         # the discovery of the endpoints that appear after the magic trick
  78.  
  79.         # Note: this is not validated yet and disabled by default
  80.         _LOGGER.debug(f"Send leave with rejoin request to {dev.ieee!r}")
  81.         res = await dev.zdo.request(0x0034, dev.ieee, 0x01, tries)
  82.         _LOGGER.debug(f"Leave with rejoin result {res!r} for {dev.ieee!r}")
  83.  
  84.         app = dev.application
  85.         # Delete the device from the database
  86.         app.listener_event("device_removed", dev)
  87.  
  88.         # Delete the device from zigpy
  89.         app.devices.pop(dev.ieee, None)
  90.  
  91.  
  92. def cast_tuya_magic_spell(dev: Device, tries: int = 3) -> None:
  93.     """Set up the magic spell asynchronously."""
  94.  
  95.     # Note for sleepy devices the number of tries may need to be increased to 100.
  96.  
  97.     dev._magic_spell_task = asyncio.create_task(
  98.         cast_tuya_magic_spell_task(dev, tries=tries)
  99.     )
  100.  
  101.  
  102. class TuyaBasicCluster(CustomCluster, Basic):
  103.     """Provide Tuya Basic Cluster with magic spell."""
  104.  
  105.     attributes = Basic.attributes.copy()
  106.     attributes.update(
  107.         {
  108.             0xFFDE: ("tuya_FFDE", t.uint8_t, True),
  109.             # 0xffe0: ("tuya_FFE0", TODO.Array, True),
  110.             # 0xffe1: ("tuya_FFE1", TODO.Array, True),
  111.             0xFFE2: ("tuya_FFE2", t.uint8_t, True),
  112.             # 0xffe3: ("tuya_FFE3", TODO.Array, True),
  113.         }
  114.     )
  115.  
  116.     async def bind(self):
  117.         """Bind cluster."""
  118.  
  119.         _LOGGER.debug(
  120.             f"Requesting Tuya Magic Spell for {self.ieee!r} in basic bind method"
  121.         )
  122.         tries = 3
  123.         await asyncio.create_task(cast_tuya_magic_spell_task(self, tries=tries))
  124.  
  125.         return await super().bind()
  126.  
  127. class Switch_3G_Zemismart_ZTB25(Switch_3G_GPP):
  128.  
  129.     def __init__(self, *args, **kwargs):
  130.         self.signature[MODELS_INFO] = [("_TZ3000_vjhcenzo", "TS0003")]
  131.         self.replacement[ENDPOINTS][3][DEVICE_TYPE] = zha.DeviceType.ON_OFF_PLUG_IN_UNIT
  132.         super().__init__(*args, **kwargs)
  133.         cast_tuya_magic_spell(self, tries=3)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement